blob: 8e35d48b5dd28de3a5fc5480daf052337ca5cd7d [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)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000037#include "mbedtls/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)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000040#include "mbedtls/aesni.h"
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +010041#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000042
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000043#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010044
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020045#if !defined(MBEDTLS_AES_ALT)
Paul Bakker90995b52013-06-24 19:20:35 +020046
Manuel Pégourié-Gonnard0e9cddb2018-12-10 16:37:51 +010047/* Parameter validation macros based on platform_util.h */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010048#define AES_VALIDATE_RET(cond) \
49 MBEDTLS_INTERNAL_VALIDATE_RET(cond, MBEDTLS_ERR_AES_BAD_INPUT_DATA)
50#define AES_VALIDATE(cond) \
51 MBEDTLS_INTERNAL_VALIDATE(cond)
Manuel Pégourié-Gonnard0e9cddb2018-12-10 16:37:51 +010052
Gilles Peskine30c356c2023-03-16 14:58:46 +010053#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Paul Bakker048d04e2012-02-12 17:31:04 +000054static int aes_padlock_ace = -1;
55#endif
56
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020057#if defined(MBEDTLS_AES_ROM_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +000058/*
59 * Forward S-box
60 */
61static const unsigned char FSb[256] =
62{
63 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
64 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
65 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
66 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
67 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
68 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
69 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
70 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
71 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
72 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
73 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
74 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
75 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
76 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
77 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
78 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
79 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
80 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
81 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
82 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
83 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
84 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
85 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
86 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
87 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
88 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
89 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
90 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
91 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
92 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
93 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
94 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
95};
96
97/*
98 * Forward tables
99 */
100#define FT \
101\
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100102 V(A5, 63, 63, C6), V(84, 7C, 7C, F8), V(99, 77, 77, EE), V(8D, 7B, 7B, F6), \
103 V(0D, F2, F2, FF), V(BD, 6B, 6B, D6), V(B1, 6F, 6F, DE), V(54, C5, C5, 91), \
104 V(50, 30, 30, 60), V(03, 01, 01, 02), V(A9, 67, 67, CE), V(7D, 2B, 2B, 56), \
105 V(19, FE, FE, E7), V(62, D7, D7, B5), V(E6, AB, AB, 4D), V(9A, 76, 76, EC), \
106 V(45, CA, CA, 8F), V(9D, 82, 82, 1F), V(40, C9, C9, 89), V(87, 7D, 7D, FA), \
107 V(15, FA, FA, EF), V(EB, 59, 59, B2), V(C9, 47, 47, 8E), V(0B, F0, F0, FB), \
108 V(EC, AD, AD, 41), V(67, D4, D4, B3), V(FD, A2, A2, 5F), V(EA, AF, AF, 45), \
109 V(BF, 9C, 9C, 23), V(F7, A4, A4, 53), V(96, 72, 72, E4), V(5B, C0, C0, 9B), \
110 V(C2, B7, B7, 75), V(1C, FD, FD, E1), V(AE, 93, 93, 3D), V(6A, 26, 26, 4C), \
111 V(5A, 36, 36, 6C), V(41, 3F, 3F, 7E), V(02, F7, F7, F5), V(4F, CC, CC, 83), \
112 V(5C, 34, 34, 68), V(F4, A5, A5, 51), V(34, E5, E5, D1), V(08, F1, F1, F9), \
113 V(93, 71, 71, E2), V(73, D8, D8, AB), V(53, 31, 31, 62), V(3F, 15, 15, 2A), \
114 V(0C, 04, 04, 08), V(52, C7, C7, 95), V(65, 23, 23, 46), V(5E, C3, C3, 9D), \
115 V(28, 18, 18, 30), V(A1, 96, 96, 37), V(0F, 05, 05, 0A), V(B5, 9A, 9A, 2F), \
116 V(09, 07, 07, 0E), V(36, 12, 12, 24), V(9B, 80, 80, 1B), V(3D, E2, E2, DF), \
117 V(26, EB, EB, CD), V(69, 27, 27, 4E), V(CD, B2, B2, 7F), V(9F, 75, 75, EA), \
118 V(1B, 09, 09, 12), V(9E, 83, 83, 1D), V(74, 2C, 2C, 58), V(2E, 1A, 1A, 34), \
119 V(2D, 1B, 1B, 36), V(B2, 6E, 6E, DC), V(EE, 5A, 5A, B4), V(FB, A0, A0, 5B), \
120 V(F6, 52, 52, A4), V(4D, 3B, 3B, 76), V(61, D6, D6, B7), V(CE, B3, B3, 7D), \
121 V(7B, 29, 29, 52), V(3E, E3, E3, DD), V(71, 2F, 2F, 5E), V(97, 84, 84, 13), \
122 V(F5, 53, 53, A6), V(68, D1, D1, B9), V(00, 00, 00, 00), V(2C, ED, ED, C1), \
123 V(60, 20, 20, 40), V(1F, FC, FC, E3), V(C8, B1, B1, 79), V(ED, 5B, 5B, B6), \
124 V(BE, 6A, 6A, D4), V(46, CB, CB, 8D), V(D9, BE, BE, 67), V(4B, 39, 39, 72), \
125 V(DE, 4A, 4A, 94), V(D4, 4C, 4C, 98), V(E8, 58, 58, B0), V(4A, CF, CF, 85), \
126 V(6B, D0, D0, BB), V(2A, EF, EF, C5), V(E5, AA, AA, 4F), V(16, FB, FB, ED), \
127 V(C5, 43, 43, 86), V(D7, 4D, 4D, 9A), V(55, 33, 33, 66), V(94, 85, 85, 11), \
128 V(CF, 45, 45, 8A), V(10, F9, F9, E9), V(06, 02, 02, 04), V(81, 7F, 7F, FE), \
129 V(F0, 50, 50, A0), V(44, 3C, 3C, 78), V(BA, 9F, 9F, 25), V(E3, A8, A8, 4B), \
130 V(F3, 51, 51, A2), V(FE, A3, A3, 5D), V(C0, 40, 40, 80), V(8A, 8F, 8F, 05), \
131 V(AD, 92, 92, 3F), V(BC, 9D, 9D, 21), V(48, 38, 38, 70), V(04, F5, F5, F1), \
132 V(DF, BC, BC, 63), V(C1, B6, B6, 77), V(75, DA, DA, AF), V(63, 21, 21, 42), \
133 V(30, 10, 10, 20), V(1A, FF, FF, E5), V(0E, F3, F3, FD), V(6D, D2, D2, BF), \
134 V(4C, CD, CD, 81), V(14, 0C, 0C, 18), V(35, 13, 13, 26), V(2F, EC, EC, C3), \
135 V(E1, 5F, 5F, BE), V(A2, 97, 97, 35), V(CC, 44, 44, 88), V(39, 17, 17, 2E), \
136 V(57, C4, C4, 93), V(F2, A7, A7, 55), V(82, 7E, 7E, FC), V(47, 3D, 3D, 7A), \
137 V(AC, 64, 64, C8), V(E7, 5D, 5D, BA), V(2B, 19, 19, 32), V(95, 73, 73, E6), \
138 V(A0, 60, 60, C0), V(98, 81, 81, 19), V(D1, 4F, 4F, 9E), V(7F, DC, DC, A3), \
139 V(66, 22, 22, 44), V(7E, 2A, 2A, 54), V(AB, 90, 90, 3B), V(83, 88, 88, 0B), \
140 V(CA, 46, 46, 8C), V(29, EE, EE, C7), V(D3, B8, B8, 6B), V(3C, 14, 14, 28), \
141 V(79, DE, DE, A7), V(E2, 5E, 5E, BC), V(1D, 0B, 0B, 16), V(76, DB, DB, AD), \
142 V(3B, E0, E0, DB), V(56, 32, 32, 64), V(4E, 3A, 3A, 74), V(1E, 0A, 0A, 14), \
143 V(DB, 49, 49, 92), V(0A, 06, 06, 0C), V(6C, 24, 24, 48), V(E4, 5C, 5C, B8), \
144 V(5D, C2, C2, 9F), V(6E, D3, D3, BD), V(EF, AC, AC, 43), V(A6, 62, 62, C4), \
145 V(A8, 91, 91, 39), V(A4, 95, 95, 31), V(37, E4, E4, D3), V(8B, 79, 79, F2), \
146 V(32, E7, E7, D5), V(43, C8, C8, 8B), V(59, 37, 37, 6E), V(B7, 6D, 6D, DA), \
147 V(8C, 8D, 8D, 01), V(64, D5, D5, B1), V(D2, 4E, 4E, 9C), V(E0, A9, A9, 49), \
148 V(B4, 6C, 6C, D8), V(FA, 56, 56, AC), V(07, F4, F4, F3), V(25, EA, EA, CF), \
149 V(AF, 65, 65, CA), V(8E, 7A, 7A, F4), V(E9, AE, AE, 47), V(18, 08, 08, 10), \
150 V(D5, BA, BA, 6F), V(88, 78, 78, F0), V(6F, 25, 25, 4A), V(72, 2E, 2E, 5C), \
151 V(24, 1C, 1C, 38), V(F1, A6, A6, 57), V(C7, B4, B4, 73), V(51, C6, C6, 97), \
152 V(23, E8, E8, CB), V(7C, DD, DD, A1), V(9C, 74, 74, E8), V(21, 1F, 1F, 3E), \
153 V(DD, 4B, 4B, 96), V(DC, BD, BD, 61), V(86, 8B, 8B, 0D), V(85, 8A, 8A, 0F), \
154 V(90, 70, 70, E0), V(42, 3E, 3E, 7C), V(C4, B5, B5, 71), V(AA, 66, 66, CC), \
155 V(D8, 48, 48, 90), V(05, 03, 03, 06), V(01, F6, F6, F7), V(12, 0E, 0E, 1C), \
156 V(A3, 61, 61, C2), V(5F, 35, 35, 6A), V(F9, 57, 57, AE), V(D0, B9, B9, 69), \
157 V(91, 86, 86, 17), V(58, C1, C1, 99), V(27, 1D, 1D, 3A), V(B9, 9E, 9E, 27), \
158 V(38, E1, E1, D9), V(13, F8, F8, EB), V(B3, 98, 98, 2B), V(33, 11, 11, 22), \
159 V(BB, 69, 69, D2), V(70, D9, D9, A9), V(89, 8E, 8E, 07), V(A7, 94, 94, 33), \
160 V(B6, 9B, 9B, 2D), V(22, 1E, 1E, 3C), V(92, 87, 87, 15), V(20, E9, E9, C9), \
161 V(49, CE, CE, 87), V(FF, 55, 55, AA), V(78, 28, 28, 50), V(7A, DF, DF, A5), \
162 V(8F, 8C, 8C, 03), V(F8, A1, A1, 59), V(80, 89, 89, 09), V(17, 0D, 0D, 1A), \
163 V(DA, BF, BF, 65), V(31, E6, E6, D7), V(C6, 42, 42, 84), V(B8, 68, 68, D0), \
164 V(C3, 41, 41, 82), V(B0, 99, 99, 29), V(77, 2D, 2D, 5A), V(11, 0F, 0F, 1E), \
165 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 +0000166
Gilles Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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 Peskine1b6c09a2023-01-11 14:52:35 +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
Hanno Becker177d3cf2017-06-07 15:52:48 +0100185#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200186
Paul Bakker5121ce52009-01-03 21:22:43 +0000187#undef FT
188
Dave Rodgmandbae1842023-06-27 18:27:31 +0100189#if !(defined(MBEDTLS_AES_SETKEY_ENC_ALT) && defined(MBEDTLS_AES_DECRYPT_ALT))
Paul Bakker5121ce52009-01-03 21:22:43 +0000190/*
191 * Reverse S-box
192 */
193static const unsigned char RSb[256] =
194{
195 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
196 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
197 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
198 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
199 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
200 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
201 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
202 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
203 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
204 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
205 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
206 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
207 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
208 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
209 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
210 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
211 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
212 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
213 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
214 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
215 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
216 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
217 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
218 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
219 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
220 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
221 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
222 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
223 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
224 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
225 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
226 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
227};
Dave Rodgmandbae1842023-06-27 18:27:31 +0100228#endif /* !(defined(MBEDTLS_AES_SETKEY_ENC_ALT) && defined(MBEDTLS_AES_DECRYPT_ALT)) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000229
230/*
231 * Reverse tables
232 */
233#define RT \
234\
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100235 V(50, A7, F4, 51), V(53, 65, 41, 7E), V(C3, A4, 17, 1A), V(96, 5E, 27, 3A), \
236 V(CB, 6B, AB, 3B), V(F1, 45, 9D, 1F), V(AB, 58, FA, AC), V(93, 03, E3, 4B), \
237 V(55, FA, 30, 20), V(F6, 6D, 76, AD), V(91, 76, CC, 88), V(25, 4C, 02, F5), \
238 V(FC, D7, E5, 4F), V(D7, CB, 2A, C5), V(80, 44, 35, 26), V(8F, A3, 62, B5), \
239 V(49, 5A, B1, DE), V(67, 1B, BA, 25), V(98, 0E, EA, 45), V(E1, C0, FE, 5D), \
240 V(02, 75, 2F, C3), V(12, F0, 4C, 81), V(A3, 97, 46, 8D), V(C6, F9, D3, 6B), \
241 V(E7, 5F, 8F, 03), V(95, 9C, 92, 15), V(EB, 7A, 6D, BF), V(DA, 59, 52, 95), \
242 V(2D, 83, BE, D4), V(D3, 21, 74, 58), V(29, 69, E0, 49), V(44, C8, C9, 8E), \
243 V(6A, 89, C2, 75), V(78, 79, 8E, F4), V(6B, 3E, 58, 99), V(DD, 71, B9, 27), \
244 V(B6, 4F, E1, BE), V(17, AD, 88, F0), V(66, AC, 20, C9), V(B4, 3A, CE, 7D), \
245 V(18, 4A, DF, 63), V(82, 31, 1A, E5), V(60, 33, 51, 97), V(45, 7F, 53, 62), \
246 V(E0, 77, 64, B1), V(84, AE, 6B, BB), V(1C, A0, 81, FE), V(94, 2B, 08, F9), \
247 V(58, 68, 48, 70), V(19, FD, 45, 8F), V(87, 6C, DE, 94), V(B7, F8, 7B, 52), \
248 V(23, D3, 73, AB), V(E2, 02, 4B, 72), V(57, 8F, 1F, E3), V(2A, AB, 55, 66), \
249 V(07, 28, EB, B2), V(03, C2, B5, 2F), V(9A, 7B, C5, 86), V(A5, 08, 37, D3), \
250 V(F2, 87, 28, 30), V(B2, A5, BF, 23), V(BA, 6A, 03, 02), V(5C, 82, 16, ED), \
251 V(2B, 1C, CF, 8A), V(92, B4, 79, A7), V(F0, F2, 07, F3), V(A1, E2, 69, 4E), \
252 V(CD, F4, DA, 65), V(D5, BE, 05, 06), V(1F, 62, 34, D1), V(8A, FE, A6, C4), \
253 V(9D, 53, 2E, 34), V(A0, 55, F3, A2), V(32, E1, 8A, 05), V(75, EB, F6, A4), \
254 V(39, EC, 83, 0B), V(AA, EF, 60, 40), V(06, 9F, 71, 5E), V(51, 10, 6E, BD), \
255 V(F9, 8A, 21, 3E), V(3D, 06, DD, 96), V(AE, 05, 3E, DD), V(46, BD, E6, 4D), \
256 V(B5, 8D, 54, 91), V(05, 5D, C4, 71), V(6F, D4, 06, 04), V(FF, 15, 50, 60), \
257 V(24, FB, 98, 19), V(97, E9, BD, D6), V(CC, 43, 40, 89), V(77, 9E, D9, 67), \
258 V(BD, 42, E8, B0), V(88, 8B, 89, 07), V(38, 5B, 19, E7), V(DB, EE, C8, 79), \
259 V(47, 0A, 7C, A1), V(E9, 0F, 42, 7C), V(C9, 1E, 84, F8), V(00, 00, 00, 00), \
260 V(83, 86, 80, 09), V(48, ED, 2B, 32), V(AC, 70, 11, 1E), V(4E, 72, 5A, 6C), \
261 V(FB, FF, 0E, FD), V(56, 38, 85, 0F), V(1E, D5, AE, 3D), V(27, 39, 2D, 36), \
262 V(64, D9, 0F, 0A), V(21, A6, 5C, 68), V(D1, 54, 5B, 9B), V(3A, 2E, 36, 24), \
263 V(B1, 67, 0A, 0C), V(0F, E7, 57, 93), V(D2, 96, EE, B4), V(9E, 91, 9B, 1B), \
264 V(4F, C5, C0, 80), V(A2, 20, DC, 61), V(69, 4B, 77, 5A), V(16, 1A, 12, 1C), \
265 V(0A, BA, 93, E2), V(E5, 2A, A0, C0), V(43, E0, 22, 3C), V(1D, 17, 1B, 12), \
266 V(0B, 0D, 09, 0E), V(AD, C7, 8B, F2), V(B9, A8, B6, 2D), V(C8, A9, 1E, 14), \
267 V(85, 19, F1, 57), V(4C, 07, 75, AF), V(BB, DD, 99, EE), V(FD, 60, 7F, A3), \
268 V(9F, 26, 01, F7), V(BC, F5, 72, 5C), V(C5, 3B, 66, 44), V(34, 7E, FB, 5B), \
269 V(76, 29, 43, 8B), V(DC, C6, 23, CB), V(68, FC, ED, B6), V(63, F1, E4, B8), \
270 V(CA, DC, 31, D7), V(10, 85, 63, 42), V(40, 22, 97, 13), V(20, 11, C6, 84), \
271 V(7D, 24, 4A, 85), V(F8, 3D, BB, D2), V(11, 32, F9, AE), V(6D, A1, 29, C7), \
272 V(4B, 2F, 9E, 1D), V(F3, 30, B2, DC), V(EC, 52, 86, 0D), V(D0, E3, C1, 77), \
273 V(6C, 16, B3, 2B), V(99, B9, 70, A9), V(FA, 48, 94, 11), V(22, 64, E9, 47), \
274 V(C4, 8C, FC, A8), V(1A, 3F, F0, A0), V(D8, 2C, 7D, 56), V(EF, 90, 33, 22), \
275 V(C7, 4E, 49, 87), V(C1, D1, 38, D9), V(FE, A2, CA, 8C), V(36, 0B, D4, 98), \
276 V(CF, 81, F5, A6), V(28, DE, 7A, A5), V(26, 8E, B7, DA), V(A4, BF, AD, 3F), \
277 V(E4, 9D, 3A, 2C), V(0D, 92, 78, 50), V(9B, CC, 5F, 6A), V(62, 46, 7E, 54), \
278 V(C2, 13, 8D, F6), V(E8, B8, D8, 90), V(5E, F7, 39, 2E), V(F5, AF, C3, 82), \
279 V(BE, 80, 5D, 9F), V(7C, 93, D0, 69), V(A9, 2D, D5, 6F), V(B3, 12, 25, CF), \
280 V(3B, 99, AC, C8), V(A7, 7D, 18, 10), V(6E, 63, 9C, E8), V(7B, BB, 3B, DB), \
281 V(09, 78, 26, CD), V(F4, 18, 59, 6E), V(01, B7, 9A, EC), V(A8, 9A, 4F, 83), \
282 V(65, 6E, 95, E6), V(7E, E6, FF, AA), V(08, CF, BC, 21), V(E6, E8, 15, EF), \
283 V(D9, 9B, E7, BA), V(CE, 36, 6F, 4A), V(D4, 09, 9F, EA), V(D6, 7C, B0, 29), \
284 V(AF, B2, A4, 31), V(31, 23, 3F, 2A), V(30, 94, A5, C6), V(C0, 66, A2, 35), \
285 V(37, BC, 4E, 74), V(A6, CA, 82, FC), V(B0, D0, 90, E0), V(15, D8, A7, 33), \
286 V(4A, 98, 04, F1), V(F7, DA, EC, 41), V(0E, 50, CD, 7F), V(2F, F6, 91, 17), \
287 V(8D, D6, 4D, 76), V(4D, B0, EF, 43), V(54, 4D, AA, CC), V(DF, 04, 96, E4), \
288 V(E3, B5, D1, 9E), V(1B, 88, 6A, 4C), V(B8, 1F, 2C, C1), V(7F, 51, 65, 46), \
289 V(04, EA, 5E, 9D), V(5D, 35, 8C, 01), V(73, 74, 87, FA), V(2E, 41, 0B, FB), \
290 V(5A, 1D, 67, B3), V(52, D2, DB, 92), V(33, 56, 10, E9), V(13, 47, D6, 6D), \
291 V(8C, 61, D7, 9A), V(7A, 0C, A1, 37), V(8E, 14, F8, 59), V(89, 3C, 13, EB), \
292 V(EE, 27, A9, CE), V(35, C9, 61, B7), V(ED, E5, 1C, E1), V(3C, B1, 47, 7A), \
293 V(59, DF, D2, 9C), V(3F, 73, F2, 55), V(79, CE, 14, 18), V(BF, 37, C7, 73), \
294 V(EA, CD, F7, 53), V(5B, AA, FD, 5F), V(14, 6F, 3D, DF), V(86, DB, 44, 78), \
295 V(81, F3, AF, CA), V(3E, C4, 68, B9), V(2C, 34, 24, 38), V(5F, 40, A3, C2), \
296 V(72, C3, 1D, 16), V(0C, 25, E2, BC), V(8B, 49, 3C, 28), V(41, 95, 0D, FF), \
297 V(71, 01, A8, 39), V(DE, B3, 0C, 08), V(9C, E4, B4, D8), V(90, C1, 56, 64), \
298 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 +0000299
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100300#define V(a, b, c, d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000301static const uint32_t RT0[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000302#undef V
303
Hanno Beckerad049a92017-06-19 16:31:54 +0100304#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200305
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100306#define V(a, b, c, d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000307static const uint32_t RT1[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000308#undef V
309
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100310#define V(a, b, c, d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000311static const uint32_t RT2[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000312#undef V
313
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100314#define V(a, b, c, d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000315static const uint32_t RT3[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000316#undef V
317
Hanno Becker177d3cf2017-06-07 15:52:48 +0100318#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200319
Paul Bakker5121ce52009-01-03 21:22:43 +0000320#undef RT
321
Dave Rodgman36c8e582023-06-27 18:31:24 +0100322#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000323/*
324 * Round constants
325 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000326static const uint32_t RCON[10] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000327{
328 0x00000001, 0x00000002, 0x00000004, 0x00000008,
329 0x00000010, 0x00000020, 0x00000040, 0x00000080,
330 0x0000001B, 0x00000036
331};
Dave Rodgman36c8e582023-06-27 18:31:24 +0100332#endif /* !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000333
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200334#else /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000335
336/*
337 * Forward S-box & tables
338 */
339static unsigned char FSb[256];
Paul Bakker9af723c2014-05-01 13:03:14 +0200340static uint32_t FT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100341#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker9af723c2014-05-01 13:03:14 +0200342static uint32_t FT1[256];
343static uint32_t FT2[256];
344static uint32_t FT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100345#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000346
347/*
348 * Reverse S-box & tables
349 */
Dave Rodgmandbae1842023-06-27 18:27:31 +0100350#if !(defined(MBEDTLS_AES_SETKEY_ENC_ALT) && defined(MBEDTLS_AES_DECRYPT_ALT))
Paul Bakker5121ce52009-01-03 21:22:43 +0000351static unsigned char RSb[256];
Dave Rodgmandbae1842023-06-27 18:27:31 +0100352#endif
Paul Bakker5c2364c2012-10-01 14:41:15 +0000353static uint32_t RT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100354#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker5c2364c2012-10-01 14:41:15 +0000355static uint32_t RT1[256];
356static uint32_t RT2[256];
357static uint32_t RT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100358#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000359
Dave Rodgman1e6f7702023-06-27 18:16:13 +0100360#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000361/*
362 * Round constants
363 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000364static uint32_t RCON[10];
Paul Bakker5121ce52009-01-03 21:22:43 +0000365
366/*
367 * Tables generation code
368 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100369#define ROTL8(x) (((x) << 8) & 0xFFFFFFFF) | ((x) >> 24)
370#define XTIME(x) (((x) << 1) ^ (((x) & 0x80) ? 0x1B : 0x00))
371#define MUL(x, y) (((x) && (y)) ? pow[(log[(x)]+log[(y)]) % 255] : 0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000372
373static int aes_init_done = 0;
374
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100375static void aes_gen_tables(void)
Paul Bakker5121ce52009-01-03 21:22:43 +0000376{
377 int i, x, y, z;
378 int pow[256];
379 int log[256];
380
381 /*
382 * compute pow and log tables over GF(2^8)
383 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100384 for (i = 0, x = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000385 pow[i] = x;
386 log[x] = i;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100387 x = MBEDTLS_BYTE_0(x ^ XTIME(x));
Paul Bakker5121ce52009-01-03 21:22:43 +0000388 }
389
390 /*
391 * calculate the round constants
392 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100393 for (i = 0, x = 1; i < 10; i++) {
Paul Bakker5c2364c2012-10-01 14:41:15 +0000394 RCON[i] = (uint32_t) x;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100395 x = MBEDTLS_BYTE_0(XTIME(x));
Paul Bakker5121ce52009-01-03 21:22:43 +0000396 }
397
398 /*
399 * generate the forward and reverse S-boxes
400 */
401 FSb[0x00] = 0x63;
402 RSb[0x63] = 0x00;
403
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100404 for (i = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000405 x = pow[255 - log[i]];
406
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100407 y = x; y = MBEDTLS_BYTE_0((y << 1) | (y >> 7));
408 x ^= y; y = MBEDTLS_BYTE_0((y << 1) | (y >> 7));
409 x ^= y; y = MBEDTLS_BYTE_0((y << 1) | (y >> 7));
410 x ^= y; y = MBEDTLS_BYTE_0((y << 1) | (y >> 7));
Paul Bakker5121ce52009-01-03 21:22:43 +0000411 x ^= y ^ 0x63;
412
413 FSb[i] = (unsigned char) x;
414 RSb[x] = (unsigned char) i;
415 }
416
417 /*
418 * generate the forward and reverse tables
419 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100420 for (i = 0; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000421 x = FSb[i];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100422 y = MBEDTLS_BYTE_0(XTIME(x));
423 z = MBEDTLS_BYTE_0(y ^ x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000424
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100425 FT0[i] = ((uint32_t) y) ^
426 ((uint32_t) x << 8) ^
427 ((uint32_t) x << 16) ^
428 ((uint32_t) z << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000429
Hanno Beckerad049a92017-06-19 16:31:54 +0100430#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100431 FT1[i] = ROTL8(FT0[i]);
432 FT2[i] = ROTL8(FT1[i]);
433 FT3[i] = ROTL8(FT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100434#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000435
436 x = RSb[i];
437
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100438 RT0[i] = ((uint32_t) MUL(0x0E, x)) ^
439 ((uint32_t) MUL(0x09, x) << 8) ^
440 ((uint32_t) MUL(0x0D, x) << 16) ^
441 ((uint32_t) MUL(0x0B, x) << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000442
Hanno Beckerad049a92017-06-19 16:31:54 +0100443#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100444 RT1[i] = ROTL8(RT0[i]);
445 RT2[i] = ROTL8(RT1[i]);
446 RT3[i] = ROTL8(RT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100447#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000448 }
449}
450
Dave Rodgman1e6f7702023-06-27 18:16:13 +0100451#endif /* !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
452
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200453#undef ROTL8
454
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200455#endif /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000456
Hanno Beckerad049a92017-06-19 16:31:54 +0100457#if defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200458
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100459#define ROTL8(x) ((uint32_t) ((x) << 8) + (uint32_t) ((x) >> 24))
460#define ROTL16(x) ((uint32_t) ((x) << 16) + (uint32_t) ((x) >> 16))
461#define ROTL24(x) ((uint32_t) ((x) << 24) + (uint32_t) ((x) >> 8))
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200462
463#define AES_RT0(idx) RT0[idx]
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100464#define AES_RT1(idx) ROTL8(RT0[idx])
465#define AES_RT2(idx) ROTL16(RT0[idx])
466#define AES_RT3(idx) ROTL24(RT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200467
468#define AES_FT0(idx) FT0[idx]
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100469#define AES_FT1(idx) ROTL8(FT0[idx])
470#define AES_FT2(idx) ROTL16(FT0[idx])
471#define AES_FT3(idx) ROTL24(FT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200472
Hanno Becker177d3cf2017-06-07 15:52:48 +0100473#else /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200474
475#define AES_RT0(idx) RT0[idx]
476#define AES_RT1(idx) RT1[idx]
477#define AES_RT2(idx) RT2[idx]
478#define AES_RT3(idx) RT3[idx]
479
480#define AES_FT0(idx) FT0[idx]
481#define AES_FT1(idx) FT1[idx]
482#define AES_FT2(idx) FT2[idx]
483#define AES_FT3(idx) FT3[idx]
484
Hanno Becker177d3cf2017-06-07 15:52:48 +0100485#endif /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200486
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100487void mbedtls_aes_init(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200488{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100489 AES_VALIDATE(ctx != NULL);
Simon Butcher5201e412018-12-06 17:40:14 +0000490
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100491 memset(ctx, 0, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200492}
493
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100494void mbedtls_aes_free(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200495{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100496 if (ctx == NULL) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200497 return;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100498 }
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200499
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100500 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200501}
502
Jaeden Amero9366feb2018-05-29 18:55:17 +0100503#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100504void mbedtls_aes_xts_init(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100505{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100506 AES_VALIDATE(ctx != NULL);
Simon Butcher5201e412018-12-06 17:40:14 +0000507
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100508 mbedtls_aes_init(&ctx->crypt);
509 mbedtls_aes_init(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100510}
511
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100512void mbedtls_aes_xts_free(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100513{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100514 if (ctx == NULL) {
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100515 return;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100516 }
Simon Butcher5201e412018-12-06 17:40:14 +0000517
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100518 mbedtls_aes_free(&ctx->crypt);
519 mbedtls_aes_free(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100520}
521#endif /* MBEDTLS_CIPHER_MODE_XTS */
522
Gilles Peskineb71d4022023-03-16 17:14:59 +0100523/* Some implementations need the round keys to be aligned.
524 * Return an offset to be added to buf, such that (buf + offset) is
525 * correctly aligned.
526 * Note that the offset is in units of elements of buf, i.e. 32-bit words,
527 * i.e. an offset of 1 means 4 bytes and so on.
528 */
529#if (defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)) || \
Gilles Peskine6dec5412023-03-16 17:21:33 +0100530 (defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2)
Gilles Peskineb71d4022023-03-16 17:14:59 +0100531#define MAY_NEED_TO_ALIGN
532#endif
Dave Rodgman9b20aea2023-06-27 18:22:34 +0100533
534#if defined(MAY_NEED_TO_ALIGN) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskineb71d4022023-03-16 17:14:59 +0100535static unsigned mbedtls_aes_rk_offset(uint32_t *buf)
536{
537#if defined(MAY_NEED_TO_ALIGN)
538 int align_16_bytes = 0;
539
540#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
541 if (aes_padlock_ace == -1) {
542 aes_padlock_ace = mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE);
543 }
544 if (aes_padlock_ace) {
545 align_16_bytes = 1;
546 }
547#endif
548
Gilles Peskine6dec5412023-03-16 17:21:33 +0100549#if defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2
Gilles Peskineb71d4022023-03-16 17:14:59 +0100550 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
551 align_16_bytes = 1;
552 }
553#endif
554
555 if (align_16_bytes) {
556 /* These implementations needs 16-byte alignment
557 * for the round key array. */
558 unsigned delta = ((uintptr_t) buf & 0x0000000fU) / 4;
559 if (delta == 0) {
560 return 0;
561 } else {
562 return 4 - delta; // 16 bytes = 4 uint32_t
563 }
564 }
565#else /* MAY_NEED_TO_ALIGN */
566 (void) buf;
567#endif /* MAY_NEED_TO_ALIGN */
568
569 return 0;
570}
Dave Rodgman9b20aea2023-06-27 18:22:34 +0100571#endif /* defined(MAY_NEED_TO_ALIGN) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
Gilles Peskineb71d4022023-03-16 17:14:59 +0100572
Paul Bakker5121ce52009-01-03 21:22:43 +0000573/*
574 * AES key schedule (encryption)
575 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200576#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100577int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
578 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000579{
Paul Bakker23986e52011-04-24 08:57:21 +0000580 unsigned int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000581 uint32_t *RK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000582
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100583 AES_VALIDATE_RET(ctx != NULL);
584 AES_VALIDATE_RET(key != NULL);
Paul Bakker5121ce52009-01-03 21:22:43 +0000585
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100586 switch (keybits) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000587 case 128: ctx->nr = 10; break;
588 case 192: ctx->nr = 12; break;
589 case 256: ctx->nr = 14; break;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100590 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Paul Bakker5121ce52009-01-03 21:22:43 +0000591 }
592
Simon Butcher5201e412018-12-06 17:40:14 +0000593#if !defined(MBEDTLS_AES_ROM_TABLES)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100594 if (aes_init_done == 0) {
Simon Butcher5201e412018-12-06 17:40:14 +0000595 aes_gen_tables();
596 aes_init_done = 1;
Simon Butcher5201e412018-12-06 17:40:14 +0000597 }
598#endif
599
Gilles Peskineb71d4022023-03-16 17:14:59 +0100600 ctx->rk = RK = ctx->buf + mbedtls_aes_rk_offset(ctx->buf);
Paul Bakker5121ce52009-01-03 21:22:43 +0000601
Gilles Peskine5511a342023-03-10 22:29:32 +0100602#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100603 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
604 return mbedtls_aesni_setkey_enc((unsigned char *) ctx->rk, key, keybits);
605 }
Manuel Pégourié-Gonnard47a35362013-12-28 20:45:04 +0100606#endif
607
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100608 for (i = 0; i < (keybits >> 5); i++) {
609 RK[i] = MBEDTLS_GET_UINT32_LE(key, i << 2);
Paul Bakker5121ce52009-01-03 21:22:43 +0000610 }
611
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100612 switch (ctx->nr) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000613 case 10:
614
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100615 for (i = 0; i < 10; i++, RK += 4) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000616 RK[4] = RK[0] ^ RCON[i] ^
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100617 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[3])]) ^
618 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[3])] << 8) ^
619 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[3])] << 16) ^
620 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[3])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000621
622 RK[5] = RK[1] ^ RK[4];
623 RK[6] = RK[2] ^ RK[5];
624 RK[7] = RK[3] ^ RK[6];
625 }
626 break;
627
628 case 12:
629
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100630 for (i = 0; i < 8; i++, RK += 6) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000631 RK[6] = RK[0] ^ RCON[i] ^
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100632 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[5])]) ^
633 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[5])] << 8) ^
634 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[5])] << 16) ^
635 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[5])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000636
637 RK[7] = RK[1] ^ RK[6];
638 RK[8] = RK[2] ^ RK[7];
639 RK[9] = RK[3] ^ RK[8];
640 RK[10] = RK[4] ^ RK[9];
641 RK[11] = RK[5] ^ RK[10];
642 }
643 break;
644
645 case 14:
646
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100647 for (i = 0; i < 7; i++, RK += 8) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000648 RK[8] = RK[0] ^ RCON[i] ^
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100649 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[7])]) ^
650 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[7])] << 8) ^
651 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[7])] << 16) ^
652 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[7])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000653
654 RK[9] = RK[1] ^ RK[8];
655 RK[10] = RK[2] ^ RK[9];
656 RK[11] = RK[3] ^ RK[10];
657
658 RK[12] = RK[4] ^
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100659 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[11])]) ^
660 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[11])] << 8) ^
661 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[11])] << 16) ^
662 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[11])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000663
664 RK[13] = RK[5] ^ RK[12];
665 RK[14] = RK[6] ^ RK[13];
666 RK[15] = RK[7] ^ RK[14];
667 }
668 break;
Paul Bakker5121ce52009-01-03 21:22:43 +0000669 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000670
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100671 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000672}
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200673#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000674
675/*
676 * AES key schedule (decryption)
677 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200678#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100679int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
680 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000681{
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200682 int i, j, ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200683 mbedtls_aes_context cty;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000684 uint32_t *RK;
685 uint32_t *SK;
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200686
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100687 AES_VALIDATE_RET(ctx != NULL);
688 AES_VALIDATE_RET(key != NULL);
Simon Butcher5201e412018-12-06 17:40:14 +0000689
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100690 mbedtls_aes_init(&cty);
Paul Bakker5121ce52009-01-03 21:22:43 +0000691
Gilles Peskineb71d4022023-03-16 17:14:59 +0100692 ctx->rk = RK = ctx->buf + mbedtls_aes_rk_offset(ctx->buf);
Paul Bakker5121ce52009-01-03 21:22:43 +0000693
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200694 /* Also checks keybits */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100695 if ((ret = mbedtls_aes_setkey_enc(&cty, key, keybits)) != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200696 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100697 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000698
Manuel Pégourié-Gonnardafd5a082014-05-28 21:52:59 +0200699 ctx->nr = cty.nr;
700
Gilles Peskine5511a342023-03-10 22:29:32 +0100701#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100702 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
703 mbedtls_aesni_inverse_key((unsigned char *) ctx->rk,
704 (const unsigned char *) cty.rk, ctx->nr);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200705 goto exit;
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100706 }
707#endif
708
Paul Bakker5121ce52009-01-03 21:22:43 +0000709 SK = cty.rk + cty.nr * 4;
710
711 *RK++ = *SK++;
712 *RK++ = *SK++;
713 *RK++ = *SK++;
714 *RK++ = *SK++;
715
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100716 for (i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8) {
717 for (j = 0; j < 4; j++, SK++) {
718 *RK++ = AES_RT0(FSb[MBEDTLS_BYTE_0(*SK)]) ^
719 AES_RT1(FSb[MBEDTLS_BYTE_1(*SK)]) ^
720 AES_RT2(FSb[MBEDTLS_BYTE_2(*SK)]) ^
721 AES_RT3(FSb[MBEDTLS_BYTE_3(*SK)]);
Paul Bakker5121ce52009-01-03 21:22:43 +0000722 }
723 }
724
725 *RK++ = *SK++;
726 *RK++ = *SK++;
727 *RK++ = *SK++;
728 *RK++ = *SK++;
729
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200730exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100731 mbedtls_aes_free(&cty);
Paul Bakker2b222c82009-07-27 21:03:45 +0000732
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100733 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000734}
gabor-mezei-arm95db3012020-10-26 11:35:23 +0100735#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */
Jaeden Amero9366feb2018-05-29 18:55:17 +0100736
737#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100738static int mbedtls_aes_xts_decode_keys(const unsigned char *key,
739 unsigned int keybits,
740 const unsigned char **key1,
741 unsigned int *key1bits,
742 const unsigned char **key2,
743 unsigned int *key2bits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100744{
745 const unsigned int half_keybits = keybits / 2;
746 const unsigned int half_keybytes = half_keybits / 8;
747
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100748 switch (keybits) {
Jaeden Amero9366feb2018-05-29 18:55:17 +0100749 case 256: break;
750 case 512: break;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100751 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100752 }
753
754 *key1bits = half_keybits;
755 *key2bits = half_keybits;
756 *key1 = &key[0];
757 *key2 = &key[half_keybytes];
758
759 return 0;
760}
761
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100762int mbedtls_aes_xts_setkey_enc(mbedtls_aes_xts_context *ctx,
763 const unsigned char *key,
764 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100765{
Janos Follath24eed8d2019-11-22 13:21:35 +0000766 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100767 const unsigned char *key1, *key2;
768 unsigned int key1bits, key2bits;
769
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100770 AES_VALIDATE_RET(ctx != NULL);
771 AES_VALIDATE_RET(key != NULL);
Manuel Pégourié-Gonnard68e3dff2018-12-12 12:48:04 +0100772
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100773 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
774 &key2, &key2bits);
775 if (ret != 0) {
776 return ret;
777 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100778
779 /* Set the tweak key. Always set tweak key for the encryption mode. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100780 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
781 if (ret != 0) {
782 return ret;
783 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100784
785 /* Set crypt key for encryption. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100786 return mbedtls_aes_setkey_enc(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100787}
788
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100789int mbedtls_aes_xts_setkey_dec(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 Peskine1b6c09a2023-01-11 14:52:35 +0100797 AES_VALIDATE_RET(ctx != NULL);
798 AES_VALIDATE_RET(key != NULL);
Manuel Pégourié-Gonnard68e3dff2018-12-12 12:48:04 +0100799
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100800 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
801 &key2, &key2bits);
802 if (ret != 0) {
803 return ret;
804 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100805
806 /* Set the tweak key. Always set tweak key for encryption. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100807 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
808 if (ret != 0) {
809 return ret;
810 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100811
812 /* Set crypt key for decryption. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100813 return mbedtls_aes_setkey_dec(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100814}
815#endif /* MBEDTLS_CIPHER_MODE_XTS */
816
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100817#define AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Joe Subbiani6b897c92021-07-08 14:59:52 +0100818 do \
819 { \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100820 (X0) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y0)) ^ \
821 AES_FT1(MBEDTLS_BYTE_1(Y1)) ^ \
822 AES_FT2(MBEDTLS_BYTE_2(Y2)) ^ \
823 AES_FT3(MBEDTLS_BYTE_3(Y3)); \
Joe Subbiani6b897c92021-07-08 14:59:52 +0100824 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100825 (X1) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y1)) ^ \
826 AES_FT1(MBEDTLS_BYTE_1(Y2)) ^ \
827 AES_FT2(MBEDTLS_BYTE_2(Y3)) ^ \
828 AES_FT3(MBEDTLS_BYTE_3(Y0)); \
Joe Subbiani6b897c92021-07-08 14:59:52 +0100829 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100830 (X2) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y2)) ^ \
831 AES_FT1(MBEDTLS_BYTE_1(Y3)) ^ \
832 AES_FT2(MBEDTLS_BYTE_2(Y0)) ^ \
833 AES_FT3(MBEDTLS_BYTE_3(Y1)); \
Joe Subbiani6b897c92021-07-08 14:59:52 +0100834 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100835 (X3) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y3)) ^ \
836 AES_FT1(MBEDTLS_BYTE_1(Y0)) ^ \
837 AES_FT2(MBEDTLS_BYTE_2(Y1)) ^ \
838 AES_FT3(MBEDTLS_BYTE_3(Y2)); \
839 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000840
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100841#define AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100842 do \
843 { \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100844 (X0) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y0)) ^ \
845 AES_RT1(MBEDTLS_BYTE_1(Y3)) ^ \
846 AES_RT2(MBEDTLS_BYTE_2(Y2)) ^ \
847 AES_RT3(MBEDTLS_BYTE_3(Y1)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100848 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100849 (X1) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y1)) ^ \
850 AES_RT1(MBEDTLS_BYTE_1(Y0)) ^ \
851 AES_RT2(MBEDTLS_BYTE_2(Y3)) ^ \
852 AES_RT3(MBEDTLS_BYTE_3(Y2)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100853 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100854 (X2) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y2)) ^ \
855 AES_RT1(MBEDTLS_BYTE_1(Y1)) ^ \
856 AES_RT2(MBEDTLS_BYTE_2(Y0)) ^ \
857 AES_RT3(MBEDTLS_BYTE_3(Y3)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100858 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100859 (X3) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y3)) ^ \
860 AES_RT1(MBEDTLS_BYTE_1(Y2)) ^ \
861 AES_RT2(MBEDTLS_BYTE_2(Y1)) ^ \
862 AES_RT3(MBEDTLS_BYTE_3(Y0)); \
863 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000864
865/*
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200866 * AES-ECB block encryption
867 */
868#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100869int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx,
870 const unsigned char input[16],
871 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200872{
873 int i;
Gilles Peskine5197c662020-08-26 17:03:24 +0200874 uint32_t *RK = ctx->rk;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100875 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200876 uint32_t X[4];
877 uint32_t Y[4];
878 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200879
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100880 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
881 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
882 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
883 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200884
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100885 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
886 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]);
887 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 +0200888 }
889
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100890 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 +0200891
Gilles Peskine5197c662020-08-26 17:03:24 +0200892 t.X[0] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100893 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
894 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
895 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
896 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200897
Gilles Peskine5197c662020-08-26 17:03:24 +0200898 t.X[1] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100899 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
900 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
901 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
902 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200903
Gilles Peskine5197c662020-08-26 17:03:24 +0200904 t.X[2] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100905 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
906 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
907 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
908 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200909
Gilles Peskine5197c662020-08-26 17:03:24 +0200910 t.X[3] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100911 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
912 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
913 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
914 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200915
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100916 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
917 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
918 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
919 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +0000920
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100921 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500922
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100923 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200924}
925#endif /* !MBEDTLS_AES_ENCRYPT_ALT */
926
Gilles Peskine8db3efb2018-02-21 19:16:20 +0100927#if !defined(MBEDTLS_DEPRECATED_REMOVED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100928void mbedtls_aes_encrypt(mbedtls_aes_context *ctx,
929 const unsigned char input[16],
930 unsigned char output[16])
Hanno Beckerbedc2052017-06-26 12:46:56 +0100931{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100932 MBEDTLS_IGNORE_RETURN(mbedtls_internal_aes_encrypt(ctx, input, output));
Hanno Beckerbedc2052017-06-26 12:46:56 +0100933}
Gilles Peskine8db3efb2018-02-21 19:16:20 +0100934#endif /* !MBEDTLS_DEPRECATED_REMOVED */
Hanno Beckerbedc2052017-06-26 12:46:56 +0100935
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200936/*
937 * AES-ECB block decryption
938 */
939#if !defined(MBEDTLS_AES_DECRYPT_ALT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100940int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
941 const unsigned char input[16],
942 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200943{
944 int i;
Gilles Peskine5197c662020-08-26 17:03:24 +0200945 uint32_t *RK = ctx->rk;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100946 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200947 uint32_t X[4];
948 uint32_t Y[4];
949 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200950
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100951 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
952 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
953 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
954 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200955
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100956 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
957 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]);
958 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 +0200959 }
960
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100961 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 +0200962
Gilles Peskine5197c662020-08-26 17:03:24 +0200963 t.X[0] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100964 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
965 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
966 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
967 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200968
Gilles Peskine5197c662020-08-26 17:03:24 +0200969 t.X[1] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100970 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
971 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
972 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
973 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200974
Gilles Peskine5197c662020-08-26 17:03:24 +0200975 t.X[2] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100976 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
977 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
978 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
979 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200980
Gilles Peskine5197c662020-08-26 17:03:24 +0200981 t.X[3] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100982 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
983 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
984 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
985 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200986
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100987 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
988 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
989 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
990 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +0000991
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100992 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500993
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100994 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200995}
996#endif /* !MBEDTLS_AES_DECRYPT_ALT */
997
Gilles Peskine8db3efb2018-02-21 19:16:20 +0100998#if !defined(MBEDTLS_DEPRECATED_REMOVED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100999void mbedtls_aes_decrypt(mbedtls_aes_context *ctx,
1000 const unsigned char input[16],
1001 unsigned char output[16])
Hanno Beckerbedc2052017-06-26 12:46:56 +01001002{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001003 MBEDTLS_IGNORE_RETURN(mbedtls_internal_aes_decrypt(ctx, input, output));
Hanno Beckerbedc2052017-06-26 12:46:56 +01001004}
Gilles Peskine8db3efb2018-02-21 19:16:20 +01001005#endif /* !MBEDTLS_DEPRECATED_REMOVED */
Hanno Beckerbedc2052017-06-26 12:46:56 +01001006
Gilles Peskineb71d4022023-03-16 17:14:59 +01001007#if defined(MAY_NEED_TO_ALIGN)
Gilles Peskine6978e732023-03-16 13:08:42 +01001008/* VIA Padlock and our intrinsics-based implementation of AESNI require
1009 * the round keys to be aligned on a 16-byte boundary. We take care of this
1010 * before creating them, but the AES context may have moved (this can happen
1011 * if the library is called from a language with managed memory), and in later
1012 * calls it might have a different alignment with respect to 16-byte memory.
1013 * So we may need to realign.
1014 * NOTE: In the LTS branch, the context contains a pointer to within itself,
1015 * so if it has been moved, things will probably go pear-shaped. We keep this
1016 * code for compatibility with the development branch, in case of future changes.
1017 */
1018static void aes_maybe_realign(mbedtls_aes_context *ctx)
1019{
Tom Cosgrove2c942a32023-03-19 14:04:04 +00001020 unsigned current_offset = (unsigned) (ctx->rk - ctx->buf);
Gilles Peskineb71d4022023-03-16 17:14:59 +01001021 unsigned new_offset = mbedtls_aes_rk_offset(ctx->buf);
1022 if (new_offset != current_offset) {
Gilles Peskine6978e732023-03-16 13:08:42 +01001023 memmove(ctx->buf + new_offset, // new address
1024 ctx->buf + current_offset, // current address
1025 (ctx->nr + 1) * 16); // number of round keys * bytes per rk
1026 ctx->rk = ctx->buf + new_offset;
1027 }
1028}
1029#endif
1030
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001031/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001032 * AES-ECB block encryption/decryption
1033 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001034int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
1035 int mode,
1036 const unsigned char input[16],
1037 unsigned char output[16])
Paul Bakker5121ce52009-01-03 21:22:43 +00001038{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001039 AES_VALIDATE_RET(ctx != NULL);
1040 AES_VALIDATE_RET(input != NULL);
1041 AES_VALIDATE_RET(output != NULL);
1042 AES_VALIDATE_RET(mode == MBEDTLS_AES_ENCRYPT ||
1043 mode == MBEDTLS_AES_DECRYPT);
Manuel Pégourié-Gonnard1aca2602018-12-12 12:56:55 +01001044
Gilles Peskineb71d4022023-03-16 17:14:59 +01001045#if defined(MAY_NEED_TO_ALIGN)
1046 aes_maybe_realign(ctx);
1047#endif
1048
Gilles Peskine5511a342023-03-10 22:29:32 +01001049#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001050 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1051 return mbedtls_aesni_crypt_ecb(ctx, mode, input, output);
1052 }
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +01001053#endif
1054
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001055#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001056 if (aes_padlock_ace) {
Gilles Peskine6978e732023-03-16 13:08:42 +01001057 return mbedtls_padlock_xcryptecb(ctx, mode, input, output);
Paul Bakker5121ce52009-01-03 21:22:43 +00001058 }
1059#endif
1060
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001061 if (mode == MBEDTLS_AES_ENCRYPT) {
1062 return mbedtls_internal_aes_encrypt(ctx, input, output);
1063 } else {
1064 return mbedtls_internal_aes_decrypt(ctx, input, output);
1065 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001066}
1067
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001068#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001069/*
1070 * AES-CBC buffer encryption/decryption
1071 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001072int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
1073 int mode,
1074 size_t length,
1075 unsigned char iv[16],
1076 const unsigned char *input,
1077 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001078{
1079 int i;
Gilles Peskine377a3102021-07-07 21:08:28 +02001080 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +00001081 unsigned char temp[16];
1082
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001083 AES_VALIDATE_RET(ctx != NULL);
1084 AES_VALIDATE_RET(mode == MBEDTLS_AES_ENCRYPT ||
1085 mode == MBEDTLS_AES_DECRYPT);
1086 AES_VALIDATE_RET(iv != NULL);
1087 AES_VALIDATE_RET(input != NULL);
1088 AES_VALIDATE_RET(output != NULL);
Manuel Pégourié-Gonnard3178d1a2018-12-12 13:05:00 +01001089
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001090 if (length % 16) {
1091 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
1092 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001093
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001094#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001095 if (aes_padlock_ace) {
1096 if (mbedtls_padlock_xcryptcbc(ctx, mode, length, iv, input, output) == 0) {
1097 return 0;
1098 }
Paul Bakker9af723c2014-05-01 13:03:14 +02001099
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001100 // If padlock data misaligned, we just fall back to
1101 // unaccelerated mode
1102 //
Paul Bakker5121ce52009-01-03 21:22:43 +00001103 }
1104#endif
1105
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001106 if (mode == MBEDTLS_AES_DECRYPT) {
1107 while (length > 0) {
1108 memcpy(temp, input, 16);
1109 ret = mbedtls_aes_crypt_ecb(ctx, mode, input, output);
1110 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +02001111 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001112 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001113
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001114 for (i = 0; i < 16; i++) {
1115 output[i] = (unsigned char) (output[i] ^ iv[i]);
1116 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001117
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001118 memcpy(iv, temp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001119
1120 input += 16;
1121 output += 16;
1122 length -= 16;
1123 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001124 } else {
1125 while (length > 0) {
1126 for (i = 0; i < 16; i++) {
1127 output[i] = (unsigned char) (input[i] ^ iv[i]);
1128 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001129
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001130 ret = mbedtls_aes_crypt_ecb(ctx, mode, output, output);
1131 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +02001132 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001133 }
1134 memcpy(iv, output, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001135
1136 input += 16;
1137 output += 16;
1138 length -= 16;
1139 }
1140 }
Gilles Peskine377a3102021-07-07 21:08:28 +02001141 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001142
Gilles Peskine377a3102021-07-07 21:08:28 +02001143exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001144 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001145}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001146#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001147
Aorimn5f778012016-06-09 23:22:58 +02001148#if defined(MBEDTLS_CIPHER_MODE_XTS)
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001149
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001150typedef unsigned char mbedtls_be128[16];
1151
1152/*
1153 * GF(2^128) multiplication function
1154 *
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001155 * This function multiplies a field element by x in the polynomial field
1156 * representation. It uses 64-bit word operations to gain speed but compensates
Shaun Case0e7791f2021-12-20 21:14:10 -08001157 * for machine endianness and hence works correctly on both big and little
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001158 * endian machines.
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001159 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001160static void mbedtls_gf128mul_x_ble(unsigned char r[16],
1161 const unsigned char x[16])
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001162{
1163 uint64_t a, b, ra, rb;
1164
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001165 a = MBEDTLS_GET_UINT64_LE(x, 0);
1166 b = MBEDTLS_GET_UINT64_LE(x, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001167
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001168 ra = (a << 1) ^ 0x0087 >> (8 - ((b >> 63) << 3));
1169 rb = (a >> 63) | (b << 1);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001170
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001171 MBEDTLS_PUT_UINT64_LE(ra, r, 0);
1172 MBEDTLS_PUT_UINT64_LE(rb, r, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001173}
1174
Aorimn5f778012016-06-09 23:22:58 +02001175/*
1176 * AES-XTS buffer encryption/decryption
1177 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001178int mbedtls_aes_crypt_xts(mbedtls_aes_xts_context *ctx,
1179 int mode,
1180 size_t length,
1181 const unsigned char data_unit[16],
1182 const unsigned char *input,
1183 unsigned char *output)
Aorimn5f778012016-06-09 23:22:58 +02001184{
Janos Follath24eed8d2019-11-22 13:21:35 +00001185 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amerod82cd862018-04-28 15:02:45 +01001186 size_t blocks = length / 16;
1187 size_t leftover = length % 16;
1188 unsigned char tweak[16];
1189 unsigned char prev_tweak[16];
1190 unsigned char tmp[16];
Aorimn5f778012016-06-09 23:22:58 +02001191
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001192 AES_VALIDATE_RET(ctx != NULL);
1193 AES_VALIDATE_RET(mode == MBEDTLS_AES_ENCRYPT ||
1194 mode == MBEDTLS_AES_DECRYPT);
1195 AES_VALIDATE_RET(data_unit != NULL);
1196 AES_VALIDATE_RET(input != NULL);
1197 AES_VALIDATE_RET(output != NULL);
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01001198
Jaeden Amero8381fcb2018-10-11 12:06:15 +01001199 /* Data units must be at least 16 bytes long. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001200 if (length < 16) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001201 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001202 }
Aorimn5f778012016-06-09 23:22:58 +02001203
Jaeden Ameroa74faba2018-10-11 12:07:43 +01001204 /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001205 if (length > (1 << 20) * 16) {
Jaeden Amero0a8b0202018-05-30 15:36:06 +01001206 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001207 }
Aorimn5f778012016-06-09 23:22:58 +02001208
Jaeden Amerod82cd862018-04-28 15:02:45 +01001209 /* Compute the tweak. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001210 ret = mbedtls_aes_crypt_ecb(&ctx->tweak, MBEDTLS_AES_ENCRYPT,
1211 data_unit, tweak);
1212 if (ret != 0) {
1213 return ret;
1214 }
Aorimn5f778012016-06-09 23:22:58 +02001215
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001216 while (blocks--) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001217 size_t i;
1218
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001219 if (leftover && (mode == MBEDTLS_AES_DECRYPT) && blocks == 0) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001220 /* We are on the last block in a decrypt operation that has
1221 * leftover bytes, so we need to use the next tweak for this block,
Tom Cosgrove49f99bc2022-12-04 16:44:21 +00001222 * and this tweak for the leftover bytes. Save the current tweak for
Jaeden Amerod82cd862018-04-28 15:02:45 +01001223 * the leftovers and then update the current tweak for use on this,
1224 * the last full block. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001225 memcpy(prev_tweak, tweak, sizeof(tweak));
1226 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001227 }
1228
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001229 for (i = 0; i < 16; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001230 tmp[i] = input[i] ^ tweak[i];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001231 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001232
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001233 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1234 if (ret != 0) {
1235 return ret;
1236 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001237
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001238 for (i = 0; i < 16; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001239 output[i] = tmp[i] ^ tweak[i];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001240 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001241
1242 /* Update the tweak for the next block. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001243 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001244
1245 output += 16;
1246 input += 16;
Aorimn5f778012016-06-09 23:22:58 +02001247 }
1248
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001249 if (leftover) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001250 /* If we are on the leftover bytes in a decrypt operation, we need to
1251 * use the previous tweak for these bytes (as saved in prev_tweak). */
1252 unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
Aorimn5f778012016-06-09 23:22:58 +02001253
Jaeden Amerod82cd862018-04-28 15:02:45 +01001254 /* We are now on the final part of the data unit, which doesn't divide
1255 * evenly by 16. It's time for ciphertext stealing. */
1256 size_t i;
1257 unsigned char *prev_output = output - 16;
Aorimn5f778012016-06-09 23:22:58 +02001258
Jaeden Amerod82cd862018-04-28 15:02:45 +01001259 /* Copy ciphertext bytes from the previous block to our output for each
Shaun Case0e7791f2021-12-20 21:14:10 -08001260 * byte of ciphertext we won't steal. At the same time, copy the
Jaeden Amerod82cd862018-04-28 15:02:45 +01001261 * remainder of the input for this final round (since the loop bounds
1262 * are the same). */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001263 for (i = 0; i < leftover; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001264 output[i] = prev_output[i];
1265 tmp[i] = input[i] ^ t[i];
Aorimn5f778012016-06-09 23:22:58 +02001266 }
Aorimn5f778012016-06-09 23:22:58 +02001267
Jaeden Amerod82cd862018-04-28 15:02:45 +01001268 /* Copy ciphertext bytes from the previous block for input in this
1269 * round. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001270 for (; i < 16; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001271 tmp[i] = prev_output[i] ^ t[i];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001272 }
Aorimn5f778012016-06-09 23:22:58 +02001273
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001274 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1275 if (ret != 0) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001276 return ret;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001277 }
Aorimn5f778012016-06-09 23:22:58 +02001278
Jaeden Amerod82cd862018-04-28 15:02:45 +01001279 /* Write the result back to the previous block, overriding the previous
1280 * output we copied. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001281 for (i = 0; i < 16; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001282 prev_output[i] = tmp[i] ^ t[i];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001283 }
Aorimn5f778012016-06-09 23:22:58 +02001284 }
1285
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001286 return 0;
Aorimn5f778012016-06-09 23:22:58 +02001287}
1288#endif /* MBEDTLS_CIPHER_MODE_XTS */
1289
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001290#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001291/*
1292 * AES-CFB128 buffer encryption/decryption
1293 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001294int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx,
1295 int mode,
1296 size_t length,
1297 size_t *iv_off,
1298 unsigned char iv[16],
1299 const unsigned char *input,
1300 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001301{
Paul Bakker27fdf462011-06-09 13:55:13 +00001302 int c;
Gilles Peskine377a3102021-07-07 21:08:28 +02001303 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001304 size_t n;
1305
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001306 AES_VALIDATE_RET(ctx != NULL);
1307 AES_VALIDATE_RET(mode == MBEDTLS_AES_ENCRYPT ||
1308 mode == MBEDTLS_AES_DECRYPT);
1309 AES_VALIDATE_RET(iv_off != NULL);
1310 AES_VALIDATE_RET(iv != NULL);
1311 AES_VALIDATE_RET(input != NULL);
1312 AES_VALIDATE_RET(output != NULL);
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001313
1314 n = *iv_off;
Paul Bakker5121ce52009-01-03 21:22:43 +00001315
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001316 if (n > 15) {
1317 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1318 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001319
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001320 if (mode == MBEDTLS_AES_DECRYPT) {
1321 while (length--) {
1322 if (n == 0) {
1323 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1324 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +02001325 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001326 }
Gilles Peskine377a3102021-07-07 21:08:28 +02001327 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001328
1329 c = *input++;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001330 *output++ = (unsigned char) (c ^ iv[n]);
Paul Bakker5121ce52009-01-03 21:22:43 +00001331 iv[n] = (unsigned char) c;
1332
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001333 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001334 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001335 } else {
1336 while (length--) {
1337 if (n == 0) {
1338 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1339 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +02001340 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001341 }
Gilles Peskine377a3102021-07-07 21:08:28 +02001342 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001343
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001344 iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++);
Paul Bakker5121ce52009-01-03 21:22:43 +00001345
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001346 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001347 }
1348 }
1349
1350 *iv_off = n;
Gilles Peskine377a3102021-07-07 21:08:28 +02001351 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001352
Gilles Peskine377a3102021-07-07 21:08:28 +02001353exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001354 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001355}
Paul Bakker556efba2014-01-24 15:38:12 +01001356
1357/*
1358 * AES-CFB8 buffer encryption/decryption
1359 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001360int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx,
1361 int mode,
1362 size_t length,
1363 unsigned char iv[16],
1364 const unsigned char *input,
1365 unsigned char *output)
Paul Bakker556efba2014-01-24 15:38:12 +01001366{
Gilles Peskine377a3102021-07-07 21:08:28 +02001367 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker556efba2014-01-24 15:38:12 +01001368 unsigned char c;
1369 unsigned char ov[17];
1370
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001371 AES_VALIDATE_RET(ctx != NULL);
1372 AES_VALIDATE_RET(mode == MBEDTLS_AES_ENCRYPT ||
1373 mode == MBEDTLS_AES_DECRYPT);
1374 AES_VALIDATE_RET(iv != NULL);
1375 AES_VALIDATE_RET(input != NULL);
1376 AES_VALIDATE_RET(output != NULL);
1377 while (length--) {
1378 memcpy(ov, iv, 16);
1379 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1380 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +02001381 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001382 }
Paul Bakker556efba2014-01-24 15:38:12 +01001383
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001384 if (mode == MBEDTLS_AES_DECRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001385 ov[16] = *input;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001386 }
Paul Bakker556efba2014-01-24 15:38:12 +01001387
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001388 c = *output++ = (unsigned char) (iv[0] ^ *input++);
Paul Bakker556efba2014-01-24 15:38:12 +01001389
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001390 if (mode == MBEDTLS_AES_ENCRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001391 ov[16] = c;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001392 }
Paul Bakker556efba2014-01-24 15:38:12 +01001393
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001394 memcpy(iv, ov + 1, 16);
Paul Bakker556efba2014-01-24 15:38:12 +01001395 }
Gilles Peskine377a3102021-07-07 21:08:28 +02001396 ret = 0;
Paul Bakker556efba2014-01-24 15:38:12 +01001397
Gilles Peskine377a3102021-07-07 21:08:28 +02001398exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001399 return ret;
Paul Bakker556efba2014-01-24 15:38:12 +01001400}
Simon Butcher76a5b222018-04-22 22:57:27 +01001401#endif /* MBEDTLS_CIPHER_MODE_CFB */
1402
1403#if defined(MBEDTLS_CIPHER_MODE_OFB)
1404/*
1405 * AES-OFB (Output Feedback Mode) buffer encryption/decryption
1406 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001407int mbedtls_aes_crypt_ofb(mbedtls_aes_context *ctx,
1408 size_t length,
1409 size_t *iv_off,
1410 unsigned char iv[16],
1411 const unsigned char *input,
1412 unsigned char *output)
Simon Butcher76a5b222018-04-22 22:57:27 +01001413{
Simon Butcherad4e4932018-04-29 00:43:47 +01001414 int ret = 0;
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001415 size_t n;
1416
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001417 AES_VALIDATE_RET(ctx != NULL);
1418 AES_VALIDATE_RET(iv_off != NULL);
1419 AES_VALIDATE_RET(iv != NULL);
1420 AES_VALIDATE_RET(input != NULL);
1421 AES_VALIDATE_RET(output != NULL);
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001422
1423 n = *iv_off;
Simon Butcher76a5b222018-04-22 22:57:27 +01001424
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001425 if (n > 15) {
1426 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1427 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001428
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001429 while (length--) {
1430 if (n == 0) {
1431 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1432 if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001433 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001434 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001435 }
Simon Butcher76a5b222018-04-22 22:57:27 +01001436 *output++ = *input++ ^ iv[n];
1437
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001438 n = (n + 1) & 0x0F;
Simon Butcher76a5b222018-04-22 22:57:27 +01001439 }
1440
1441 *iv_off = n;
1442
Simon Butcherad4e4932018-04-29 00:43:47 +01001443exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001444 return ret;
Simon Butcher76a5b222018-04-22 22:57:27 +01001445}
1446#endif /* MBEDTLS_CIPHER_MODE_OFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001447
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001448#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001449/*
1450 * AES-CTR buffer encryption/decryption
1451 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001452int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
1453 size_t length,
1454 size_t *nc_off,
1455 unsigned char nonce_counter[16],
1456 unsigned char stream_block[16],
1457 const unsigned char *input,
1458 unsigned char *output)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001459{
Paul Bakker369e14b2012-04-18 14:16:09 +00001460 int c, i;
Gilles Peskine377a3102021-07-07 21:08:28 +02001461 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001462 size_t n;
1463
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001464 AES_VALIDATE_RET(ctx != NULL);
1465 AES_VALIDATE_RET(nc_off != NULL);
1466 AES_VALIDATE_RET(nonce_counter != NULL);
1467 AES_VALIDATE_RET(stream_block != NULL);
1468 AES_VALIDATE_RET(input != NULL);
1469 AES_VALIDATE_RET(output != NULL);
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001470
1471 n = *nc_off;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001472
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001473 if (n > 0x0F) {
1474 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1475 }
Mohammad Azim Khan3f7f8172017-11-23 17:49:05 +00001476
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001477 while (length--) {
1478 if (n == 0) {
1479 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block);
1480 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +02001481 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001482 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001483
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001484 for (i = 16; i > 0; i--) {
1485 if (++nonce_counter[i - 1] != 0) {
Paul Bakker369e14b2012-04-18 14:16:09 +00001486 break;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001487 }
1488 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001489 }
1490 c = *input++;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001491 *output++ = (unsigned char) (c ^ stream_block[n]);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001492
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001493 n = (n + 1) & 0x0F;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001494 }
1495
1496 *nc_off = n;
Gilles Peskine377a3102021-07-07 21:08:28 +02001497 ret = 0;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001498
Gilles Peskine377a3102021-07-07 21:08:28 +02001499exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001500 return ret;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001501}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001502#endif /* MBEDTLS_CIPHER_MODE_CTR */
Manuel Pégourié-Gonnard1ec220b2014-03-10 11:20:17 +01001503
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001504#endif /* !MBEDTLS_AES_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001505
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001506#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001507/*
1508 * AES test vectors from:
1509 *
1510 * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
1511 */
1512static const unsigned char aes_test_ecb_dec[3][16] =
1513{
1514 { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
1515 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
1516 { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
1517 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
1518 { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
1519 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
1520};
1521
1522static const unsigned char aes_test_ecb_enc[3][16] =
1523{
1524 { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
1525 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
1526 { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
1527 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
1528 { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
1529 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
1530};
1531
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001532#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001533static const unsigned char aes_test_cbc_dec[3][16] =
1534{
1535 { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
1536 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
1537 { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
1538 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
1539 { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
1540 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
1541};
1542
1543static const unsigned char aes_test_cbc_enc[3][16] =
1544{
1545 { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
1546 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
1547 { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
1548 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
1549 { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
1550 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
1551};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001552#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001553
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001554#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001555/*
1556 * AES-CFB128 test vectors from:
1557 *
1558 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
1559 */
1560static const unsigned char aes_test_cfb128_key[3][32] =
1561{
1562 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1563 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
1564 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1565 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1566 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1567 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1568 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1569 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1570 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
1571};
1572
1573static const unsigned char aes_test_cfb128_iv[16] =
1574{
1575 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1576 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1577};
1578
1579static const unsigned char aes_test_cfb128_pt[64] =
1580{
1581 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1582 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1583 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1584 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1585 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1586 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1587 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1588 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1589};
1590
1591static const unsigned char aes_test_cfb128_ct[3][64] =
1592{
1593 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1594 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1595 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F,
1596 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B,
1597 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40,
1598 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF,
1599 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E,
1600 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 },
1601 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1602 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1603 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21,
1604 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A,
1605 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1,
1606 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9,
1607 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0,
1608 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF },
1609 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1610 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1611 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8,
1612 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B,
1613 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92,
1614 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9,
1615 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8,
1616 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 }
1617};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001618#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001619
Simon Butcherad4e4932018-04-29 00:43:47 +01001620#if defined(MBEDTLS_CIPHER_MODE_OFB)
1621/*
1622 * AES-OFB test vectors from:
1623 *
Simon Butcher5db13622018-06-04 22:11:25 +01001624 * https://csrc.nist.gov/publications/detail/sp/800-38a/final
Simon Butcherad4e4932018-04-29 00:43:47 +01001625 */
1626static const unsigned char aes_test_ofb_key[3][32] =
1627{
1628 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1629 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
1630 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1631 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1632 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1633 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1634 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1635 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1636 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
1637};
1638
1639static const unsigned char aes_test_ofb_iv[16] =
1640{
1641 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1642 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1643};
1644
1645static const unsigned char aes_test_ofb_pt[64] =
1646{
1647 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1648 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1649 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1650 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1651 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1652 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1653 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1654 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1655};
1656
1657static const unsigned char aes_test_ofb_ct[3][64] =
1658{
1659 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1660 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1661 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
1662 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
1663 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
1664 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
1665 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
1666 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e },
1667 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1668 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1669 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
1670 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
1671 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f,
1672 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
1673 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e,
1674 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a },
1675 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1676 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1677 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
1678 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
1679 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed,
1680 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
1681 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8,
1682 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 }
1683};
1684#endif /* MBEDTLS_CIPHER_MODE_OFB */
1685
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001686#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001687/*
1688 * AES-CTR test vectors from:
1689 *
1690 * http://www.faqs.org/rfcs/rfc3686.html
1691 */
1692
1693static const unsigned char aes_test_ctr_key[3][16] =
1694{
1695 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
1696 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
1697 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
1698 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
1699 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
1700 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
1701};
1702
1703static const unsigned char aes_test_ctr_nonce_counter[3][16] =
1704{
1705 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
1706 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
1707 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
1708 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
1709 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
1710 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
1711};
1712
1713static const unsigned char aes_test_ctr_pt[3][48] =
1714{
1715 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
1716 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
1717
1718 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1719 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1720 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1721 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
1722
1723 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1724 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1725 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1726 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
1727 0x20, 0x21, 0x22, 0x23 }
1728};
1729
1730static const unsigned char aes_test_ctr_ct[3][48] =
1731{
1732 { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79,
1733 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 },
1734 { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9,
1735 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88,
1736 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8,
1737 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 },
1738 { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
1739 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
1740 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
1741 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
1742 0x25, 0xB2, 0x07, 0x2F }
1743};
1744
1745static const int aes_test_ctr_len[3] =
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001746{ 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001747#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00001748
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001749#if defined(MBEDTLS_CIPHER_MODE_XTS)
1750/*
1751 * AES-XTS test vectors from:
1752 *
1753 * IEEE P1619/D16 Annex B
1754 * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf
1755 * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf)
1756 */
1757static const unsigned char aes_test_xts_key[][32] =
1758{
1759 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1760 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1761 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1762 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1763 { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1764 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1765 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1766 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1767 { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
1768 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
1769 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1770 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1771};
1772
1773static const unsigned char aes_test_xts_pt32[][32] =
1774{
1775 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1776 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1777 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1778 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
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 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1785 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1786 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1787};
1788
1789static const unsigned char aes_test_xts_ct32[][32] =
1790{
1791 { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec,
1792 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92,
1793 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85,
1794 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e },
1795 { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e,
1796 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b,
1797 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4,
1798 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 },
1799 { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a,
1800 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2,
1801 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53,
1802 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 },
1803};
1804
1805static const unsigned char aes_test_xts_data_unit[][16] =
1806{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001807 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1808 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1809 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1810 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1811 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1812 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001813};
1814
1815#endif /* MBEDTLS_CIPHER_MODE_XTS */
1816
Paul Bakker5121ce52009-01-03 21:22:43 +00001817/*
1818 * Checkup routine
1819 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001820int mbedtls_aes_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +00001821{
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001822 int ret = 0, i, j, u, mode;
1823 unsigned int keybits;
Paul Bakker5121ce52009-01-03 21:22:43 +00001824 unsigned char key[32];
1825 unsigned char buf[64];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001826 const unsigned char *aes_tests;
Andrzej Kurek8ffd8a62022-09-27 07:54:16 -04001827#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1828 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001829 unsigned char iv[16];
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03001830#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001831#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +02001832 unsigned char prv[16];
1833#endif
Simon Butcher2ff0e522018-06-14 09:57:07 +01001834#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1835 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker27fdf462011-06-09 13:55:13 +00001836 size_t offset;
Paul Bakkere91d01e2011-04-19 15:55:50 +00001837#endif
Simon Butcher66a89032018-06-15 18:20:29 +01001838#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS)
Paul Bakkere91d01e2011-04-19 15:55:50 +00001839 int len;
Simon Butcher66a89032018-06-15 18:20:29 +01001840#endif
1841#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001842 unsigned char nonce_counter[16];
1843 unsigned char stream_block[16];
1844#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001845 mbedtls_aes_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001846
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001847 memset(key, 0, 32);
1848 mbedtls_aes_init(&ctx);
Paul Bakker5121ce52009-01-03 21:22:43 +00001849
Gilles Peskine2c8ad942023-03-10 22:35:24 +01001850 if (verbose != 0) {
1851#if defined(MBEDTLS_AES_ALT)
1852 mbedtls_printf(" AES note: alternative implementation.\n");
1853#else /* MBEDTLS_AES_ALT */
1854#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
1855 if (mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE)) {
1856 mbedtls_printf(" AES note: using VIA Padlock.\n");
1857 } else
1858#endif
1859#if defined(MBEDTLS_AESNI_HAVE_CODE)
1860 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
Tom Cosgrove20458c02023-03-18 14:48:49 +00001861 mbedtls_printf(" AES note: using AESNI via ");
1862#if MBEDTLS_AESNI_HAVE_CODE == 1
1863 mbedtls_printf("assembly");
1864#elif MBEDTLS_AESNI_HAVE_CODE == 2
1865 mbedtls_printf("intrinsics");
1866#else
1867 mbedtls_printf("(unknown)");
1868#endif
1869 mbedtls_printf(".\n");
Gilles Peskine2c8ad942023-03-10 22:35:24 +01001870 } else
1871#endif
Gilles Peskine2c8ad942023-03-10 22:35:24 +01001872 mbedtls_printf(" AES note: built-in implementation.\n");
1873#endif /* MBEDTLS_AES_ALT */
1874 }
1875
Paul Bakker5121ce52009-01-03 21:22:43 +00001876 /*
1877 * ECB mode
1878 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001879 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +00001880 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001881 keybits = 128 + u * 64;
1882 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001883
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001884 if (verbose != 0) {
1885 mbedtls_printf(" AES-ECB-%3u (%s): ", keybits,
1886 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00001887 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001888
1889 memset(buf, 0, 16);
1890
1891 if (mode == MBEDTLS_AES_DECRYPT) {
1892 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1893 aes_tests = aes_test_ecb_dec[u];
1894 } else {
1895 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001896 aes_tests = aes_test_ecb_enc[u];
1897 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001898
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01001899 /*
1900 * AES-192 is an optional feature that may be unavailable when
1901 * there is an alternative underlying implementation i.e. when
1902 * MBEDTLS_AES_ALT is defined.
1903 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001904 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1905 mbedtls_printf("skipped\n");
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001906 continue;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001907 } else if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001908 goto exit;
1909 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001910
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001911 for (j = 0; j < 10000; j++) {
1912 ret = mbedtls_aes_crypt_ecb(&ctx, mode, buf, buf);
1913 if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001914 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001915 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001916 }
1917
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001918 if (memcmp(buf, aes_tests, 16) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001919 ret = 1;
1920 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001921 }
1922
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001923 if (verbose != 0) {
1924 mbedtls_printf("passed\n");
1925 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001926 }
1927
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001928 if (verbose != 0) {
1929 mbedtls_printf("\n");
1930 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001931
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001932#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001933 /*
1934 * CBC mode
1935 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001936 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +00001937 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001938 keybits = 128 + u * 64;
1939 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001940
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001941 if (verbose != 0) {
1942 mbedtls_printf(" AES-CBC-%3u (%s): ", keybits,
1943 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00001944 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001945
1946 memset(iv, 0, 16);
1947 memset(prv, 0, 16);
1948 memset(buf, 0, 16);
1949
1950 if (mode == MBEDTLS_AES_DECRYPT) {
1951 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1952 aes_tests = aes_test_cbc_dec[u];
1953 } else {
1954 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001955 aes_tests = aes_test_cbc_enc[u];
1956 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001957
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01001958 /*
1959 * AES-192 is an optional feature that may be unavailable when
1960 * there is an alternative underlying implementation i.e. when
1961 * MBEDTLS_AES_ALT is defined.
1962 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001963 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1964 mbedtls_printf("skipped\n");
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001965 continue;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001966 } else if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001967 goto exit;
1968 }
1969
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001970 for (j = 0; j < 10000; j++) {
1971 if (mode == MBEDTLS_AES_ENCRYPT) {
Paul Bakker5121ce52009-01-03 21:22:43 +00001972 unsigned char tmp[16];
1973
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001974 memcpy(tmp, prv, 16);
1975 memcpy(prv, buf, 16);
1976 memcpy(buf, tmp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001977 }
1978
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001979 ret = mbedtls_aes_crypt_cbc(&ctx, mode, 16, iv, buf, buf);
1980 if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001981 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001982 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001983
1984 }
1985
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001986 if (memcmp(buf, aes_tests, 16) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001987 ret = 1;
1988 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001989 }
1990
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001991 if (verbose != 0) {
1992 mbedtls_printf("passed\n");
1993 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001994 }
1995
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001996 if (verbose != 0) {
1997 mbedtls_printf("\n");
1998 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001999#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00002000
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002001#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00002002 /*
2003 * CFB128 mode
2004 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002005 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +00002006 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002007 keybits = 128 + u * 64;
2008 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00002009
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002010 if (verbose != 0) {
2011 mbedtls_printf(" AES-CFB128-%3u (%s): ", keybits,
2012 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2013 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002014
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002015 memcpy(iv, aes_test_cfb128_iv, 16);
2016 memcpy(key, aes_test_cfb128_key[u], keybits / 8);
Paul Bakker5121ce52009-01-03 21:22:43 +00002017
2018 offset = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002019 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01002020 /*
2021 * AES-192 is an optional feature that may be unavailable when
2022 * there is an alternative underlying implementation i.e. when
2023 * MBEDTLS_AES_ALT is defined.
2024 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002025 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2026 mbedtls_printf("skipped\n");
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002027 continue;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002028 } else if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002029 goto exit;
2030 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002031
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002032 if (mode == MBEDTLS_AES_DECRYPT) {
2033 memcpy(buf, aes_test_cfb128_ct[u], 64);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002034 aes_tests = aes_test_cfb128_pt;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002035 } else {
2036 memcpy(buf, aes_test_cfb128_pt, 64);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002037 aes_tests = aes_test_cfb128_ct[u];
2038 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002039
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002040 ret = mbedtls_aes_crypt_cfb128(&ctx, mode, 64, &offset, iv, buf, buf);
2041 if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002042 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002043 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002044
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002045 if (memcmp(buf, aes_tests, 64) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002046 ret = 1;
2047 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00002048 }
2049
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002050 if (verbose != 0) {
2051 mbedtls_printf("passed\n");
2052 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002053 }
2054
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002055 if (verbose != 0) {
2056 mbedtls_printf("\n");
2057 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002058#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002059
Simon Butcherad4e4932018-04-29 00:43:47 +01002060#if defined(MBEDTLS_CIPHER_MODE_OFB)
2061 /*
2062 * OFB mode
2063 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002064 for (i = 0; i < 6; i++) {
Simon Butcherad4e4932018-04-29 00:43:47 +01002065 u = i >> 1;
2066 keybits = 128 + u * 64;
2067 mode = i & 1;
2068
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002069 if (verbose != 0) {
2070 mbedtls_printf(" AES-OFB-%3u (%s): ", keybits,
2071 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2072 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002073
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002074 memcpy(iv, aes_test_ofb_iv, 16);
2075 memcpy(key, aes_test_ofb_key[u], keybits / 8);
Simon Butcherad4e4932018-04-29 00:43:47 +01002076
2077 offset = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002078 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Simon Butcherad4e4932018-04-29 00:43:47 +01002079 /*
2080 * AES-192 is an optional feature that may be unavailable when
2081 * there is an alternative underlying implementation i.e. when
2082 * MBEDTLS_AES_ALT is defined.
2083 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002084 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2085 mbedtls_printf("skipped\n");
Simon Butcherad4e4932018-04-29 00:43:47 +01002086 continue;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002087 } else if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01002088 goto exit;
2089 }
2090
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002091 if (mode == MBEDTLS_AES_DECRYPT) {
2092 memcpy(buf, aes_test_ofb_ct[u], 64);
Simon Butcherad4e4932018-04-29 00:43:47 +01002093 aes_tests = aes_test_ofb_pt;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002094 } else {
2095 memcpy(buf, aes_test_ofb_pt, 64);
Simon Butcherad4e4932018-04-29 00:43:47 +01002096 aes_tests = aes_test_ofb_ct[u];
2097 }
2098
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002099 ret = mbedtls_aes_crypt_ofb(&ctx, 64, &offset, iv, buf, buf);
2100 if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01002101 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002102 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002103
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002104 if (memcmp(buf, aes_tests, 64) != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01002105 ret = 1;
2106 goto exit;
2107 }
2108
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002109 if (verbose != 0) {
2110 mbedtls_printf("passed\n");
2111 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002112 }
2113
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002114 if (verbose != 0) {
2115 mbedtls_printf("\n");
2116 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002117#endif /* MBEDTLS_CIPHER_MODE_OFB */
2118
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002119#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002120 /*
2121 * CTR mode
2122 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002123 for (i = 0; i < 6; i++) {
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002124 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002125 mode = i & 1;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002126
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002127 if (verbose != 0) {
2128 mbedtls_printf(" AES-CTR-128 (%s): ",
2129 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2130 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002131
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002132 memcpy(nonce_counter, aes_test_ctr_nonce_counter[u], 16);
2133 memcpy(key, aes_test_ctr_key[u], 16);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002134
2135 offset = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002136 if ((ret = mbedtls_aes_setkey_enc(&ctx, key, 128)) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002137 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002138 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002139
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002140 len = aes_test_ctr_len[u];
2141
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002142 if (mode == MBEDTLS_AES_DECRYPT) {
2143 memcpy(buf, aes_test_ctr_ct[u], len);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002144 aes_tests = aes_test_ctr_pt[u];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002145 } else {
2146 memcpy(buf, aes_test_ctr_pt[u], len);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002147 aes_tests = aes_test_ctr_ct[u];
2148 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002149
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002150 ret = mbedtls_aes_crypt_ctr(&ctx, len, &offset, nonce_counter,
2151 stream_block, buf, buf);
2152 if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002153 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002154 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002155
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002156 if (memcmp(buf, aes_tests, len) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002157 ret = 1;
2158 goto exit;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002159 }
2160
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002161 if (verbose != 0) {
2162 mbedtls_printf("passed\n");
2163 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002164 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002165
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002166 if (verbose != 0) {
2167 mbedtls_printf("\n");
2168 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002169#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00002170
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002171#if defined(MBEDTLS_CIPHER_MODE_XTS)
2172 {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002173 static const int num_tests =
2174 sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key);
2175 mbedtls_aes_xts_context ctx_xts;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002176
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002177 /*
2178 * XTS mode
2179 */
2180 mbedtls_aes_xts_init(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002181
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002182 for (i = 0; i < num_tests << 1; i++) {
2183 const unsigned char *data_unit;
2184 u = i >> 1;
2185 mode = i & 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002186
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002187 if (verbose != 0) {
2188 mbedtls_printf(" AES-XTS-128 (%s): ",
2189 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2190 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002191
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002192 memset(key, 0, sizeof(key));
2193 memcpy(key, aes_test_xts_key[u], 32);
2194 data_unit = aes_test_xts_data_unit[u];
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002195
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002196 len = sizeof(*aes_test_xts_ct32);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002197
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002198 if (mode == MBEDTLS_AES_DECRYPT) {
2199 ret = mbedtls_aes_xts_setkey_dec(&ctx_xts, key, 256);
2200 if (ret != 0) {
2201 goto exit;
2202 }
2203 memcpy(buf, aes_test_xts_ct32[u], len);
2204 aes_tests = aes_test_xts_pt32[u];
2205 } else {
2206 ret = mbedtls_aes_xts_setkey_enc(&ctx_xts, key, 256);
2207 if (ret != 0) {
2208 goto exit;
2209 }
2210 memcpy(buf, aes_test_xts_pt32[u], len);
2211 aes_tests = aes_test_xts_ct32[u];
2212 }
2213
2214
2215 ret = mbedtls_aes_crypt_xts(&ctx_xts, mode, len, data_unit,
2216 buf, buf);
2217 if (ret != 0) {
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002218 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002219 }
2220
2221 if (memcmp(buf, aes_tests, len) != 0) {
2222 ret = 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002223 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002224 }
2225
2226 if (verbose != 0) {
2227 mbedtls_printf("passed\n");
2228 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002229 }
2230
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002231 if (verbose != 0) {
2232 mbedtls_printf("\n");
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002233 }
2234
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002235 mbedtls_aes_xts_free(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002236 }
2237#endif /* MBEDTLS_CIPHER_MODE_XTS */
2238
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002239 ret = 0;
2240
2241exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002242 if (ret != 0 && verbose != 0) {
2243 mbedtls_printf("failed\n");
2244 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002245
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002246 mbedtls_aes_free(&ctx);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002247
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002248 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002249}
2250
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002251#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002252
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002253#endif /* MBEDTLS_AES_C */