blob: 22c56c9e155e2ffd7cef37f99fb58626b6f92d54 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * FIPS-197 compliant AES implementation
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Paul Bakker5121ce52009-01-03 21:22:43 +000018 */
19/*
20 * The AES block cipher was designed by Vincent Rijmen and Joan Daemen.
21 *
22 * http://csrc.nist.gov/encryption/aes/rijndael/Rijndael.pdf
23 * http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
24 */
25
Gilles Peskinedb09ef62020-06-03 01:43:33 +020026#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000027
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020028#if defined(MBEDTLS_AES_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000029
Rich Evans00ab4702015-02-06 13:43:58 +000030#include <string.h>
31
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000032#include "mbedtls/aes.h"
Ron Eldor9924bdc2018-10-04 10:59:13 +030033#include "mbedtls/platform.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050034#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000035#include "mbedtls/error.h"
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020036#if defined(MBEDTLS_PADLOCK_C)
Chris Jones16dbaeb2021-03-09 17:47:55 +000037#include "padlock.h"
Paul Bakker67820bd2012-06-04 12:47:23 +000038#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020039#if defined(MBEDTLS_AESNI_C)
Chris Jones187782f2021-03-09 17:28:35 +000040#include "aesni.h"
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +010041#endif
Jerry Yu3f2fb712023-01-10 17:05:42 +080042#if defined(MBEDTLS_AESCE_C)
43#include "aesce.h"
44#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000045
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000046#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010047
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020048#if !defined(MBEDTLS_AES_ALT)
Paul Bakker90995b52013-06-24 19:20:35 +020049
Gilles Peskine0f454e42023-03-16 14:58:46 +010050#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Paul Bakker048d04e2012-02-12 17:31:04 +000051static int aes_padlock_ace = -1;
52#endif
53
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020054#if defined(MBEDTLS_AES_ROM_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +000055/*
56 * Forward S-box
57 */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +010058#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +000059static const unsigned char FSb[256] =
60{
61 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
62 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
63 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
64 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
65 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
66 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
67 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
68 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
69 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
70 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
71 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
72 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
73 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
74 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
75 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
76 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
77 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
78 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
79 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
80 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
81 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
82 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
83 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
84 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
85 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
86 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
87 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
88 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
89 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
90 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
91 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
92 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
93};
Dave Rodgmanad4e76b2023-06-27 19:20:27 +010094#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +000095
96/*
97 * Forward tables
98 */
99#define FT \
100\
Gilles Peskine449bd832023-01-11 14:50:10 +0100101 V(A5, 63, 63, C6), V(84, 7C, 7C, F8), V(99, 77, 77, EE), V(8D, 7B, 7B, F6), \
102 V(0D, F2, F2, FF), V(BD, 6B, 6B, D6), V(B1, 6F, 6F, DE), V(54, C5, C5, 91), \
103 V(50, 30, 30, 60), V(03, 01, 01, 02), V(A9, 67, 67, CE), V(7D, 2B, 2B, 56), \
104 V(19, FE, FE, E7), V(62, D7, D7, B5), V(E6, AB, AB, 4D), V(9A, 76, 76, EC), \
105 V(45, CA, CA, 8F), V(9D, 82, 82, 1F), V(40, C9, C9, 89), V(87, 7D, 7D, FA), \
106 V(15, FA, FA, EF), V(EB, 59, 59, B2), V(C9, 47, 47, 8E), V(0B, F0, F0, FB), \
107 V(EC, AD, AD, 41), V(67, D4, D4, B3), V(FD, A2, A2, 5F), V(EA, AF, AF, 45), \
108 V(BF, 9C, 9C, 23), V(F7, A4, A4, 53), V(96, 72, 72, E4), V(5B, C0, C0, 9B), \
109 V(C2, B7, B7, 75), V(1C, FD, FD, E1), V(AE, 93, 93, 3D), V(6A, 26, 26, 4C), \
110 V(5A, 36, 36, 6C), V(41, 3F, 3F, 7E), V(02, F7, F7, F5), V(4F, CC, CC, 83), \
111 V(5C, 34, 34, 68), V(F4, A5, A5, 51), V(34, E5, E5, D1), V(08, F1, F1, F9), \
112 V(93, 71, 71, E2), V(73, D8, D8, AB), V(53, 31, 31, 62), V(3F, 15, 15, 2A), \
113 V(0C, 04, 04, 08), V(52, C7, C7, 95), V(65, 23, 23, 46), V(5E, C3, C3, 9D), \
114 V(28, 18, 18, 30), V(A1, 96, 96, 37), V(0F, 05, 05, 0A), V(B5, 9A, 9A, 2F), \
115 V(09, 07, 07, 0E), V(36, 12, 12, 24), V(9B, 80, 80, 1B), V(3D, E2, E2, DF), \
116 V(26, EB, EB, CD), V(69, 27, 27, 4E), V(CD, B2, B2, 7F), V(9F, 75, 75, EA), \
117 V(1B, 09, 09, 12), V(9E, 83, 83, 1D), V(74, 2C, 2C, 58), V(2E, 1A, 1A, 34), \
118 V(2D, 1B, 1B, 36), V(B2, 6E, 6E, DC), V(EE, 5A, 5A, B4), V(FB, A0, A0, 5B), \
119 V(F6, 52, 52, A4), V(4D, 3B, 3B, 76), V(61, D6, D6, B7), V(CE, B3, B3, 7D), \
120 V(7B, 29, 29, 52), V(3E, E3, E3, DD), V(71, 2F, 2F, 5E), V(97, 84, 84, 13), \
121 V(F5, 53, 53, A6), V(68, D1, D1, B9), V(00, 00, 00, 00), V(2C, ED, ED, C1), \
122 V(60, 20, 20, 40), V(1F, FC, FC, E3), V(C8, B1, B1, 79), V(ED, 5B, 5B, B6), \
123 V(BE, 6A, 6A, D4), V(46, CB, CB, 8D), V(D9, BE, BE, 67), V(4B, 39, 39, 72), \
124 V(DE, 4A, 4A, 94), V(D4, 4C, 4C, 98), V(E8, 58, 58, B0), V(4A, CF, CF, 85), \
125 V(6B, D0, D0, BB), V(2A, EF, EF, C5), V(E5, AA, AA, 4F), V(16, FB, FB, ED), \
126 V(C5, 43, 43, 86), V(D7, 4D, 4D, 9A), V(55, 33, 33, 66), V(94, 85, 85, 11), \
127 V(CF, 45, 45, 8A), V(10, F9, F9, E9), V(06, 02, 02, 04), V(81, 7F, 7F, FE), \
128 V(F0, 50, 50, A0), V(44, 3C, 3C, 78), V(BA, 9F, 9F, 25), V(E3, A8, A8, 4B), \
129 V(F3, 51, 51, A2), V(FE, A3, A3, 5D), V(C0, 40, 40, 80), V(8A, 8F, 8F, 05), \
130 V(AD, 92, 92, 3F), V(BC, 9D, 9D, 21), V(48, 38, 38, 70), V(04, F5, F5, F1), \
131 V(DF, BC, BC, 63), V(C1, B6, B6, 77), V(75, DA, DA, AF), V(63, 21, 21, 42), \
132 V(30, 10, 10, 20), V(1A, FF, FF, E5), V(0E, F3, F3, FD), V(6D, D2, D2, BF), \
133 V(4C, CD, CD, 81), V(14, 0C, 0C, 18), V(35, 13, 13, 26), V(2F, EC, EC, C3), \
134 V(E1, 5F, 5F, BE), V(A2, 97, 97, 35), V(CC, 44, 44, 88), V(39, 17, 17, 2E), \
135 V(57, C4, C4, 93), V(F2, A7, A7, 55), V(82, 7E, 7E, FC), V(47, 3D, 3D, 7A), \
136 V(AC, 64, 64, C8), V(E7, 5D, 5D, BA), V(2B, 19, 19, 32), V(95, 73, 73, E6), \
137 V(A0, 60, 60, C0), V(98, 81, 81, 19), V(D1, 4F, 4F, 9E), V(7F, DC, DC, A3), \
138 V(66, 22, 22, 44), V(7E, 2A, 2A, 54), V(AB, 90, 90, 3B), V(83, 88, 88, 0B), \
139 V(CA, 46, 46, 8C), V(29, EE, EE, C7), V(D3, B8, B8, 6B), V(3C, 14, 14, 28), \
140 V(79, DE, DE, A7), V(E2, 5E, 5E, BC), V(1D, 0B, 0B, 16), V(76, DB, DB, AD), \
141 V(3B, E0, E0, DB), V(56, 32, 32, 64), V(4E, 3A, 3A, 74), V(1E, 0A, 0A, 14), \
142 V(DB, 49, 49, 92), V(0A, 06, 06, 0C), V(6C, 24, 24, 48), V(E4, 5C, 5C, B8), \
143 V(5D, C2, C2, 9F), V(6E, D3, D3, BD), V(EF, AC, AC, 43), V(A6, 62, 62, C4), \
144 V(A8, 91, 91, 39), V(A4, 95, 95, 31), V(37, E4, E4, D3), V(8B, 79, 79, F2), \
145 V(32, E7, E7, D5), V(43, C8, C8, 8B), V(59, 37, 37, 6E), V(B7, 6D, 6D, DA), \
146 V(8C, 8D, 8D, 01), V(64, D5, D5, B1), V(D2, 4E, 4E, 9C), V(E0, A9, A9, 49), \
147 V(B4, 6C, 6C, D8), V(FA, 56, 56, AC), V(07, F4, F4, F3), V(25, EA, EA, CF), \
148 V(AF, 65, 65, CA), V(8E, 7A, 7A, F4), V(E9, AE, AE, 47), V(18, 08, 08, 10), \
149 V(D5, BA, BA, 6F), V(88, 78, 78, F0), V(6F, 25, 25, 4A), V(72, 2E, 2E, 5C), \
150 V(24, 1C, 1C, 38), V(F1, A6, A6, 57), V(C7, B4, B4, 73), V(51, C6, C6, 97), \
151 V(23, E8, E8, CB), V(7C, DD, DD, A1), V(9C, 74, 74, E8), V(21, 1F, 1F, 3E), \
152 V(DD, 4B, 4B, 96), V(DC, BD, BD, 61), V(86, 8B, 8B, 0D), V(85, 8A, 8A, 0F), \
153 V(90, 70, 70, E0), V(42, 3E, 3E, 7C), V(C4, B5, B5, 71), V(AA, 66, 66, CC), \
154 V(D8, 48, 48, 90), V(05, 03, 03, 06), V(01, F6, F6, F7), V(12, 0E, 0E, 1C), \
155 V(A3, 61, 61, C2), V(5F, 35, 35, 6A), V(F9, 57, 57, AE), V(D0, B9, B9, 69), \
156 V(91, 86, 86, 17), V(58, C1, C1, 99), V(27, 1D, 1D, 3A), V(B9, 9E, 9E, 27), \
157 V(38, E1, E1, D9), V(13, F8, F8, EB), V(B3, 98, 98, 2B), V(33, 11, 11, 22), \
158 V(BB, 69, 69, D2), V(70, D9, D9, A9), V(89, 8E, 8E, 07), V(A7, 94, 94, 33), \
159 V(B6, 9B, 9B, 2D), V(22, 1E, 1E, 3C), V(92, 87, 87, 15), V(20, E9, E9, C9), \
160 V(49, CE, CE, 87), V(FF, 55, 55, AA), V(78, 28, 28, 50), V(7A, DF, DF, A5), \
161 V(8F, 8C, 8C, 03), V(F8, A1, A1, 59), V(80, 89, 89, 09), V(17, 0D, 0D, 1A), \
162 V(DA, BF, BF, 65), V(31, E6, E6, D7), V(C6, 42, 42, 84), V(B8, 68, 68, D0), \
163 V(C3, 41, 41, 82), V(B0, 99, 99, 29), V(77, 2D, 2D, 5A), V(11, 0F, 0F, 1E), \
164 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 +0000165
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100166#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100167#define V(a, b, c, d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000168static const uint32_t FT0[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000169#undef V
170
Hanno Beckerad049a92017-06-19 16:31:54 +0100171#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200172
Gilles Peskine449bd832023-01-11 14:50:10 +0100173#define V(a, b, c, d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000174static const uint32_t FT1[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000175#undef V
176
Gilles Peskine449bd832023-01-11 14:50:10 +0100177#define V(a, b, c, d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000178static const uint32_t FT2[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000179#undef V
180
Gilles Peskine449bd832023-01-11 14:50:10 +0100181#define V(a, b, c, d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000182static const uint32_t FT3[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000183#undef V
184
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100185#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) */
186
Hanno Becker177d3cf2017-06-07 15:52:48 +0100187#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200188
Paul Bakker5121ce52009-01-03 21:22:43 +0000189#undef FT
190
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100191#if !defined(MBEDTLS_AES_DECRYPT_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000192/*
193 * Reverse S-box
194 */
195static const unsigned char RSb[256] =
196{
197 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
198 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
199 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
200 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
201 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
202 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
203 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
204 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
205 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
206 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
207 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
208 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
209 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
210 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
211 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
212 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
213 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
214 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
215 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
216 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
217 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
218 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
219 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
220 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
221 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
222 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
223 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
224 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
225 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
226 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
227 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
228 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
229};
Dave Rodgman15cd28a2023-06-27 18:27:31 +0100230#endif /* !(defined(MBEDTLS_AES_SETKEY_ENC_ALT) && defined(MBEDTLS_AES_DECRYPT_ALT)) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000231
232/*
233 * Reverse tables
234 */
235#define RT \
236\
Gilles Peskine449bd832023-01-11 14:50:10 +0100237 V(50, A7, F4, 51), V(53, 65, 41, 7E), V(C3, A4, 17, 1A), V(96, 5E, 27, 3A), \
238 V(CB, 6B, AB, 3B), V(F1, 45, 9D, 1F), V(AB, 58, FA, AC), V(93, 03, E3, 4B), \
239 V(55, FA, 30, 20), V(F6, 6D, 76, AD), V(91, 76, CC, 88), V(25, 4C, 02, F5), \
240 V(FC, D7, E5, 4F), V(D7, CB, 2A, C5), V(80, 44, 35, 26), V(8F, A3, 62, B5), \
241 V(49, 5A, B1, DE), V(67, 1B, BA, 25), V(98, 0E, EA, 45), V(E1, C0, FE, 5D), \
242 V(02, 75, 2F, C3), V(12, F0, 4C, 81), V(A3, 97, 46, 8D), V(C6, F9, D3, 6B), \
243 V(E7, 5F, 8F, 03), V(95, 9C, 92, 15), V(EB, 7A, 6D, BF), V(DA, 59, 52, 95), \
244 V(2D, 83, BE, D4), V(D3, 21, 74, 58), V(29, 69, E0, 49), V(44, C8, C9, 8E), \
245 V(6A, 89, C2, 75), V(78, 79, 8E, F4), V(6B, 3E, 58, 99), V(DD, 71, B9, 27), \
246 V(B6, 4F, E1, BE), V(17, AD, 88, F0), V(66, AC, 20, C9), V(B4, 3A, CE, 7D), \
247 V(18, 4A, DF, 63), V(82, 31, 1A, E5), V(60, 33, 51, 97), V(45, 7F, 53, 62), \
248 V(E0, 77, 64, B1), V(84, AE, 6B, BB), V(1C, A0, 81, FE), V(94, 2B, 08, F9), \
249 V(58, 68, 48, 70), V(19, FD, 45, 8F), V(87, 6C, DE, 94), V(B7, F8, 7B, 52), \
250 V(23, D3, 73, AB), V(E2, 02, 4B, 72), V(57, 8F, 1F, E3), V(2A, AB, 55, 66), \
251 V(07, 28, EB, B2), V(03, C2, B5, 2F), V(9A, 7B, C5, 86), V(A5, 08, 37, D3), \
252 V(F2, 87, 28, 30), V(B2, A5, BF, 23), V(BA, 6A, 03, 02), V(5C, 82, 16, ED), \
253 V(2B, 1C, CF, 8A), V(92, B4, 79, A7), V(F0, F2, 07, F3), V(A1, E2, 69, 4E), \
254 V(CD, F4, DA, 65), V(D5, BE, 05, 06), V(1F, 62, 34, D1), V(8A, FE, A6, C4), \
255 V(9D, 53, 2E, 34), V(A0, 55, F3, A2), V(32, E1, 8A, 05), V(75, EB, F6, A4), \
256 V(39, EC, 83, 0B), V(AA, EF, 60, 40), V(06, 9F, 71, 5E), V(51, 10, 6E, BD), \
257 V(F9, 8A, 21, 3E), V(3D, 06, DD, 96), V(AE, 05, 3E, DD), V(46, BD, E6, 4D), \
258 V(B5, 8D, 54, 91), V(05, 5D, C4, 71), V(6F, D4, 06, 04), V(FF, 15, 50, 60), \
259 V(24, FB, 98, 19), V(97, E9, BD, D6), V(CC, 43, 40, 89), V(77, 9E, D9, 67), \
260 V(BD, 42, E8, B0), V(88, 8B, 89, 07), V(38, 5B, 19, E7), V(DB, EE, C8, 79), \
261 V(47, 0A, 7C, A1), V(E9, 0F, 42, 7C), V(C9, 1E, 84, F8), V(00, 00, 00, 00), \
262 V(83, 86, 80, 09), V(48, ED, 2B, 32), V(AC, 70, 11, 1E), V(4E, 72, 5A, 6C), \
263 V(FB, FF, 0E, FD), V(56, 38, 85, 0F), V(1E, D5, AE, 3D), V(27, 39, 2D, 36), \
264 V(64, D9, 0F, 0A), V(21, A6, 5C, 68), V(D1, 54, 5B, 9B), V(3A, 2E, 36, 24), \
265 V(B1, 67, 0A, 0C), V(0F, E7, 57, 93), V(D2, 96, EE, B4), V(9E, 91, 9B, 1B), \
266 V(4F, C5, C0, 80), V(A2, 20, DC, 61), V(69, 4B, 77, 5A), V(16, 1A, 12, 1C), \
267 V(0A, BA, 93, E2), V(E5, 2A, A0, C0), V(43, E0, 22, 3C), V(1D, 17, 1B, 12), \
268 V(0B, 0D, 09, 0E), V(AD, C7, 8B, F2), V(B9, A8, B6, 2D), V(C8, A9, 1E, 14), \
269 V(85, 19, F1, 57), V(4C, 07, 75, AF), V(BB, DD, 99, EE), V(FD, 60, 7F, A3), \
270 V(9F, 26, 01, F7), V(BC, F5, 72, 5C), V(C5, 3B, 66, 44), V(34, 7E, FB, 5B), \
271 V(76, 29, 43, 8B), V(DC, C6, 23, CB), V(68, FC, ED, B6), V(63, F1, E4, B8), \
272 V(CA, DC, 31, D7), V(10, 85, 63, 42), V(40, 22, 97, 13), V(20, 11, C6, 84), \
273 V(7D, 24, 4A, 85), V(F8, 3D, BB, D2), V(11, 32, F9, AE), V(6D, A1, 29, C7), \
274 V(4B, 2F, 9E, 1D), V(F3, 30, B2, DC), V(EC, 52, 86, 0D), V(D0, E3, C1, 77), \
275 V(6C, 16, B3, 2B), V(99, B9, 70, A9), V(FA, 48, 94, 11), V(22, 64, E9, 47), \
276 V(C4, 8C, FC, A8), V(1A, 3F, F0, A0), V(D8, 2C, 7D, 56), V(EF, 90, 33, 22), \
277 V(C7, 4E, 49, 87), V(C1, D1, 38, D9), V(FE, A2, CA, 8C), V(36, 0B, D4, 98), \
278 V(CF, 81, F5, A6), V(28, DE, 7A, A5), V(26, 8E, B7, DA), V(A4, BF, AD, 3F), \
279 V(E4, 9D, 3A, 2C), V(0D, 92, 78, 50), V(9B, CC, 5F, 6A), V(62, 46, 7E, 54), \
280 V(C2, 13, 8D, F6), V(E8, B8, D8, 90), V(5E, F7, 39, 2E), V(F5, AF, C3, 82), \
281 V(BE, 80, 5D, 9F), V(7C, 93, D0, 69), V(A9, 2D, D5, 6F), V(B3, 12, 25, CF), \
282 V(3B, 99, AC, C8), V(A7, 7D, 18, 10), V(6E, 63, 9C, E8), V(7B, BB, 3B, DB), \
283 V(09, 78, 26, CD), V(F4, 18, 59, 6E), V(01, B7, 9A, EC), V(A8, 9A, 4F, 83), \
284 V(65, 6E, 95, E6), V(7E, E6, FF, AA), V(08, CF, BC, 21), V(E6, E8, 15, EF), \
285 V(D9, 9B, E7, BA), V(CE, 36, 6F, 4A), V(D4, 09, 9F, EA), V(D6, 7C, B0, 29), \
286 V(AF, B2, A4, 31), V(31, 23, 3F, 2A), V(30, 94, A5, C6), V(C0, 66, A2, 35), \
287 V(37, BC, 4E, 74), V(A6, CA, 82, FC), V(B0, D0, 90, E0), V(15, D8, A7, 33), \
288 V(4A, 98, 04, F1), V(F7, DA, EC, 41), V(0E, 50, CD, 7F), V(2F, F6, 91, 17), \
289 V(8D, D6, 4D, 76), V(4D, B0, EF, 43), V(54, 4D, AA, CC), V(DF, 04, 96, E4), \
290 V(E3, B5, D1, 9E), V(1B, 88, 6A, 4C), V(B8, 1F, 2C, C1), V(7F, 51, 65, 46), \
291 V(04, EA, 5E, 9D), V(5D, 35, 8C, 01), V(73, 74, 87, FA), V(2E, 41, 0B, FB), \
292 V(5A, 1D, 67, B3), V(52, D2, DB, 92), V(33, 56, 10, E9), V(13, 47, D6, 6D), \
293 V(8C, 61, D7, 9A), V(7A, 0C, A1, 37), V(8E, 14, F8, 59), V(89, 3C, 13, EB), \
294 V(EE, 27, A9, CE), V(35, C9, 61, B7), V(ED, E5, 1C, E1), V(3C, B1, 47, 7A), \
295 V(59, DF, D2, 9C), V(3F, 73, F2, 55), V(79, CE, 14, 18), V(BF, 37, C7, 73), \
296 V(EA, CD, F7, 53), V(5B, AA, FD, 5F), V(14, 6F, 3D, DF), V(86, DB, 44, 78), \
297 V(81, F3, AF, CA), V(3E, C4, 68, B9), V(2C, 34, 24, 38), V(5F, 40, A3, C2), \
298 V(72, C3, 1D, 16), V(0C, 25, E2, BC), V(8B, 49, 3C, 28), V(41, 95, 0D, FF), \
299 V(71, 01, A8, 39), V(DE, B3, 0C, 08), V(9C, E4, B4, D8), V(90, C1, 56, 64), \
300 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 +0000301
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100302#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
303
Gilles Peskine449bd832023-01-11 14:50:10 +0100304#define V(a, b, c, d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000305static const uint32_t RT0[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000306#undef V
307
Hanno Beckerad049a92017-06-19 16:31:54 +0100308#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200309
Gilles Peskine449bd832023-01-11 14:50:10 +0100310#define V(a, b, c, d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000311static const uint32_t RT1[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000312#undef V
313
Gilles Peskine449bd832023-01-11 14:50:10 +0100314#define V(a, b, c, d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000315static const uint32_t RT2[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000316#undef V
317
Gilles Peskine449bd832023-01-11 14:50:10 +0100318#define V(a, b, c, d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000319static const uint32_t RT3[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000320#undef V
321
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100322#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC) */
323
Hanno Becker177d3cf2017-06-07 15:52:48 +0100324#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200325
Paul Bakker5121ce52009-01-03 21:22:43 +0000326#undef RT
327
Dave Rodgman34152a42023-06-27 18:31:24 +0100328#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000329/*
330 * Round constants
331 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000332static const uint32_t RCON[10] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000333{
334 0x00000001, 0x00000002, 0x00000004, 0x00000008,
335 0x00000010, 0x00000020, 0x00000040, 0x00000080,
336 0x0000001B, 0x00000036
337};
Dave Rodgman34152a42023-06-27 18:31:24 +0100338#endif /* !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000339
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200340#else /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000341
342/*
343 * Forward S-box & tables
344 */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100345#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000346static unsigned char FSb[256];
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100347#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
348#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker9af723c2014-05-01 13:03:14 +0200349static uint32_t FT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100350#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker9af723c2014-05-01 13:03:14 +0200351static uint32_t FT1[256];
352static uint32_t FT2[256];
353static uint32_t FT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100354#endif /* !MBEDTLS_AES_FEWER_TABLES */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100355#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000356
357/*
358 * Reverse S-box & tables
359 */
Dave Rodgman15cd28a2023-06-27 18:27:31 +0100360#if !(defined(MBEDTLS_AES_SETKEY_ENC_ALT) && defined(MBEDTLS_AES_DECRYPT_ALT))
Paul Bakker5121ce52009-01-03 21:22:43 +0000361static unsigned char RSb[256];
Dave Rodgman15cd28a2023-06-27 18:27:31 +0100362#endif
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100363
364#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Paul Bakker5c2364c2012-10-01 14:41:15 +0000365static uint32_t RT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100366#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker5c2364c2012-10-01 14:41:15 +0000367static uint32_t RT1[256];
368static uint32_t RT2[256];
369static uint32_t RT3[256];
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100370#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Hanno Becker177d3cf2017-06-07 15:52:48 +0100371#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000372
Dave Rodgman8c753f92023-06-27 18:16:13 +0100373#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000374/*
375 * Round constants
376 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000377static uint32_t RCON[10];
Paul Bakker5121ce52009-01-03 21:22:43 +0000378
379/*
380 * Tables generation code
381 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100382#define ROTL8(x) (((x) << 8) & 0xFFFFFFFF) | ((x) >> 24)
383#define XTIME(x) (((x) << 1) ^ (((x) & 0x80) ? 0x1B : 0x00))
384#define MUL(x, y) (((x) && (y)) ? pow[(log[(x)]+log[(y)]) % 255] : 0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000385
386static int aes_init_done = 0;
387
Gilles Peskine449bd832023-01-11 14:50:10 +0100388static void aes_gen_tables(void)
Paul Bakker5121ce52009-01-03 21:22:43 +0000389{
390 int i, x, y, z;
391 int pow[256];
392 int log[256];
393
394 /*
395 * compute pow and log tables over GF(2^8)
396 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100397 for (i = 0, x = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000398 pow[i] = x;
399 log[x] = i;
Gilles Peskine449bd832023-01-11 14:50:10 +0100400 x = MBEDTLS_BYTE_0(x ^ XTIME(x));
Paul Bakker5121ce52009-01-03 21:22:43 +0000401 }
402
403 /*
404 * calculate the round constants
405 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100406 for (i = 0, x = 1; i < 10; i++) {
Paul Bakker5c2364c2012-10-01 14:41:15 +0000407 RCON[i] = (uint32_t) x;
Gilles Peskine449bd832023-01-11 14:50:10 +0100408 x = MBEDTLS_BYTE_0(XTIME(x));
Paul Bakker5121ce52009-01-03 21:22:43 +0000409 }
410
411 /*
412 * generate the forward and reverse S-boxes
413 */
414 FSb[0x00] = 0x63;
415 RSb[0x63] = 0x00;
416
Gilles Peskine449bd832023-01-11 14:50:10 +0100417 for (i = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000418 x = pow[255 - log[i]];
419
Gilles Peskine449bd832023-01-11 14:50:10 +0100420 y = x; y = MBEDTLS_BYTE_0((y << 1) | (y >> 7));
421 x ^= y; y = MBEDTLS_BYTE_0((y << 1) | (y >> 7));
422 x ^= y; y = MBEDTLS_BYTE_0((y << 1) | (y >> 7));
423 x ^= y; y = MBEDTLS_BYTE_0((y << 1) | (y >> 7));
Paul Bakker5121ce52009-01-03 21:22:43 +0000424 x ^= y ^ 0x63;
425
426 FSb[i] = (unsigned char) x;
427 RSb[x] = (unsigned char) i;
428 }
429
430 /*
431 * generate the forward and reverse tables
432 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100433 for (i = 0; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000434 x = FSb[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100435 y = MBEDTLS_BYTE_0(XTIME(x));
436 z = MBEDTLS_BYTE_0(y ^ x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000437
Gilles Peskine449bd832023-01-11 14:50:10 +0100438 FT0[i] = ((uint32_t) y) ^
439 ((uint32_t) x << 8) ^
440 ((uint32_t) x << 16) ^
441 ((uint32_t) z << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000442
Hanno Beckerad049a92017-06-19 16:31:54 +0100443#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100444 FT1[i] = ROTL8(FT0[i]);
445 FT2[i] = ROTL8(FT1[i]);
446 FT3[i] = ROTL8(FT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100447#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000448
449 x = RSb[i];
450
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100451#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100452 RT0[i] = ((uint32_t) MUL(0x0E, x)) ^
453 ((uint32_t) MUL(0x09, x) << 8) ^
454 ((uint32_t) MUL(0x0D, x) << 16) ^
455 ((uint32_t) MUL(0x0B, x) << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000456
Hanno Beckerad049a92017-06-19 16:31:54 +0100457#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100458 RT1[i] = ROTL8(RT0[i]);
459 RT2[i] = ROTL8(RT1[i]);
460 RT3[i] = ROTL8(RT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100461#endif /* !MBEDTLS_AES_FEWER_TABLES */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100462#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000463 }
464}
465
Dave Rodgman8c753f92023-06-27 18:16:13 +0100466#endif /* !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
467
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200468#undef ROTL8
469
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200470#endif /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000471
Hanno Beckerad049a92017-06-19 16:31:54 +0100472#if defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200473
Gilles Peskine449bd832023-01-11 14:50:10 +0100474#define ROTL8(x) ((uint32_t) ((x) << 8) + (uint32_t) ((x) >> 24))
475#define ROTL16(x) ((uint32_t) ((x) << 16) + (uint32_t) ((x) >> 16))
476#define ROTL24(x) ((uint32_t) ((x) << 24) + (uint32_t) ((x) >> 8))
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200477
478#define AES_RT0(idx) RT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100479#define AES_RT1(idx) ROTL8(RT0[idx])
480#define AES_RT2(idx) ROTL16(RT0[idx])
481#define AES_RT3(idx) ROTL24(RT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200482
483#define AES_FT0(idx) FT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100484#define AES_FT1(idx) ROTL8(FT0[idx])
485#define AES_FT2(idx) ROTL16(FT0[idx])
486#define AES_FT3(idx) ROTL24(FT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200487
Hanno Becker177d3cf2017-06-07 15:52:48 +0100488#else /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200489
490#define AES_RT0(idx) RT0[idx]
491#define AES_RT1(idx) RT1[idx]
492#define AES_RT2(idx) RT2[idx]
493#define AES_RT3(idx) RT3[idx]
494
495#define AES_FT0(idx) FT0[idx]
496#define AES_FT1(idx) FT1[idx]
497#define AES_FT2(idx) FT2[idx]
498#define AES_FT3(idx) FT3[idx]
499
Hanno Becker177d3cf2017-06-07 15:52:48 +0100500#endif /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200501
Gilles Peskine449bd832023-01-11 14:50:10 +0100502void mbedtls_aes_init(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200503{
Gilles Peskine449bd832023-01-11 14:50:10 +0100504 memset(ctx, 0, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200505}
506
Gilles Peskine449bd832023-01-11 14:50:10 +0100507void mbedtls_aes_free(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200508{
Gilles Peskine449bd832023-01-11 14:50:10 +0100509 if (ctx == NULL) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200510 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100511 }
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200512
Gilles Peskine449bd832023-01-11 14:50:10 +0100513 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200514}
515
Jaeden Amero9366feb2018-05-29 18:55:17 +0100516#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100517void mbedtls_aes_xts_init(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100518{
Gilles Peskine449bd832023-01-11 14:50:10 +0100519 mbedtls_aes_init(&ctx->crypt);
520 mbedtls_aes_init(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100521}
522
Gilles Peskine449bd832023-01-11 14:50:10 +0100523void mbedtls_aes_xts_free(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100524{
Gilles Peskine449bd832023-01-11 14:50:10 +0100525 if (ctx == NULL) {
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100526 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100527 }
Simon Butcher5201e412018-12-06 17:40:14 +0000528
Gilles Peskine449bd832023-01-11 14:50:10 +0100529 mbedtls_aes_free(&ctx->crypt);
530 mbedtls_aes_free(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100531}
532#endif /* MBEDTLS_CIPHER_MODE_XTS */
533
Gilles Peskine0de8f852023-03-16 17:14:59 +0100534/* Some implementations need the round keys to be aligned.
535 * Return an offset to be added to buf, such that (buf + offset) is
536 * correctly aligned.
537 * Note that the offset is in units of elements of buf, i.e. 32-bit words,
538 * i.e. an offset of 1 means 4 bytes and so on.
539 */
540#if (defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)) || \
Gilles Peskine9c682e72023-03-16 17:21:33 +0100541 (defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100542#define MAY_NEED_TO_ALIGN
543#endif
Dave Rodgman28a539a2023-06-27 18:22:34 +0100544
545#if defined(MAY_NEED_TO_ALIGN) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100546static unsigned mbedtls_aes_rk_offset(uint32_t *buf)
547{
548#if defined(MAY_NEED_TO_ALIGN)
549 int align_16_bytes = 0;
550
551#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
552 if (aes_padlock_ace == -1) {
553 aes_padlock_ace = mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE);
554 }
555 if (aes_padlock_ace) {
556 align_16_bytes = 1;
557 }
558#endif
559
Gilles Peskine9c682e72023-03-16 17:21:33 +0100560#if defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2
Gilles Peskine0de8f852023-03-16 17:14:59 +0100561 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
562 align_16_bytes = 1;
563 }
564#endif
565
566 if (align_16_bytes) {
567 /* These implementations needs 16-byte alignment
568 * for the round key array. */
569 unsigned delta = ((uintptr_t) buf & 0x0000000fU) / 4;
570 if (delta == 0) {
571 return 0;
572 } else {
573 return 4 - delta; // 16 bytes = 4 uint32_t
574 }
575 }
576#else /* MAY_NEED_TO_ALIGN */
577 (void) buf;
578#endif /* MAY_NEED_TO_ALIGN */
579
580 return 0;
581}
Dave Rodgman28a539a2023-06-27 18:22:34 +0100582#endif /* defined(MAY_NEED_TO_ALIGN) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
Gilles Peskine0de8f852023-03-16 17:14:59 +0100583
Paul Bakker5121ce52009-01-03 21:22:43 +0000584/*
585 * AES key schedule (encryption)
586 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200587#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100588int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
589 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000590{
Paul Bakker23986e52011-04-24 08:57:21 +0000591 unsigned int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000592 uint32_t *RK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000593
Gilles Peskine449bd832023-01-11 14:50:10 +0100594 switch (keybits) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000595 case 128: ctx->nr = 10; break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800596#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000597 case 192: ctx->nr = 12; break;
598 case 256: ctx->nr = 14; break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800599#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Gilles Peskine449bd832023-01-11 14:50:10 +0100600 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Paul Bakker5121ce52009-01-03 21:22:43 +0000601 }
602
Simon Butcher5201e412018-12-06 17:40:14 +0000603#if !defined(MBEDTLS_AES_ROM_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100604 if (aes_init_done == 0) {
Simon Butcher5201e412018-12-06 17:40:14 +0000605 aes_gen_tables();
606 aes_init_done = 1;
Simon Butcher5201e412018-12-06 17:40:14 +0000607 }
608#endif
609
Gilles Peskine0de8f852023-03-16 17:14:59 +0100610 ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf);
Werner Lewisdd76ef32022-05-30 12:00:21 +0100611 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000612
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100613#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100614 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
615 return mbedtls_aesni_setkey_enc((unsigned char *) RK, key, keybits);
616 }
Manuel Pégourié-Gonnard47a35362013-12-28 20:45:04 +0100617#endif
618
Jerry Yu3f2fb712023-01-10 17:05:42 +0800619#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
620 if (mbedtls_aesce_has_support()) {
621 return mbedtls_aesce_setkey_enc((unsigned char *) RK, key, keybits);
622 }
623#endif
624
Gilles Peskine449bd832023-01-11 14:50:10 +0100625 for (i = 0; i < (keybits >> 5); i++) {
626 RK[i] = MBEDTLS_GET_UINT32_LE(key, i << 2);
Paul Bakker5121ce52009-01-03 21:22:43 +0000627 }
628
Gilles Peskine449bd832023-01-11 14:50:10 +0100629 switch (ctx->nr) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000630 case 10:
631
Gilles Peskine449bd832023-01-11 14:50:10 +0100632 for (i = 0; i < 10; i++, RK += 4) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000633 RK[4] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100634 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[3])]) ^
635 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[3])] << 8) ^
636 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[3])] << 16) ^
637 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[3])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000638
639 RK[5] = RK[1] ^ RK[4];
640 RK[6] = RK[2] ^ RK[5];
641 RK[7] = RK[3] ^ RK[6];
642 }
643 break;
644
Arto Kinnunen732ca322023-04-14 14:26:10 +0800645#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000646 case 12:
647
Gilles Peskine449bd832023-01-11 14:50:10 +0100648 for (i = 0; i < 8; i++, RK += 6) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000649 RK[6] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100650 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[5])]) ^
651 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[5])] << 8) ^
652 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[5])] << 16) ^
653 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[5])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000654
655 RK[7] = RK[1] ^ RK[6];
656 RK[8] = RK[2] ^ RK[7];
657 RK[9] = RK[3] ^ RK[8];
658 RK[10] = RK[4] ^ RK[9];
659 RK[11] = RK[5] ^ RK[10];
660 }
661 break;
662
663 case 14:
664
Gilles Peskine449bd832023-01-11 14:50:10 +0100665 for (i = 0; i < 7; i++, RK += 8) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000666 RK[8] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100667 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[7])]) ^
668 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[7])] << 8) ^
669 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[7])] << 16) ^
670 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[7])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000671
672 RK[9] = RK[1] ^ RK[8];
673 RK[10] = RK[2] ^ RK[9];
674 RK[11] = RK[3] ^ RK[10];
675
676 RK[12] = RK[4] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100677 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[11])]) ^
678 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[11])] << 8) ^
679 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[11])] << 16) ^
680 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[11])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000681
682 RK[13] = RK[5] ^ RK[12];
683 RK[14] = RK[6] ^ RK[13];
684 RK[15] = RK[7] ^ RK[14];
685 }
686 break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800687#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Paul Bakker5121ce52009-01-03 21:22:43 +0000688 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000689
Gilles Peskine449bd832023-01-11 14:50:10 +0100690 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000691}
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200692#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000693
694/*
695 * AES key schedule (decryption)
696 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200697#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100698int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
699 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000700{
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200701 int i, j, ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200702 mbedtls_aes_context cty;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000703 uint32_t *RK;
704 uint32_t *SK;
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200705
Gilles Peskine449bd832023-01-11 14:50:10 +0100706 mbedtls_aes_init(&cty);
Paul Bakker5121ce52009-01-03 21:22:43 +0000707
Gilles Peskine0de8f852023-03-16 17:14:59 +0100708 ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf);
Werner Lewisdd76ef32022-05-30 12:00:21 +0100709 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000710
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200711 /* Also checks keybits */
Gilles Peskine449bd832023-01-11 14:50:10 +0100712 if ((ret = mbedtls_aes_setkey_enc(&cty, key, keybits)) != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200713 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100714 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000715
Manuel Pégourié-Gonnardafd5a082014-05-28 21:52:59 +0200716 ctx->nr = cty.nr;
717
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100718#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100719 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
720 mbedtls_aesni_inverse_key((unsigned char *) RK,
721 (const unsigned char *) (cty.buf + cty.rk_offset), ctx->nr);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200722 goto exit;
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100723 }
724#endif
725
Jerry Yue096da12023-01-10 17:07:01 +0800726#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
727 if (mbedtls_aesce_has_support()) {
728 mbedtls_aesce_inverse_key(
729 (unsigned char *) RK,
730 (const unsigned char *) (cty.buf + cty.rk_offset),
731 ctx->nr);
732 goto exit;
733 }
734#endif
735
Werner Lewisdd76ef32022-05-30 12:00:21 +0100736 SK = cty.buf + cty.rk_offset + cty.nr * 4;
Paul Bakker5121ce52009-01-03 21:22:43 +0000737
738 *RK++ = *SK++;
739 *RK++ = *SK++;
740 *RK++ = *SK++;
741 *RK++ = *SK++;
742
Gilles Peskine449bd832023-01-11 14:50:10 +0100743 for (i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8) {
744 for (j = 0; j < 4; j++, SK++) {
745 *RK++ = AES_RT0(FSb[MBEDTLS_BYTE_0(*SK)]) ^
746 AES_RT1(FSb[MBEDTLS_BYTE_1(*SK)]) ^
747 AES_RT2(FSb[MBEDTLS_BYTE_2(*SK)]) ^
748 AES_RT3(FSb[MBEDTLS_BYTE_3(*SK)]);
Paul Bakker5121ce52009-01-03 21:22:43 +0000749 }
750 }
751
752 *RK++ = *SK++;
753 *RK++ = *SK++;
754 *RK++ = *SK++;
755 *RK++ = *SK++;
756
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200757exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100758 mbedtls_aes_free(&cty);
Paul Bakker2b222c82009-07-27 21:03:45 +0000759
Gilles Peskine449bd832023-01-11 14:50:10 +0100760 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000761}
gabor-mezei-arm95db3012020-10-26 11:35:23 +0100762#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */
Jaeden Amero9366feb2018-05-29 18:55:17 +0100763
764#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100765static int mbedtls_aes_xts_decode_keys(const unsigned char *key,
766 unsigned int keybits,
767 const unsigned char **key1,
768 unsigned int *key1bits,
769 const unsigned char **key2,
770 unsigned int *key2bits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100771{
772 const unsigned int half_keybits = keybits / 2;
773 const unsigned int half_keybytes = half_keybits / 8;
774
Gilles Peskine449bd832023-01-11 14:50:10 +0100775 switch (keybits) {
Jaeden Amero9366feb2018-05-29 18:55:17 +0100776 case 256: break;
777 case 512: break;
Gilles Peskine449bd832023-01-11 14:50:10 +0100778 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100779 }
780
781 *key1bits = half_keybits;
782 *key2bits = half_keybits;
783 *key1 = &key[0];
784 *key2 = &key[half_keybytes];
785
786 return 0;
787}
788
Gilles Peskine449bd832023-01-11 14:50:10 +0100789int mbedtls_aes_xts_setkey_enc(mbedtls_aes_xts_context *ctx,
790 const unsigned char *key,
791 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100792{
Janos Follath24eed8d2019-11-22 13:21:35 +0000793 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100794 const unsigned char *key1, *key2;
795 unsigned int key1bits, key2bits;
796
Gilles Peskine449bd832023-01-11 14:50:10 +0100797 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
798 &key2, &key2bits);
799 if (ret != 0) {
800 return ret;
801 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100802
803 /* Set the tweak key. Always set tweak key for the encryption mode. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100804 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
805 if (ret != 0) {
806 return ret;
807 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100808
809 /* Set crypt key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100810 return mbedtls_aes_setkey_enc(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100811}
812
Gilles Peskine449bd832023-01-11 14:50:10 +0100813int mbedtls_aes_xts_setkey_dec(mbedtls_aes_xts_context *ctx,
814 const unsigned char *key,
815 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100816{
Janos Follath24eed8d2019-11-22 13:21:35 +0000817 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100818 const unsigned char *key1, *key2;
819 unsigned int key1bits, key2bits;
820
Gilles Peskine449bd832023-01-11 14:50:10 +0100821 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
822 &key2, &key2bits);
823 if (ret != 0) {
824 return ret;
825 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100826
827 /* Set the tweak key. Always set tweak key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100828 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
829 if (ret != 0) {
830 return ret;
831 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100832
833 /* Set crypt key for decryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100834 return mbedtls_aes_setkey_dec(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100835}
836#endif /* MBEDTLS_CIPHER_MODE_XTS */
837
Gilles Peskine449bd832023-01-11 14:50:10 +0100838#define AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Joe Subbianicd84d762021-07-08 14:59:52 +0100839 do \
840 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100841 (X0) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y0)) ^ \
842 AES_FT1(MBEDTLS_BYTE_1(Y1)) ^ \
843 AES_FT2(MBEDTLS_BYTE_2(Y2)) ^ \
844 AES_FT3(MBEDTLS_BYTE_3(Y3)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100845 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100846 (X1) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y1)) ^ \
847 AES_FT1(MBEDTLS_BYTE_1(Y2)) ^ \
848 AES_FT2(MBEDTLS_BYTE_2(Y3)) ^ \
849 AES_FT3(MBEDTLS_BYTE_3(Y0)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100850 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100851 (X2) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y2)) ^ \
852 AES_FT1(MBEDTLS_BYTE_1(Y3)) ^ \
853 AES_FT2(MBEDTLS_BYTE_2(Y0)) ^ \
854 AES_FT3(MBEDTLS_BYTE_3(Y1)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100855 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100856 (X3) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y3)) ^ \
857 AES_FT1(MBEDTLS_BYTE_1(Y0)) ^ \
858 AES_FT2(MBEDTLS_BYTE_2(Y1)) ^ \
859 AES_FT3(MBEDTLS_BYTE_3(Y2)); \
860 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000861
Gilles Peskine449bd832023-01-11 14:50:10 +0100862#define AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100863 do \
864 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100865 (X0) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y0)) ^ \
866 AES_RT1(MBEDTLS_BYTE_1(Y3)) ^ \
867 AES_RT2(MBEDTLS_BYTE_2(Y2)) ^ \
868 AES_RT3(MBEDTLS_BYTE_3(Y1)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100869 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100870 (X1) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y1)) ^ \
871 AES_RT1(MBEDTLS_BYTE_1(Y0)) ^ \
872 AES_RT2(MBEDTLS_BYTE_2(Y3)) ^ \
873 AES_RT3(MBEDTLS_BYTE_3(Y2)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100874 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100875 (X2) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y2)) ^ \
876 AES_RT1(MBEDTLS_BYTE_1(Y1)) ^ \
877 AES_RT2(MBEDTLS_BYTE_2(Y0)) ^ \
878 AES_RT3(MBEDTLS_BYTE_3(Y3)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100879 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100880 (X3) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y3)) ^ \
881 AES_RT1(MBEDTLS_BYTE_1(Y2)) ^ \
882 AES_RT2(MBEDTLS_BYTE_2(Y1)) ^ \
883 AES_RT3(MBEDTLS_BYTE_3(Y0)); \
884 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000885
886/*
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200887 * AES-ECB block encryption
888 */
889#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100890int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx,
891 const unsigned char input[16],
892 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200893{
894 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100895 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100896 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200897 uint32_t X[4];
898 uint32_t Y[4];
899 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200900
Gilles Peskine449bd832023-01-11 14:50:10 +0100901 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
902 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
903 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
904 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200905
Gilles Peskine449bd832023-01-11 14:50:10 +0100906 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
907 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]);
908 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 +0200909 }
910
Gilles Peskine449bd832023-01-11 14:50:10 +0100911 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 +0200912
Gilles Peskine5197c662020-08-26 17:03:24 +0200913 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100914 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
915 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
916 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
917 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200918
Gilles Peskine5197c662020-08-26 17:03:24 +0200919 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100920 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
921 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
922 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
923 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200924
Gilles Peskine5197c662020-08-26 17:03:24 +0200925 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100926 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
927 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
928 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
929 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200930
Gilles Peskine5197c662020-08-26 17:03:24 +0200931 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100932 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
933 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
934 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
935 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200936
Gilles Peskine449bd832023-01-11 14:50:10 +0100937 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
938 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
939 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
940 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +0000941
Gilles Peskine449bd832023-01-11 14:50:10 +0100942 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500943
Gilles Peskine449bd832023-01-11 14:50:10 +0100944 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200945}
946#endif /* !MBEDTLS_AES_ENCRYPT_ALT */
947
948/*
949 * AES-ECB block decryption
950 */
951#if !defined(MBEDTLS_AES_DECRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100952int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
953 const unsigned char input[16],
954 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200955{
956 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100957 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100958 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200959 uint32_t X[4];
960 uint32_t Y[4];
961 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200962
Gilles Peskine449bd832023-01-11 14:50:10 +0100963 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
964 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
965 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
966 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200967
Gilles Peskine449bd832023-01-11 14:50:10 +0100968 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
969 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]);
970 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 +0200971 }
972
Gilles Peskine449bd832023-01-11 14:50:10 +0100973 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 +0200974
Gilles Peskine5197c662020-08-26 17:03:24 +0200975 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100976 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
977 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
978 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
979 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200980
Gilles Peskine5197c662020-08-26 17:03:24 +0200981 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100982 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
983 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
984 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
985 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200986
Gilles Peskine5197c662020-08-26 17:03:24 +0200987 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100988 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
989 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
990 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
991 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200992
Gilles Peskine5197c662020-08-26 17:03:24 +0200993 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100994 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
995 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
996 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
997 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200998
Gilles Peskine449bd832023-01-11 14:50:10 +0100999 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
1000 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
1001 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
1002 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +00001003
Gilles Peskine449bd832023-01-11 14:50:10 +01001004 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -05001005
Gilles Peskine449bd832023-01-11 14:50:10 +01001006 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001007}
1008#endif /* !MBEDTLS_AES_DECRYPT_ALT */
1009
Gilles Peskine0de8f852023-03-16 17:14:59 +01001010#if defined(MAY_NEED_TO_ALIGN)
Gilles Peskine148cad12023-03-16 13:08:42 +01001011/* VIA Padlock and our intrinsics-based implementation of AESNI require
1012 * the round keys to be aligned on a 16-byte boundary. We take care of this
1013 * before creating them, but the AES context may have moved (this can happen
1014 * if the library is called from a language with managed memory), and in later
1015 * calls it might have a different alignment with respect to 16-byte memory.
1016 * So we may need to realign.
1017 */
1018static void aes_maybe_realign(mbedtls_aes_context *ctx)
1019{
Gilles Peskine0de8f852023-03-16 17:14:59 +01001020 unsigned new_offset = mbedtls_aes_rk_offset(ctx->buf);
1021 if (new_offset != ctx->rk_offset) {
Gilles Peskine148cad12023-03-16 13:08:42 +01001022 memmove(ctx->buf + new_offset, // new address
1023 ctx->buf + ctx->rk_offset, // current address
1024 (ctx->nr + 1) * 16); // number of round keys * bytes per rk
1025 ctx->rk_offset = new_offset;
1026 }
1027}
1028#endif
1029
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001030/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001031 * AES-ECB block encryption/decryption
1032 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001033int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
1034 int mode,
1035 const unsigned char input[16],
1036 unsigned char output[16])
Paul Bakker5121ce52009-01-03 21:22:43 +00001037{
Gilles Peskine449bd832023-01-11 14:50:10 +01001038 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001039 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001040 }
Manuel Pégourié-Gonnard1aca2602018-12-12 12:56:55 +01001041
Gilles Peskine0de8f852023-03-16 17:14:59 +01001042#if defined(MAY_NEED_TO_ALIGN)
1043 aes_maybe_realign(ctx);
1044#endif
1045
Gilles Peskine9af58cd2023-03-10 22:29:32 +01001046#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001047 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1048 return mbedtls_aesni_crypt_ecb(ctx, mode, input, output);
1049 }
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +01001050#endif
1051
Jerry Yu2bb3d812023-01-10 17:38:26 +08001052#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
1053 if (mbedtls_aesce_has_support()) {
1054 return mbedtls_aesce_crypt_ecb(ctx, mode, input, output);
1055 }
1056#endif
1057
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001058#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Gilles Peskine449bd832023-01-11 14:50:10 +01001059 if (aes_padlock_ace > 0) {
Gilles Peskine148cad12023-03-16 13:08:42 +01001060 return mbedtls_padlock_xcryptecb(ctx, mode, input, output);
Paul Bakker5121ce52009-01-03 21:22:43 +00001061 }
1062#endif
1063
Gilles Peskine449bd832023-01-11 14:50:10 +01001064 if (mode == MBEDTLS_AES_ENCRYPT) {
1065 return mbedtls_internal_aes_encrypt(ctx, input, output);
1066 } else {
1067 return mbedtls_internal_aes_decrypt(ctx, input, output);
1068 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001069}
1070
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001071#if defined(MBEDTLS_CIPHER_MODE_CBC)
Dave Rodgmand05e7f12023-06-14 18:58:48 +01001072
1073#if defined(__ARM_NEON) && defined(__aarch64__)
Dave Rodgman28a97ac2023-06-14 20:15:15 +01001074/* Avoid using the NEON implementation of mbedtls_xor. Because of the dependency on
1075 * the result for the next block in CBC, and the cost of transferring that data from
1076 * NEON registers, it is faster to use the following on aarch64.
1077 * For 32-bit arm, NEON should be faster. */
Dave Rodgmand05e7f12023-06-14 18:58:48 +01001078#define CBC_XOR_16(r, a, b) do { \
Dave Rodgman28a97ac2023-06-14 20:15:15 +01001079 mbedtls_put_unaligned_uint64(r, \
1080 mbedtls_get_unaligned_uint64(a) ^ \
1081 mbedtls_get_unaligned_uint64(b)); \
1082 mbedtls_put_unaligned_uint64(r + 8, \
1083 mbedtls_get_unaligned_uint64(a + 8) ^ \
1084 mbedtls_get_unaligned_uint64(b + 8)); \
Dave Rodgmand05e7f12023-06-14 18:58:48 +01001085} while (0)
1086#else
1087#define CBC_XOR_16(r, a, b) mbedtls_xor(r, a, b, 16)
1088#endif
1089
Paul Bakker5121ce52009-01-03 21:22:43 +00001090/*
1091 * AES-CBC buffer encryption/decryption
1092 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001093int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
1094 int mode,
1095 size_t length,
1096 unsigned char iv[16],
1097 const unsigned char *input,
1098 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001099{
Gilles Peskine7820a572021-07-07 21:08:28 +02001100 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +00001101 unsigned char temp[16];
1102
Gilles Peskine449bd832023-01-11 14:50:10 +01001103 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001104 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001105 }
Manuel Pégourié-Gonnard3178d1a2018-12-12 13:05:00 +01001106
Gilles Peskine449bd832023-01-11 14:50:10 +01001107 if (length % 16) {
1108 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
1109 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001110
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001111#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Gilles Peskine449bd832023-01-11 14:50:10 +01001112 if (aes_padlock_ace > 0) {
1113 if (mbedtls_padlock_xcryptcbc(ctx, mode, length, iv, input, output) == 0) {
1114 return 0;
1115 }
Paul Bakker9af723c2014-05-01 13:03:14 +02001116
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001117 // If padlock data misaligned, we just fall back to
1118 // unaccelerated mode
1119 //
Paul Bakker5121ce52009-01-03 21:22:43 +00001120 }
1121#endif
1122
Dave Rodgman906c63c2023-06-14 17:53:51 +01001123 const unsigned char *ivp = iv;
1124
Gilles Peskine449bd832023-01-11 14:50:10 +01001125 if (mode == MBEDTLS_AES_DECRYPT) {
1126 while (length > 0) {
1127 memcpy(temp, input, 16);
1128 ret = mbedtls_aes_crypt_ecb(ctx, mode, input, output);
1129 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001130 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001131 }
Dave Rodgmand05e7f12023-06-14 18:58:48 +01001132 CBC_XOR_16(output, output, iv);
Paul Bakker5121ce52009-01-03 21:22:43 +00001133
Gilles Peskine449bd832023-01-11 14:50:10 +01001134 memcpy(iv, temp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001135
1136 input += 16;
1137 output += 16;
1138 length -= 16;
1139 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001140 } else {
1141 while (length > 0) {
Dave Rodgmand05e7f12023-06-14 18:58:48 +01001142 CBC_XOR_16(output, input, ivp);
Paul Bakker5121ce52009-01-03 21:22:43 +00001143
Gilles Peskine449bd832023-01-11 14:50:10 +01001144 ret = mbedtls_aes_crypt_ecb(ctx, mode, output, output);
1145 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001146 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001147 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001148 ivp = output;
Paul Bakker5121ce52009-01-03 21:22:43 +00001149
1150 input += 16;
1151 output += 16;
1152 length -= 16;
1153 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001154 memcpy(iv, ivp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001155 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001156 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001157
Gilles Peskine7820a572021-07-07 21:08:28 +02001158exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001159 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001160}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001161#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001162
Aorimn5f778012016-06-09 23:22:58 +02001163#if defined(MBEDTLS_CIPHER_MODE_XTS)
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001164
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001165typedef unsigned char mbedtls_be128[16];
1166
1167/*
1168 * GF(2^128) multiplication function
1169 *
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001170 * This function multiplies a field element by x in the polynomial field
1171 * representation. It uses 64-bit word operations to gain speed but compensates
Shaun Case8b0ecbc2021-12-20 21:14:10 -08001172 * for machine endianness and hence works correctly on both big and little
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001173 * endian machines.
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001174 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001175static void mbedtls_gf128mul_x_ble(unsigned char r[16],
1176 const unsigned char x[16])
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001177{
1178 uint64_t a, b, ra, rb;
1179
Gilles Peskine449bd832023-01-11 14:50:10 +01001180 a = MBEDTLS_GET_UINT64_LE(x, 0);
1181 b = MBEDTLS_GET_UINT64_LE(x, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001182
Gilles Peskine449bd832023-01-11 14:50:10 +01001183 ra = (a << 1) ^ 0x0087 >> (8 - ((b >> 63) << 3));
1184 rb = (a >> 63) | (b << 1);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001185
Gilles Peskine449bd832023-01-11 14:50:10 +01001186 MBEDTLS_PUT_UINT64_LE(ra, r, 0);
1187 MBEDTLS_PUT_UINT64_LE(rb, r, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001188}
1189
Aorimn5f778012016-06-09 23:22:58 +02001190/*
1191 * AES-XTS buffer encryption/decryption
1192 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001193int mbedtls_aes_crypt_xts(mbedtls_aes_xts_context *ctx,
1194 int mode,
1195 size_t length,
1196 const unsigned char data_unit[16],
1197 const unsigned char *input,
1198 unsigned char *output)
Aorimn5f778012016-06-09 23:22:58 +02001199{
Janos Follath24eed8d2019-11-22 13:21:35 +00001200 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amerod82cd862018-04-28 15:02:45 +01001201 size_t blocks = length / 16;
1202 size_t leftover = length % 16;
1203 unsigned char tweak[16];
1204 unsigned char prev_tweak[16];
1205 unsigned char tmp[16];
Aorimn5f778012016-06-09 23:22:58 +02001206
Gilles Peskine449bd832023-01-11 14:50:10 +01001207 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001208 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001209 }
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01001210
Jaeden Amero8381fcb2018-10-11 12:06:15 +01001211 /* Data units must be at least 16 bytes long. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001212 if (length < 16) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001213 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001214 }
Aorimn5f778012016-06-09 23:22:58 +02001215
Jaeden Ameroa74faba2018-10-11 12:07:43 +01001216 /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001217 if (length > (1 << 20) * 16) {
Jaeden Amero0a8b0202018-05-30 15:36:06 +01001218 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001219 }
Aorimn5f778012016-06-09 23:22:58 +02001220
Jaeden Amerod82cd862018-04-28 15:02:45 +01001221 /* Compute the tweak. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001222 ret = mbedtls_aes_crypt_ecb(&ctx->tweak, MBEDTLS_AES_ENCRYPT,
1223 data_unit, tweak);
1224 if (ret != 0) {
1225 return ret;
1226 }
Aorimn5f778012016-06-09 23:22:58 +02001227
Gilles Peskine449bd832023-01-11 14:50:10 +01001228 while (blocks--) {
Dave Rodgman360e04f2023-06-09 17:18:32 +01001229 if (MBEDTLS_UNLIKELY(leftover && (mode == MBEDTLS_AES_DECRYPT) && blocks == 0)) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001230 /* We are on the last block in a decrypt operation that has
1231 * leftover bytes, so we need to use the next tweak for this block,
Tom Cosgrove1797b052022-12-04 17:19:59 +00001232 * and this tweak for the leftover bytes. Save the current tweak for
Jaeden Amerod82cd862018-04-28 15:02:45 +01001233 * the leftovers and then update the current tweak for use on this,
1234 * the last full block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001235 memcpy(prev_tweak, tweak, sizeof(tweak));
1236 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001237 }
1238
Gilles Peskine449bd832023-01-11 14:50:10 +01001239 mbedtls_xor(tmp, input, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001240
Gilles Peskine449bd832023-01-11 14:50:10 +01001241 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1242 if (ret != 0) {
1243 return ret;
1244 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001245
Gilles Peskine449bd832023-01-11 14:50:10 +01001246 mbedtls_xor(output, tmp, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001247
1248 /* Update the tweak for the next block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001249 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001250
1251 output += 16;
1252 input += 16;
Aorimn5f778012016-06-09 23:22:58 +02001253 }
1254
Gilles Peskine449bd832023-01-11 14:50:10 +01001255 if (leftover) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001256 /* If we are on the leftover bytes in a decrypt operation, we need to
1257 * use the previous tweak for these bytes (as saved in prev_tweak). */
1258 unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
Aorimn5f778012016-06-09 23:22:58 +02001259
Jaeden Amerod82cd862018-04-28 15:02:45 +01001260 /* We are now on the final part of the data unit, which doesn't divide
1261 * evenly by 16. It's time for ciphertext stealing. */
1262 size_t i;
1263 unsigned char *prev_output = output - 16;
Aorimn5f778012016-06-09 23:22:58 +02001264
Jaeden Amerod82cd862018-04-28 15:02:45 +01001265 /* Copy ciphertext bytes from the previous block to our output for each
Dave Rodgman069e7f42022-11-24 19:37:26 +00001266 * byte of ciphertext we won't steal. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001267 for (i = 0; i < leftover; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001268 output[i] = prev_output[i];
Aorimn5f778012016-06-09 23:22:58 +02001269 }
Aorimn5f778012016-06-09 23:22:58 +02001270
Dave Rodgman069e7f42022-11-24 19:37:26 +00001271 /* Copy the remainder of the input for this final round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001272 mbedtls_xor(tmp, input, t, leftover);
Dave Rodgmana8cf6072022-11-22 15:02:54 +00001273
Jaeden Amerod82cd862018-04-28 15:02:45 +01001274 /* Copy ciphertext bytes from the previous block for input in this
1275 * round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001276 mbedtls_xor(tmp + i, prev_output + i, t + i, 16 - i);
Aorimn5f778012016-06-09 23:22:58 +02001277
Gilles Peskine449bd832023-01-11 14:50:10 +01001278 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1279 if (ret != 0) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001280 return ret;
Gilles Peskine449bd832023-01-11 14:50:10 +01001281 }
Aorimn5f778012016-06-09 23:22:58 +02001282
Jaeden Amerod82cd862018-04-28 15:02:45 +01001283 /* Write the result back to the previous block, overriding the previous
1284 * output we copied. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001285 mbedtls_xor(prev_output, tmp, t, 16);
Aorimn5f778012016-06-09 23:22:58 +02001286 }
1287
Gilles Peskine449bd832023-01-11 14:50:10 +01001288 return 0;
Aorimn5f778012016-06-09 23:22:58 +02001289}
1290#endif /* MBEDTLS_CIPHER_MODE_XTS */
1291
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001292#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001293/*
1294 * AES-CFB128 buffer encryption/decryption
1295 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001296int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx,
1297 int mode,
1298 size_t length,
1299 size_t *iv_off,
1300 unsigned char iv[16],
1301 const unsigned char *input,
1302 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001303{
Paul Bakker27fdf462011-06-09 13:55:13 +00001304 int c;
Gilles Peskine7820a572021-07-07 21:08:28 +02001305 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001306 size_t n;
1307
Gilles Peskine449bd832023-01-11 14:50:10 +01001308 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001309 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001310 }
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001311
1312 n = *iv_off;
Paul Bakker5121ce52009-01-03 21:22:43 +00001313
Gilles Peskine449bd832023-01-11 14:50:10 +01001314 if (n > 15) {
1315 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1316 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001317
Gilles Peskine449bd832023-01-11 14:50:10 +01001318 if (mode == MBEDTLS_AES_DECRYPT) {
1319 while (length--) {
1320 if (n == 0) {
1321 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1322 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001323 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001324 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001325 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001326
1327 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001328 *output++ = (unsigned char) (c ^ iv[n]);
Paul Bakker5121ce52009-01-03 21:22:43 +00001329 iv[n] = (unsigned char) c;
1330
Gilles Peskine449bd832023-01-11 14:50:10 +01001331 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001332 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001333 } else {
1334 while (length--) {
1335 if (n == 0) {
1336 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1337 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001338 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001339 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001340 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001341
Gilles Peskine449bd832023-01-11 14:50:10 +01001342 iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++);
Paul Bakker5121ce52009-01-03 21:22:43 +00001343
Gilles Peskine449bd832023-01-11 14:50:10 +01001344 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001345 }
1346 }
1347
1348 *iv_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001349 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001350
Gilles Peskine7820a572021-07-07 21:08:28 +02001351exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001352 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001353}
Paul Bakker556efba2014-01-24 15:38:12 +01001354
1355/*
1356 * AES-CFB8 buffer encryption/decryption
1357 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001358int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx,
1359 int mode,
1360 size_t length,
1361 unsigned char iv[16],
1362 const unsigned char *input,
1363 unsigned char *output)
Paul Bakker556efba2014-01-24 15:38:12 +01001364{
Gilles Peskine7820a572021-07-07 21:08:28 +02001365 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker556efba2014-01-24 15:38:12 +01001366 unsigned char c;
1367 unsigned char ov[17];
1368
Gilles Peskine449bd832023-01-11 14:50:10 +01001369 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001370 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001371 }
1372 while (length--) {
1373 memcpy(ov, iv, 16);
1374 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1375 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001376 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001377 }
Paul Bakker556efba2014-01-24 15:38:12 +01001378
Gilles Peskine449bd832023-01-11 14:50:10 +01001379 if (mode == MBEDTLS_AES_DECRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001380 ov[16] = *input;
Gilles Peskine449bd832023-01-11 14:50:10 +01001381 }
Paul Bakker556efba2014-01-24 15:38:12 +01001382
Gilles Peskine449bd832023-01-11 14:50:10 +01001383 c = *output++ = (unsigned char) (iv[0] ^ *input++);
Paul Bakker556efba2014-01-24 15:38:12 +01001384
Gilles Peskine449bd832023-01-11 14:50:10 +01001385 if (mode == MBEDTLS_AES_ENCRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001386 ov[16] = c;
Gilles Peskine449bd832023-01-11 14:50:10 +01001387 }
Paul Bakker556efba2014-01-24 15:38:12 +01001388
Gilles Peskine449bd832023-01-11 14:50:10 +01001389 memcpy(iv, ov + 1, 16);
Paul Bakker556efba2014-01-24 15:38:12 +01001390 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001391 ret = 0;
Paul Bakker556efba2014-01-24 15:38:12 +01001392
Gilles Peskine7820a572021-07-07 21:08:28 +02001393exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001394 return ret;
Paul Bakker556efba2014-01-24 15:38:12 +01001395}
Simon Butcher76a5b222018-04-22 22:57:27 +01001396#endif /* MBEDTLS_CIPHER_MODE_CFB */
1397
1398#if defined(MBEDTLS_CIPHER_MODE_OFB)
1399/*
1400 * AES-OFB (Output Feedback Mode) buffer encryption/decryption
1401 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001402int mbedtls_aes_crypt_ofb(mbedtls_aes_context *ctx,
1403 size_t length,
1404 size_t *iv_off,
1405 unsigned char iv[16],
1406 const unsigned char *input,
1407 unsigned char *output)
Simon Butcher76a5b222018-04-22 22:57:27 +01001408{
Simon Butcherad4e4932018-04-29 00:43:47 +01001409 int ret = 0;
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001410 size_t n;
1411
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001412 n = *iv_off;
Simon Butcher76a5b222018-04-22 22:57:27 +01001413
Gilles Peskine449bd832023-01-11 14:50:10 +01001414 if (n > 15) {
1415 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1416 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001417
Gilles Peskine449bd832023-01-11 14:50:10 +01001418 while (length--) {
1419 if (n == 0) {
1420 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1421 if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001422 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001423 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001424 }
Simon Butcher76a5b222018-04-22 22:57:27 +01001425 *output++ = *input++ ^ iv[n];
1426
Gilles Peskine449bd832023-01-11 14:50:10 +01001427 n = (n + 1) & 0x0F;
Simon Butcher76a5b222018-04-22 22:57:27 +01001428 }
1429
1430 *iv_off = n;
1431
Simon Butcherad4e4932018-04-29 00:43:47 +01001432exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001433 return ret;
Simon Butcher76a5b222018-04-22 22:57:27 +01001434}
1435#endif /* MBEDTLS_CIPHER_MODE_OFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001436
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001437#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001438/*
1439 * AES-CTR buffer encryption/decryption
1440 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001441int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
1442 size_t length,
1443 size_t *nc_off,
1444 unsigned char nonce_counter[16],
1445 unsigned char stream_block[16],
1446 const unsigned char *input,
1447 unsigned char *output)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001448{
Paul Bakker369e14b2012-04-18 14:16:09 +00001449 int c, i;
Gilles Peskine7820a572021-07-07 21:08:28 +02001450 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001451 size_t n;
1452
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001453 n = *nc_off;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001454
Gilles Peskine449bd832023-01-11 14:50:10 +01001455 if (n > 0x0F) {
1456 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1457 }
Mohammad Azim Khan3f7f8172017-11-23 17:49:05 +00001458
Gilles Peskine449bd832023-01-11 14:50:10 +01001459 while (length--) {
1460 if (n == 0) {
1461 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block);
1462 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001463 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001464 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001465
Gilles Peskine449bd832023-01-11 14:50:10 +01001466 for (i = 16; i > 0; i--) {
1467 if (++nonce_counter[i - 1] != 0) {
Paul Bakker369e14b2012-04-18 14:16:09 +00001468 break;
Gilles Peskine449bd832023-01-11 14:50:10 +01001469 }
1470 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001471 }
1472 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001473 *output++ = (unsigned char) (c ^ stream_block[n]);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001474
Gilles Peskine449bd832023-01-11 14:50:10 +01001475 n = (n + 1) & 0x0F;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001476 }
1477
1478 *nc_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001479 ret = 0;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001480
Gilles Peskine7820a572021-07-07 21:08:28 +02001481exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001482 return ret;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001483}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001484#endif /* MBEDTLS_CIPHER_MODE_CTR */
Manuel Pégourié-Gonnard1ec220b2014-03-10 11:20:17 +01001485
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001486#endif /* !MBEDTLS_AES_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001487
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001488#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001489/*
1490 * AES test vectors from:
1491 *
1492 * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
1493 */
Yanray Wang62c99912023-05-11 11:06:53 +08001494static const unsigned char aes_test_ecb_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001495{
1496 { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
1497 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
Yanray Wang62c99912023-05-11 11:06:53 +08001498#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001499 { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
1500 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
1501 { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
1502 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
Yanray Wang62c99912023-05-11 11:06:53 +08001503#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001504};
1505
Yanray Wang62c99912023-05-11 11:06:53 +08001506static const unsigned char aes_test_ecb_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001507{
1508 { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
1509 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
Yanray Wang62c99912023-05-11 11:06:53 +08001510#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001511 { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
1512 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
1513 { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
1514 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001515#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001516};
1517
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001518#if defined(MBEDTLS_CIPHER_MODE_CBC)
Yanray Wang62c99912023-05-11 11:06:53 +08001519static const unsigned char aes_test_cbc_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001520{
1521 { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
1522 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
Yanray Wang62c99912023-05-11 11:06:53 +08001523#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001524 { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
1525 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
1526 { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
1527 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
Yanray Wang62c99912023-05-11 11:06:53 +08001528#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001529};
1530
Yanray Wang62c99912023-05-11 11:06:53 +08001531static const unsigned char aes_test_cbc_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001532{
1533 { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
1534 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
Yanray Wang62c99912023-05-11 11:06:53 +08001535#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001536 { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
1537 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
1538 { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
1539 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
Yanray Wang62c99912023-05-11 11:06:53 +08001540#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001541};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001542#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001543
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001544#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001545/*
1546 * AES-CFB128 test vectors from:
1547 *
1548 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
1549 */
Yanray Wang62c99912023-05-11 11:06:53 +08001550static const unsigned char aes_test_cfb128_key[][32] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001551{
1552 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1553 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001554#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001555 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1556 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1557 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1558 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1559 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1560 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1561 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001562#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001563};
1564
1565static const unsigned char aes_test_cfb128_iv[16] =
1566{
1567 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1568 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1569};
1570
1571static const unsigned char aes_test_cfb128_pt[64] =
1572{
1573 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1574 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1575 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1576 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1577 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1578 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1579 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1580 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1581};
1582
Yanray Wang62c99912023-05-11 11:06:53 +08001583static const unsigned char aes_test_cfb128_ct[][64] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001584{
1585 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1586 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1587 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F,
1588 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B,
1589 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40,
1590 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF,
1591 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E,
1592 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 },
Yanray Wang62c99912023-05-11 11:06:53 +08001593#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001594 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1595 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1596 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21,
1597 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A,
1598 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1,
1599 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9,
1600 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0,
1601 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF },
1602 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1603 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1604 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8,
1605 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B,
1606 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92,
1607 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9,
1608 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8,
1609 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 }
Yanray Wang62c99912023-05-11 11:06:53 +08001610#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001611};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001612#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001613
Simon Butcherad4e4932018-04-29 00:43:47 +01001614#if defined(MBEDTLS_CIPHER_MODE_OFB)
1615/*
1616 * AES-OFB test vectors from:
1617 *
Simon Butcher5db13622018-06-04 22:11:25 +01001618 * https://csrc.nist.gov/publications/detail/sp/800-38a/final
Simon Butcherad4e4932018-04-29 00:43:47 +01001619 */
Yanray Wang62c99912023-05-11 11:06:53 +08001620static const unsigned char aes_test_ofb_key[][32] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001621{
1622 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1623 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001624#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001625 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1626 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1627 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1628 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1629 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1630 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1631 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001632#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001633};
1634
1635static const unsigned char aes_test_ofb_iv[16] =
1636{
1637 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1638 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1639};
1640
1641static const unsigned char aes_test_ofb_pt[64] =
1642{
1643 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1644 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1645 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1646 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1647 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1648 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1649 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1650 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1651};
1652
Yanray Wang62c99912023-05-11 11:06:53 +08001653static const unsigned char aes_test_ofb_ct[][64] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001654{
1655 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1656 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1657 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
1658 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
1659 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
1660 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
1661 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
1662 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e },
Yanray Wang62c99912023-05-11 11:06:53 +08001663#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001664 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1665 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1666 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
1667 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
1668 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f,
1669 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
1670 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e,
1671 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a },
1672 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1673 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1674 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
1675 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
1676 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed,
1677 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
1678 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8,
1679 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 }
Yanray Wang62c99912023-05-11 11:06:53 +08001680#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001681};
1682#endif /* MBEDTLS_CIPHER_MODE_OFB */
1683
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001684#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001685/*
1686 * AES-CTR test vectors from:
1687 *
1688 * http://www.faqs.org/rfcs/rfc3686.html
1689 */
1690
Yanray Wang62c99912023-05-11 11:06:53 +08001691static const unsigned char aes_test_ctr_key[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001692{
1693 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
1694 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
1695 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
1696 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
1697 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
1698 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
1699};
1700
Yanray Wang62c99912023-05-11 11:06:53 +08001701static const unsigned char aes_test_ctr_nonce_counter[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001702{
1703 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
1704 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
1705 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
1706 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
1707 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
1708 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
1709};
1710
Yanray Wang62c99912023-05-11 11:06:53 +08001711static const unsigned char aes_test_ctr_pt[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001712{
1713 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
1714 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001715 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1716 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1717 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1718 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
1719
1720 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1721 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1722 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1723 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
1724 0x20, 0x21, 0x22, 0x23 }
1725};
1726
Yanray Wang62c99912023-05-11 11:06:53 +08001727static const unsigned char aes_test_ctr_ct[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001728{
1729 { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79,
1730 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 },
1731 { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9,
1732 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88,
1733 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8,
1734 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 },
1735 { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
1736 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
1737 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
1738 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
1739 0x25, 0xB2, 0x07, 0x2F }
1740};
1741
1742static const int aes_test_ctr_len[3] =
Gilles Peskine449bd832023-01-11 14:50:10 +01001743{ 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001744#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00001745
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001746#if defined(MBEDTLS_CIPHER_MODE_XTS)
1747/*
1748 * AES-XTS test vectors from:
1749 *
1750 * IEEE P1619/D16 Annex B
1751 * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf
1752 * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf)
1753 */
1754static const unsigned char aes_test_xts_key[][32] =
1755{
1756 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1757 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1758 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1759 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1760 { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1761 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1762 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1763 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1764 { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
1765 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
1766 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1767 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1768};
1769
1770static const unsigned char aes_test_xts_pt32[][32] =
1771{
1772 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1773 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1774 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1775 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1776 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1777 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1778 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1779 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1780 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1781 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1782 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1783 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1784};
1785
1786static const unsigned char aes_test_xts_ct32[][32] =
1787{
1788 { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec,
1789 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92,
1790 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85,
1791 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e },
1792 { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e,
1793 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b,
1794 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4,
1795 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 },
1796 { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a,
1797 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2,
1798 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53,
1799 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 },
1800};
1801
1802static const unsigned char aes_test_xts_data_unit[][16] =
1803{
Gilles Peskine449bd832023-01-11 14:50:10 +01001804 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1805 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1806 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1807 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1808 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1809 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001810};
1811
1812#endif /* MBEDTLS_CIPHER_MODE_XTS */
1813
Paul Bakker5121ce52009-01-03 21:22:43 +00001814/*
1815 * Checkup routine
1816 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001817int mbedtls_aes_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +00001818{
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001819 int ret = 0, i, j, u, mode;
1820 unsigned int keybits;
Paul Bakker5121ce52009-01-03 21:22:43 +00001821 unsigned char key[32];
1822 unsigned char buf[64];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001823 const unsigned char *aes_tests;
Andrzej Kurek252283f2022-09-27 07:54:16 -04001824#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1825 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001826 unsigned char iv[16];
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03001827#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001828#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +02001829 unsigned char prv[16];
1830#endif
Simon Butcher2ff0e522018-06-14 09:57:07 +01001831#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1832 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker27fdf462011-06-09 13:55:13 +00001833 size_t offset;
Paul Bakkere91d01e2011-04-19 15:55:50 +00001834#endif
Simon Butcher66a89032018-06-15 18:20:29 +01001835#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS)
Paul Bakkere91d01e2011-04-19 15:55:50 +00001836 int len;
Simon Butcher66a89032018-06-15 18:20:29 +01001837#endif
1838#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001839 unsigned char nonce_counter[16];
1840 unsigned char stream_block[16];
1841#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001842 mbedtls_aes_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001843
Gilles Peskine449bd832023-01-11 14:50:10 +01001844 memset(key, 0, 32);
1845 mbedtls_aes_init(&ctx);
Paul Bakker5121ce52009-01-03 21:22:43 +00001846
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001847 if (verbose != 0) {
1848#if defined(MBEDTLS_AES_ALT)
1849 mbedtls_printf(" AES note: alternative implementation.\n");
1850#else /* MBEDTLS_AES_ALT */
1851#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
1852 if (mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE)) {
1853 mbedtls_printf(" AES note: using VIA Padlock.\n");
1854 } else
1855#endif
1856#if defined(MBEDTLS_AESNI_HAVE_CODE)
1857 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1858 mbedtls_printf(" AES note: using AESNI.\n");
1859 } else
1860#endif
1861#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
1862 if (mbedtls_aesce_has_support()) {
1863 mbedtls_printf(" AES note: using AESCE.\n");
1864 } else
1865#endif
1866 mbedtls_printf(" AES note: built-in implementation.\n");
1867#endif /* MBEDTLS_AES_ALT */
1868 }
1869
Paul Bakker5121ce52009-01-03 21:22:43 +00001870 /*
1871 * ECB mode
1872 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001873 {
1874 static const int num_tests =
1875 sizeof(aes_test_ecb_dec) / sizeof(*aes_test_ecb_dec);
Paul Bakker5121ce52009-01-03 21:22:43 +00001876
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001877 for (i = 0; i < num_tests << 1; i++) {
1878 u = i >> 1;
1879 keybits = 128 + u * 64;
1880 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001881
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001882 if (verbose != 0) {
1883 mbedtls_printf(" AES-ECB-%3u (%s): ", keybits,
1884 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
1885 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08001886
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001887 memset(buf, 0, 16);
Gilles Peskine449bd832023-01-11 14:50:10 +01001888
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001889 if (mode == MBEDTLS_AES_DECRYPT) {
1890 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1891 aes_tests = aes_test_ecb_dec[u];
1892 } else {
1893 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
1894 aes_tests = aes_test_ecb_enc[u];
1895 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001896
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001897 /*
1898 * AES-192 is an optional feature that may be unavailable when
1899 * there is an alternative underlying implementation i.e. when
1900 * MBEDTLS_AES_ALT is defined.
1901 */
1902 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1903 mbedtls_printf("skipped\n");
1904 continue;
1905 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001906 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001907 }
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001908
1909 for (j = 0; j < 10000; j++) {
1910 ret = mbedtls_aes_crypt_ecb(&ctx, mode, buf, buf);
1911 if (ret != 0) {
1912 goto exit;
1913 }
1914 }
1915
1916 if (memcmp(buf, aes_tests, 16) != 0) {
1917 ret = 1;
1918 goto exit;
1919 }
1920
1921 if (verbose != 0) {
1922 mbedtls_printf("passed\n");
1923 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001924 }
1925
Gilles Peskine449bd832023-01-11 14:50:10 +01001926 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001927 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01001928 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001929 }
1930
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001931#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001932 /*
1933 * CBC mode
1934 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001935 {
1936 static const int num_tests =
1937 sizeof(aes_test_cbc_dec) / sizeof(*aes_test_cbc_dec);
Paul Bakker5121ce52009-01-03 21:22:43 +00001938
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001939 for (i = 0; i < num_tests << 1; i++) {
1940 u = i >> 1;
1941 keybits = 128 + u * 64;
1942 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001943
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001944 if (verbose != 0) {
1945 mbedtls_printf(" AES-CBC-%3u (%s): ", keybits,
1946 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00001947 }
1948
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001949 memset(iv, 0, 16);
1950 memset(prv, 0, 16);
1951 memset(buf, 0, 16);
1952
1953 if (mode == MBEDTLS_AES_DECRYPT) {
1954 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1955 aes_tests = aes_test_cbc_dec[u];
1956 } else {
1957 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
1958 aes_tests = aes_test_cbc_enc[u];
1959 }
1960
1961 /*
1962 * AES-192 is an optional feature that may be unavailable when
1963 * there is an alternative underlying implementation i.e. when
1964 * MBEDTLS_AES_ALT is defined.
1965 */
1966 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1967 mbedtls_printf("skipped\n");
1968 continue;
1969 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001970 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001971 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001972
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001973 for (j = 0; j < 10000; j++) {
1974 if (mode == MBEDTLS_AES_ENCRYPT) {
1975 unsigned char tmp[16];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001976
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001977 memcpy(tmp, prv, 16);
1978 memcpy(prv, buf, 16);
1979 memcpy(buf, tmp, 16);
1980 }
1981
1982 ret = mbedtls_aes_crypt_cbc(&ctx, mode, 16, iv, buf, buf);
1983 if (ret != 0) {
1984 goto exit;
1985 }
1986
1987 }
1988
1989 if (memcmp(buf, aes_tests, 16) != 0) {
1990 ret = 1;
1991 goto exit;
1992 }
1993
1994 if (verbose != 0) {
1995 mbedtls_printf("passed\n");
1996 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001997 }
1998
Gilles Peskine449bd832023-01-11 14:50:10 +01001999 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002000 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002001 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002002 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002003#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00002004
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002005#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00002006 /*
2007 * CFB128 mode
2008 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002009 {
2010 static const int num_tests =
2011 sizeof(aes_test_cfb128_key) / sizeof(*aes_test_cfb128_key);
Paul Bakker5121ce52009-01-03 21:22:43 +00002012
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002013 for (i = 0; i < num_tests << 1; i++) {
2014 u = i >> 1;
2015 keybits = 128 + u * 64;
2016 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00002017
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002018 if (verbose != 0) {
2019 mbedtls_printf(" AES-CFB128-%3u (%s): ", keybits,
2020 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2021 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08002022
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002023 memcpy(iv, aes_test_cfb128_iv, 16);
2024 memcpy(key, aes_test_cfb128_key[u], keybits / 8);
Paul Bakker5121ce52009-01-03 21:22:43 +00002025
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002026 offset = 0;
2027 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2028 /*
2029 * AES-192 is an optional feature that may be unavailable when
2030 * there is an alternative underlying implementation i.e. when
2031 * MBEDTLS_AES_ALT is defined.
2032 */
2033 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2034 mbedtls_printf("skipped\n");
2035 continue;
2036 } else if (ret != 0) {
2037 goto exit;
2038 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002039
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002040 if (mode == MBEDTLS_AES_DECRYPT) {
2041 memcpy(buf, aes_test_cfb128_ct[u], 64);
2042 aes_tests = aes_test_cfb128_pt;
2043 } else {
2044 memcpy(buf, aes_test_cfb128_pt, 64);
2045 aes_tests = aes_test_cfb128_ct[u];
2046 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002047
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002048 ret = mbedtls_aes_crypt_cfb128(&ctx, mode, 64, &offset, iv, buf, buf);
2049 if (ret != 0) {
2050 goto exit;
2051 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002052
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002053 if (memcmp(buf, aes_tests, 64) != 0) {
2054 ret = 1;
2055 goto exit;
2056 }
2057
2058 if (verbose != 0) {
2059 mbedtls_printf("passed\n");
2060 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002061 }
2062
Gilles Peskine449bd832023-01-11 14:50:10 +01002063 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002064 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002065 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002066 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002067#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002068
Simon Butcherad4e4932018-04-29 00:43:47 +01002069#if defined(MBEDTLS_CIPHER_MODE_OFB)
2070 /*
2071 * OFB mode
2072 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002073 {
2074 static const int num_tests =
2075 sizeof(aes_test_ofb_key) / sizeof(*aes_test_ofb_key);
Simon Butcherad4e4932018-04-29 00:43:47 +01002076
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002077 for (i = 0; i < num_tests << 1; i++) {
2078 u = i >> 1;
2079 keybits = 128 + u * 64;
2080 mode = i & 1;
Simon Butcherad4e4932018-04-29 00:43:47 +01002081
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002082 if (verbose != 0) {
2083 mbedtls_printf(" AES-OFB-%3u (%s): ", keybits,
2084 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2085 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08002086
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002087 memcpy(iv, aes_test_ofb_iv, 16);
2088 memcpy(key, aes_test_ofb_key[u], keybits / 8);
Simon Butcherad4e4932018-04-29 00:43:47 +01002089
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002090 offset = 0;
2091 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2092 /*
2093 * AES-192 is an optional feature that may be unavailable when
2094 * there is an alternative underlying implementation i.e. when
2095 * MBEDTLS_AES_ALT is defined.
2096 */
2097 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2098 mbedtls_printf("skipped\n");
2099 continue;
2100 } else if (ret != 0) {
2101 goto exit;
2102 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002103
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002104 if (mode == MBEDTLS_AES_DECRYPT) {
2105 memcpy(buf, aes_test_ofb_ct[u], 64);
2106 aes_tests = aes_test_ofb_pt;
2107 } else {
2108 memcpy(buf, aes_test_ofb_pt, 64);
2109 aes_tests = aes_test_ofb_ct[u];
2110 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002111
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002112 ret = mbedtls_aes_crypt_ofb(&ctx, 64, &offset, iv, buf, buf);
2113 if (ret != 0) {
2114 goto exit;
2115 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002116
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002117 if (memcmp(buf, aes_tests, 64) != 0) {
2118 ret = 1;
2119 goto exit;
2120 }
2121
2122 if (verbose != 0) {
2123 mbedtls_printf("passed\n");
2124 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002125 }
2126
Gilles Peskine449bd832023-01-11 14:50:10 +01002127 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002128 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002129 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002130 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002131#endif /* MBEDTLS_CIPHER_MODE_OFB */
2132
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002133#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002134 /*
2135 * CTR mode
2136 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002137 {
2138 static const int num_tests =
2139 sizeof(aes_test_ctr_key) / sizeof(*aes_test_ctr_key);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002140
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002141 for (i = 0; i < num_tests << 1; i++) {
2142 u = i >> 1;
2143 mode = i & 1;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002144
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002145 if (verbose != 0) {
2146 mbedtls_printf(" AES-CTR-128 (%s): ",
2147 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2148 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002149
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002150 memcpy(nonce_counter, aes_test_ctr_nonce_counter[u], 16);
2151 memcpy(key, aes_test_ctr_key[u], 16);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002152
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002153 offset = 0;
2154 if ((ret = mbedtls_aes_setkey_enc(&ctx, key, 128)) != 0) {
2155 goto exit;
2156 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002157
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002158 len = aes_test_ctr_len[u];
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002159
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002160 if (mode == MBEDTLS_AES_DECRYPT) {
2161 memcpy(buf, aes_test_ctr_ct[u], len);
2162 aes_tests = aes_test_ctr_pt[u];
2163 } else {
2164 memcpy(buf, aes_test_ctr_pt[u], len);
2165 aes_tests = aes_test_ctr_ct[u];
2166 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002167
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002168 ret = mbedtls_aes_crypt_ctr(&ctx, len, &offset, nonce_counter,
2169 stream_block, buf, buf);
2170 if (ret != 0) {
2171 goto exit;
2172 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002173
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002174 if (memcmp(buf, aes_tests, len) != 0) {
2175 ret = 1;
2176 goto exit;
2177 }
2178
2179 if (verbose != 0) {
2180 mbedtls_printf("passed\n");
2181 }
Gilles Peskine449bd832023-01-11 14:50:10 +01002182 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002183 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002184
Gilles Peskine449bd832023-01-11 14:50:10 +01002185 if (verbose != 0) {
2186 mbedtls_printf("\n");
2187 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002188#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00002189
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002190#if defined(MBEDTLS_CIPHER_MODE_XTS)
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002191 /*
2192 * XTS mode
2193 */
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002194 {
Gilles Peskine449bd832023-01-11 14:50:10 +01002195 static const int num_tests =
2196 sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key);
2197 mbedtls_aes_xts_context ctx_xts;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002198
Gilles Peskine449bd832023-01-11 14:50:10 +01002199 mbedtls_aes_xts_init(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002200
Gilles Peskine449bd832023-01-11 14:50:10 +01002201 for (i = 0; i < num_tests << 1; i++) {
2202 const unsigned char *data_unit;
2203 u = i >> 1;
2204 mode = i & 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002205
Gilles Peskine449bd832023-01-11 14:50:10 +01002206 if (verbose != 0) {
2207 mbedtls_printf(" AES-XTS-128 (%s): ",
2208 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2209 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002210
Gilles Peskine449bd832023-01-11 14:50:10 +01002211 memset(key, 0, sizeof(key));
2212 memcpy(key, aes_test_xts_key[u], 32);
2213 data_unit = aes_test_xts_data_unit[u];
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002214
Gilles Peskine449bd832023-01-11 14:50:10 +01002215 len = sizeof(*aes_test_xts_ct32);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002216
Gilles Peskine449bd832023-01-11 14:50:10 +01002217 if (mode == MBEDTLS_AES_DECRYPT) {
2218 ret = mbedtls_aes_xts_setkey_dec(&ctx_xts, key, 256);
2219 if (ret != 0) {
2220 goto exit;
2221 }
2222 memcpy(buf, aes_test_xts_ct32[u], len);
2223 aes_tests = aes_test_xts_pt32[u];
2224 } else {
2225 ret = mbedtls_aes_xts_setkey_enc(&ctx_xts, key, 256);
2226 if (ret != 0) {
2227 goto exit;
2228 }
2229 memcpy(buf, aes_test_xts_pt32[u], len);
2230 aes_tests = aes_test_xts_ct32[u];
2231 }
2232
2233
2234 ret = mbedtls_aes_crypt_xts(&ctx_xts, mode, len, data_unit,
2235 buf, buf);
2236 if (ret != 0) {
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002237 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002238 }
2239
2240 if (memcmp(buf, aes_tests, len) != 0) {
2241 ret = 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002242 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002243 }
2244
2245 if (verbose != 0) {
2246 mbedtls_printf("passed\n");
2247 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002248 }
2249
Gilles Peskine449bd832023-01-11 14:50:10 +01002250 if (verbose != 0) {
2251 mbedtls_printf("\n");
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002252 }
2253
Gilles Peskine449bd832023-01-11 14:50:10 +01002254 mbedtls_aes_xts_free(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002255 }
2256#endif /* MBEDTLS_CIPHER_MODE_XTS */
2257
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002258 ret = 0;
2259
2260exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01002261 if (ret != 0 && verbose != 0) {
2262 mbedtls_printf("failed\n");
2263 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002264
Gilles Peskine449bd832023-01-11 14:50:10 +01002265 mbedtls_aes_free(&ctx);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002266
Gilles Peskine449bd832023-01-11 14:50:10 +01002267 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002268}
2269
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002270#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002271
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002272#endif /* MBEDTLS_AES_C */