blob: 69d4eadfa839ae3d5022c446b4c763663aa67a78 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * FIPS-197 compliant AES implementation
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Paul Bakker5121ce52009-01-03 21:22:43 +000018 */
19/*
20 * The AES block cipher was designed by Vincent Rijmen and Joan Daemen.
21 *
22 * http://csrc.nist.gov/encryption/aes/rijndael/Rijndael.pdf
23 * http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
24 */
25
Gilles Peskinedb09ef62020-06-03 01:43:33 +020026#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000027
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020028#if defined(MBEDTLS_AES_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000029
Rich Evans00ab4702015-02-06 13:43:58 +000030#include <string.h>
31
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000032#include "mbedtls/aes.h"
Ron Eldor9924bdc2018-10-04 10:59:13 +030033#include "mbedtls/platform.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050034#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000035#include "mbedtls/error.h"
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020036#if defined(MBEDTLS_PADLOCK_C)
Chris Jones16dbaeb2021-03-09 17:47:55 +000037#include "padlock.h"
Paul Bakker67820bd2012-06-04 12:47:23 +000038#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020039#if defined(MBEDTLS_AESNI_C)
Chris Jones187782f2021-03-09 17:28:35 +000040#include "aesni.h"
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +010041#endif
Jerry Yu3f2fb712023-01-10 17:05:42 +080042#if defined(MBEDTLS_AESCE_C)
43#include "aesce.h"
44#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000045
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000046#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010047
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020048#if !defined(MBEDTLS_AES_ALT)
Paul Bakker90995b52013-06-24 19:20:35 +020049
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020050#if defined(MBEDTLS_PADLOCK_C) && \
Gilles Peskine449bd832023-01-11 14:50:10 +010051 (defined(MBEDTLS_HAVE_X86) || defined(MBEDTLS_PADLOCK_ALIGN16))
Paul Bakker048d04e2012-02-12 17:31:04 +000052static int aes_padlock_ace = -1;
53#endif
54
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020055#if defined(MBEDTLS_AES_ROM_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +000056/*
57 * Forward S-box
58 */
59static const unsigned char FSb[256] =
60{
61 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
62 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
63 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
64 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
65 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
66 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
67 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
68 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
69 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
70 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
71 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
72 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
73 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
74 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
75 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
76 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
77 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
78 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
79 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
80 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
81 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
82 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
83 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
84 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
85 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
86 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
87 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
88 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
89 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
90 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
91 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
92 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
93};
94
95/*
96 * Forward tables
97 */
98#define FT \
99\
Gilles Peskine449bd832023-01-11 14:50:10 +0100100 V(A5, 63, 63, C6), V(84, 7C, 7C, F8), V(99, 77, 77, EE), V(8D, 7B, 7B, F6), \
101 V(0D, F2, F2, FF), V(BD, 6B, 6B, D6), V(B1, 6F, 6F, DE), V(54, C5, C5, 91), \
102 V(50, 30, 30, 60), V(03, 01, 01, 02), V(A9, 67, 67, CE), V(7D, 2B, 2B, 56), \
103 V(19, FE, FE, E7), V(62, D7, D7, B5), V(E6, AB, AB, 4D), V(9A, 76, 76, EC), \
104 V(45, CA, CA, 8F), V(9D, 82, 82, 1F), V(40, C9, C9, 89), V(87, 7D, 7D, FA), \
105 V(15, FA, FA, EF), V(EB, 59, 59, B2), V(C9, 47, 47, 8E), V(0B, F0, F0, FB), \
106 V(EC, AD, AD, 41), V(67, D4, D4, B3), V(FD, A2, A2, 5F), V(EA, AF, AF, 45), \
107 V(BF, 9C, 9C, 23), V(F7, A4, A4, 53), V(96, 72, 72, E4), V(5B, C0, C0, 9B), \
108 V(C2, B7, B7, 75), V(1C, FD, FD, E1), V(AE, 93, 93, 3D), V(6A, 26, 26, 4C), \
109 V(5A, 36, 36, 6C), V(41, 3F, 3F, 7E), V(02, F7, F7, F5), V(4F, CC, CC, 83), \
110 V(5C, 34, 34, 68), V(F4, A5, A5, 51), V(34, E5, E5, D1), V(08, F1, F1, F9), \
111 V(93, 71, 71, E2), V(73, D8, D8, AB), V(53, 31, 31, 62), V(3F, 15, 15, 2A), \
112 V(0C, 04, 04, 08), V(52, C7, C7, 95), V(65, 23, 23, 46), V(5E, C3, C3, 9D), \
113 V(28, 18, 18, 30), V(A1, 96, 96, 37), V(0F, 05, 05, 0A), V(B5, 9A, 9A, 2F), \
114 V(09, 07, 07, 0E), V(36, 12, 12, 24), V(9B, 80, 80, 1B), V(3D, E2, E2, DF), \
115 V(26, EB, EB, CD), V(69, 27, 27, 4E), V(CD, B2, B2, 7F), V(9F, 75, 75, EA), \
116 V(1B, 09, 09, 12), V(9E, 83, 83, 1D), V(74, 2C, 2C, 58), V(2E, 1A, 1A, 34), \
117 V(2D, 1B, 1B, 36), V(B2, 6E, 6E, DC), V(EE, 5A, 5A, B4), V(FB, A0, A0, 5B), \
118 V(F6, 52, 52, A4), V(4D, 3B, 3B, 76), V(61, D6, D6, B7), V(CE, B3, B3, 7D), \
119 V(7B, 29, 29, 52), V(3E, E3, E3, DD), V(71, 2F, 2F, 5E), V(97, 84, 84, 13), \
120 V(F5, 53, 53, A6), V(68, D1, D1, B9), V(00, 00, 00, 00), V(2C, ED, ED, C1), \
121 V(60, 20, 20, 40), V(1F, FC, FC, E3), V(C8, B1, B1, 79), V(ED, 5B, 5B, B6), \
122 V(BE, 6A, 6A, D4), V(46, CB, CB, 8D), V(D9, BE, BE, 67), V(4B, 39, 39, 72), \
123 V(DE, 4A, 4A, 94), V(D4, 4C, 4C, 98), V(E8, 58, 58, B0), V(4A, CF, CF, 85), \
124 V(6B, D0, D0, BB), V(2A, EF, EF, C5), V(E5, AA, AA, 4F), V(16, FB, FB, ED), \
125 V(C5, 43, 43, 86), V(D7, 4D, 4D, 9A), V(55, 33, 33, 66), V(94, 85, 85, 11), \
126 V(CF, 45, 45, 8A), V(10, F9, F9, E9), V(06, 02, 02, 04), V(81, 7F, 7F, FE), \
127 V(F0, 50, 50, A0), V(44, 3C, 3C, 78), V(BA, 9F, 9F, 25), V(E3, A8, A8, 4B), \
128 V(F3, 51, 51, A2), V(FE, A3, A3, 5D), V(C0, 40, 40, 80), V(8A, 8F, 8F, 05), \
129 V(AD, 92, 92, 3F), V(BC, 9D, 9D, 21), V(48, 38, 38, 70), V(04, F5, F5, F1), \
130 V(DF, BC, BC, 63), V(C1, B6, B6, 77), V(75, DA, DA, AF), V(63, 21, 21, 42), \
131 V(30, 10, 10, 20), V(1A, FF, FF, E5), V(0E, F3, F3, FD), V(6D, D2, D2, BF), \
132 V(4C, CD, CD, 81), V(14, 0C, 0C, 18), V(35, 13, 13, 26), V(2F, EC, EC, C3), \
133 V(E1, 5F, 5F, BE), V(A2, 97, 97, 35), V(CC, 44, 44, 88), V(39, 17, 17, 2E), \
134 V(57, C4, C4, 93), V(F2, A7, A7, 55), V(82, 7E, 7E, FC), V(47, 3D, 3D, 7A), \
135 V(AC, 64, 64, C8), V(E7, 5D, 5D, BA), V(2B, 19, 19, 32), V(95, 73, 73, E6), \
136 V(A0, 60, 60, C0), V(98, 81, 81, 19), V(D1, 4F, 4F, 9E), V(7F, DC, DC, A3), \
137 V(66, 22, 22, 44), V(7E, 2A, 2A, 54), V(AB, 90, 90, 3B), V(83, 88, 88, 0B), \
138 V(CA, 46, 46, 8C), V(29, EE, EE, C7), V(D3, B8, B8, 6B), V(3C, 14, 14, 28), \
139 V(79, DE, DE, A7), V(E2, 5E, 5E, BC), V(1D, 0B, 0B, 16), V(76, DB, DB, AD), \
140 V(3B, E0, E0, DB), V(56, 32, 32, 64), V(4E, 3A, 3A, 74), V(1E, 0A, 0A, 14), \
141 V(DB, 49, 49, 92), V(0A, 06, 06, 0C), V(6C, 24, 24, 48), V(E4, 5C, 5C, B8), \
142 V(5D, C2, C2, 9F), V(6E, D3, D3, BD), V(EF, AC, AC, 43), V(A6, 62, 62, C4), \
143 V(A8, 91, 91, 39), V(A4, 95, 95, 31), V(37, E4, E4, D3), V(8B, 79, 79, F2), \
144 V(32, E7, E7, D5), V(43, C8, C8, 8B), V(59, 37, 37, 6E), V(B7, 6D, 6D, DA), \
145 V(8C, 8D, 8D, 01), V(64, D5, D5, B1), V(D2, 4E, 4E, 9C), V(E0, A9, A9, 49), \
146 V(B4, 6C, 6C, D8), V(FA, 56, 56, AC), V(07, F4, F4, F3), V(25, EA, EA, CF), \
147 V(AF, 65, 65, CA), V(8E, 7A, 7A, F4), V(E9, AE, AE, 47), V(18, 08, 08, 10), \
148 V(D5, BA, BA, 6F), V(88, 78, 78, F0), V(6F, 25, 25, 4A), V(72, 2E, 2E, 5C), \
149 V(24, 1C, 1C, 38), V(F1, A6, A6, 57), V(C7, B4, B4, 73), V(51, C6, C6, 97), \
150 V(23, E8, E8, CB), V(7C, DD, DD, A1), V(9C, 74, 74, E8), V(21, 1F, 1F, 3E), \
151 V(DD, 4B, 4B, 96), V(DC, BD, BD, 61), V(86, 8B, 8B, 0D), V(85, 8A, 8A, 0F), \
152 V(90, 70, 70, E0), V(42, 3E, 3E, 7C), V(C4, B5, B5, 71), V(AA, 66, 66, CC), \
153 V(D8, 48, 48, 90), V(05, 03, 03, 06), V(01, F6, F6, F7), V(12, 0E, 0E, 1C), \
154 V(A3, 61, 61, C2), V(5F, 35, 35, 6A), V(F9, 57, 57, AE), V(D0, B9, B9, 69), \
155 V(91, 86, 86, 17), V(58, C1, C1, 99), V(27, 1D, 1D, 3A), V(B9, 9E, 9E, 27), \
156 V(38, E1, E1, D9), V(13, F8, F8, EB), V(B3, 98, 98, 2B), V(33, 11, 11, 22), \
157 V(BB, 69, 69, D2), V(70, D9, D9, A9), V(89, 8E, 8E, 07), V(A7, 94, 94, 33), \
158 V(B6, 9B, 9B, 2D), V(22, 1E, 1E, 3C), V(92, 87, 87, 15), V(20, E9, E9, C9), \
159 V(49, CE, CE, 87), V(FF, 55, 55, AA), V(78, 28, 28, 50), V(7A, DF, DF, A5), \
160 V(8F, 8C, 8C, 03), V(F8, A1, A1, 59), V(80, 89, 89, 09), V(17, 0D, 0D, 1A), \
161 V(DA, BF, BF, 65), V(31, E6, E6, D7), V(C6, 42, 42, 84), V(B8, 68, 68, D0), \
162 V(C3, 41, 41, 82), V(B0, 99, 99, 29), V(77, 2D, 2D, 5A), V(11, 0F, 0F, 1E), \
163 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 +0000164
Gilles Peskine449bd832023-01-11 14:50:10 +0100165#define V(a, b, c, d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000166static const uint32_t FT0[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000167#undef V
168
Hanno Beckerad049a92017-06-19 16:31:54 +0100169#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200170
Gilles Peskine449bd832023-01-11 14:50:10 +0100171#define V(a, b, c, d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000172static const uint32_t FT1[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000173#undef V
174
Gilles Peskine449bd832023-01-11 14:50:10 +0100175#define V(a, b, c, d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000176static const uint32_t FT2[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000177#undef V
178
Gilles Peskine449bd832023-01-11 14:50:10 +0100179#define V(a, b, c, d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000180static const uint32_t FT3[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000181#undef V
182
Hanno Becker177d3cf2017-06-07 15:52:48 +0100183#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200184
Paul Bakker5121ce52009-01-03 21:22:43 +0000185#undef FT
186
187/*
188 * Reverse S-box
189 */
190static const unsigned char RSb[256] =
191{
192 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
193 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
194 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
195 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
196 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
197 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
198 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
199 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
200 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
201 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
202 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
203 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
204 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
205 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
206 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
207 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
208 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
209 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
210 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
211 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
212 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
213 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
214 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
215 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
216 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
217 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
218 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
219 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
220 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
221 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
222 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
223 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
224};
225
226/*
227 * Reverse tables
228 */
229#define RT \
230\
Gilles Peskine449bd832023-01-11 14:50:10 +0100231 V(50, A7, F4, 51), V(53, 65, 41, 7E), V(C3, A4, 17, 1A), V(96, 5E, 27, 3A), \
232 V(CB, 6B, AB, 3B), V(F1, 45, 9D, 1F), V(AB, 58, FA, AC), V(93, 03, E3, 4B), \
233 V(55, FA, 30, 20), V(F6, 6D, 76, AD), V(91, 76, CC, 88), V(25, 4C, 02, F5), \
234 V(FC, D7, E5, 4F), V(D7, CB, 2A, C5), V(80, 44, 35, 26), V(8F, A3, 62, B5), \
235 V(49, 5A, B1, DE), V(67, 1B, BA, 25), V(98, 0E, EA, 45), V(E1, C0, FE, 5D), \
236 V(02, 75, 2F, C3), V(12, F0, 4C, 81), V(A3, 97, 46, 8D), V(C6, F9, D3, 6B), \
237 V(E7, 5F, 8F, 03), V(95, 9C, 92, 15), V(EB, 7A, 6D, BF), V(DA, 59, 52, 95), \
238 V(2D, 83, BE, D4), V(D3, 21, 74, 58), V(29, 69, E0, 49), V(44, C8, C9, 8E), \
239 V(6A, 89, C2, 75), V(78, 79, 8E, F4), V(6B, 3E, 58, 99), V(DD, 71, B9, 27), \
240 V(B6, 4F, E1, BE), V(17, AD, 88, F0), V(66, AC, 20, C9), V(B4, 3A, CE, 7D), \
241 V(18, 4A, DF, 63), V(82, 31, 1A, E5), V(60, 33, 51, 97), V(45, 7F, 53, 62), \
242 V(E0, 77, 64, B1), V(84, AE, 6B, BB), V(1C, A0, 81, FE), V(94, 2B, 08, F9), \
243 V(58, 68, 48, 70), V(19, FD, 45, 8F), V(87, 6C, DE, 94), V(B7, F8, 7B, 52), \
244 V(23, D3, 73, AB), V(E2, 02, 4B, 72), V(57, 8F, 1F, E3), V(2A, AB, 55, 66), \
245 V(07, 28, EB, B2), V(03, C2, B5, 2F), V(9A, 7B, C5, 86), V(A5, 08, 37, D3), \
246 V(F2, 87, 28, 30), V(B2, A5, BF, 23), V(BA, 6A, 03, 02), V(5C, 82, 16, ED), \
247 V(2B, 1C, CF, 8A), V(92, B4, 79, A7), V(F0, F2, 07, F3), V(A1, E2, 69, 4E), \
248 V(CD, F4, DA, 65), V(D5, BE, 05, 06), V(1F, 62, 34, D1), V(8A, FE, A6, C4), \
249 V(9D, 53, 2E, 34), V(A0, 55, F3, A2), V(32, E1, 8A, 05), V(75, EB, F6, A4), \
250 V(39, EC, 83, 0B), V(AA, EF, 60, 40), V(06, 9F, 71, 5E), V(51, 10, 6E, BD), \
251 V(F9, 8A, 21, 3E), V(3D, 06, DD, 96), V(AE, 05, 3E, DD), V(46, BD, E6, 4D), \
252 V(B5, 8D, 54, 91), V(05, 5D, C4, 71), V(6F, D4, 06, 04), V(FF, 15, 50, 60), \
253 V(24, FB, 98, 19), V(97, E9, BD, D6), V(CC, 43, 40, 89), V(77, 9E, D9, 67), \
254 V(BD, 42, E8, B0), V(88, 8B, 89, 07), V(38, 5B, 19, E7), V(DB, EE, C8, 79), \
255 V(47, 0A, 7C, A1), V(E9, 0F, 42, 7C), V(C9, 1E, 84, F8), V(00, 00, 00, 00), \
256 V(83, 86, 80, 09), V(48, ED, 2B, 32), V(AC, 70, 11, 1E), V(4E, 72, 5A, 6C), \
257 V(FB, FF, 0E, FD), V(56, 38, 85, 0F), V(1E, D5, AE, 3D), V(27, 39, 2D, 36), \
258 V(64, D9, 0F, 0A), V(21, A6, 5C, 68), V(D1, 54, 5B, 9B), V(3A, 2E, 36, 24), \
259 V(B1, 67, 0A, 0C), V(0F, E7, 57, 93), V(D2, 96, EE, B4), V(9E, 91, 9B, 1B), \
260 V(4F, C5, C0, 80), V(A2, 20, DC, 61), V(69, 4B, 77, 5A), V(16, 1A, 12, 1C), \
261 V(0A, BA, 93, E2), V(E5, 2A, A0, C0), V(43, E0, 22, 3C), V(1D, 17, 1B, 12), \
262 V(0B, 0D, 09, 0E), V(AD, C7, 8B, F2), V(B9, A8, B6, 2D), V(C8, A9, 1E, 14), \
263 V(85, 19, F1, 57), V(4C, 07, 75, AF), V(BB, DD, 99, EE), V(FD, 60, 7F, A3), \
264 V(9F, 26, 01, F7), V(BC, F5, 72, 5C), V(C5, 3B, 66, 44), V(34, 7E, FB, 5B), \
265 V(76, 29, 43, 8B), V(DC, C6, 23, CB), V(68, FC, ED, B6), V(63, F1, E4, B8), \
266 V(CA, DC, 31, D7), V(10, 85, 63, 42), V(40, 22, 97, 13), V(20, 11, C6, 84), \
267 V(7D, 24, 4A, 85), V(F8, 3D, BB, D2), V(11, 32, F9, AE), V(6D, A1, 29, C7), \
268 V(4B, 2F, 9E, 1D), V(F3, 30, B2, DC), V(EC, 52, 86, 0D), V(D0, E3, C1, 77), \
269 V(6C, 16, B3, 2B), V(99, B9, 70, A9), V(FA, 48, 94, 11), V(22, 64, E9, 47), \
270 V(C4, 8C, FC, A8), V(1A, 3F, F0, A0), V(D8, 2C, 7D, 56), V(EF, 90, 33, 22), \
271 V(C7, 4E, 49, 87), V(C1, D1, 38, D9), V(FE, A2, CA, 8C), V(36, 0B, D4, 98), \
272 V(CF, 81, F5, A6), V(28, DE, 7A, A5), V(26, 8E, B7, DA), V(A4, BF, AD, 3F), \
273 V(E4, 9D, 3A, 2C), V(0D, 92, 78, 50), V(9B, CC, 5F, 6A), V(62, 46, 7E, 54), \
274 V(C2, 13, 8D, F6), V(E8, B8, D8, 90), V(5E, F7, 39, 2E), V(F5, AF, C3, 82), \
275 V(BE, 80, 5D, 9F), V(7C, 93, D0, 69), V(A9, 2D, D5, 6F), V(B3, 12, 25, CF), \
276 V(3B, 99, AC, C8), V(A7, 7D, 18, 10), V(6E, 63, 9C, E8), V(7B, BB, 3B, DB), \
277 V(09, 78, 26, CD), V(F4, 18, 59, 6E), V(01, B7, 9A, EC), V(A8, 9A, 4F, 83), \
278 V(65, 6E, 95, E6), V(7E, E6, FF, AA), V(08, CF, BC, 21), V(E6, E8, 15, EF), \
279 V(D9, 9B, E7, BA), V(CE, 36, 6F, 4A), V(D4, 09, 9F, EA), V(D6, 7C, B0, 29), \
280 V(AF, B2, A4, 31), V(31, 23, 3F, 2A), V(30, 94, A5, C6), V(C0, 66, A2, 35), \
281 V(37, BC, 4E, 74), V(A6, CA, 82, FC), V(B0, D0, 90, E0), V(15, D8, A7, 33), \
282 V(4A, 98, 04, F1), V(F7, DA, EC, 41), V(0E, 50, CD, 7F), V(2F, F6, 91, 17), \
283 V(8D, D6, 4D, 76), V(4D, B0, EF, 43), V(54, 4D, AA, CC), V(DF, 04, 96, E4), \
284 V(E3, B5, D1, 9E), V(1B, 88, 6A, 4C), V(B8, 1F, 2C, C1), V(7F, 51, 65, 46), \
285 V(04, EA, 5E, 9D), V(5D, 35, 8C, 01), V(73, 74, 87, FA), V(2E, 41, 0B, FB), \
286 V(5A, 1D, 67, B3), V(52, D2, DB, 92), V(33, 56, 10, E9), V(13, 47, D6, 6D), \
287 V(8C, 61, D7, 9A), V(7A, 0C, A1, 37), V(8E, 14, F8, 59), V(89, 3C, 13, EB), \
288 V(EE, 27, A9, CE), V(35, C9, 61, B7), V(ED, E5, 1C, E1), V(3C, B1, 47, 7A), \
289 V(59, DF, D2, 9C), V(3F, 73, F2, 55), V(79, CE, 14, 18), V(BF, 37, C7, 73), \
290 V(EA, CD, F7, 53), V(5B, AA, FD, 5F), V(14, 6F, 3D, DF), V(86, DB, 44, 78), \
291 V(81, F3, AF, CA), V(3E, C4, 68, B9), V(2C, 34, 24, 38), V(5F, 40, A3, C2), \
292 V(72, C3, 1D, 16), V(0C, 25, E2, BC), V(8B, 49, 3C, 28), V(41, 95, 0D, FF), \
293 V(71, 01, A8, 39), V(DE, B3, 0C, 08), V(9C, E4, B4, D8), V(90, C1, 56, 64), \
294 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 +0000295
Gilles Peskine449bd832023-01-11 14:50:10 +0100296#define V(a, b, c, d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000297static const uint32_t RT0[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000298#undef V
299
Hanno Beckerad049a92017-06-19 16:31:54 +0100300#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200301
Gilles Peskine449bd832023-01-11 14:50:10 +0100302#define V(a, b, c, d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000303static const uint32_t RT1[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000304#undef V
305
Gilles Peskine449bd832023-01-11 14:50:10 +0100306#define V(a, b, c, d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000307static const uint32_t RT2[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000308#undef V
309
Gilles Peskine449bd832023-01-11 14:50:10 +0100310#define V(a, b, c, d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000311static const uint32_t RT3[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000312#undef V
313
Hanno Becker177d3cf2017-06-07 15:52:48 +0100314#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200315
Paul Bakker5121ce52009-01-03 21:22:43 +0000316#undef RT
317
318/*
319 * Round constants
320 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000321static const uint32_t RCON[10] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000322{
323 0x00000001, 0x00000002, 0x00000004, 0x00000008,
324 0x00000010, 0x00000020, 0x00000040, 0x00000080,
325 0x0000001B, 0x00000036
326};
327
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200328#else /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000329
330/*
331 * Forward S-box & tables
332 */
333static unsigned char FSb[256];
Paul Bakker9af723c2014-05-01 13:03:14 +0200334static uint32_t FT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100335#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker9af723c2014-05-01 13:03:14 +0200336static uint32_t FT1[256];
337static uint32_t FT2[256];
338static uint32_t FT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100339#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000340
341/*
342 * Reverse S-box & tables
343 */
344static unsigned char RSb[256];
Paul Bakker5c2364c2012-10-01 14:41:15 +0000345static uint32_t RT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100346#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker5c2364c2012-10-01 14:41:15 +0000347static uint32_t RT1[256];
348static uint32_t RT2[256];
349static uint32_t RT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100350#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000351
352/*
353 * Round constants
354 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000355static uint32_t RCON[10];
Paul Bakker5121ce52009-01-03 21:22:43 +0000356
357/*
358 * Tables generation code
359 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100360#define ROTL8(x) (((x) << 8) & 0xFFFFFFFF) | ((x) >> 24)
361#define XTIME(x) (((x) << 1) ^ (((x) & 0x80) ? 0x1B : 0x00))
362#define MUL(x, y) (((x) && (y)) ? pow[(log[(x)]+log[(y)]) % 255] : 0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000363
364static int aes_init_done = 0;
365
Gilles Peskine449bd832023-01-11 14:50:10 +0100366static void aes_gen_tables(void)
Paul Bakker5121ce52009-01-03 21:22:43 +0000367{
368 int i, x, y, z;
369 int pow[256];
370 int log[256];
371
372 /*
373 * compute pow and log tables over GF(2^8)
374 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100375 for (i = 0, x = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000376 pow[i] = x;
377 log[x] = i;
Gilles Peskine449bd832023-01-11 14:50:10 +0100378 x = MBEDTLS_BYTE_0(x ^ XTIME(x));
Paul Bakker5121ce52009-01-03 21:22:43 +0000379 }
380
381 /*
382 * calculate the round constants
383 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100384 for (i = 0, x = 1; i < 10; i++) {
Paul Bakker5c2364c2012-10-01 14:41:15 +0000385 RCON[i] = (uint32_t) x;
Gilles Peskine449bd832023-01-11 14:50:10 +0100386 x = MBEDTLS_BYTE_0(XTIME(x));
Paul Bakker5121ce52009-01-03 21:22:43 +0000387 }
388
389 /*
390 * generate the forward and reverse S-boxes
391 */
392 FSb[0x00] = 0x63;
393 RSb[0x63] = 0x00;
394
Gilles Peskine449bd832023-01-11 14:50:10 +0100395 for (i = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000396 x = pow[255 - log[i]];
397
Gilles Peskine449bd832023-01-11 14:50:10 +0100398 y = x; y = MBEDTLS_BYTE_0((y << 1) | (y >> 7));
399 x ^= y; y = MBEDTLS_BYTE_0((y << 1) | (y >> 7));
400 x ^= y; y = MBEDTLS_BYTE_0((y << 1) | (y >> 7));
401 x ^= y; y = MBEDTLS_BYTE_0((y << 1) | (y >> 7));
Paul Bakker5121ce52009-01-03 21:22:43 +0000402 x ^= y ^ 0x63;
403
404 FSb[i] = (unsigned char) x;
405 RSb[x] = (unsigned char) i;
406 }
407
408 /*
409 * generate the forward and reverse tables
410 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100411 for (i = 0; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000412 x = FSb[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100413 y = MBEDTLS_BYTE_0(XTIME(x));
414 z = MBEDTLS_BYTE_0(y ^ x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000415
Gilles Peskine449bd832023-01-11 14:50:10 +0100416 FT0[i] = ((uint32_t) y) ^
417 ((uint32_t) x << 8) ^
418 ((uint32_t) x << 16) ^
419 ((uint32_t) z << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000420
Hanno Beckerad049a92017-06-19 16:31:54 +0100421#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100422 FT1[i] = ROTL8(FT0[i]);
423 FT2[i] = ROTL8(FT1[i]);
424 FT3[i] = ROTL8(FT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100425#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000426
427 x = RSb[i];
428
Gilles Peskine449bd832023-01-11 14:50:10 +0100429 RT0[i] = ((uint32_t) MUL(0x0E, x)) ^
430 ((uint32_t) MUL(0x09, x) << 8) ^
431 ((uint32_t) MUL(0x0D, x) << 16) ^
432 ((uint32_t) MUL(0x0B, x) << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000433
Hanno Beckerad049a92017-06-19 16:31:54 +0100434#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100435 RT1[i] = ROTL8(RT0[i]);
436 RT2[i] = ROTL8(RT1[i]);
437 RT3[i] = ROTL8(RT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100438#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000439 }
440}
441
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200442#undef ROTL8
443
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200444#endif /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000445
Hanno Beckerad049a92017-06-19 16:31:54 +0100446#if defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200447
Gilles Peskine449bd832023-01-11 14:50:10 +0100448#define ROTL8(x) ((uint32_t) ((x) << 8) + (uint32_t) ((x) >> 24))
449#define ROTL16(x) ((uint32_t) ((x) << 16) + (uint32_t) ((x) >> 16))
450#define ROTL24(x) ((uint32_t) ((x) << 24) + (uint32_t) ((x) >> 8))
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200451
452#define AES_RT0(idx) RT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100453#define AES_RT1(idx) ROTL8(RT0[idx])
454#define AES_RT2(idx) ROTL16(RT0[idx])
455#define AES_RT3(idx) ROTL24(RT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200456
457#define AES_FT0(idx) FT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100458#define AES_FT1(idx) ROTL8(FT0[idx])
459#define AES_FT2(idx) ROTL16(FT0[idx])
460#define AES_FT3(idx) ROTL24(FT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200461
Hanno Becker177d3cf2017-06-07 15:52:48 +0100462#else /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200463
464#define AES_RT0(idx) RT0[idx]
465#define AES_RT1(idx) RT1[idx]
466#define AES_RT2(idx) RT2[idx]
467#define AES_RT3(idx) RT3[idx]
468
469#define AES_FT0(idx) FT0[idx]
470#define AES_FT1(idx) FT1[idx]
471#define AES_FT2(idx) FT2[idx]
472#define AES_FT3(idx) FT3[idx]
473
Hanno Becker177d3cf2017-06-07 15:52:48 +0100474#endif /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200475
Gilles Peskine449bd832023-01-11 14:50:10 +0100476void mbedtls_aes_init(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200477{
Gilles Peskine449bd832023-01-11 14:50:10 +0100478 memset(ctx, 0, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200479}
480
Gilles Peskine449bd832023-01-11 14:50:10 +0100481void mbedtls_aes_free(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200482{
Gilles Peskine449bd832023-01-11 14:50:10 +0100483 if (ctx == NULL) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200484 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100485 }
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200486
Gilles Peskine449bd832023-01-11 14:50:10 +0100487 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200488}
489
Jaeden Amero9366feb2018-05-29 18:55:17 +0100490#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100491void mbedtls_aes_xts_init(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100492{
Gilles Peskine449bd832023-01-11 14:50:10 +0100493 mbedtls_aes_init(&ctx->crypt);
494 mbedtls_aes_init(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100495}
496
Gilles Peskine449bd832023-01-11 14:50:10 +0100497void mbedtls_aes_xts_free(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100498{
Gilles Peskine449bd832023-01-11 14:50:10 +0100499 if (ctx == NULL) {
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100500 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100501 }
Simon Butcher5201e412018-12-06 17:40:14 +0000502
Gilles Peskine449bd832023-01-11 14:50:10 +0100503 mbedtls_aes_free(&ctx->crypt);
504 mbedtls_aes_free(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100505}
506#endif /* MBEDTLS_CIPHER_MODE_XTS */
507
Paul Bakker5121ce52009-01-03 21:22:43 +0000508/*
509 * AES key schedule (encryption)
510 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200511#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100512int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
513 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000514{
Paul Bakker23986e52011-04-24 08:57:21 +0000515 unsigned int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000516 uint32_t *RK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000517
Gilles Peskine449bd832023-01-11 14:50:10 +0100518 switch (keybits) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000519 case 128: ctx->nr = 10; break;
520 case 192: ctx->nr = 12; break;
521 case 256: ctx->nr = 14; break;
Gilles Peskine449bd832023-01-11 14:50:10 +0100522 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Paul Bakker5121ce52009-01-03 21:22:43 +0000523 }
524
Simon Butcher5201e412018-12-06 17:40:14 +0000525#if !defined(MBEDTLS_AES_ROM_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100526 if (aes_init_done == 0) {
Simon Butcher5201e412018-12-06 17:40:14 +0000527 aes_gen_tables();
528 aes_init_done = 1;
Simon Butcher5201e412018-12-06 17:40:14 +0000529 }
530#endif
531
Werner Lewis7656a372022-06-13 12:28:20 +0100532 ctx->rk_offset = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200533#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_PADLOCK_ALIGN16)
Gilles Peskine449bd832023-01-11 14:50:10 +0100534 if (aes_padlock_ace == -1) {
535 aes_padlock_ace = mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE);
536 }
Paul Bakker048d04e2012-02-12 17:31:04 +0000537
Gilles Peskine449bd832023-01-11 14:50:10 +0100538 if (aes_padlock_ace) {
539 ctx->rk_offset = MBEDTLS_PADLOCK_ALIGN16(ctx->buf) - ctx->buf;
540 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000541#endif
Werner Lewisdd76ef32022-05-30 12:00:21 +0100542 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000543
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100544#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100545 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
Gilles Peskined6719172023-03-10 22:37:11 +0100546 /* The intrinsics-based implementation needs 16-byte alignment
547 * for the round key array. */
548 unsigned delta = (uintptr_t) ctx->buf & 0x0000000f;
549 if (delta != 0) {
550 ctx->rk_offset = 4 - delta / 4; // 16 bytes = 4 uint32_t
551 }
552 RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100553 return mbedtls_aesni_setkey_enc((unsigned char *) RK, key, keybits);
554 }
Manuel Pégourié-Gonnard47a35362013-12-28 20:45:04 +0100555#endif
556
Jerry Yu3f2fb712023-01-10 17:05:42 +0800557#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
558 if (mbedtls_aesce_has_support()) {
559 return mbedtls_aesce_setkey_enc((unsigned char *) RK, key, keybits);
560 }
561#endif
562
Gilles Peskine449bd832023-01-11 14:50:10 +0100563 for (i = 0; i < (keybits >> 5); i++) {
564 RK[i] = MBEDTLS_GET_UINT32_LE(key, i << 2);
Paul Bakker5121ce52009-01-03 21:22:43 +0000565 }
566
Gilles Peskine449bd832023-01-11 14:50:10 +0100567 switch (ctx->nr) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000568 case 10:
569
Gilles Peskine449bd832023-01-11 14:50:10 +0100570 for (i = 0; i < 10; i++, RK += 4) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000571 RK[4] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100572 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[3])]) ^
573 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[3])] << 8) ^
574 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[3])] << 16) ^
575 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[3])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000576
577 RK[5] = RK[1] ^ RK[4];
578 RK[6] = RK[2] ^ RK[5];
579 RK[7] = RK[3] ^ RK[6];
580 }
581 break;
582
583 case 12:
584
Gilles Peskine449bd832023-01-11 14:50:10 +0100585 for (i = 0; i < 8; i++, RK += 6) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000586 RK[6] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100587 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[5])]) ^
588 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[5])] << 8) ^
589 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[5])] << 16) ^
590 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[5])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000591
592 RK[7] = RK[1] ^ RK[6];
593 RK[8] = RK[2] ^ RK[7];
594 RK[9] = RK[3] ^ RK[8];
595 RK[10] = RK[4] ^ RK[9];
596 RK[11] = RK[5] ^ RK[10];
597 }
598 break;
599
600 case 14:
601
Gilles Peskine449bd832023-01-11 14:50:10 +0100602 for (i = 0; i < 7; i++, RK += 8) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000603 RK[8] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100604 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[7])]) ^
605 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[7])] << 8) ^
606 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[7])] << 16) ^
607 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[7])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000608
609 RK[9] = RK[1] ^ RK[8];
610 RK[10] = RK[2] ^ RK[9];
611 RK[11] = RK[3] ^ RK[10];
612
613 RK[12] = RK[4] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100614 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[11])]) ^
615 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[11])] << 8) ^
616 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[11])] << 16) ^
617 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[11])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000618
619 RK[13] = RK[5] ^ RK[12];
620 RK[14] = RK[6] ^ RK[13];
621 RK[15] = RK[7] ^ RK[14];
622 }
623 break;
Paul Bakker5121ce52009-01-03 21:22:43 +0000624 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000625
Gilles Peskine449bd832023-01-11 14:50:10 +0100626 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000627}
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200628#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000629
630/*
631 * AES key schedule (decryption)
632 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200633#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100634int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
635 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000636{
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200637 int i, j, ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200638 mbedtls_aes_context cty;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000639 uint32_t *RK;
640 uint32_t *SK;
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200641
Gilles Peskine449bd832023-01-11 14:50:10 +0100642 mbedtls_aes_init(&cty);
Paul Bakker5121ce52009-01-03 21:22:43 +0000643
Werner Lewis7656a372022-06-13 12:28:20 +0100644 ctx->rk_offset = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200645#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_PADLOCK_ALIGN16)
Gilles Peskine449bd832023-01-11 14:50:10 +0100646 if (aes_padlock_ace == -1) {
647 aes_padlock_ace = mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE);
648 }
Paul Bakker048d04e2012-02-12 17:31:04 +0000649
Gilles Peskine449bd832023-01-11 14:50:10 +0100650 if (aes_padlock_ace) {
651 ctx->rk_offset = MBEDTLS_PADLOCK_ALIGN16(ctx->buf) - ctx->buf;
652 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000653#endif
Gilles Peskined6719172023-03-10 22:37:11 +0100654#if defined(MBEDTLS_AESNI_HAVE_CODE)
655 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
656 /* The intrinsics-based implementation needs 16-byte alignment
657 * for the round key array. */
658 unsigned delta = (uintptr_t) ctx->buf & 0x0000000f;
659 if (delta != 0) {
660 ctx->rk_offset = 4 - delta / 4; // 16 bytes = 4 uint32_t
661 }
662 }
663#endif
Werner Lewisdd76ef32022-05-30 12:00:21 +0100664 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000665
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200666 /* Also checks keybits */
Gilles Peskine449bd832023-01-11 14:50:10 +0100667 if ((ret = mbedtls_aes_setkey_enc(&cty, key, keybits)) != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200668 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100669 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000670
Manuel Pégourié-Gonnardafd5a082014-05-28 21:52:59 +0200671 ctx->nr = cty.nr;
672
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100673#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100674 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
675 mbedtls_aesni_inverse_key((unsigned char *) RK,
676 (const unsigned char *) (cty.buf + cty.rk_offset), ctx->nr);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200677 goto exit;
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100678 }
679#endif
680
Jerry Yue096da12023-01-10 17:07:01 +0800681#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
682 if (mbedtls_aesce_has_support()) {
683 mbedtls_aesce_inverse_key(
684 (unsigned char *) RK,
685 (const unsigned char *) (cty.buf + cty.rk_offset),
686 ctx->nr);
687 goto exit;
688 }
689#endif
690
Werner Lewisdd76ef32022-05-30 12:00:21 +0100691 SK = cty.buf + cty.rk_offset + cty.nr * 4;
Paul Bakker5121ce52009-01-03 21:22:43 +0000692
693 *RK++ = *SK++;
694 *RK++ = *SK++;
695 *RK++ = *SK++;
696 *RK++ = *SK++;
697
Gilles Peskine449bd832023-01-11 14:50:10 +0100698 for (i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8) {
699 for (j = 0; j < 4; j++, SK++) {
700 *RK++ = AES_RT0(FSb[MBEDTLS_BYTE_0(*SK)]) ^
701 AES_RT1(FSb[MBEDTLS_BYTE_1(*SK)]) ^
702 AES_RT2(FSb[MBEDTLS_BYTE_2(*SK)]) ^
703 AES_RT3(FSb[MBEDTLS_BYTE_3(*SK)]);
Paul Bakker5121ce52009-01-03 21:22:43 +0000704 }
705 }
706
707 *RK++ = *SK++;
708 *RK++ = *SK++;
709 *RK++ = *SK++;
710 *RK++ = *SK++;
711
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200712exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100713 mbedtls_aes_free(&cty);
Paul Bakker2b222c82009-07-27 21:03:45 +0000714
Gilles Peskine449bd832023-01-11 14:50:10 +0100715 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000716}
gabor-mezei-arm95db3012020-10-26 11:35:23 +0100717#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */
Jaeden Amero9366feb2018-05-29 18:55:17 +0100718
719#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100720static int mbedtls_aes_xts_decode_keys(const unsigned char *key,
721 unsigned int keybits,
722 const unsigned char **key1,
723 unsigned int *key1bits,
724 const unsigned char **key2,
725 unsigned int *key2bits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100726{
727 const unsigned int half_keybits = keybits / 2;
728 const unsigned int half_keybytes = half_keybits / 8;
729
Gilles Peskine449bd832023-01-11 14:50:10 +0100730 switch (keybits) {
Jaeden Amero9366feb2018-05-29 18:55:17 +0100731 case 256: break;
732 case 512: break;
Gilles Peskine449bd832023-01-11 14:50:10 +0100733 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100734 }
735
736 *key1bits = half_keybits;
737 *key2bits = half_keybits;
738 *key1 = &key[0];
739 *key2 = &key[half_keybytes];
740
741 return 0;
742}
743
Gilles Peskine449bd832023-01-11 14:50:10 +0100744int mbedtls_aes_xts_setkey_enc(mbedtls_aes_xts_context *ctx,
745 const unsigned char *key,
746 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100747{
Janos Follath24eed8d2019-11-22 13:21:35 +0000748 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100749 const unsigned char *key1, *key2;
750 unsigned int key1bits, key2bits;
751
Gilles Peskine449bd832023-01-11 14:50:10 +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 Peskine449bd832023-01-11 14:50:10 +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 Peskine449bd832023-01-11 14:50:10 +0100765 return mbedtls_aes_setkey_enc(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100766}
767
Gilles Peskine449bd832023-01-11 14:50:10 +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 Peskine449bd832023-01-11 14:50:10 +0100776 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
777 &key2, &key2bits);
778 if (ret != 0) {
779 return ret;
780 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100781
782 /* Set the tweak key. Always set tweak key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100783 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
784 if (ret != 0) {
785 return ret;
786 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100787
788 /* Set crypt key for decryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100789 return mbedtls_aes_setkey_dec(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100790}
791#endif /* MBEDTLS_CIPHER_MODE_XTS */
792
Gilles Peskine449bd832023-01-11 14:50:10 +0100793#define AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Joe Subbianicd84d762021-07-08 14:59:52 +0100794 do \
795 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100796 (X0) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y0)) ^ \
797 AES_FT1(MBEDTLS_BYTE_1(Y1)) ^ \
798 AES_FT2(MBEDTLS_BYTE_2(Y2)) ^ \
799 AES_FT3(MBEDTLS_BYTE_3(Y3)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100800 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100801 (X1) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y1)) ^ \
802 AES_FT1(MBEDTLS_BYTE_1(Y2)) ^ \
803 AES_FT2(MBEDTLS_BYTE_2(Y3)) ^ \
804 AES_FT3(MBEDTLS_BYTE_3(Y0)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100805 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100806 (X2) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y2)) ^ \
807 AES_FT1(MBEDTLS_BYTE_1(Y3)) ^ \
808 AES_FT2(MBEDTLS_BYTE_2(Y0)) ^ \
809 AES_FT3(MBEDTLS_BYTE_3(Y1)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100810 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100811 (X3) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y3)) ^ \
812 AES_FT1(MBEDTLS_BYTE_1(Y0)) ^ \
813 AES_FT2(MBEDTLS_BYTE_2(Y1)) ^ \
814 AES_FT3(MBEDTLS_BYTE_3(Y2)); \
815 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000816
Gilles Peskine449bd832023-01-11 14:50:10 +0100817#define AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100818 do \
819 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100820 (X0) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y0)) ^ \
821 AES_RT1(MBEDTLS_BYTE_1(Y3)) ^ \
822 AES_RT2(MBEDTLS_BYTE_2(Y2)) ^ \
823 AES_RT3(MBEDTLS_BYTE_3(Y1)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100824 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100825 (X1) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y1)) ^ \
826 AES_RT1(MBEDTLS_BYTE_1(Y0)) ^ \
827 AES_RT2(MBEDTLS_BYTE_2(Y3)) ^ \
828 AES_RT3(MBEDTLS_BYTE_3(Y2)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100829 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100830 (X2) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y2)) ^ \
831 AES_RT1(MBEDTLS_BYTE_1(Y1)) ^ \
832 AES_RT2(MBEDTLS_BYTE_2(Y0)) ^ \
833 AES_RT3(MBEDTLS_BYTE_3(Y3)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100834 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100835 (X3) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y3)) ^ \
836 AES_RT1(MBEDTLS_BYTE_1(Y2)) ^ \
837 AES_RT2(MBEDTLS_BYTE_2(Y1)) ^ \
838 AES_RT3(MBEDTLS_BYTE_3(Y0)); \
839 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000840
841/*
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200842 * AES-ECB block encryption
843 */
844#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100845int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx,
846 const unsigned char input[16],
847 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200848{
849 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100850 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100851 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200852 uint32_t X[4];
853 uint32_t Y[4];
854 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200855
Gilles Peskine449bd832023-01-11 14:50:10 +0100856 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
857 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
858 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
859 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200860
Gilles Peskine449bd832023-01-11 14:50:10 +0100861 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
862 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]);
863 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 +0200864 }
865
Gilles Peskine449bd832023-01-11 14:50:10 +0100866 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 +0200867
Gilles Peskine5197c662020-08-26 17:03:24 +0200868 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100869 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
870 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
871 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
872 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200873
Gilles Peskine5197c662020-08-26 17:03:24 +0200874 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100875 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
876 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
877 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
878 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200879
Gilles Peskine5197c662020-08-26 17:03:24 +0200880 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100881 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
882 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
883 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
884 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200885
Gilles Peskine5197c662020-08-26 17:03:24 +0200886 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100887 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
888 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
889 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
890 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200891
Gilles Peskine449bd832023-01-11 14:50:10 +0100892 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
893 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
894 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
895 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +0000896
Gilles Peskine449bd832023-01-11 14:50:10 +0100897 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500898
Gilles Peskine449bd832023-01-11 14:50:10 +0100899 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200900}
901#endif /* !MBEDTLS_AES_ENCRYPT_ALT */
902
903/*
904 * AES-ECB block decryption
905 */
906#if !defined(MBEDTLS_AES_DECRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100907int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
908 const unsigned char input[16],
909 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200910{
911 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100912 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100913 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200914 uint32_t X[4];
915 uint32_t Y[4];
916 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200917
Gilles Peskine449bd832023-01-11 14:50:10 +0100918 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
919 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
920 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
921 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200922
Gilles Peskine449bd832023-01-11 14:50:10 +0100923 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
924 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]);
925 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 +0200926 }
927
Gilles Peskine449bd832023-01-11 14:50:10 +0100928 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 +0200929
Gilles Peskine5197c662020-08-26 17:03:24 +0200930 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100931 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
932 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
933 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
934 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200935
Gilles Peskine5197c662020-08-26 17:03:24 +0200936 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100937 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
938 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
939 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
940 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200941
Gilles Peskine5197c662020-08-26 17:03:24 +0200942 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100943 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
944 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
945 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
946 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200947
Gilles Peskine5197c662020-08-26 17:03:24 +0200948 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100949 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
950 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
951 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
952 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200953
Gilles Peskine449bd832023-01-11 14:50:10 +0100954 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
955 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
956 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
957 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +0000958
Gilles Peskine449bd832023-01-11 14:50:10 +0100959 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500960
Gilles Peskine449bd832023-01-11 14:50:10 +0100961 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200962}
963#endif /* !MBEDTLS_AES_DECRYPT_ALT */
964
965/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000966 * AES-ECB block encryption/decryption
967 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100968int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
969 int mode,
970 const unsigned char input[16],
971 unsigned char output[16])
Paul Bakker5121ce52009-01-03 21:22:43 +0000972{
Gilles Peskine449bd832023-01-11 14:50:10 +0100973 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +0100974 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100975 }
Manuel Pégourié-Gonnard1aca2602018-12-12 12:56:55 +0100976
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100977#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100978 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
979 return mbedtls_aesni_crypt_ecb(ctx, mode, input, output);
980 }
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +0100981#endif
982
Jerry Yu2bb3d812023-01-10 17:38:26 +0800983#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
984 if (mbedtls_aesce_has_support()) {
985 return mbedtls_aesce_crypt_ecb(ctx, mode, input, output);
986 }
987#endif
988
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200989#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Gilles Peskine449bd832023-01-11 14:50:10 +0100990 if (aes_padlock_ace > 0) {
991 if (mbedtls_padlock_xcryptecb(ctx, mode, input, output) == 0) {
992 return 0;
993 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000994
995 // If padlock data misaligned, we just fall back to
996 // unaccelerated mode
997 //
Paul Bakker5121ce52009-01-03 21:22:43 +0000998 }
999#endif
1000
Gilles Peskine449bd832023-01-11 14:50:10 +01001001 if (mode == MBEDTLS_AES_ENCRYPT) {
1002 return mbedtls_internal_aes_encrypt(ctx, input, output);
1003 } else {
1004 return mbedtls_internal_aes_decrypt(ctx, input, output);
1005 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001006}
1007
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001008#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001009/*
1010 * AES-CBC buffer encryption/decryption
1011 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001012int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
1013 int mode,
1014 size_t length,
1015 unsigned char iv[16],
1016 const unsigned char *input,
1017 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001018{
Gilles Peskine7820a572021-07-07 21:08:28 +02001019 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +00001020 unsigned char temp[16];
1021
Gilles Peskine449bd832023-01-11 14:50:10 +01001022 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001023 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001024 }
Manuel Pégourié-Gonnard3178d1a2018-12-12 13:05:00 +01001025
Gilles Peskine449bd832023-01-11 14:50:10 +01001026 if (length % 16) {
1027 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
1028 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001029
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001030#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Gilles Peskine449bd832023-01-11 14:50:10 +01001031 if (aes_padlock_ace > 0) {
1032 if (mbedtls_padlock_xcryptcbc(ctx, mode, length, iv, input, output) == 0) {
1033 return 0;
1034 }
Paul Bakker9af723c2014-05-01 13:03:14 +02001035
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001036 // If padlock data misaligned, we just fall back to
1037 // unaccelerated mode
1038 //
Paul Bakker5121ce52009-01-03 21:22:43 +00001039 }
1040#endif
1041
Gilles Peskine449bd832023-01-11 14:50:10 +01001042 if (mode == MBEDTLS_AES_DECRYPT) {
1043 while (length > 0) {
1044 memcpy(temp, input, 16);
1045 ret = mbedtls_aes_crypt_ecb(ctx, mode, input, output);
1046 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001047 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001048 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001049
Gilles Peskine449bd832023-01-11 14:50:10 +01001050 mbedtls_xor(output, output, iv, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001051
Gilles Peskine449bd832023-01-11 14:50:10 +01001052 memcpy(iv, temp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001053
1054 input += 16;
1055 output += 16;
1056 length -= 16;
1057 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001058 } else {
1059 while (length > 0) {
1060 mbedtls_xor(output, input, iv, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001061
Gilles Peskine449bd832023-01-11 14:50:10 +01001062 ret = mbedtls_aes_crypt_ecb(ctx, mode, output, output);
1063 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001064 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001065 }
1066 memcpy(iv, output, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001067
1068 input += 16;
1069 output += 16;
1070 length -= 16;
1071 }
1072 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001073 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001074
Gilles Peskine7820a572021-07-07 21:08:28 +02001075exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001076 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001077}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001078#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001079
Aorimn5f778012016-06-09 23:22:58 +02001080#if defined(MBEDTLS_CIPHER_MODE_XTS)
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001081
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001082typedef unsigned char mbedtls_be128[16];
1083
1084/*
1085 * GF(2^128) multiplication function
1086 *
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001087 * This function multiplies a field element by x in the polynomial field
1088 * representation. It uses 64-bit word operations to gain speed but compensates
Shaun Case8b0ecbc2021-12-20 21:14:10 -08001089 * for machine endianness and hence works correctly on both big and little
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001090 * endian machines.
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001091 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001092static void mbedtls_gf128mul_x_ble(unsigned char r[16],
1093 const unsigned char x[16])
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001094{
1095 uint64_t a, b, ra, rb;
1096
Gilles Peskine449bd832023-01-11 14:50:10 +01001097 a = MBEDTLS_GET_UINT64_LE(x, 0);
1098 b = MBEDTLS_GET_UINT64_LE(x, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001099
Gilles Peskine449bd832023-01-11 14:50:10 +01001100 ra = (a << 1) ^ 0x0087 >> (8 - ((b >> 63) << 3));
1101 rb = (a >> 63) | (b << 1);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001102
Gilles Peskine449bd832023-01-11 14:50:10 +01001103 MBEDTLS_PUT_UINT64_LE(ra, r, 0);
1104 MBEDTLS_PUT_UINT64_LE(rb, r, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001105}
1106
Aorimn5f778012016-06-09 23:22:58 +02001107/*
1108 * AES-XTS buffer encryption/decryption
1109 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001110int mbedtls_aes_crypt_xts(mbedtls_aes_xts_context *ctx,
1111 int mode,
1112 size_t length,
1113 const unsigned char data_unit[16],
1114 const unsigned char *input,
1115 unsigned char *output)
Aorimn5f778012016-06-09 23:22:58 +02001116{
Janos Follath24eed8d2019-11-22 13:21:35 +00001117 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amerod82cd862018-04-28 15:02:45 +01001118 size_t blocks = length / 16;
1119 size_t leftover = length % 16;
1120 unsigned char tweak[16];
1121 unsigned char prev_tweak[16];
1122 unsigned char tmp[16];
Aorimn5f778012016-06-09 23:22:58 +02001123
Gilles Peskine449bd832023-01-11 14:50:10 +01001124 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001125 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001126 }
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01001127
Jaeden Amero8381fcb2018-10-11 12:06:15 +01001128 /* Data units must be at least 16 bytes long. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001129 if (length < 16) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001130 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001131 }
Aorimn5f778012016-06-09 23:22:58 +02001132
Jaeden Ameroa74faba2018-10-11 12:07:43 +01001133 /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001134 if (length > (1 << 20) * 16) {
Jaeden Amero0a8b0202018-05-30 15:36:06 +01001135 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001136 }
Aorimn5f778012016-06-09 23:22:58 +02001137
Jaeden Amerod82cd862018-04-28 15:02:45 +01001138 /* Compute the tweak. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001139 ret = mbedtls_aes_crypt_ecb(&ctx->tweak, MBEDTLS_AES_ENCRYPT,
1140 data_unit, tweak);
1141 if (ret != 0) {
1142 return ret;
1143 }
Aorimn5f778012016-06-09 23:22:58 +02001144
Gilles Peskine449bd832023-01-11 14:50:10 +01001145 while (blocks--) {
1146 if (leftover && (mode == MBEDTLS_AES_DECRYPT) && blocks == 0) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001147 /* We are on the last block in a decrypt operation that has
1148 * leftover bytes, so we need to use the next tweak for this block,
Tom Cosgrove1797b052022-12-04 17:19:59 +00001149 * and this tweak for the leftover bytes. Save the current tweak for
Jaeden Amerod82cd862018-04-28 15:02:45 +01001150 * the leftovers and then update the current tweak for use on this,
1151 * the last full block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001152 memcpy(prev_tweak, tweak, sizeof(tweak));
1153 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001154 }
1155
Gilles Peskine449bd832023-01-11 14:50:10 +01001156 mbedtls_xor(tmp, input, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001157
Gilles Peskine449bd832023-01-11 14:50:10 +01001158 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1159 if (ret != 0) {
1160 return ret;
1161 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001162
Gilles Peskine449bd832023-01-11 14:50:10 +01001163 mbedtls_xor(output, tmp, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001164
1165 /* Update the tweak for the next block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001166 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001167
1168 output += 16;
1169 input += 16;
Aorimn5f778012016-06-09 23:22:58 +02001170 }
1171
Gilles Peskine449bd832023-01-11 14:50:10 +01001172 if (leftover) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001173 /* If we are on the leftover bytes in a decrypt operation, we need to
1174 * use the previous tweak for these bytes (as saved in prev_tweak). */
1175 unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
Aorimn5f778012016-06-09 23:22:58 +02001176
Jaeden Amerod82cd862018-04-28 15:02:45 +01001177 /* We are now on the final part of the data unit, which doesn't divide
1178 * evenly by 16. It's time for ciphertext stealing. */
1179 size_t i;
1180 unsigned char *prev_output = output - 16;
Aorimn5f778012016-06-09 23:22:58 +02001181
Jaeden Amerod82cd862018-04-28 15:02:45 +01001182 /* Copy ciphertext bytes from the previous block to our output for each
Dave Rodgman069e7f42022-11-24 19:37:26 +00001183 * byte of ciphertext we won't steal. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001184 for (i = 0; i < leftover; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001185 output[i] = prev_output[i];
Aorimn5f778012016-06-09 23:22:58 +02001186 }
Aorimn5f778012016-06-09 23:22:58 +02001187
Dave Rodgman069e7f42022-11-24 19:37:26 +00001188 /* Copy the remainder of the input for this final round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001189 mbedtls_xor(tmp, input, t, leftover);
Dave Rodgmana8cf6072022-11-22 15:02:54 +00001190
Jaeden Amerod82cd862018-04-28 15:02:45 +01001191 /* Copy ciphertext bytes from the previous block for input in this
1192 * round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001193 mbedtls_xor(tmp + i, prev_output + i, t + i, 16 - i);
Aorimn5f778012016-06-09 23:22:58 +02001194
Gilles Peskine449bd832023-01-11 14:50:10 +01001195 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1196 if (ret != 0) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001197 return ret;
Gilles Peskine449bd832023-01-11 14:50:10 +01001198 }
Aorimn5f778012016-06-09 23:22:58 +02001199
Jaeden Amerod82cd862018-04-28 15:02:45 +01001200 /* Write the result back to the previous block, overriding the previous
1201 * output we copied. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001202 mbedtls_xor(prev_output, tmp, t, 16);
Aorimn5f778012016-06-09 23:22:58 +02001203 }
1204
Gilles Peskine449bd832023-01-11 14:50:10 +01001205 return 0;
Aorimn5f778012016-06-09 23:22:58 +02001206}
1207#endif /* MBEDTLS_CIPHER_MODE_XTS */
1208
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001209#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001210/*
1211 * AES-CFB128 buffer encryption/decryption
1212 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001213int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx,
1214 int mode,
1215 size_t length,
1216 size_t *iv_off,
1217 unsigned char iv[16],
1218 const unsigned char *input,
1219 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001220{
Paul Bakker27fdf462011-06-09 13:55:13 +00001221 int c;
Gilles Peskine7820a572021-07-07 21:08:28 +02001222 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001223 size_t n;
1224
Gilles Peskine449bd832023-01-11 14:50:10 +01001225 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001226 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001227 }
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001228
1229 n = *iv_off;
Paul Bakker5121ce52009-01-03 21:22:43 +00001230
Gilles Peskine449bd832023-01-11 14:50:10 +01001231 if (n > 15) {
1232 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1233 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001234
Gilles Peskine449bd832023-01-11 14:50:10 +01001235 if (mode == MBEDTLS_AES_DECRYPT) {
1236 while (length--) {
1237 if (n == 0) {
1238 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1239 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001240 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001241 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001242 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001243
1244 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001245 *output++ = (unsigned char) (c ^ iv[n]);
Paul Bakker5121ce52009-01-03 21:22:43 +00001246 iv[n] = (unsigned char) c;
1247
Gilles Peskine449bd832023-01-11 14:50:10 +01001248 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001249 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001250 } else {
1251 while (length--) {
1252 if (n == 0) {
1253 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1254 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001255 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001256 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001257 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001258
Gilles Peskine449bd832023-01-11 14:50:10 +01001259 iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++);
Paul Bakker5121ce52009-01-03 21:22:43 +00001260
Gilles Peskine449bd832023-01-11 14:50:10 +01001261 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001262 }
1263 }
1264
1265 *iv_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001266 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001267
Gilles Peskine7820a572021-07-07 21:08:28 +02001268exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001269 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001270}
Paul Bakker556efba2014-01-24 15:38:12 +01001271
1272/*
1273 * AES-CFB8 buffer encryption/decryption
1274 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001275int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx,
1276 int mode,
1277 size_t length,
1278 unsigned char iv[16],
1279 const unsigned char *input,
1280 unsigned char *output)
Paul Bakker556efba2014-01-24 15:38:12 +01001281{
Gilles Peskine7820a572021-07-07 21:08:28 +02001282 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker556efba2014-01-24 15:38:12 +01001283 unsigned char c;
1284 unsigned char ov[17];
1285
Gilles Peskine449bd832023-01-11 14:50:10 +01001286 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001287 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001288 }
1289 while (length--) {
1290 memcpy(ov, iv, 16);
1291 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1292 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001293 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001294 }
Paul Bakker556efba2014-01-24 15:38:12 +01001295
Gilles Peskine449bd832023-01-11 14:50:10 +01001296 if (mode == MBEDTLS_AES_DECRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001297 ov[16] = *input;
Gilles Peskine449bd832023-01-11 14:50:10 +01001298 }
Paul Bakker556efba2014-01-24 15:38:12 +01001299
Gilles Peskine449bd832023-01-11 14:50:10 +01001300 c = *output++ = (unsigned char) (iv[0] ^ *input++);
Paul Bakker556efba2014-01-24 15:38:12 +01001301
Gilles Peskine449bd832023-01-11 14:50:10 +01001302 if (mode == MBEDTLS_AES_ENCRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001303 ov[16] = c;
Gilles Peskine449bd832023-01-11 14:50:10 +01001304 }
Paul Bakker556efba2014-01-24 15:38:12 +01001305
Gilles Peskine449bd832023-01-11 14:50:10 +01001306 memcpy(iv, ov + 1, 16);
Paul Bakker556efba2014-01-24 15:38:12 +01001307 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001308 ret = 0;
Paul Bakker556efba2014-01-24 15:38:12 +01001309
Gilles Peskine7820a572021-07-07 21:08:28 +02001310exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001311 return ret;
Paul Bakker556efba2014-01-24 15:38:12 +01001312}
Simon Butcher76a5b222018-04-22 22:57:27 +01001313#endif /* MBEDTLS_CIPHER_MODE_CFB */
1314
1315#if defined(MBEDTLS_CIPHER_MODE_OFB)
1316/*
1317 * AES-OFB (Output Feedback Mode) buffer encryption/decryption
1318 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001319int mbedtls_aes_crypt_ofb(mbedtls_aes_context *ctx,
1320 size_t length,
1321 size_t *iv_off,
1322 unsigned char iv[16],
1323 const unsigned char *input,
1324 unsigned char *output)
Simon Butcher76a5b222018-04-22 22:57:27 +01001325{
Simon Butcherad4e4932018-04-29 00:43:47 +01001326 int ret = 0;
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001327 size_t n;
1328
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001329 n = *iv_off;
Simon Butcher76a5b222018-04-22 22:57:27 +01001330
Gilles Peskine449bd832023-01-11 14:50:10 +01001331 if (n > 15) {
1332 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1333 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001334
Gilles Peskine449bd832023-01-11 14:50:10 +01001335 while (length--) {
1336 if (n == 0) {
1337 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1338 if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001339 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001340 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001341 }
Simon Butcher76a5b222018-04-22 22:57:27 +01001342 *output++ = *input++ ^ iv[n];
1343
Gilles Peskine449bd832023-01-11 14:50:10 +01001344 n = (n + 1) & 0x0F;
Simon Butcher76a5b222018-04-22 22:57:27 +01001345 }
1346
1347 *iv_off = n;
1348
Simon Butcherad4e4932018-04-29 00:43:47 +01001349exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001350 return ret;
Simon Butcher76a5b222018-04-22 22:57:27 +01001351}
1352#endif /* MBEDTLS_CIPHER_MODE_OFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001353
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001354#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001355/*
1356 * AES-CTR buffer encryption/decryption
1357 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001358int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
1359 size_t length,
1360 size_t *nc_off,
1361 unsigned char nonce_counter[16],
1362 unsigned char stream_block[16],
1363 const unsigned char *input,
1364 unsigned char *output)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001365{
Paul Bakker369e14b2012-04-18 14:16:09 +00001366 int c, i;
Gilles Peskine7820a572021-07-07 21:08:28 +02001367 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001368 size_t n;
1369
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001370 n = *nc_off;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001371
Gilles Peskine449bd832023-01-11 14:50:10 +01001372 if (n > 0x0F) {
1373 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1374 }
Mohammad Azim Khan3f7f8172017-11-23 17:49:05 +00001375
Gilles Peskine449bd832023-01-11 14:50:10 +01001376 while (length--) {
1377 if (n == 0) {
1378 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block);
1379 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001380 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001381 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001382
Gilles Peskine449bd832023-01-11 14:50:10 +01001383 for (i = 16; i > 0; i--) {
1384 if (++nonce_counter[i - 1] != 0) {
Paul Bakker369e14b2012-04-18 14:16:09 +00001385 break;
Gilles Peskine449bd832023-01-11 14:50:10 +01001386 }
1387 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001388 }
1389 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001390 *output++ = (unsigned char) (c ^ stream_block[n]);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001391
Gilles Peskine449bd832023-01-11 14:50:10 +01001392 n = (n + 1) & 0x0F;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001393 }
1394
1395 *nc_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001396 ret = 0;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001397
Gilles Peskine7820a572021-07-07 21:08:28 +02001398exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001399 return ret;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001400}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001401#endif /* MBEDTLS_CIPHER_MODE_CTR */
Manuel Pégourié-Gonnard1ec220b2014-03-10 11:20:17 +01001402
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001403#endif /* !MBEDTLS_AES_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001404
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001405#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001406/*
1407 * AES test vectors from:
1408 *
1409 * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
1410 */
1411static const unsigned char aes_test_ecb_dec[3][16] =
1412{
1413 { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
1414 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
1415 { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
1416 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
1417 { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
1418 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
1419};
1420
1421static const unsigned char aes_test_ecb_enc[3][16] =
1422{
1423 { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
1424 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
1425 { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
1426 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
1427 { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
1428 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
1429};
1430
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001431#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001432static const unsigned char aes_test_cbc_dec[3][16] =
1433{
1434 { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
1435 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
1436 { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
1437 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
1438 { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
1439 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
1440};
1441
1442static const unsigned char aes_test_cbc_enc[3][16] =
1443{
1444 { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
1445 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
1446 { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
1447 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
1448 { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
1449 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
1450};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001451#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001452
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001453#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001454/*
1455 * AES-CFB128 test vectors from:
1456 *
1457 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
1458 */
1459static const unsigned char aes_test_cfb128_key[3][32] =
1460{
1461 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1462 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
1463 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1464 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1465 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1466 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1467 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1468 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1469 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
1470};
1471
1472static const unsigned char aes_test_cfb128_iv[16] =
1473{
1474 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1475 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1476};
1477
1478static const unsigned char aes_test_cfb128_pt[64] =
1479{
1480 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1481 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1482 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1483 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1484 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1485 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1486 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1487 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1488};
1489
1490static const unsigned char aes_test_cfb128_ct[3][64] =
1491{
1492 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1493 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1494 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F,
1495 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B,
1496 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40,
1497 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF,
1498 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E,
1499 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 },
1500 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1501 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1502 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21,
1503 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A,
1504 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1,
1505 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9,
1506 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0,
1507 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF },
1508 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1509 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1510 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8,
1511 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B,
1512 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92,
1513 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9,
1514 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8,
1515 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 }
1516};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001517#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001518
Simon Butcherad4e4932018-04-29 00:43:47 +01001519#if defined(MBEDTLS_CIPHER_MODE_OFB)
1520/*
1521 * AES-OFB test vectors from:
1522 *
Simon Butcher5db13622018-06-04 22:11:25 +01001523 * https://csrc.nist.gov/publications/detail/sp/800-38a/final
Simon Butcherad4e4932018-04-29 00:43:47 +01001524 */
1525static const unsigned char aes_test_ofb_key[3][32] =
1526{
1527 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1528 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
1529 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1530 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1531 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1532 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1533 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1534 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1535 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
1536};
1537
1538static const unsigned char aes_test_ofb_iv[16] =
1539{
1540 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1541 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1542};
1543
1544static const unsigned char aes_test_ofb_pt[64] =
1545{
1546 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1547 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1548 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1549 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1550 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1551 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1552 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1553 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1554};
1555
1556static const unsigned char aes_test_ofb_ct[3][64] =
1557{
1558 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1559 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1560 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
1561 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
1562 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
1563 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
1564 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
1565 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e },
1566 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1567 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1568 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
1569 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
1570 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f,
1571 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
1572 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e,
1573 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a },
1574 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1575 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1576 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
1577 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
1578 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed,
1579 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
1580 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8,
1581 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 }
1582};
1583#endif /* MBEDTLS_CIPHER_MODE_OFB */
1584
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001585#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001586/*
1587 * AES-CTR test vectors from:
1588 *
1589 * http://www.faqs.org/rfcs/rfc3686.html
1590 */
1591
1592static const unsigned char aes_test_ctr_key[3][16] =
1593{
1594 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
1595 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
1596 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
1597 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
1598 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
1599 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
1600};
1601
1602static const unsigned char aes_test_ctr_nonce_counter[3][16] =
1603{
1604 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
1605 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
1606 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
1607 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
1608 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
1609 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
1610};
1611
1612static const unsigned char aes_test_ctr_pt[3][48] =
1613{
1614 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
1615 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
1616
1617 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1618 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1619 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1620 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
1621
1622 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1623 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1624 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1625 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
1626 0x20, 0x21, 0x22, 0x23 }
1627};
1628
1629static const unsigned char aes_test_ctr_ct[3][48] =
1630{
1631 { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79,
1632 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 },
1633 { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9,
1634 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88,
1635 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8,
1636 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 },
1637 { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
1638 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
1639 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
1640 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
1641 0x25, 0xB2, 0x07, 0x2F }
1642};
1643
1644static const int aes_test_ctr_len[3] =
Gilles Peskine449bd832023-01-11 14:50:10 +01001645{ 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001646#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00001647
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001648#if defined(MBEDTLS_CIPHER_MODE_XTS)
1649/*
1650 * AES-XTS test vectors from:
1651 *
1652 * IEEE P1619/D16 Annex B
1653 * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf
1654 * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf)
1655 */
1656static const unsigned char aes_test_xts_key[][32] =
1657{
1658 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1659 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1660 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1661 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1662 { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1663 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1664 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1665 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1666 { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
1667 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
1668 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1669 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1670};
1671
1672static const unsigned char aes_test_xts_pt32[][32] =
1673{
1674 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1675 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1676 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1677 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1678 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1679 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1680 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1681 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1682 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1683 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1684 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1685 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1686};
1687
1688static const unsigned char aes_test_xts_ct32[][32] =
1689{
1690 { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec,
1691 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92,
1692 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85,
1693 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e },
1694 { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e,
1695 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b,
1696 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4,
1697 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 },
1698 { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a,
1699 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2,
1700 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53,
1701 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 },
1702};
1703
1704static const unsigned char aes_test_xts_data_unit[][16] =
1705{
Gilles Peskine449bd832023-01-11 14:50:10 +01001706 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1707 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1708 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1709 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1710 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1711 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001712};
1713
1714#endif /* MBEDTLS_CIPHER_MODE_XTS */
1715
Paul Bakker5121ce52009-01-03 21:22:43 +00001716/*
1717 * Checkup routine
1718 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001719int mbedtls_aes_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +00001720{
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001721 int ret = 0, i, j, u, mode;
1722 unsigned int keybits;
Paul Bakker5121ce52009-01-03 21:22:43 +00001723 unsigned char key[32];
1724 unsigned char buf[64];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001725 const unsigned char *aes_tests;
Andrzej Kurek252283f2022-09-27 07:54:16 -04001726#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1727 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001728 unsigned char iv[16];
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03001729#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001730#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +02001731 unsigned char prv[16];
1732#endif
Simon Butcher2ff0e522018-06-14 09:57:07 +01001733#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1734 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker27fdf462011-06-09 13:55:13 +00001735 size_t offset;
Paul Bakkere91d01e2011-04-19 15:55:50 +00001736#endif
Simon Butcher66a89032018-06-15 18:20:29 +01001737#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS)
Paul Bakkere91d01e2011-04-19 15:55:50 +00001738 int len;
Simon Butcher66a89032018-06-15 18:20:29 +01001739#endif
1740#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001741 unsigned char nonce_counter[16];
1742 unsigned char stream_block[16];
1743#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001744 mbedtls_aes_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001745
Gilles Peskine449bd832023-01-11 14:50:10 +01001746 memset(key, 0, 32);
1747 mbedtls_aes_init(&ctx);
Paul Bakker5121ce52009-01-03 21:22:43 +00001748
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001749 if (verbose != 0) {
1750#if defined(MBEDTLS_AES_ALT)
1751 mbedtls_printf(" AES note: alternative implementation.\n");
1752#else /* MBEDTLS_AES_ALT */
1753#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
1754 if (mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE)) {
1755 mbedtls_printf(" AES note: using VIA Padlock.\n");
1756 } else
1757#endif
1758#if defined(MBEDTLS_AESNI_HAVE_CODE)
1759 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1760 mbedtls_printf(" AES note: using AESNI.\n");
1761 } else
1762#endif
1763#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
1764 if (mbedtls_aesce_has_support()) {
1765 mbedtls_printf(" AES note: using AESCE.\n");
1766 } else
1767#endif
1768 mbedtls_printf(" AES note: built-in implementation.\n");
1769#endif /* MBEDTLS_AES_ALT */
1770 }
1771
Paul Bakker5121ce52009-01-03 21:22:43 +00001772 /*
1773 * ECB mode
1774 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001775 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +00001776 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001777 keybits = 128 + u * 64;
1778 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001779
Gilles Peskine449bd832023-01-11 14:50:10 +01001780 if (verbose != 0) {
1781 mbedtls_printf(" AES-ECB-%3u (%s): ", keybits,
1782 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00001783 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001784
1785 memset(buf, 0, 16);
1786
1787 if (mode == MBEDTLS_AES_DECRYPT) {
1788 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1789 aes_tests = aes_test_ecb_dec[u];
1790 } else {
1791 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001792 aes_tests = aes_test_ecb_enc[u];
1793 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001794
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01001795 /*
1796 * AES-192 is an optional feature that may be unavailable when
1797 * there is an alternative underlying implementation i.e. when
1798 * MBEDTLS_AES_ALT is defined.
1799 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001800 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1801 mbedtls_printf("skipped\n");
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001802 continue;
Gilles Peskine449bd832023-01-11 14:50:10 +01001803 } else if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001804 goto exit;
1805 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001806
Gilles Peskine449bd832023-01-11 14:50:10 +01001807 for (j = 0; j < 10000; j++) {
1808 ret = mbedtls_aes_crypt_ecb(&ctx, mode, buf, buf);
1809 if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001810 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001811 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001812 }
1813
Gilles Peskine449bd832023-01-11 14:50:10 +01001814 if (memcmp(buf, aes_tests, 16) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001815 ret = 1;
1816 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001817 }
1818
Gilles Peskine449bd832023-01-11 14:50:10 +01001819 if (verbose != 0) {
1820 mbedtls_printf("passed\n");
1821 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001822 }
1823
Gilles Peskine449bd832023-01-11 14:50:10 +01001824 if (verbose != 0) {
1825 mbedtls_printf("\n");
1826 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001827
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001828#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001829 /*
1830 * CBC mode
1831 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001832 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +00001833 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001834 keybits = 128 + u * 64;
1835 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001836
Gilles Peskine449bd832023-01-11 14:50:10 +01001837 if (verbose != 0) {
1838 mbedtls_printf(" AES-CBC-%3u (%s): ", keybits,
1839 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00001840 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001841
1842 memset(iv, 0, 16);
1843 memset(prv, 0, 16);
1844 memset(buf, 0, 16);
1845
1846 if (mode == MBEDTLS_AES_DECRYPT) {
1847 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1848 aes_tests = aes_test_cbc_dec[u];
1849 } else {
1850 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001851 aes_tests = aes_test_cbc_enc[u];
1852 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001853
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01001854 /*
1855 * AES-192 is an optional feature that may be unavailable when
1856 * there is an alternative underlying implementation i.e. when
1857 * MBEDTLS_AES_ALT is defined.
1858 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001859 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1860 mbedtls_printf("skipped\n");
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001861 continue;
Gilles Peskine449bd832023-01-11 14:50:10 +01001862 } else if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001863 goto exit;
1864 }
1865
Gilles Peskine449bd832023-01-11 14:50:10 +01001866 for (j = 0; j < 10000; j++) {
1867 if (mode == MBEDTLS_AES_ENCRYPT) {
Paul Bakker5121ce52009-01-03 21:22:43 +00001868 unsigned char tmp[16];
1869
Gilles Peskine449bd832023-01-11 14:50:10 +01001870 memcpy(tmp, prv, 16);
1871 memcpy(prv, buf, 16);
1872 memcpy(buf, tmp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001873 }
1874
Gilles Peskine449bd832023-01-11 14:50:10 +01001875 ret = mbedtls_aes_crypt_cbc(&ctx, mode, 16, iv, buf, buf);
1876 if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001877 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001878 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001879
1880 }
1881
Gilles Peskine449bd832023-01-11 14:50:10 +01001882 if (memcmp(buf, aes_tests, 16) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001883 ret = 1;
1884 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001885 }
1886
Gilles Peskine449bd832023-01-11 14:50:10 +01001887 if (verbose != 0) {
1888 mbedtls_printf("passed\n");
1889 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001890 }
1891
Gilles Peskine449bd832023-01-11 14:50:10 +01001892 if (verbose != 0) {
1893 mbedtls_printf("\n");
1894 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001895#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001896
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001897#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001898 /*
1899 * CFB128 mode
1900 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001901 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +00001902 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001903 keybits = 128 + u * 64;
1904 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001905
Gilles Peskine449bd832023-01-11 14:50:10 +01001906 if (verbose != 0) {
1907 mbedtls_printf(" AES-CFB128-%3u (%s): ", keybits,
1908 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
1909 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001910
Gilles Peskine449bd832023-01-11 14:50:10 +01001911 memcpy(iv, aes_test_cfb128_iv, 16);
1912 memcpy(key, aes_test_cfb128_key[u], keybits / 8);
Paul Bakker5121ce52009-01-03 21:22:43 +00001913
1914 offset = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +01001915 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01001916 /*
1917 * AES-192 is an optional feature that may be unavailable when
1918 * there is an alternative underlying implementation i.e. when
1919 * MBEDTLS_AES_ALT is defined.
1920 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001921 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1922 mbedtls_printf("skipped\n");
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001923 continue;
Gilles Peskine449bd832023-01-11 14:50:10 +01001924 } else if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001925 goto exit;
1926 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001927
Gilles Peskine449bd832023-01-11 14:50:10 +01001928 if (mode == MBEDTLS_AES_DECRYPT) {
1929 memcpy(buf, aes_test_cfb128_ct[u], 64);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001930 aes_tests = aes_test_cfb128_pt;
Gilles Peskine449bd832023-01-11 14:50:10 +01001931 } else {
1932 memcpy(buf, aes_test_cfb128_pt, 64);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001933 aes_tests = aes_test_cfb128_ct[u];
1934 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001935
Gilles Peskine449bd832023-01-11 14:50:10 +01001936 ret = mbedtls_aes_crypt_cfb128(&ctx, mode, 64, &offset, iv, buf, buf);
1937 if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001938 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001939 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001940
Gilles Peskine449bd832023-01-11 14:50:10 +01001941 if (memcmp(buf, aes_tests, 64) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001942 ret = 1;
1943 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001944 }
1945
Gilles Peskine449bd832023-01-11 14:50:10 +01001946 if (verbose != 0) {
1947 mbedtls_printf("passed\n");
1948 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001949 }
1950
Gilles Peskine449bd832023-01-11 14:50:10 +01001951 if (verbose != 0) {
1952 mbedtls_printf("\n");
1953 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001954#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001955
Simon Butcherad4e4932018-04-29 00:43:47 +01001956#if defined(MBEDTLS_CIPHER_MODE_OFB)
1957 /*
1958 * OFB mode
1959 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001960 for (i = 0; i < 6; i++) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001961 u = i >> 1;
1962 keybits = 128 + u * 64;
1963 mode = i & 1;
1964
Gilles Peskine449bd832023-01-11 14:50:10 +01001965 if (verbose != 0) {
1966 mbedtls_printf(" AES-OFB-%3u (%s): ", keybits,
1967 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
1968 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001969
Gilles Peskine449bd832023-01-11 14:50:10 +01001970 memcpy(iv, aes_test_ofb_iv, 16);
1971 memcpy(key, aes_test_ofb_key[u], keybits / 8);
Simon Butcherad4e4932018-04-29 00:43:47 +01001972
1973 offset = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +01001974 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Simon Butcherad4e4932018-04-29 00:43:47 +01001975 /*
1976 * AES-192 is an optional feature that may be unavailable when
1977 * there is an alternative underlying implementation i.e. when
1978 * MBEDTLS_AES_ALT is defined.
1979 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001980 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1981 mbedtls_printf("skipped\n");
Simon Butcherad4e4932018-04-29 00:43:47 +01001982 continue;
Gilles Peskine449bd832023-01-11 14:50:10 +01001983 } else if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001984 goto exit;
1985 }
1986
Gilles Peskine449bd832023-01-11 14:50:10 +01001987 if (mode == MBEDTLS_AES_DECRYPT) {
1988 memcpy(buf, aes_test_ofb_ct[u], 64);
Simon Butcherad4e4932018-04-29 00:43:47 +01001989 aes_tests = aes_test_ofb_pt;
Gilles Peskine449bd832023-01-11 14:50:10 +01001990 } else {
1991 memcpy(buf, aes_test_ofb_pt, 64);
Simon Butcherad4e4932018-04-29 00:43:47 +01001992 aes_tests = aes_test_ofb_ct[u];
1993 }
1994
Gilles Peskine449bd832023-01-11 14:50:10 +01001995 ret = mbedtls_aes_crypt_ofb(&ctx, 64, &offset, iv, buf, buf);
1996 if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001997 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001998 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001999
Gilles Peskine449bd832023-01-11 14:50:10 +01002000 if (memcmp(buf, aes_tests, 64) != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01002001 ret = 1;
2002 goto exit;
2003 }
2004
Gilles Peskine449bd832023-01-11 14:50:10 +01002005 if (verbose != 0) {
2006 mbedtls_printf("passed\n");
2007 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002008 }
2009
Gilles Peskine449bd832023-01-11 14:50:10 +01002010 if (verbose != 0) {
2011 mbedtls_printf("\n");
2012 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002013#endif /* MBEDTLS_CIPHER_MODE_OFB */
2014
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002015#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002016 /*
2017 * CTR mode
2018 */
Gilles Peskine449bd832023-01-11 14:50:10 +01002019 for (i = 0; i < 6; i++) {
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002020 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002021 mode = i & 1;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002022
Gilles Peskine449bd832023-01-11 14:50:10 +01002023 if (verbose != 0) {
2024 mbedtls_printf(" AES-CTR-128 (%s): ",
2025 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2026 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002027
Gilles Peskine449bd832023-01-11 14:50:10 +01002028 memcpy(nonce_counter, aes_test_ctr_nonce_counter[u], 16);
2029 memcpy(key, aes_test_ctr_key[u], 16);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002030
2031 offset = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +01002032 if ((ret = mbedtls_aes_setkey_enc(&ctx, key, 128)) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002033 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002034 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002035
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002036 len = aes_test_ctr_len[u];
2037
Gilles Peskine449bd832023-01-11 14:50:10 +01002038 if (mode == MBEDTLS_AES_DECRYPT) {
2039 memcpy(buf, aes_test_ctr_ct[u], len);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002040 aes_tests = aes_test_ctr_pt[u];
Gilles Peskine449bd832023-01-11 14:50:10 +01002041 } else {
2042 memcpy(buf, aes_test_ctr_pt[u], len);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002043 aes_tests = aes_test_ctr_ct[u];
2044 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002045
Gilles Peskine449bd832023-01-11 14:50:10 +01002046 ret = mbedtls_aes_crypt_ctr(&ctx, len, &offset, nonce_counter,
2047 stream_block, buf, buf);
2048 if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002049 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002050 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002051
Gilles Peskine449bd832023-01-11 14:50:10 +01002052 if (memcmp(buf, aes_tests, len) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002053 ret = 1;
2054 goto exit;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002055 }
2056
Gilles Peskine449bd832023-01-11 14:50:10 +01002057 if (verbose != 0) {
2058 mbedtls_printf("passed\n");
2059 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002060 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002061
Gilles Peskine449bd832023-01-11 14:50:10 +01002062 if (verbose != 0) {
2063 mbedtls_printf("\n");
2064 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002065#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00002066
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002067#if defined(MBEDTLS_CIPHER_MODE_XTS)
2068 {
Gilles Peskine449bd832023-01-11 14:50:10 +01002069 static const int num_tests =
2070 sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key);
2071 mbedtls_aes_xts_context ctx_xts;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002072
Gilles Peskine449bd832023-01-11 14:50:10 +01002073 /*
2074 * XTS mode
2075 */
2076 mbedtls_aes_xts_init(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002077
Gilles Peskine449bd832023-01-11 14:50:10 +01002078 for (i = 0; i < num_tests << 1; i++) {
2079 const unsigned char *data_unit;
2080 u = i >> 1;
2081 mode = i & 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002082
Gilles Peskine449bd832023-01-11 14:50:10 +01002083 if (verbose != 0) {
2084 mbedtls_printf(" AES-XTS-128 (%s): ",
2085 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2086 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002087
Gilles Peskine449bd832023-01-11 14:50:10 +01002088 memset(key, 0, sizeof(key));
2089 memcpy(key, aes_test_xts_key[u], 32);
2090 data_unit = aes_test_xts_data_unit[u];
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002091
Gilles Peskine449bd832023-01-11 14:50:10 +01002092 len = sizeof(*aes_test_xts_ct32);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002093
Gilles Peskine449bd832023-01-11 14:50:10 +01002094 if (mode == MBEDTLS_AES_DECRYPT) {
2095 ret = mbedtls_aes_xts_setkey_dec(&ctx_xts, key, 256);
2096 if (ret != 0) {
2097 goto exit;
2098 }
2099 memcpy(buf, aes_test_xts_ct32[u], len);
2100 aes_tests = aes_test_xts_pt32[u];
2101 } else {
2102 ret = mbedtls_aes_xts_setkey_enc(&ctx_xts, key, 256);
2103 if (ret != 0) {
2104 goto exit;
2105 }
2106 memcpy(buf, aes_test_xts_pt32[u], len);
2107 aes_tests = aes_test_xts_ct32[u];
2108 }
2109
2110
2111 ret = mbedtls_aes_crypt_xts(&ctx_xts, mode, len, data_unit,
2112 buf, buf);
2113 if (ret != 0) {
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002114 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002115 }
2116
2117 if (memcmp(buf, aes_tests, len) != 0) {
2118 ret = 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002119 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002120 }
2121
2122 if (verbose != 0) {
2123 mbedtls_printf("passed\n");
2124 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002125 }
2126
Gilles Peskine449bd832023-01-11 14:50:10 +01002127 if (verbose != 0) {
2128 mbedtls_printf("\n");
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002129 }
2130
Gilles Peskine449bd832023-01-11 14:50:10 +01002131 mbedtls_aes_xts_free(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002132 }
2133#endif /* MBEDTLS_CIPHER_MODE_XTS */
2134
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002135 ret = 0;
2136
2137exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01002138 if (ret != 0 && verbose != 0) {
2139 mbedtls_printf("failed\n");
2140 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002141
Gilles Peskine449bd832023-01-11 14:50:10 +01002142 mbedtls_aes_free(&ctx);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002143
Gilles Peskine449bd832023-01-11 14:50:10 +01002144 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002145}
2146
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002147#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002148
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002149#endif /* MBEDTLS_AES_C */