blob: 36aa7f29997d8b34c5b45e54a102e2c6027698cb [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
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020053#if defined(MBEDTLS_PADLOCK_C) && \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010054 (defined(MBEDTLS_HAVE_X86) || defined(MBEDTLS_PADLOCK_ALIGN16))
Paul Bakker048d04e2012-02-12 17:31:04 +000055static int aes_padlock_ace = -1;
56#endif
57
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020058#if defined(MBEDTLS_AES_ROM_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +000059/*
60 * Forward S-box
61 */
62static const unsigned char FSb[256] =
63{
64 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
65 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
66 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
67 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
68 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
69 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
70 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
71 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
72 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
73 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
74 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
75 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
76 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
77 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
78 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
79 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
80 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
81 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
82 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
83 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
84 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
85 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
86 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
87 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
88 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
89 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
90 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
91 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
92 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
93 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
94 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
95 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
96};
97
98/*
99 * Forward tables
100 */
101#define FT \
102\
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100103 V(A5, 63, 63, C6), V(84, 7C, 7C, F8), V(99, 77, 77, EE), V(8D, 7B, 7B, F6), \
104 V(0D, F2, F2, FF), V(BD, 6B, 6B, D6), V(B1, 6F, 6F, DE), V(54, C5, C5, 91), \
105 V(50, 30, 30, 60), V(03, 01, 01, 02), V(A9, 67, 67, CE), V(7D, 2B, 2B, 56), \
106 V(19, FE, FE, E7), V(62, D7, D7, B5), V(E6, AB, AB, 4D), V(9A, 76, 76, EC), \
107 V(45, CA, CA, 8F), V(9D, 82, 82, 1F), V(40, C9, C9, 89), V(87, 7D, 7D, FA), \
108 V(15, FA, FA, EF), V(EB, 59, 59, B2), V(C9, 47, 47, 8E), V(0B, F0, F0, FB), \
109 V(EC, AD, AD, 41), V(67, D4, D4, B3), V(FD, A2, A2, 5F), V(EA, AF, AF, 45), \
110 V(BF, 9C, 9C, 23), V(F7, A4, A4, 53), V(96, 72, 72, E4), V(5B, C0, C0, 9B), \
111 V(C2, B7, B7, 75), V(1C, FD, FD, E1), V(AE, 93, 93, 3D), V(6A, 26, 26, 4C), \
112 V(5A, 36, 36, 6C), V(41, 3F, 3F, 7E), V(02, F7, F7, F5), V(4F, CC, CC, 83), \
113 V(5C, 34, 34, 68), V(F4, A5, A5, 51), V(34, E5, E5, D1), V(08, F1, F1, F9), \
114 V(93, 71, 71, E2), V(73, D8, D8, AB), V(53, 31, 31, 62), V(3F, 15, 15, 2A), \
115 V(0C, 04, 04, 08), V(52, C7, C7, 95), V(65, 23, 23, 46), V(5E, C3, C3, 9D), \
116 V(28, 18, 18, 30), V(A1, 96, 96, 37), V(0F, 05, 05, 0A), V(B5, 9A, 9A, 2F), \
117 V(09, 07, 07, 0E), V(36, 12, 12, 24), V(9B, 80, 80, 1B), V(3D, E2, E2, DF), \
118 V(26, EB, EB, CD), V(69, 27, 27, 4E), V(CD, B2, B2, 7F), V(9F, 75, 75, EA), \
119 V(1B, 09, 09, 12), V(9E, 83, 83, 1D), V(74, 2C, 2C, 58), V(2E, 1A, 1A, 34), \
120 V(2D, 1B, 1B, 36), V(B2, 6E, 6E, DC), V(EE, 5A, 5A, B4), V(FB, A0, A0, 5B), \
121 V(F6, 52, 52, A4), V(4D, 3B, 3B, 76), V(61, D6, D6, B7), V(CE, B3, B3, 7D), \
122 V(7B, 29, 29, 52), V(3E, E3, E3, DD), V(71, 2F, 2F, 5E), V(97, 84, 84, 13), \
123 V(F5, 53, 53, A6), V(68, D1, D1, B9), V(00, 00, 00, 00), V(2C, ED, ED, C1), \
124 V(60, 20, 20, 40), V(1F, FC, FC, E3), V(C8, B1, B1, 79), V(ED, 5B, 5B, B6), \
125 V(BE, 6A, 6A, D4), V(46, CB, CB, 8D), V(D9, BE, BE, 67), V(4B, 39, 39, 72), \
126 V(DE, 4A, 4A, 94), V(D4, 4C, 4C, 98), V(E8, 58, 58, B0), V(4A, CF, CF, 85), \
127 V(6B, D0, D0, BB), V(2A, EF, EF, C5), V(E5, AA, AA, 4F), V(16, FB, FB, ED), \
128 V(C5, 43, 43, 86), V(D7, 4D, 4D, 9A), V(55, 33, 33, 66), V(94, 85, 85, 11), \
129 V(CF, 45, 45, 8A), V(10, F9, F9, E9), V(06, 02, 02, 04), V(81, 7F, 7F, FE), \
130 V(F0, 50, 50, A0), V(44, 3C, 3C, 78), V(BA, 9F, 9F, 25), V(E3, A8, A8, 4B), \
131 V(F3, 51, 51, A2), V(FE, A3, A3, 5D), V(C0, 40, 40, 80), V(8A, 8F, 8F, 05), \
132 V(AD, 92, 92, 3F), V(BC, 9D, 9D, 21), V(48, 38, 38, 70), V(04, F5, F5, F1), \
133 V(DF, BC, BC, 63), V(C1, B6, B6, 77), V(75, DA, DA, AF), V(63, 21, 21, 42), \
134 V(30, 10, 10, 20), V(1A, FF, FF, E5), V(0E, F3, F3, FD), V(6D, D2, D2, BF), \
135 V(4C, CD, CD, 81), V(14, 0C, 0C, 18), V(35, 13, 13, 26), V(2F, EC, EC, C3), \
136 V(E1, 5F, 5F, BE), V(A2, 97, 97, 35), V(CC, 44, 44, 88), V(39, 17, 17, 2E), \
137 V(57, C4, C4, 93), V(F2, A7, A7, 55), V(82, 7E, 7E, FC), V(47, 3D, 3D, 7A), \
138 V(AC, 64, 64, C8), V(E7, 5D, 5D, BA), V(2B, 19, 19, 32), V(95, 73, 73, E6), \
139 V(A0, 60, 60, C0), V(98, 81, 81, 19), V(D1, 4F, 4F, 9E), V(7F, DC, DC, A3), \
140 V(66, 22, 22, 44), V(7E, 2A, 2A, 54), V(AB, 90, 90, 3B), V(83, 88, 88, 0B), \
141 V(CA, 46, 46, 8C), V(29, EE, EE, C7), V(D3, B8, B8, 6B), V(3C, 14, 14, 28), \
142 V(79, DE, DE, A7), V(E2, 5E, 5E, BC), V(1D, 0B, 0B, 16), V(76, DB, DB, AD), \
143 V(3B, E0, E0, DB), V(56, 32, 32, 64), V(4E, 3A, 3A, 74), V(1E, 0A, 0A, 14), \
144 V(DB, 49, 49, 92), V(0A, 06, 06, 0C), V(6C, 24, 24, 48), V(E4, 5C, 5C, B8), \
145 V(5D, C2, C2, 9F), V(6E, D3, D3, BD), V(EF, AC, AC, 43), V(A6, 62, 62, C4), \
146 V(A8, 91, 91, 39), V(A4, 95, 95, 31), V(37, E4, E4, D3), V(8B, 79, 79, F2), \
147 V(32, E7, E7, D5), V(43, C8, C8, 8B), V(59, 37, 37, 6E), V(B7, 6D, 6D, DA), \
148 V(8C, 8D, 8D, 01), V(64, D5, D5, B1), V(D2, 4E, 4E, 9C), V(E0, A9, A9, 49), \
149 V(B4, 6C, 6C, D8), V(FA, 56, 56, AC), V(07, F4, F4, F3), V(25, EA, EA, CF), \
150 V(AF, 65, 65, CA), V(8E, 7A, 7A, F4), V(E9, AE, AE, 47), V(18, 08, 08, 10), \
151 V(D5, BA, BA, 6F), V(88, 78, 78, F0), V(6F, 25, 25, 4A), V(72, 2E, 2E, 5C), \
152 V(24, 1C, 1C, 38), V(F1, A6, A6, 57), V(C7, B4, B4, 73), V(51, C6, C6, 97), \
153 V(23, E8, E8, CB), V(7C, DD, DD, A1), V(9C, 74, 74, E8), V(21, 1F, 1F, 3E), \
154 V(DD, 4B, 4B, 96), V(DC, BD, BD, 61), V(86, 8B, 8B, 0D), V(85, 8A, 8A, 0F), \
155 V(90, 70, 70, E0), V(42, 3E, 3E, 7C), V(C4, B5, B5, 71), V(AA, 66, 66, CC), \
156 V(D8, 48, 48, 90), V(05, 03, 03, 06), V(01, F6, F6, F7), V(12, 0E, 0E, 1C), \
157 V(A3, 61, 61, C2), V(5F, 35, 35, 6A), V(F9, 57, 57, AE), V(D0, B9, B9, 69), \
158 V(91, 86, 86, 17), V(58, C1, C1, 99), V(27, 1D, 1D, 3A), V(B9, 9E, 9E, 27), \
159 V(38, E1, E1, D9), V(13, F8, F8, EB), V(B3, 98, 98, 2B), V(33, 11, 11, 22), \
160 V(BB, 69, 69, D2), V(70, D9, D9, A9), V(89, 8E, 8E, 07), V(A7, 94, 94, 33), \
161 V(B6, 9B, 9B, 2D), V(22, 1E, 1E, 3C), V(92, 87, 87, 15), V(20, E9, E9, C9), \
162 V(49, CE, CE, 87), V(FF, 55, 55, AA), V(78, 28, 28, 50), V(7A, DF, DF, A5), \
163 V(8F, 8C, 8C, 03), V(F8, A1, A1, 59), V(80, 89, 89, 09), V(17, 0D, 0D, 1A), \
164 V(DA, BF, BF, 65), V(31, E6, E6, D7), V(C6, 42, 42, 84), V(B8, 68, 68, D0), \
165 V(C3, 41, 41, 82), V(B0, 99, 99, 29), V(77, 2D, 2D, 5A), V(11, 0F, 0F, 1E), \
166 V(CB, B0, B0, 7B), V(FC, 54, 54, A8), V(D6, BB, BB, 6D), V(3A, 16, 16, 2C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000167
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100168#define V(a, b, c, d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000169static const uint32_t FT0[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000170#undef V
171
Hanno Beckerad049a92017-06-19 16:31:54 +0100172#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200173
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100174#define V(a, b, c, d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000175static const uint32_t FT1[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000176#undef V
177
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100178#define V(a, b, c, d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000179static const uint32_t FT2[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000180#undef V
181
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100182#define V(a, b, c, d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000183static const uint32_t FT3[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000184#undef V
185
Hanno Becker177d3cf2017-06-07 15:52:48 +0100186#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200187
Paul Bakker5121ce52009-01-03 21:22:43 +0000188#undef FT
189
190/*
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};
228
229/*
230 * Reverse tables
231 */
232#define RT \
233\
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100234 V(50, A7, F4, 51), V(53, 65, 41, 7E), V(C3, A4, 17, 1A), V(96, 5E, 27, 3A), \
235 V(CB, 6B, AB, 3B), V(F1, 45, 9D, 1F), V(AB, 58, FA, AC), V(93, 03, E3, 4B), \
236 V(55, FA, 30, 20), V(F6, 6D, 76, AD), V(91, 76, CC, 88), V(25, 4C, 02, F5), \
237 V(FC, D7, E5, 4F), V(D7, CB, 2A, C5), V(80, 44, 35, 26), V(8F, A3, 62, B5), \
238 V(49, 5A, B1, DE), V(67, 1B, BA, 25), V(98, 0E, EA, 45), V(E1, C0, FE, 5D), \
239 V(02, 75, 2F, C3), V(12, F0, 4C, 81), V(A3, 97, 46, 8D), V(C6, F9, D3, 6B), \
240 V(E7, 5F, 8F, 03), V(95, 9C, 92, 15), V(EB, 7A, 6D, BF), V(DA, 59, 52, 95), \
241 V(2D, 83, BE, D4), V(D3, 21, 74, 58), V(29, 69, E0, 49), V(44, C8, C9, 8E), \
242 V(6A, 89, C2, 75), V(78, 79, 8E, F4), V(6B, 3E, 58, 99), V(DD, 71, B9, 27), \
243 V(B6, 4F, E1, BE), V(17, AD, 88, F0), V(66, AC, 20, C9), V(B4, 3A, CE, 7D), \
244 V(18, 4A, DF, 63), V(82, 31, 1A, E5), V(60, 33, 51, 97), V(45, 7F, 53, 62), \
245 V(E0, 77, 64, B1), V(84, AE, 6B, BB), V(1C, A0, 81, FE), V(94, 2B, 08, F9), \
246 V(58, 68, 48, 70), V(19, FD, 45, 8F), V(87, 6C, DE, 94), V(B7, F8, 7B, 52), \
247 V(23, D3, 73, AB), V(E2, 02, 4B, 72), V(57, 8F, 1F, E3), V(2A, AB, 55, 66), \
248 V(07, 28, EB, B2), V(03, C2, B5, 2F), V(9A, 7B, C5, 86), V(A5, 08, 37, D3), \
249 V(F2, 87, 28, 30), V(B2, A5, BF, 23), V(BA, 6A, 03, 02), V(5C, 82, 16, ED), \
250 V(2B, 1C, CF, 8A), V(92, B4, 79, A7), V(F0, F2, 07, F3), V(A1, E2, 69, 4E), \
251 V(CD, F4, DA, 65), V(D5, BE, 05, 06), V(1F, 62, 34, D1), V(8A, FE, A6, C4), \
252 V(9D, 53, 2E, 34), V(A0, 55, F3, A2), V(32, E1, 8A, 05), V(75, EB, F6, A4), \
253 V(39, EC, 83, 0B), V(AA, EF, 60, 40), V(06, 9F, 71, 5E), V(51, 10, 6E, BD), \
254 V(F9, 8A, 21, 3E), V(3D, 06, DD, 96), V(AE, 05, 3E, DD), V(46, BD, E6, 4D), \
255 V(B5, 8D, 54, 91), V(05, 5D, C4, 71), V(6F, D4, 06, 04), V(FF, 15, 50, 60), \
256 V(24, FB, 98, 19), V(97, E9, BD, D6), V(CC, 43, 40, 89), V(77, 9E, D9, 67), \
257 V(BD, 42, E8, B0), V(88, 8B, 89, 07), V(38, 5B, 19, E7), V(DB, EE, C8, 79), \
258 V(47, 0A, 7C, A1), V(E9, 0F, 42, 7C), V(C9, 1E, 84, F8), V(00, 00, 00, 00), \
259 V(83, 86, 80, 09), V(48, ED, 2B, 32), V(AC, 70, 11, 1E), V(4E, 72, 5A, 6C), \
260 V(FB, FF, 0E, FD), V(56, 38, 85, 0F), V(1E, D5, AE, 3D), V(27, 39, 2D, 36), \
261 V(64, D9, 0F, 0A), V(21, A6, 5C, 68), V(D1, 54, 5B, 9B), V(3A, 2E, 36, 24), \
262 V(B1, 67, 0A, 0C), V(0F, E7, 57, 93), V(D2, 96, EE, B4), V(9E, 91, 9B, 1B), \
263 V(4F, C5, C0, 80), V(A2, 20, DC, 61), V(69, 4B, 77, 5A), V(16, 1A, 12, 1C), \
264 V(0A, BA, 93, E2), V(E5, 2A, A0, C0), V(43, E0, 22, 3C), V(1D, 17, 1B, 12), \
265 V(0B, 0D, 09, 0E), V(AD, C7, 8B, F2), V(B9, A8, B6, 2D), V(C8, A9, 1E, 14), \
266 V(85, 19, F1, 57), V(4C, 07, 75, AF), V(BB, DD, 99, EE), V(FD, 60, 7F, A3), \
267 V(9F, 26, 01, F7), V(BC, F5, 72, 5C), V(C5, 3B, 66, 44), V(34, 7E, FB, 5B), \
268 V(76, 29, 43, 8B), V(DC, C6, 23, CB), V(68, FC, ED, B6), V(63, F1, E4, B8), \
269 V(CA, DC, 31, D7), V(10, 85, 63, 42), V(40, 22, 97, 13), V(20, 11, C6, 84), \
270 V(7D, 24, 4A, 85), V(F8, 3D, BB, D2), V(11, 32, F9, AE), V(6D, A1, 29, C7), \
271 V(4B, 2F, 9E, 1D), V(F3, 30, B2, DC), V(EC, 52, 86, 0D), V(D0, E3, C1, 77), \
272 V(6C, 16, B3, 2B), V(99, B9, 70, A9), V(FA, 48, 94, 11), V(22, 64, E9, 47), \
273 V(C4, 8C, FC, A8), V(1A, 3F, F0, A0), V(D8, 2C, 7D, 56), V(EF, 90, 33, 22), \
274 V(C7, 4E, 49, 87), V(C1, D1, 38, D9), V(FE, A2, CA, 8C), V(36, 0B, D4, 98), \
275 V(CF, 81, F5, A6), V(28, DE, 7A, A5), V(26, 8E, B7, DA), V(A4, BF, AD, 3F), \
276 V(E4, 9D, 3A, 2C), V(0D, 92, 78, 50), V(9B, CC, 5F, 6A), V(62, 46, 7E, 54), \
277 V(C2, 13, 8D, F6), V(E8, B8, D8, 90), V(5E, F7, 39, 2E), V(F5, AF, C3, 82), \
278 V(BE, 80, 5D, 9F), V(7C, 93, D0, 69), V(A9, 2D, D5, 6F), V(B3, 12, 25, CF), \
279 V(3B, 99, AC, C8), V(A7, 7D, 18, 10), V(6E, 63, 9C, E8), V(7B, BB, 3B, DB), \
280 V(09, 78, 26, CD), V(F4, 18, 59, 6E), V(01, B7, 9A, EC), V(A8, 9A, 4F, 83), \
281 V(65, 6E, 95, E6), V(7E, E6, FF, AA), V(08, CF, BC, 21), V(E6, E8, 15, EF), \
282 V(D9, 9B, E7, BA), V(CE, 36, 6F, 4A), V(D4, 09, 9F, EA), V(D6, 7C, B0, 29), \
283 V(AF, B2, A4, 31), V(31, 23, 3F, 2A), V(30, 94, A5, C6), V(C0, 66, A2, 35), \
284 V(37, BC, 4E, 74), V(A6, CA, 82, FC), V(B0, D0, 90, E0), V(15, D8, A7, 33), \
285 V(4A, 98, 04, F1), V(F7, DA, EC, 41), V(0E, 50, CD, 7F), V(2F, F6, 91, 17), \
286 V(8D, D6, 4D, 76), V(4D, B0, EF, 43), V(54, 4D, AA, CC), V(DF, 04, 96, E4), \
287 V(E3, B5, D1, 9E), V(1B, 88, 6A, 4C), V(B8, 1F, 2C, C1), V(7F, 51, 65, 46), \
288 V(04, EA, 5E, 9D), V(5D, 35, 8C, 01), V(73, 74, 87, FA), V(2E, 41, 0B, FB), \
289 V(5A, 1D, 67, B3), V(52, D2, DB, 92), V(33, 56, 10, E9), V(13, 47, D6, 6D), \
290 V(8C, 61, D7, 9A), V(7A, 0C, A1, 37), V(8E, 14, F8, 59), V(89, 3C, 13, EB), \
291 V(EE, 27, A9, CE), V(35, C9, 61, B7), V(ED, E5, 1C, E1), V(3C, B1, 47, 7A), \
292 V(59, DF, D2, 9C), V(3F, 73, F2, 55), V(79, CE, 14, 18), V(BF, 37, C7, 73), \
293 V(EA, CD, F7, 53), V(5B, AA, FD, 5F), V(14, 6F, 3D, DF), V(86, DB, 44, 78), \
294 V(81, F3, AF, CA), V(3E, C4, 68, B9), V(2C, 34, 24, 38), V(5F, 40, A3, C2), \
295 V(72, C3, 1D, 16), V(0C, 25, E2, BC), V(8B, 49, 3C, 28), V(41, 95, 0D, FF), \
296 V(71, 01, A8, 39), V(DE, B3, 0C, 08), V(9C, E4, B4, D8), V(90, C1, 56, 64), \
297 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 +0000298
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100299#define V(a, b, c, d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000300static const uint32_t RT0[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000301#undef V
302
Hanno Beckerad049a92017-06-19 16:31:54 +0100303#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200304
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100305#define V(a, b, c, d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000306static const uint32_t RT1[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000307#undef V
308
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100309#define V(a, b, c, d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000310static const uint32_t RT2[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000311#undef V
312
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100313#define V(a, b, c, d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000314static const uint32_t RT3[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000315#undef V
316
Hanno Becker177d3cf2017-06-07 15:52:48 +0100317#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200318
Paul Bakker5121ce52009-01-03 21:22:43 +0000319#undef RT
320
321/*
322 * Round constants
323 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000324static const uint32_t RCON[10] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000325{
326 0x00000001, 0x00000002, 0x00000004, 0x00000008,
327 0x00000010, 0x00000020, 0x00000040, 0x00000080,
328 0x0000001B, 0x00000036
329};
330
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200331#else /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000332
333/*
334 * Forward S-box & tables
335 */
336static unsigned char FSb[256];
Paul Bakker9af723c2014-05-01 13:03:14 +0200337static uint32_t FT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100338#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker9af723c2014-05-01 13:03:14 +0200339static uint32_t FT1[256];
340static uint32_t FT2[256];
341static uint32_t FT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100342#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000343
344/*
345 * Reverse S-box & tables
346 */
347static unsigned char RSb[256];
Paul Bakker5c2364c2012-10-01 14:41:15 +0000348static uint32_t RT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100349#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker5c2364c2012-10-01 14:41:15 +0000350static uint32_t RT1[256];
351static uint32_t RT2[256];
352static uint32_t RT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100353#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000354
355/*
356 * Round constants
357 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000358static uint32_t RCON[10];
Paul Bakker5121ce52009-01-03 21:22:43 +0000359
360/*
361 * Tables generation code
362 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100363#define ROTL8(x) (((x) << 8) & 0xFFFFFFFF) | ((x) >> 24)
364#define XTIME(x) (((x) << 1) ^ (((x) & 0x80) ? 0x1B : 0x00))
365#define MUL(x, y) (((x) && (y)) ? pow[(log[(x)]+log[(y)]) % 255] : 0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000366
367static int aes_init_done = 0;
368
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100369static void aes_gen_tables(void)
Paul Bakker5121ce52009-01-03 21:22:43 +0000370{
371 int i, x, y, z;
372 int pow[256];
373 int log[256];
374
375 /*
376 * compute pow and log tables over GF(2^8)
377 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100378 for (i = 0, x = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000379 pow[i] = x;
380 log[x] = i;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100381 x = MBEDTLS_BYTE_0(x ^ XTIME(x));
Paul Bakker5121ce52009-01-03 21:22:43 +0000382 }
383
384 /*
385 * calculate the round constants
386 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100387 for (i = 0, x = 1; i < 10; i++) {
Paul Bakker5c2364c2012-10-01 14:41:15 +0000388 RCON[i] = (uint32_t) x;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100389 x = MBEDTLS_BYTE_0(XTIME(x));
Paul Bakker5121ce52009-01-03 21:22:43 +0000390 }
391
392 /*
393 * generate the forward and reverse S-boxes
394 */
395 FSb[0x00] = 0x63;
396 RSb[0x63] = 0x00;
397
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100398 for (i = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000399 x = pow[255 - log[i]];
400
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100401 y = x; y = MBEDTLS_BYTE_0((y << 1) | (y >> 7));
402 x ^= y; y = MBEDTLS_BYTE_0((y << 1) | (y >> 7));
403 x ^= y; y = MBEDTLS_BYTE_0((y << 1) | (y >> 7));
404 x ^= y; y = MBEDTLS_BYTE_0((y << 1) | (y >> 7));
Paul Bakker5121ce52009-01-03 21:22:43 +0000405 x ^= y ^ 0x63;
406
407 FSb[i] = (unsigned char) x;
408 RSb[x] = (unsigned char) i;
409 }
410
411 /*
412 * generate the forward and reverse tables
413 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100414 for (i = 0; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000415 x = FSb[i];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100416 y = MBEDTLS_BYTE_0(XTIME(x));
417 z = MBEDTLS_BYTE_0(y ^ x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000418
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100419 FT0[i] = ((uint32_t) y) ^
420 ((uint32_t) x << 8) ^
421 ((uint32_t) x << 16) ^
422 ((uint32_t) z << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000423
Hanno Beckerad049a92017-06-19 16:31:54 +0100424#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100425 FT1[i] = ROTL8(FT0[i]);
426 FT2[i] = ROTL8(FT1[i]);
427 FT3[i] = ROTL8(FT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100428#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000429
430 x = RSb[i];
431
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100432 RT0[i] = ((uint32_t) MUL(0x0E, x)) ^
433 ((uint32_t) MUL(0x09, x) << 8) ^
434 ((uint32_t) MUL(0x0D, x) << 16) ^
435 ((uint32_t) MUL(0x0B, x) << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000436
Hanno Beckerad049a92017-06-19 16:31:54 +0100437#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100438 RT1[i] = ROTL8(RT0[i]);
439 RT2[i] = ROTL8(RT1[i]);
440 RT3[i] = ROTL8(RT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100441#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000442 }
443}
444
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200445#undef ROTL8
446
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200447#endif /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000448
Hanno Beckerad049a92017-06-19 16:31:54 +0100449#if defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200450
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100451#define ROTL8(x) ((uint32_t) ((x) << 8) + (uint32_t) ((x) >> 24))
452#define ROTL16(x) ((uint32_t) ((x) << 16) + (uint32_t) ((x) >> 16))
453#define ROTL24(x) ((uint32_t) ((x) << 24) + (uint32_t) ((x) >> 8))
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200454
455#define AES_RT0(idx) RT0[idx]
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100456#define AES_RT1(idx) ROTL8(RT0[idx])
457#define AES_RT2(idx) ROTL16(RT0[idx])
458#define AES_RT3(idx) ROTL24(RT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200459
460#define AES_FT0(idx) FT0[idx]
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100461#define AES_FT1(idx) ROTL8(FT0[idx])
462#define AES_FT2(idx) ROTL16(FT0[idx])
463#define AES_FT3(idx) ROTL24(FT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200464
Hanno Becker177d3cf2017-06-07 15:52:48 +0100465#else /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200466
467#define AES_RT0(idx) RT0[idx]
468#define AES_RT1(idx) RT1[idx]
469#define AES_RT2(idx) RT2[idx]
470#define AES_RT3(idx) RT3[idx]
471
472#define AES_FT0(idx) FT0[idx]
473#define AES_FT1(idx) FT1[idx]
474#define AES_FT2(idx) FT2[idx]
475#define AES_FT3(idx) FT3[idx]
476
Hanno Becker177d3cf2017-06-07 15:52:48 +0100477#endif /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200478
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100479void mbedtls_aes_init(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200480{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100481 AES_VALIDATE(ctx != NULL);
Simon Butcher5201e412018-12-06 17:40:14 +0000482
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100483 memset(ctx, 0, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200484}
485
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100486void mbedtls_aes_free(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200487{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100488 if (ctx == NULL) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200489 return;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100490 }
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200491
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100492 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200493}
494
Jaeden Amero9366feb2018-05-29 18:55:17 +0100495#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100496void mbedtls_aes_xts_init(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100497{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100498 AES_VALIDATE(ctx != NULL);
Simon Butcher5201e412018-12-06 17:40:14 +0000499
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100500 mbedtls_aes_init(&ctx->crypt);
501 mbedtls_aes_init(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100502}
503
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100504void mbedtls_aes_xts_free(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100505{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100506 if (ctx == NULL) {
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100507 return;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100508 }
Simon Butcher5201e412018-12-06 17:40:14 +0000509
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100510 mbedtls_aes_free(&ctx->crypt);
511 mbedtls_aes_free(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100512}
513#endif /* MBEDTLS_CIPHER_MODE_XTS */
514
Paul Bakker5121ce52009-01-03 21:22:43 +0000515/*
516 * AES key schedule (encryption)
517 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200518#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100519int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
520 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000521{
Paul Bakker23986e52011-04-24 08:57:21 +0000522 unsigned int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000523 uint32_t *RK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000524
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100525 AES_VALIDATE_RET(ctx != NULL);
526 AES_VALIDATE_RET(key != NULL);
Paul Bakker5121ce52009-01-03 21:22:43 +0000527
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100528 switch (keybits) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000529 case 128: ctx->nr = 10; break;
530 case 192: ctx->nr = 12; break;
531 case 256: ctx->nr = 14; break;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100532 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Paul Bakker5121ce52009-01-03 21:22:43 +0000533 }
534
Simon Butcher5201e412018-12-06 17:40:14 +0000535#if !defined(MBEDTLS_AES_ROM_TABLES)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100536 if (aes_init_done == 0) {
Simon Butcher5201e412018-12-06 17:40:14 +0000537 aes_gen_tables();
538 aes_init_done = 1;
Simon Butcher5201e412018-12-06 17:40:14 +0000539 }
540#endif
541
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200542#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_PADLOCK_ALIGN16)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100543 if (aes_padlock_ace == -1) {
544 aes_padlock_ace = mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE);
545 }
Paul Bakker048d04e2012-02-12 17:31:04 +0000546
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100547 if (aes_padlock_ace) {
548 ctx->rk = RK = MBEDTLS_PADLOCK_ALIGN16(ctx->buf);
549 } else
Paul Bakker5121ce52009-01-03 21:22:43 +0000550#endif
Paul Bakker048d04e2012-02-12 17:31:04 +0000551 ctx->rk = RK = ctx->buf;
Paul Bakker5121ce52009-01-03 21:22:43 +0000552
Gilles Peskine5511a342023-03-10 22:29:32 +0100553#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100554 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
Gilles Peskinee7dc21f2023-03-10 22:37:11 +0100555 /* The intrinsics-based implementation needs 16-byte alignment
556 * for the round key array. */
557 unsigned delta = (uintptr_t) ctx->buf & 0x0000000f;
558 size_t rk_offset = 0;
559 if (delta != 0) {
560 rk_offset = 4 - delta / 4; // 16 bytes = 4 uint32_t
561 }
562 ctx->rk = RK = ctx->buf + rk_offset;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100563 return mbedtls_aesni_setkey_enc((unsigned char *) ctx->rk, key, keybits);
564 }
Manuel Pégourié-Gonnard47a35362013-12-28 20:45:04 +0100565#endif
566
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100567 for (i = 0; i < (keybits >> 5); i++) {
568 RK[i] = MBEDTLS_GET_UINT32_LE(key, i << 2);
Paul Bakker5121ce52009-01-03 21:22:43 +0000569 }
570
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100571 switch (ctx->nr) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000572 case 10:
573
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100574 for (i = 0; i < 10; i++, RK += 4) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000575 RK[4] = RK[0] ^ RCON[i] ^
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100576 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[3])]) ^
577 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[3])] << 8) ^
578 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[3])] << 16) ^
579 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[3])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000580
581 RK[5] = RK[1] ^ RK[4];
582 RK[6] = RK[2] ^ RK[5];
583 RK[7] = RK[3] ^ RK[6];
584 }
585 break;
586
587 case 12:
588
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100589 for (i = 0; i < 8; i++, RK += 6) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000590 RK[6] = RK[0] ^ RCON[i] ^
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100591 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[5])]) ^
592 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[5])] << 8) ^
593 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[5])] << 16) ^
594 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[5])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000595
596 RK[7] = RK[1] ^ RK[6];
597 RK[8] = RK[2] ^ RK[7];
598 RK[9] = RK[3] ^ RK[8];
599 RK[10] = RK[4] ^ RK[9];
600 RK[11] = RK[5] ^ RK[10];
601 }
602 break;
603
604 case 14:
605
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100606 for (i = 0; i < 7; i++, RK += 8) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000607 RK[8] = RK[0] ^ RCON[i] ^
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100608 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[7])]) ^
609 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[7])] << 8) ^
610 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[7])] << 16) ^
611 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[7])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000612
613 RK[9] = RK[1] ^ RK[8];
614 RK[10] = RK[2] ^ RK[9];
615 RK[11] = RK[3] ^ RK[10];
616
617 RK[12] = RK[4] ^
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100618 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[11])]) ^
619 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[11])] << 8) ^
620 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[11])] << 16) ^
621 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[11])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000622
623 RK[13] = RK[5] ^ RK[12];
624 RK[14] = RK[6] ^ RK[13];
625 RK[15] = RK[7] ^ RK[14];
626 }
627 break;
Paul Bakker5121ce52009-01-03 21:22:43 +0000628 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000629
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100630 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000631}
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200632#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000633
634/*
635 * AES key schedule (decryption)
636 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200637#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100638int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
639 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000640{
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200641 int i, j, ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200642 mbedtls_aes_context cty;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000643 uint32_t *RK;
644 uint32_t *SK;
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200645
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100646 AES_VALIDATE_RET(ctx != NULL);
647 AES_VALIDATE_RET(key != NULL);
Simon Butcher5201e412018-12-06 17:40:14 +0000648
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100649 mbedtls_aes_init(&cty);
Paul Bakker5121ce52009-01-03 21:22:43 +0000650
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200651#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_PADLOCK_ALIGN16)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100652 if (aes_padlock_ace == -1) {
653 aes_padlock_ace = mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE);
654 }
Paul Bakker048d04e2012-02-12 17:31:04 +0000655
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100656 if (aes_padlock_ace) {
657 ctx->rk = RK = MBEDTLS_PADLOCK_ALIGN16(ctx->buf);
658 } else
Paul Bakker5121ce52009-01-03 21:22:43 +0000659#endif
Paul Bakker048d04e2012-02-12 17:31:04 +0000660 ctx->rk = RK = ctx->buf;
Paul Bakker5121ce52009-01-03 21:22:43 +0000661
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200662 /* Also checks keybits */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100663 if ((ret = mbedtls_aes_setkey_enc(&cty, key, keybits)) != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200664 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100665 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000666
Manuel Pégourié-Gonnardafd5a082014-05-28 21:52:59 +0200667 ctx->nr = cty.nr;
668
Gilles Peskine5511a342023-03-10 22:29:32 +0100669#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100670 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
671 mbedtls_aesni_inverse_key((unsigned char *) ctx->rk,
672 (const unsigned char *) cty.rk, ctx->nr);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200673 goto exit;
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100674 }
675#endif
Gilles Peskinee7dc21f2023-03-10 22:37:11 +0100676#if defined(MBEDTLS_AESNI_HAVE_CODE)
677 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
678 /* The intrinsics-based implementation needs 16-byte alignment
679 * for the round key array. */
680 unsigned delta = (uintptr_t) ctx->buf & 0x0000000f;
681 if (delta != 0) {
682 size_t rk_offset = 4 - delta / 4; // 16 bytes = 4 uint32_t
683 ctx->rk = RK = ctx->buf + rk_offset;
684 }
685 }
686#endif
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100687
Paul Bakker5121ce52009-01-03 21:22:43 +0000688 SK = cty.rk + cty.nr * 4;
689
690 *RK++ = *SK++;
691 *RK++ = *SK++;
692 *RK++ = *SK++;
693 *RK++ = *SK++;
694
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100695 for (i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8) {
696 for (j = 0; j < 4; j++, SK++) {
697 *RK++ = AES_RT0(FSb[MBEDTLS_BYTE_0(*SK)]) ^
698 AES_RT1(FSb[MBEDTLS_BYTE_1(*SK)]) ^
699 AES_RT2(FSb[MBEDTLS_BYTE_2(*SK)]) ^
700 AES_RT3(FSb[MBEDTLS_BYTE_3(*SK)]);
Paul Bakker5121ce52009-01-03 21:22:43 +0000701 }
702 }
703
704 *RK++ = *SK++;
705 *RK++ = *SK++;
706 *RK++ = *SK++;
707 *RK++ = *SK++;
708
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200709exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100710 mbedtls_aes_free(&cty);
Paul Bakker2b222c82009-07-27 21:03:45 +0000711
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100712 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000713}
gabor-mezei-arm95db3012020-10-26 11:35:23 +0100714#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */
Jaeden Amero9366feb2018-05-29 18:55:17 +0100715
716#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100717static int mbedtls_aes_xts_decode_keys(const unsigned char *key,
718 unsigned int keybits,
719 const unsigned char **key1,
720 unsigned int *key1bits,
721 const unsigned char **key2,
722 unsigned int *key2bits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100723{
724 const unsigned int half_keybits = keybits / 2;
725 const unsigned int half_keybytes = half_keybits / 8;
726
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100727 switch (keybits) {
Jaeden Amero9366feb2018-05-29 18:55:17 +0100728 case 256: break;
729 case 512: break;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100730 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100731 }
732
733 *key1bits = half_keybits;
734 *key2bits = half_keybits;
735 *key1 = &key[0];
736 *key2 = &key[half_keybytes];
737
738 return 0;
739}
740
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100741int mbedtls_aes_xts_setkey_enc(mbedtls_aes_xts_context *ctx,
742 const unsigned char *key,
743 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100744{
Janos Follath24eed8d2019-11-22 13:21:35 +0000745 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100746 const unsigned char *key1, *key2;
747 unsigned int key1bits, key2bits;
748
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100749 AES_VALIDATE_RET(ctx != NULL);
750 AES_VALIDATE_RET(key != NULL);
Manuel Pégourié-Gonnard68e3dff2018-12-12 12:48:04 +0100751
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100752 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
753 &key2, &key2bits);
754 if (ret != 0) {
755 return ret;
756 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100757
758 /* Set the tweak key. Always set tweak key for the encryption mode. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100759 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
760 if (ret != 0) {
761 return ret;
762 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100763
764 /* Set crypt key for encryption. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100765 return mbedtls_aes_setkey_enc(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100766}
767
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100768int mbedtls_aes_xts_setkey_dec(mbedtls_aes_xts_context *ctx,
769 const unsigned char *key,
770 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100771{
Janos Follath24eed8d2019-11-22 13:21:35 +0000772 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100773 const unsigned char *key1, *key2;
774 unsigned int key1bits, key2bits;
775
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100776 AES_VALIDATE_RET(ctx != NULL);
777 AES_VALIDATE_RET(key != NULL);
Manuel Pégourié-Gonnard68e3dff2018-12-12 12:48:04 +0100778
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100779 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
780 &key2, &key2bits);
781 if (ret != 0) {
782 return ret;
783 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100784
785 /* Set the tweak key. Always set tweak key for encryption. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100786 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
787 if (ret != 0) {
788 return ret;
789 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100790
791 /* Set crypt key for decryption. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100792 return mbedtls_aes_setkey_dec(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100793}
794#endif /* MBEDTLS_CIPHER_MODE_XTS */
795
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100796#define AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Joe Subbiani6b897c92021-07-08 14:59:52 +0100797 do \
798 { \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100799 (X0) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y0)) ^ \
800 AES_FT1(MBEDTLS_BYTE_1(Y1)) ^ \
801 AES_FT2(MBEDTLS_BYTE_2(Y2)) ^ \
802 AES_FT3(MBEDTLS_BYTE_3(Y3)); \
Joe Subbiani6b897c92021-07-08 14:59:52 +0100803 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100804 (X1) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y1)) ^ \
805 AES_FT1(MBEDTLS_BYTE_1(Y2)) ^ \
806 AES_FT2(MBEDTLS_BYTE_2(Y3)) ^ \
807 AES_FT3(MBEDTLS_BYTE_3(Y0)); \
Joe Subbiani6b897c92021-07-08 14:59:52 +0100808 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100809 (X2) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y2)) ^ \
810 AES_FT1(MBEDTLS_BYTE_1(Y3)) ^ \
811 AES_FT2(MBEDTLS_BYTE_2(Y0)) ^ \
812 AES_FT3(MBEDTLS_BYTE_3(Y1)); \
Joe Subbiani6b897c92021-07-08 14:59:52 +0100813 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100814 (X3) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y3)) ^ \
815 AES_FT1(MBEDTLS_BYTE_1(Y0)) ^ \
816 AES_FT2(MBEDTLS_BYTE_2(Y1)) ^ \
817 AES_FT3(MBEDTLS_BYTE_3(Y2)); \
818 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000819
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100820#define AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100821 do \
822 { \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100823 (X0) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y0)) ^ \
824 AES_RT1(MBEDTLS_BYTE_1(Y3)) ^ \
825 AES_RT2(MBEDTLS_BYTE_2(Y2)) ^ \
826 AES_RT3(MBEDTLS_BYTE_3(Y1)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100827 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100828 (X1) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y1)) ^ \
829 AES_RT1(MBEDTLS_BYTE_1(Y0)) ^ \
830 AES_RT2(MBEDTLS_BYTE_2(Y3)) ^ \
831 AES_RT3(MBEDTLS_BYTE_3(Y2)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100832 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100833 (X2) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y2)) ^ \
834 AES_RT1(MBEDTLS_BYTE_1(Y1)) ^ \
835 AES_RT2(MBEDTLS_BYTE_2(Y0)) ^ \
836 AES_RT3(MBEDTLS_BYTE_3(Y3)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100837 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100838 (X3) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y3)) ^ \
839 AES_RT1(MBEDTLS_BYTE_1(Y2)) ^ \
840 AES_RT2(MBEDTLS_BYTE_2(Y1)) ^ \
841 AES_RT3(MBEDTLS_BYTE_3(Y0)); \
842 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000843
844/*
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200845 * AES-ECB block encryption
846 */
847#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100848int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx,
849 const unsigned char input[16],
850 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200851{
852 int i;
Gilles Peskine5197c662020-08-26 17:03:24 +0200853 uint32_t *RK = ctx->rk;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100854 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200855 uint32_t X[4];
856 uint32_t Y[4];
857 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200858
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100859 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
860 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
861 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
862 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200863
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100864 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
865 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]);
866 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 +0200867 }
868
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100869 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 +0200870
Gilles Peskine5197c662020-08-26 17:03:24 +0200871 t.X[0] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100872 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
873 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
874 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
875 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200876
Gilles Peskine5197c662020-08-26 17:03:24 +0200877 t.X[1] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100878 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
879 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
880 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
881 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200882
Gilles Peskine5197c662020-08-26 17:03:24 +0200883 t.X[2] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100884 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
885 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
886 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
887 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200888
Gilles Peskine5197c662020-08-26 17:03:24 +0200889 t.X[3] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100890 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
891 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
892 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
893 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200894
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100895 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
896 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
897 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
898 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +0000899
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100900 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500901
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100902 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200903}
904#endif /* !MBEDTLS_AES_ENCRYPT_ALT */
905
Gilles Peskine8db3efb2018-02-21 19:16:20 +0100906#if !defined(MBEDTLS_DEPRECATED_REMOVED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100907void mbedtls_aes_encrypt(mbedtls_aes_context *ctx,
908 const unsigned char input[16],
909 unsigned char output[16])
Hanno Beckerbedc2052017-06-26 12:46:56 +0100910{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100911 MBEDTLS_IGNORE_RETURN(mbedtls_internal_aes_encrypt(ctx, input, output));
Hanno Beckerbedc2052017-06-26 12:46:56 +0100912}
Gilles Peskine8db3efb2018-02-21 19:16:20 +0100913#endif /* !MBEDTLS_DEPRECATED_REMOVED */
Hanno Beckerbedc2052017-06-26 12:46:56 +0100914
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200915/*
916 * AES-ECB block decryption
917 */
918#if !defined(MBEDTLS_AES_DECRYPT_ALT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100919int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
920 const unsigned char input[16],
921 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200922{
923 int i;
Gilles Peskine5197c662020-08-26 17:03:24 +0200924 uint32_t *RK = ctx->rk;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100925 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200926 uint32_t X[4];
927 uint32_t Y[4];
928 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200929
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100930 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
931 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
932 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
933 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200934
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100935 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
936 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]);
937 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 +0200938 }
939
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100940 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 +0200941
Gilles Peskine5197c662020-08-26 17:03:24 +0200942 t.X[0] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100943 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
944 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
945 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
946 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200947
Gilles Peskine5197c662020-08-26 17:03:24 +0200948 t.X[1] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100949 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
950 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
951 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
952 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200953
Gilles Peskine5197c662020-08-26 17:03:24 +0200954 t.X[2] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100955 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
956 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
957 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
958 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200959
Gilles Peskine5197c662020-08-26 17:03:24 +0200960 t.X[3] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100961 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
962 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
963 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
964 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200965
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100966 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
967 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
968 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
969 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +0000970
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100971 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500972
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100973 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200974}
975#endif /* !MBEDTLS_AES_DECRYPT_ALT */
976
Gilles Peskine8db3efb2018-02-21 19:16:20 +0100977#if !defined(MBEDTLS_DEPRECATED_REMOVED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100978void mbedtls_aes_decrypt(mbedtls_aes_context *ctx,
979 const unsigned char input[16],
980 unsigned char output[16])
Hanno Beckerbedc2052017-06-26 12:46:56 +0100981{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100982 MBEDTLS_IGNORE_RETURN(mbedtls_internal_aes_decrypt(ctx, input, output));
Hanno Beckerbedc2052017-06-26 12:46:56 +0100983}
Gilles Peskine8db3efb2018-02-21 19:16:20 +0100984#endif /* !MBEDTLS_DEPRECATED_REMOVED */
Hanno Beckerbedc2052017-06-26 12:46:56 +0100985
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200986/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000987 * AES-ECB block encryption/decryption
988 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100989int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
990 int mode,
991 const unsigned char input[16],
992 unsigned char output[16])
Paul Bakker5121ce52009-01-03 21:22:43 +0000993{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100994 AES_VALIDATE_RET(ctx != NULL);
995 AES_VALIDATE_RET(input != NULL);
996 AES_VALIDATE_RET(output != NULL);
997 AES_VALIDATE_RET(mode == MBEDTLS_AES_ENCRYPT ||
998 mode == MBEDTLS_AES_DECRYPT);
Manuel Pégourié-Gonnard1aca2602018-12-12 12:56:55 +0100999
Gilles Peskine5511a342023-03-10 22:29:32 +01001000#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001001 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1002 return mbedtls_aesni_crypt_ecb(ctx, mode, input, output);
1003 }
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +01001004#endif
1005
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001006#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001007 if (aes_padlock_ace) {
1008 if (mbedtls_padlock_xcryptecb(ctx, mode, input, output) == 0) {
1009 return 0;
1010 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001011
1012 // If padlock data misaligned, we just fall back to
1013 // unaccelerated mode
1014 //
Paul Bakker5121ce52009-01-03 21:22:43 +00001015 }
1016#endif
1017
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001018 if (mode == MBEDTLS_AES_ENCRYPT) {
1019 return mbedtls_internal_aes_encrypt(ctx, input, output);
1020 } else {
1021 return mbedtls_internal_aes_decrypt(ctx, input, output);
1022 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001023}
1024
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001025#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001026/*
1027 * AES-CBC buffer encryption/decryption
1028 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001029int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
1030 int mode,
1031 size_t length,
1032 unsigned char iv[16],
1033 const unsigned char *input,
1034 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001035{
1036 int i;
Gilles Peskine377a3102021-07-07 21:08:28 +02001037 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +00001038 unsigned char temp[16];
1039
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001040 AES_VALIDATE_RET(ctx != NULL);
1041 AES_VALIDATE_RET(mode == MBEDTLS_AES_ENCRYPT ||
1042 mode == MBEDTLS_AES_DECRYPT);
1043 AES_VALIDATE_RET(iv != NULL);
1044 AES_VALIDATE_RET(input != NULL);
1045 AES_VALIDATE_RET(output != NULL);
Manuel Pégourié-Gonnard3178d1a2018-12-12 13:05:00 +01001046
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001047 if (length % 16) {
1048 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
1049 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001050
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001051#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001052 if (aes_padlock_ace) {
1053 if (mbedtls_padlock_xcryptcbc(ctx, mode, length, iv, input, output) == 0) {
1054 return 0;
1055 }
Paul Bakker9af723c2014-05-01 13:03:14 +02001056
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001057 // If padlock data misaligned, we just fall back to
1058 // unaccelerated mode
1059 //
Paul Bakker5121ce52009-01-03 21:22:43 +00001060 }
1061#endif
1062
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001063 if (mode == MBEDTLS_AES_DECRYPT) {
1064 while (length > 0) {
1065 memcpy(temp, input, 16);
1066 ret = mbedtls_aes_crypt_ecb(ctx, mode, input, output);
1067 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +02001068 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001069 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001070
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001071 for (i = 0; i < 16; i++) {
1072 output[i] = (unsigned char) (output[i] ^ iv[i]);
1073 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001074
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001075 memcpy(iv, temp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001076
1077 input += 16;
1078 output += 16;
1079 length -= 16;
1080 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001081 } else {
1082 while (length > 0) {
1083 for (i = 0; i < 16; i++) {
1084 output[i] = (unsigned char) (input[i] ^ iv[i]);
1085 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001086
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001087 ret = mbedtls_aes_crypt_ecb(ctx, mode, output, output);
1088 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +02001089 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001090 }
1091 memcpy(iv, output, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001092
1093 input += 16;
1094 output += 16;
1095 length -= 16;
1096 }
1097 }
Gilles Peskine377a3102021-07-07 21:08:28 +02001098 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001099
Gilles Peskine377a3102021-07-07 21:08:28 +02001100exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001101 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001102}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001103#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001104
Aorimn5f778012016-06-09 23:22:58 +02001105#if defined(MBEDTLS_CIPHER_MODE_XTS)
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001106
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001107typedef unsigned char mbedtls_be128[16];
1108
1109/*
1110 * GF(2^128) multiplication function
1111 *
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001112 * This function multiplies a field element by x in the polynomial field
1113 * representation. It uses 64-bit word operations to gain speed but compensates
Shaun Case0e7791f2021-12-20 21:14:10 -08001114 * for machine endianness and hence works correctly on both big and little
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001115 * endian machines.
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001116 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001117static void mbedtls_gf128mul_x_ble(unsigned char r[16],
1118 const unsigned char x[16])
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001119{
1120 uint64_t a, b, ra, rb;
1121
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001122 a = MBEDTLS_GET_UINT64_LE(x, 0);
1123 b = MBEDTLS_GET_UINT64_LE(x, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001124
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001125 ra = (a << 1) ^ 0x0087 >> (8 - ((b >> 63) << 3));
1126 rb = (a >> 63) | (b << 1);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001127
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001128 MBEDTLS_PUT_UINT64_LE(ra, r, 0);
1129 MBEDTLS_PUT_UINT64_LE(rb, r, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001130}
1131
Aorimn5f778012016-06-09 23:22:58 +02001132/*
1133 * AES-XTS buffer encryption/decryption
1134 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001135int mbedtls_aes_crypt_xts(mbedtls_aes_xts_context *ctx,
1136 int mode,
1137 size_t length,
1138 const unsigned char data_unit[16],
1139 const unsigned char *input,
1140 unsigned char *output)
Aorimn5f778012016-06-09 23:22:58 +02001141{
Janos Follath24eed8d2019-11-22 13:21:35 +00001142 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amerod82cd862018-04-28 15:02:45 +01001143 size_t blocks = length / 16;
1144 size_t leftover = length % 16;
1145 unsigned char tweak[16];
1146 unsigned char prev_tweak[16];
1147 unsigned char tmp[16];
Aorimn5f778012016-06-09 23:22:58 +02001148
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001149 AES_VALIDATE_RET(ctx != NULL);
1150 AES_VALIDATE_RET(mode == MBEDTLS_AES_ENCRYPT ||
1151 mode == MBEDTLS_AES_DECRYPT);
1152 AES_VALIDATE_RET(data_unit != NULL);
1153 AES_VALIDATE_RET(input != NULL);
1154 AES_VALIDATE_RET(output != NULL);
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01001155
Jaeden Amero8381fcb2018-10-11 12:06:15 +01001156 /* Data units must be at least 16 bytes long. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001157 if (length < 16) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001158 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001159 }
Aorimn5f778012016-06-09 23:22:58 +02001160
Jaeden Ameroa74faba2018-10-11 12:07:43 +01001161 /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001162 if (length > (1 << 20) * 16) {
Jaeden Amero0a8b0202018-05-30 15:36:06 +01001163 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001164 }
Aorimn5f778012016-06-09 23:22:58 +02001165
Jaeden Amerod82cd862018-04-28 15:02:45 +01001166 /* Compute the tweak. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001167 ret = mbedtls_aes_crypt_ecb(&ctx->tweak, MBEDTLS_AES_ENCRYPT,
1168 data_unit, tweak);
1169 if (ret != 0) {
1170 return ret;
1171 }
Aorimn5f778012016-06-09 23:22:58 +02001172
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001173 while (blocks--) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001174 size_t i;
1175
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001176 if (leftover && (mode == MBEDTLS_AES_DECRYPT) && blocks == 0) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001177 /* We are on the last block in a decrypt operation that has
1178 * leftover bytes, so we need to use the next tweak for this block,
Tom Cosgrove49f99bc2022-12-04 16:44:21 +00001179 * and this tweak for the leftover bytes. Save the current tweak for
Jaeden Amerod82cd862018-04-28 15:02:45 +01001180 * the leftovers and then update the current tweak for use on this,
1181 * the last full block. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001182 memcpy(prev_tweak, tweak, sizeof(tweak));
1183 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001184 }
1185
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001186 for (i = 0; i < 16; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001187 tmp[i] = input[i] ^ tweak[i];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001188 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001189
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001190 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1191 if (ret != 0) {
1192 return ret;
1193 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001194
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001195 for (i = 0; i < 16; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001196 output[i] = tmp[i] ^ tweak[i];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001197 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001198
1199 /* Update the tweak for the next block. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001200 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001201
1202 output += 16;
1203 input += 16;
Aorimn5f778012016-06-09 23:22:58 +02001204 }
1205
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001206 if (leftover) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001207 /* If we are on the leftover bytes in a decrypt operation, we need to
1208 * use the previous tweak for these bytes (as saved in prev_tweak). */
1209 unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
Aorimn5f778012016-06-09 23:22:58 +02001210
Jaeden Amerod82cd862018-04-28 15:02:45 +01001211 /* We are now on the final part of the data unit, which doesn't divide
1212 * evenly by 16. It's time for ciphertext stealing. */
1213 size_t i;
1214 unsigned char *prev_output = output - 16;
Aorimn5f778012016-06-09 23:22:58 +02001215
Jaeden Amerod82cd862018-04-28 15:02:45 +01001216 /* Copy ciphertext bytes from the previous block to our output for each
Shaun Case0e7791f2021-12-20 21:14:10 -08001217 * byte of ciphertext we won't steal. At the same time, copy the
Jaeden Amerod82cd862018-04-28 15:02:45 +01001218 * remainder of the input for this final round (since the loop bounds
1219 * are the same). */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001220 for (i = 0; i < leftover; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001221 output[i] = prev_output[i];
1222 tmp[i] = input[i] ^ t[i];
Aorimn5f778012016-06-09 23:22:58 +02001223 }
Aorimn5f778012016-06-09 23:22:58 +02001224
Jaeden Amerod82cd862018-04-28 15:02:45 +01001225 /* Copy ciphertext bytes from the previous block for input in this
1226 * round. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001227 for (; i < 16; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001228 tmp[i] = prev_output[i] ^ t[i];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001229 }
Aorimn5f778012016-06-09 23:22:58 +02001230
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001231 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1232 if (ret != 0) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001233 return ret;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001234 }
Aorimn5f778012016-06-09 23:22:58 +02001235
Jaeden Amerod82cd862018-04-28 15:02:45 +01001236 /* Write the result back to the previous block, overriding the previous
1237 * output we copied. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001238 for (i = 0; i < 16; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001239 prev_output[i] = tmp[i] ^ t[i];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001240 }
Aorimn5f778012016-06-09 23:22:58 +02001241 }
1242
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001243 return 0;
Aorimn5f778012016-06-09 23:22:58 +02001244}
1245#endif /* MBEDTLS_CIPHER_MODE_XTS */
1246
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001247#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001248/*
1249 * AES-CFB128 buffer encryption/decryption
1250 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001251int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx,
1252 int mode,
1253 size_t length,
1254 size_t *iv_off,
1255 unsigned char iv[16],
1256 const unsigned char *input,
1257 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001258{
Paul Bakker27fdf462011-06-09 13:55:13 +00001259 int c;
Gilles Peskine377a3102021-07-07 21:08:28 +02001260 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001261 size_t n;
1262
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001263 AES_VALIDATE_RET(ctx != NULL);
1264 AES_VALIDATE_RET(mode == MBEDTLS_AES_ENCRYPT ||
1265 mode == MBEDTLS_AES_DECRYPT);
1266 AES_VALIDATE_RET(iv_off != NULL);
1267 AES_VALIDATE_RET(iv != NULL);
1268 AES_VALIDATE_RET(input != NULL);
1269 AES_VALIDATE_RET(output != NULL);
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001270
1271 n = *iv_off;
Paul Bakker5121ce52009-01-03 21:22:43 +00001272
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001273 if (n > 15) {
1274 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1275 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001276
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001277 if (mode == MBEDTLS_AES_DECRYPT) {
1278 while (length--) {
1279 if (n == 0) {
1280 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1281 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +02001282 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001283 }
Gilles Peskine377a3102021-07-07 21:08:28 +02001284 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001285
1286 c = *input++;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001287 *output++ = (unsigned char) (c ^ iv[n]);
Paul Bakker5121ce52009-01-03 21:22:43 +00001288 iv[n] = (unsigned char) c;
1289
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001290 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001291 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001292 } else {
1293 while (length--) {
1294 if (n == 0) {
1295 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1296 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +02001297 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001298 }
Gilles Peskine377a3102021-07-07 21:08:28 +02001299 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001300
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001301 iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++);
Paul Bakker5121ce52009-01-03 21:22:43 +00001302
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001303 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001304 }
1305 }
1306
1307 *iv_off = n;
Gilles Peskine377a3102021-07-07 21:08:28 +02001308 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001309
Gilles Peskine377a3102021-07-07 21:08:28 +02001310exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001311 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001312}
Paul Bakker556efba2014-01-24 15:38:12 +01001313
1314/*
1315 * AES-CFB8 buffer encryption/decryption
1316 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001317int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx,
1318 int mode,
1319 size_t length,
1320 unsigned char iv[16],
1321 const unsigned char *input,
1322 unsigned char *output)
Paul Bakker556efba2014-01-24 15:38:12 +01001323{
Gilles Peskine377a3102021-07-07 21:08:28 +02001324 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker556efba2014-01-24 15:38:12 +01001325 unsigned char c;
1326 unsigned char ov[17];
1327
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001328 AES_VALIDATE_RET(ctx != NULL);
1329 AES_VALIDATE_RET(mode == MBEDTLS_AES_ENCRYPT ||
1330 mode == MBEDTLS_AES_DECRYPT);
1331 AES_VALIDATE_RET(iv != NULL);
1332 AES_VALIDATE_RET(input != NULL);
1333 AES_VALIDATE_RET(output != NULL);
1334 while (length--) {
1335 memcpy(ov, iv, 16);
1336 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1337 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +02001338 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001339 }
Paul Bakker556efba2014-01-24 15:38:12 +01001340
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001341 if (mode == MBEDTLS_AES_DECRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001342 ov[16] = *input;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001343 }
Paul Bakker556efba2014-01-24 15:38:12 +01001344
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001345 c = *output++ = (unsigned char) (iv[0] ^ *input++);
Paul Bakker556efba2014-01-24 15:38:12 +01001346
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001347 if (mode == MBEDTLS_AES_ENCRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001348 ov[16] = c;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001349 }
Paul Bakker556efba2014-01-24 15:38:12 +01001350
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001351 memcpy(iv, ov + 1, 16);
Paul Bakker556efba2014-01-24 15:38:12 +01001352 }
Gilles Peskine377a3102021-07-07 21:08:28 +02001353 ret = 0;
Paul Bakker556efba2014-01-24 15:38:12 +01001354
Gilles Peskine377a3102021-07-07 21:08:28 +02001355exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001356 return ret;
Paul Bakker556efba2014-01-24 15:38:12 +01001357}
Simon Butcher76a5b222018-04-22 22:57:27 +01001358#endif /* MBEDTLS_CIPHER_MODE_CFB */
1359
1360#if defined(MBEDTLS_CIPHER_MODE_OFB)
1361/*
1362 * AES-OFB (Output Feedback Mode) buffer encryption/decryption
1363 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001364int mbedtls_aes_crypt_ofb(mbedtls_aes_context *ctx,
1365 size_t length,
1366 size_t *iv_off,
1367 unsigned char iv[16],
1368 const unsigned char *input,
1369 unsigned char *output)
Simon Butcher76a5b222018-04-22 22:57:27 +01001370{
Simon Butcherad4e4932018-04-29 00:43:47 +01001371 int ret = 0;
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001372 size_t n;
1373
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001374 AES_VALIDATE_RET(ctx != NULL);
1375 AES_VALIDATE_RET(iv_off != NULL);
1376 AES_VALIDATE_RET(iv != NULL);
1377 AES_VALIDATE_RET(input != NULL);
1378 AES_VALIDATE_RET(output != NULL);
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001379
1380 n = *iv_off;
Simon Butcher76a5b222018-04-22 22:57:27 +01001381
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001382 if (n > 15) {
1383 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1384 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001385
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001386 while (length--) {
1387 if (n == 0) {
1388 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1389 if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001390 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001391 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001392 }
Simon Butcher76a5b222018-04-22 22:57:27 +01001393 *output++ = *input++ ^ iv[n];
1394
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001395 n = (n + 1) & 0x0F;
Simon Butcher76a5b222018-04-22 22:57:27 +01001396 }
1397
1398 *iv_off = n;
1399
Simon Butcherad4e4932018-04-29 00:43:47 +01001400exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001401 return ret;
Simon Butcher76a5b222018-04-22 22:57:27 +01001402}
1403#endif /* MBEDTLS_CIPHER_MODE_OFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001404
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001405#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001406/*
1407 * AES-CTR buffer encryption/decryption
1408 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001409int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
1410 size_t length,
1411 size_t *nc_off,
1412 unsigned char nonce_counter[16],
1413 unsigned char stream_block[16],
1414 const unsigned char *input,
1415 unsigned char *output)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001416{
Paul Bakker369e14b2012-04-18 14:16:09 +00001417 int c, i;
Gilles Peskine377a3102021-07-07 21:08:28 +02001418 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001419 size_t n;
1420
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001421 AES_VALIDATE_RET(ctx != NULL);
1422 AES_VALIDATE_RET(nc_off != NULL);
1423 AES_VALIDATE_RET(nonce_counter != NULL);
1424 AES_VALIDATE_RET(stream_block != NULL);
1425 AES_VALIDATE_RET(input != NULL);
1426 AES_VALIDATE_RET(output != NULL);
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001427
1428 n = *nc_off;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001429
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001430 if (n > 0x0F) {
1431 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1432 }
Mohammad Azim Khan3f7f8172017-11-23 17:49:05 +00001433
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001434 while (length--) {
1435 if (n == 0) {
1436 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block);
1437 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +02001438 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001439 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001440
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001441 for (i = 16; i > 0; i--) {
1442 if (++nonce_counter[i - 1] != 0) {
Paul Bakker369e14b2012-04-18 14:16:09 +00001443 break;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001444 }
1445 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001446 }
1447 c = *input++;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001448 *output++ = (unsigned char) (c ^ stream_block[n]);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001449
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001450 n = (n + 1) & 0x0F;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001451 }
1452
1453 *nc_off = n;
Gilles Peskine377a3102021-07-07 21:08:28 +02001454 ret = 0;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001455
Gilles Peskine377a3102021-07-07 21:08:28 +02001456exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001457 return ret;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001458}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001459#endif /* MBEDTLS_CIPHER_MODE_CTR */
Manuel Pégourié-Gonnard1ec220b2014-03-10 11:20:17 +01001460
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001461#endif /* !MBEDTLS_AES_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001462
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001463#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001464/*
1465 * AES test vectors from:
1466 *
1467 * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
1468 */
1469static const unsigned char aes_test_ecb_dec[3][16] =
1470{
1471 { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
1472 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
1473 { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
1474 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
1475 { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
1476 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
1477};
1478
1479static const unsigned char aes_test_ecb_enc[3][16] =
1480{
1481 { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
1482 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
1483 { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
1484 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
1485 { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
1486 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
1487};
1488
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001489#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001490static const unsigned char aes_test_cbc_dec[3][16] =
1491{
1492 { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
1493 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
1494 { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
1495 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
1496 { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
1497 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
1498};
1499
1500static const unsigned char aes_test_cbc_enc[3][16] =
1501{
1502 { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
1503 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
1504 { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
1505 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
1506 { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
1507 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
1508};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001509#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001510
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001511#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001512/*
1513 * AES-CFB128 test vectors from:
1514 *
1515 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
1516 */
1517static const unsigned char aes_test_cfb128_key[3][32] =
1518{
1519 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1520 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
1521 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1522 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1523 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1524 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1525 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1526 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1527 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
1528};
1529
1530static const unsigned char aes_test_cfb128_iv[16] =
1531{
1532 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1533 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1534};
1535
1536static const unsigned char aes_test_cfb128_pt[64] =
1537{
1538 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1539 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1540 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1541 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1542 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1543 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1544 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1545 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1546};
1547
1548static const unsigned char aes_test_cfb128_ct[3][64] =
1549{
1550 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1551 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1552 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F,
1553 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B,
1554 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40,
1555 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF,
1556 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E,
1557 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 },
1558 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1559 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1560 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21,
1561 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A,
1562 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1,
1563 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9,
1564 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0,
1565 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF },
1566 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1567 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1568 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8,
1569 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B,
1570 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92,
1571 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9,
1572 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8,
1573 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 }
1574};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001575#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001576
Simon Butcherad4e4932018-04-29 00:43:47 +01001577#if defined(MBEDTLS_CIPHER_MODE_OFB)
1578/*
1579 * AES-OFB test vectors from:
1580 *
Simon Butcher5db13622018-06-04 22:11:25 +01001581 * https://csrc.nist.gov/publications/detail/sp/800-38a/final
Simon Butcherad4e4932018-04-29 00:43:47 +01001582 */
1583static const unsigned char aes_test_ofb_key[3][32] =
1584{
1585 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1586 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
1587 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1588 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1589 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1590 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1591 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1592 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1593 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
1594};
1595
1596static const unsigned char aes_test_ofb_iv[16] =
1597{
1598 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1599 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1600};
1601
1602static const unsigned char aes_test_ofb_pt[64] =
1603{
1604 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1605 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1606 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1607 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1608 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1609 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1610 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1611 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1612};
1613
1614static const unsigned char aes_test_ofb_ct[3][64] =
1615{
1616 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1617 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1618 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
1619 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
1620 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
1621 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
1622 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
1623 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e },
1624 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1625 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1626 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
1627 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
1628 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f,
1629 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
1630 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e,
1631 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a },
1632 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1633 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1634 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
1635 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
1636 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed,
1637 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
1638 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8,
1639 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 }
1640};
1641#endif /* MBEDTLS_CIPHER_MODE_OFB */
1642
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001643#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001644/*
1645 * AES-CTR test vectors from:
1646 *
1647 * http://www.faqs.org/rfcs/rfc3686.html
1648 */
1649
1650static const unsigned char aes_test_ctr_key[3][16] =
1651{
1652 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
1653 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
1654 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
1655 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
1656 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
1657 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
1658};
1659
1660static const unsigned char aes_test_ctr_nonce_counter[3][16] =
1661{
1662 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
1663 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
1664 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
1665 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
1666 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
1667 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
1668};
1669
1670static const unsigned char aes_test_ctr_pt[3][48] =
1671{
1672 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
1673 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
1674
1675 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1676 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1677 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1678 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
1679
1680 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1681 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1682 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1683 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
1684 0x20, 0x21, 0x22, 0x23 }
1685};
1686
1687static const unsigned char aes_test_ctr_ct[3][48] =
1688{
1689 { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79,
1690 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 },
1691 { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9,
1692 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88,
1693 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8,
1694 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 },
1695 { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
1696 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
1697 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
1698 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
1699 0x25, 0xB2, 0x07, 0x2F }
1700};
1701
1702static const int aes_test_ctr_len[3] =
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001703{ 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001704#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00001705
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001706#if defined(MBEDTLS_CIPHER_MODE_XTS)
1707/*
1708 * AES-XTS test vectors from:
1709 *
1710 * IEEE P1619/D16 Annex B
1711 * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf
1712 * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf)
1713 */
1714static const unsigned char aes_test_xts_key[][32] =
1715{
1716 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1717 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1718 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1719 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1720 { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1721 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1722 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1723 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1724 { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
1725 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
1726 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1727 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1728};
1729
1730static const unsigned char aes_test_xts_pt32[][32] =
1731{
1732 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1733 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1734 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1735 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1736 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1737 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1738 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1739 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1740 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1741 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1742 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1743 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1744};
1745
1746static const unsigned char aes_test_xts_ct32[][32] =
1747{
1748 { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec,
1749 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92,
1750 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85,
1751 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e },
1752 { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e,
1753 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b,
1754 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4,
1755 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 },
1756 { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a,
1757 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2,
1758 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53,
1759 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 },
1760};
1761
1762static const unsigned char aes_test_xts_data_unit[][16] =
1763{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001764 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1765 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1766 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1767 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1768 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1769 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001770};
1771
1772#endif /* MBEDTLS_CIPHER_MODE_XTS */
1773
Paul Bakker5121ce52009-01-03 21:22:43 +00001774/*
1775 * Checkup routine
1776 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001777int mbedtls_aes_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +00001778{
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001779 int ret = 0, i, j, u, mode;
1780 unsigned int keybits;
Paul Bakker5121ce52009-01-03 21:22:43 +00001781 unsigned char key[32];
1782 unsigned char buf[64];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001783 const unsigned char *aes_tests;
Andrzej Kurek8ffd8a62022-09-27 07:54:16 -04001784#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1785 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001786 unsigned char iv[16];
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03001787#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001788#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +02001789 unsigned char prv[16];
1790#endif
Simon Butcher2ff0e522018-06-14 09:57:07 +01001791#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1792 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker27fdf462011-06-09 13:55:13 +00001793 size_t offset;
Paul Bakkere91d01e2011-04-19 15:55:50 +00001794#endif
Simon Butcher66a89032018-06-15 18:20:29 +01001795#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS)
Paul Bakkere91d01e2011-04-19 15:55:50 +00001796 int len;
Simon Butcher66a89032018-06-15 18:20:29 +01001797#endif
1798#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001799 unsigned char nonce_counter[16];
1800 unsigned char stream_block[16];
1801#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001802 mbedtls_aes_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001803
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001804 memset(key, 0, 32);
1805 mbedtls_aes_init(&ctx);
Paul Bakker5121ce52009-01-03 21:22:43 +00001806
Gilles Peskine2c8ad942023-03-10 22:35:24 +01001807 if (verbose != 0) {
1808#if defined(MBEDTLS_AES_ALT)
1809 mbedtls_printf(" AES note: alternative implementation.\n");
1810#else /* MBEDTLS_AES_ALT */
1811#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
1812 if (mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE)) {
1813 mbedtls_printf(" AES note: using VIA Padlock.\n");
1814 } else
1815#endif
1816#if defined(MBEDTLS_AESNI_HAVE_CODE)
1817 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1818 mbedtls_printf(" AES note: using AESNI.\n");
1819 } else
1820#endif
1821#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
1822 if (mbedtls_aesce_has_support()) {
1823 mbedtls_printf(" AES note: using AESCE.\n");
1824 } else
1825#endif
1826 mbedtls_printf(" AES note: built-in implementation.\n");
1827#endif /* MBEDTLS_AES_ALT */
1828 }
1829
Paul Bakker5121ce52009-01-03 21:22:43 +00001830 /*
1831 * ECB mode
1832 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001833 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +00001834 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001835 keybits = 128 + u * 64;
1836 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001837
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001838 if (verbose != 0) {
1839 mbedtls_printf(" AES-ECB-%3u (%s): ", keybits,
1840 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00001841 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001842
1843 memset(buf, 0, 16);
1844
1845 if (mode == MBEDTLS_AES_DECRYPT) {
1846 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1847 aes_tests = aes_test_ecb_dec[u];
1848 } else {
1849 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001850 aes_tests = aes_test_ecb_enc[u];
1851 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001852
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01001853 /*
1854 * AES-192 is an optional feature that may be unavailable when
1855 * there is an alternative underlying implementation i.e. when
1856 * MBEDTLS_AES_ALT is defined.
1857 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001858 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1859 mbedtls_printf("skipped\n");
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001860 continue;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001861 } else if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001862 goto exit;
1863 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001864
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001865 for (j = 0; j < 10000; j++) {
1866 ret = mbedtls_aes_crypt_ecb(&ctx, mode, buf, buf);
1867 if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001868 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001869 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001870 }
1871
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001872 if (memcmp(buf, aes_tests, 16) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001873 ret = 1;
1874 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001875 }
1876
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001877 if (verbose != 0) {
1878 mbedtls_printf("passed\n");
1879 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001880 }
1881
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001882 if (verbose != 0) {
1883 mbedtls_printf("\n");
1884 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001885
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001886#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001887 /*
1888 * CBC mode
1889 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001890 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +00001891 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001892 keybits = 128 + u * 64;
1893 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001894
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001895 if (verbose != 0) {
1896 mbedtls_printf(" AES-CBC-%3u (%s): ", keybits,
1897 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00001898 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001899
1900 memset(iv, 0, 16);
1901 memset(prv, 0, 16);
1902 memset(buf, 0, 16);
1903
1904 if (mode == MBEDTLS_AES_DECRYPT) {
1905 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1906 aes_tests = aes_test_cbc_dec[u];
1907 } else {
1908 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001909 aes_tests = aes_test_cbc_enc[u];
1910 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001911
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01001912 /*
1913 * AES-192 is an optional feature that may be unavailable when
1914 * there is an alternative underlying implementation i.e. when
1915 * MBEDTLS_AES_ALT is defined.
1916 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001917 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1918 mbedtls_printf("skipped\n");
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001919 continue;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001920 } else if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001921 goto exit;
1922 }
1923
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001924 for (j = 0; j < 10000; j++) {
1925 if (mode == MBEDTLS_AES_ENCRYPT) {
Paul Bakker5121ce52009-01-03 21:22:43 +00001926 unsigned char tmp[16];
1927
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001928 memcpy(tmp, prv, 16);
1929 memcpy(prv, buf, 16);
1930 memcpy(buf, tmp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001931 }
1932
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001933 ret = mbedtls_aes_crypt_cbc(&ctx, mode, 16, iv, buf, buf);
1934 if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001935 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001936 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001937
1938 }
1939
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001940 if (memcmp(buf, aes_tests, 16) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001941 ret = 1;
1942 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001943 }
1944
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001945 if (verbose != 0) {
1946 mbedtls_printf("passed\n");
1947 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001948 }
1949
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001950 if (verbose != 0) {
1951 mbedtls_printf("\n");
1952 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001953#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001954
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001955#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001956 /*
1957 * CFB128 mode
1958 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001959 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +00001960 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001961 keybits = 128 + u * 64;
1962 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001963
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001964 if (verbose != 0) {
1965 mbedtls_printf(" AES-CFB128-%3u (%s): ", keybits,
1966 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
1967 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001968
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001969 memcpy(iv, aes_test_cfb128_iv, 16);
1970 memcpy(key, aes_test_cfb128_key[u], keybits / 8);
Paul Bakker5121ce52009-01-03 21:22:43 +00001971
1972 offset = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001973 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01001974 /*
1975 * AES-192 is an optional feature that may be unavailable when
1976 * there is an alternative underlying implementation i.e. when
1977 * MBEDTLS_AES_ALT is defined.
1978 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001979 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1980 mbedtls_printf("skipped\n");
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001981 continue;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001982 } else if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001983 goto exit;
1984 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001985
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001986 if (mode == MBEDTLS_AES_DECRYPT) {
1987 memcpy(buf, aes_test_cfb128_ct[u], 64);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001988 aes_tests = aes_test_cfb128_pt;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001989 } else {
1990 memcpy(buf, aes_test_cfb128_pt, 64);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001991 aes_tests = aes_test_cfb128_ct[u];
1992 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001993
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001994 ret = mbedtls_aes_crypt_cfb128(&ctx, mode, 64, &offset, iv, buf, buf);
1995 if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001996 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001997 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001998
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001999 if (memcmp(buf, aes_tests, 64) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002000 ret = 1;
2001 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00002002 }
2003
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002004 if (verbose != 0) {
2005 mbedtls_printf("passed\n");
2006 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002007 }
2008
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002009 if (verbose != 0) {
2010 mbedtls_printf("\n");
2011 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002012#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002013
Simon Butcherad4e4932018-04-29 00:43:47 +01002014#if defined(MBEDTLS_CIPHER_MODE_OFB)
2015 /*
2016 * OFB mode
2017 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002018 for (i = 0; i < 6; i++) {
Simon Butcherad4e4932018-04-29 00:43:47 +01002019 u = i >> 1;
2020 keybits = 128 + u * 64;
2021 mode = i & 1;
2022
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002023 if (verbose != 0) {
2024 mbedtls_printf(" AES-OFB-%3u (%s): ", keybits,
2025 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2026 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002027
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002028 memcpy(iv, aes_test_ofb_iv, 16);
2029 memcpy(key, aes_test_ofb_key[u], keybits / 8);
Simon Butcherad4e4932018-04-29 00:43:47 +01002030
2031 offset = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002032 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Simon Butcherad4e4932018-04-29 00:43:47 +01002033 /*
2034 * AES-192 is an optional feature that may be unavailable when
2035 * there is an alternative underlying implementation i.e. when
2036 * MBEDTLS_AES_ALT is defined.
2037 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002038 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2039 mbedtls_printf("skipped\n");
Simon Butcherad4e4932018-04-29 00:43:47 +01002040 continue;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002041 } else if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01002042 goto exit;
2043 }
2044
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002045 if (mode == MBEDTLS_AES_DECRYPT) {
2046 memcpy(buf, aes_test_ofb_ct[u], 64);
Simon Butcherad4e4932018-04-29 00:43:47 +01002047 aes_tests = aes_test_ofb_pt;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002048 } else {
2049 memcpy(buf, aes_test_ofb_pt, 64);
Simon Butcherad4e4932018-04-29 00:43:47 +01002050 aes_tests = aes_test_ofb_ct[u];
2051 }
2052
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002053 ret = mbedtls_aes_crypt_ofb(&ctx, 64, &offset, iv, buf, buf);
2054 if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01002055 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002056 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002057
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002058 if (memcmp(buf, aes_tests, 64) != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01002059 ret = 1;
2060 goto exit;
2061 }
2062
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002063 if (verbose != 0) {
2064 mbedtls_printf("passed\n");
2065 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002066 }
2067
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002068 if (verbose != 0) {
2069 mbedtls_printf("\n");
2070 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002071#endif /* MBEDTLS_CIPHER_MODE_OFB */
2072
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002073#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002074 /*
2075 * CTR mode
2076 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002077 for (i = 0; i < 6; i++) {
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002078 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002079 mode = i & 1;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002080
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002081 if (verbose != 0) {
2082 mbedtls_printf(" AES-CTR-128 (%s): ",
2083 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2084 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002085
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002086 memcpy(nonce_counter, aes_test_ctr_nonce_counter[u], 16);
2087 memcpy(key, aes_test_ctr_key[u], 16);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002088
2089 offset = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002090 if ((ret = mbedtls_aes_setkey_enc(&ctx, key, 128)) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002091 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002092 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002093
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002094 len = aes_test_ctr_len[u];
2095
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002096 if (mode == MBEDTLS_AES_DECRYPT) {
2097 memcpy(buf, aes_test_ctr_ct[u], len);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002098 aes_tests = aes_test_ctr_pt[u];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002099 } else {
2100 memcpy(buf, aes_test_ctr_pt[u], len);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002101 aes_tests = aes_test_ctr_ct[u];
2102 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002103
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002104 ret = mbedtls_aes_crypt_ctr(&ctx, len, &offset, nonce_counter,
2105 stream_block, buf, buf);
2106 if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002107 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002108 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002109
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002110 if (memcmp(buf, aes_tests, len) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002111 ret = 1;
2112 goto exit;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002113 }
2114
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002115 if (verbose != 0) {
2116 mbedtls_printf("passed\n");
2117 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002118 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002119
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002120 if (verbose != 0) {
2121 mbedtls_printf("\n");
2122 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002123#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00002124
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002125#if defined(MBEDTLS_CIPHER_MODE_XTS)
2126 {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002127 static const int num_tests =
2128 sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key);
2129 mbedtls_aes_xts_context ctx_xts;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002130
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002131 /*
2132 * XTS mode
2133 */
2134 mbedtls_aes_xts_init(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002135
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002136 for (i = 0; i < num_tests << 1; i++) {
2137 const unsigned char *data_unit;
2138 u = i >> 1;
2139 mode = i & 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002140
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002141 if (verbose != 0) {
2142 mbedtls_printf(" AES-XTS-128 (%s): ",
2143 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2144 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002145
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002146 memset(key, 0, sizeof(key));
2147 memcpy(key, aes_test_xts_key[u], 32);
2148 data_unit = aes_test_xts_data_unit[u];
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002149
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002150 len = sizeof(*aes_test_xts_ct32);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002151
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002152 if (mode == MBEDTLS_AES_DECRYPT) {
2153 ret = mbedtls_aes_xts_setkey_dec(&ctx_xts, key, 256);
2154 if (ret != 0) {
2155 goto exit;
2156 }
2157 memcpy(buf, aes_test_xts_ct32[u], len);
2158 aes_tests = aes_test_xts_pt32[u];
2159 } else {
2160 ret = mbedtls_aes_xts_setkey_enc(&ctx_xts, key, 256);
2161 if (ret != 0) {
2162 goto exit;
2163 }
2164 memcpy(buf, aes_test_xts_pt32[u], len);
2165 aes_tests = aes_test_xts_ct32[u];
2166 }
2167
2168
2169 ret = mbedtls_aes_crypt_xts(&ctx_xts, mode, len, data_unit,
2170 buf, buf);
2171 if (ret != 0) {
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002172 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002173 }
2174
2175 if (memcmp(buf, aes_tests, len) != 0) {
2176 ret = 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002177 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002178 }
2179
2180 if (verbose != 0) {
2181 mbedtls_printf("passed\n");
2182 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002183 }
2184
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002185 if (verbose != 0) {
2186 mbedtls_printf("\n");
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002187 }
2188
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002189 mbedtls_aes_xts_free(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002190 }
2191#endif /* MBEDTLS_CIPHER_MODE_XTS */
2192
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002193 ret = 0;
2194
2195exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002196 if (ret != 0 && verbose != 0) {
2197 mbedtls_printf("failed\n");
2198 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002199
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002200 mbedtls_aes_free(&ctx);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002201
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002202 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002203}
2204
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002205#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002206
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002207#endif /* MBEDTLS_AES_C */