blob: f0ade21490028f49734043deafdc544b411b3561 [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
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200544#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Gilles Peskine449bd832023-01-11 14:50:10 +0100545 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
546 return mbedtls_aesni_setkey_enc((unsigned char *) RK, key, keybits);
547 }
Manuel Pégourié-Gonnard47a35362013-12-28 20:45:04 +0100548#endif
549
Jerry Yu3f2fb712023-01-10 17:05:42 +0800550#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
551 if (mbedtls_aesce_has_support()) {
552 return mbedtls_aesce_setkey_enc((unsigned char *) RK, key, keybits);
553 }
554#endif
555
Gilles Peskine449bd832023-01-11 14:50:10 +0100556 for (i = 0; i < (keybits >> 5); i++) {
557 RK[i] = MBEDTLS_GET_UINT32_LE(key, i << 2);
Paul Bakker5121ce52009-01-03 21:22:43 +0000558 }
559
Gilles Peskine449bd832023-01-11 14:50:10 +0100560 switch (ctx->nr) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000561 case 10:
562
Gilles Peskine449bd832023-01-11 14:50:10 +0100563 for (i = 0; i < 10; i++, RK += 4) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000564 RK[4] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100565 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[3])]) ^
566 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[3])] << 8) ^
567 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[3])] << 16) ^
568 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[3])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000569
570 RK[5] = RK[1] ^ RK[4];
571 RK[6] = RK[2] ^ RK[5];
572 RK[7] = RK[3] ^ RK[6];
573 }
574 break;
575
576 case 12:
577
Gilles Peskine449bd832023-01-11 14:50:10 +0100578 for (i = 0; i < 8; i++, RK += 6) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000579 RK[6] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100580 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[5])]) ^
581 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[5])] << 8) ^
582 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[5])] << 16) ^
583 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[5])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000584
585 RK[7] = RK[1] ^ RK[6];
586 RK[8] = RK[2] ^ RK[7];
587 RK[9] = RK[3] ^ RK[8];
588 RK[10] = RK[4] ^ RK[9];
589 RK[11] = RK[5] ^ RK[10];
590 }
591 break;
592
593 case 14:
594
Gilles Peskine449bd832023-01-11 14:50:10 +0100595 for (i = 0; i < 7; i++, RK += 8) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000596 RK[8] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100597 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[7])]) ^
598 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[7])] << 8) ^
599 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[7])] << 16) ^
600 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[7])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000601
602 RK[9] = RK[1] ^ RK[8];
603 RK[10] = RK[2] ^ RK[9];
604 RK[11] = RK[3] ^ RK[10];
605
606 RK[12] = RK[4] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100607 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[11])]) ^
608 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[11])] << 8) ^
609 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[11])] << 16) ^
610 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[11])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000611
612 RK[13] = RK[5] ^ RK[12];
613 RK[14] = RK[6] ^ RK[13];
614 RK[15] = RK[7] ^ RK[14];
615 }
616 break;
Paul Bakker5121ce52009-01-03 21:22:43 +0000617 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000618
Gilles Peskine449bd832023-01-11 14:50:10 +0100619 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000620}
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200621#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000622
623/*
624 * AES key schedule (decryption)
625 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200626#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100627int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
628 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000629{
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200630 int i, j, ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200631 mbedtls_aes_context cty;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000632 uint32_t *RK;
633 uint32_t *SK;
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200634
Gilles Peskine449bd832023-01-11 14:50:10 +0100635 mbedtls_aes_init(&cty);
Paul Bakker5121ce52009-01-03 21:22:43 +0000636
Werner Lewis7656a372022-06-13 12:28:20 +0100637 ctx->rk_offset = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200638#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_PADLOCK_ALIGN16)
Gilles Peskine449bd832023-01-11 14:50:10 +0100639 if (aes_padlock_ace == -1) {
640 aes_padlock_ace = mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE);
641 }
Paul Bakker048d04e2012-02-12 17:31:04 +0000642
Gilles Peskine449bd832023-01-11 14:50:10 +0100643 if (aes_padlock_ace) {
644 ctx->rk_offset = MBEDTLS_PADLOCK_ALIGN16(ctx->buf) - ctx->buf;
645 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000646#endif
Werner Lewisdd76ef32022-05-30 12:00:21 +0100647 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000648
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200649 /* Also checks keybits */
Gilles Peskine449bd832023-01-11 14:50:10 +0100650 if ((ret = mbedtls_aes_setkey_enc(&cty, key, keybits)) != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200651 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100652 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000653
Manuel Pégourié-Gonnardafd5a082014-05-28 21:52:59 +0200654 ctx->nr = cty.nr;
655
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200656#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Gilles Peskine449bd832023-01-11 14:50:10 +0100657 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
658 mbedtls_aesni_inverse_key((unsigned char *) RK,
659 (const unsigned char *) (cty.buf + cty.rk_offset), ctx->nr);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200660 goto exit;
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100661 }
662#endif
663
Werner Lewisdd76ef32022-05-30 12:00:21 +0100664 SK = cty.buf + cty.rk_offset + cty.nr * 4;
Paul Bakker5121ce52009-01-03 21:22:43 +0000665
666 *RK++ = *SK++;
667 *RK++ = *SK++;
668 *RK++ = *SK++;
669 *RK++ = *SK++;
670
Gilles Peskine449bd832023-01-11 14:50:10 +0100671 for (i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8) {
672 for (j = 0; j < 4; j++, SK++) {
673 *RK++ = AES_RT0(FSb[MBEDTLS_BYTE_0(*SK)]) ^
674 AES_RT1(FSb[MBEDTLS_BYTE_1(*SK)]) ^
675 AES_RT2(FSb[MBEDTLS_BYTE_2(*SK)]) ^
676 AES_RT3(FSb[MBEDTLS_BYTE_3(*SK)]);
Paul Bakker5121ce52009-01-03 21:22:43 +0000677 }
678 }
679
680 *RK++ = *SK++;
681 *RK++ = *SK++;
682 *RK++ = *SK++;
683 *RK++ = *SK++;
684
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200685exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100686 mbedtls_aes_free(&cty);
Paul Bakker2b222c82009-07-27 21:03:45 +0000687
Gilles Peskine449bd832023-01-11 14:50:10 +0100688 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000689}
gabor-mezei-arm95db3012020-10-26 11:35:23 +0100690#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */
Jaeden Amero9366feb2018-05-29 18:55:17 +0100691
692#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100693static int mbedtls_aes_xts_decode_keys(const unsigned char *key,
694 unsigned int keybits,
695 const unsigned char **key1,
696 unsigned int *key1bits,
697 const unsigned char **key2,
698 unsigned int *key2bits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100699{
700 const unsigned int half_keybits = keybits / 2;
701 const unsigned int half_keybytes = half_keybits / 8;
702
Gilles Peskine449bd832023-01-11 14:50:10 +0100703 switch (keybits) {
Jaeden Amero9366feb2018-05-29 18:55:17 +0100704 case 256: break;
705 case 512: break;
Gilles Peskine449bd832023-01-11 14:50:10 +0100706 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100707 }
708
709 *key1bits = half_keybits;
710 *key2bits = half_keybits;
711 *key1 = &key[0];
712 *key2 = &key[half_keybytes];
713
714 return 0;
715}
716
Gilles Peskine449bd832023-01-11 14:50:10 +0100717int mbedtls_aes_xts_setkey_enc(mbedtls_aes_xts_context *ctx,
718 const unsigned char *key,
719 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100720{
Janos Follath24eed8d2019-11-22 13:21:35 +0000721 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100722 const unsigned char *key1, *key2;
723 unsigned int key1bits, key2bits;
724
Gilles Peskine449bd832023-01-11 14:50:10 +0100725 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
726 &key2, &key2bits);
727 if (ret != 0) {
728 return ret;
729 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100730
731 /* Set the tweak key. Always set tweak key for the encryption mode. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100732 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
733 if (ret != 0) {
734 return ret;
735 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100736
737 /* Set crypt key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100738 return mbedtls_aes_setkey_enc(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100739}
740
Gilles Peskine449bd832023-01-11 14:50:10 +0100741int mbedtls_aes_xts_setkey_dec(mbedtls_aes_xts_context *ctx,
742 const unsigned char *key,
743 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100744{
Janos Follath24eed8d2019-11-22 13:21:35 +0000745 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100746 const unsigned char *key1, *key2;
747 unsigned int key1bits, key2bits;
748
Gilles Peskine449bd832023-01-11 14:50:10 +0100749 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
750 &key2, &key2bits);
751 if (ret != 0) {
752 return ret;
753 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100754
755 /* Set the tweak key. Always set tweak key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100756 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
757 if (ret != 0) {
758 return ret;
759 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100760
761 /* Set crypt key for decryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100762 return mbedtls_aes_setkey_dec(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100763}
764#endif /* MBEDTLS_CIPHER_MODE_XTS */
765
Gilles Peskine449bd832023-01-11 14:50:10 +0100766#define AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Joe Subbianicd84d762021-07-08 14:59:52 +0100767 do \
768 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100769 (X0) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y0)) ^ \
770 AES_FT1(MBEDTLS_BYTE_1(Y1)) ^ \
771 AES_FT2(MBEDTLS_BYTE_2(Y2)) ^ \
772 AES_FT3(MBEDTLS_BYTE_3(Y3)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100773 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100774 (X1) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y1)) ^ \
775 AES_FT1(MBEDTLS_BYTE_1(Y2)) ^ \
776 AES_FT2(MBEDTLS_BYTE_2(Y3)) ^ \
777 AES_FT3(MBEDTLS_BYTE_3(Y0)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100778 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100779 (X2) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y2)) ^ \
780 AES_FT1(MBEDTLS_BYTE_1(Y3)) ^ \
781 AES_FT2(MBEDTLS_BYTE_2(Y0)) ^ \
782 AES_FT3(MBEDTLS_BYTE_3(Y1)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100783 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100784 (X3) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y3)) ^ \
785 AES_FT1(MBEDTLS_BYTE_1(Y0)) ^ \
786 AES_FT2(MBEDTLS_BYTE_2(Y1)) ^ \
787 AES_FT3(MBEDTLS_BYTE_3(Y2)); \
788 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000789
Gilles Peskine449bd832023-01-11 14:50:10 +0100790#define AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100791 do \
792 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100793 (X0) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y0)) ^ \
794 AES_RT1(MBEDTLS_BYTE_1(Y3)) ^ \
795 AES_RT2(MBEDTLS_BYTE_2(Y2)) ^ \
796 AES_RT3(MBEDTLS_BYTE_3(Y1)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100797 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100798 (X1) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y1)) ^ \
799 AES_RT1(MBEDTLS_BYTE_1(Y0)) ^ \
800 AES_RT2(MBEDTLS_BYTE_2(Y3)) ^ \
801 AES_RT3(MBEDTLS_BYTE_3(Y2)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100802 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100803 (X2) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y2)) ^ \
804 AES_RT1(MBEDTLS_BYTE_1(Y1)) ^ \
805 AES_RT2(MBEDTLS_BYTE_2(Y0)) ^ \
806 AES_RT3(MBEDTLS_BYTE_3(Y3)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100807 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100808 (X3) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y3)) ^ \
809 AES_RT1(MBEDTLS_BYTE_1(Y2)) ^ \
810 AES_RT2(MBEDTLS_BYTE_2(Y1)) ^ \
811 AES_RT3(MBEDTLS_BYTE_3(Y0)); \
812 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000813
814/*
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200815 * AES-ECB block encryption
816 */
817#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100818int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx,
819 const unsigned char input[16],
820 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200821{
822 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100823 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100824 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200825 uint32_t X[4];
826 uint32_t Y[4];
827 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200828
Gilles Peskine449bd832023-01-11 14:50:10 +0100829 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
830 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
831 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
832 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200833
Gilles Peskine449bd832023-01-11 14:50:10 +0100834 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
835 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]);
836 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 +0200837 }
838
Gilles Peskine449bd832023-01-11 14:50:10 +0100839 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 +0200840
Gilles Peskine5197c662020-08-26 17:03:24 +0200841 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100842 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
843 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
844 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
845 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200846
Gilles Peskine5197c662020-08-26 17:03:24 +0200847 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100848 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
849 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
850 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
851 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200852
Gilles Peskine5197c662020-08-26 17:03:24 +0200853 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100854 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
855 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
856 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
857 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200858
Gilles Peskine5197c662020-08-26 17:03:24 +0200859 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100860 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
861 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
862 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
863 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200864
Gilles Peskine449bd832023-01-11 14:50:10 +0100865 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
866 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
867 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
868 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +0000869
Gilles Peskine449bd832023-01-11 14:50:10 +0100870 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500871
Gilles Peskine449bd832023-01-11 14:50:10 +0100872 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200873}
874#endif /* !MBEDTLS_AES_ENCRYPT_ALT */
875
876/*
877 * AES-ECB block decryption
878 */
879#if !defined(MBEDTLS_AES_DECRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100880int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
881 const unsigned char input[16],
882 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200883{
884 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100885 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100886 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200887 uint32_t X[4];
888 uint32_t Y[4];
889 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200890
Gilles Peskine449bd832023-01-11 14:50:10 +0100891 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
892 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
893 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
894 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200895
Gilles Peskine449bd832023-01-11 14:50:10 +0100896 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
897 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]);
898 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 +0200899 }
900
Gilles Peskine449bd832023-01-11 14:50:10 +0100901 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 +0200902
Gilles Peskine5197c662020-08-26 17:03:24 +0200903 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100904 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
905 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
906 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
907 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200908
Gilles Peskine5197c662020-08-26 17:03:24 +0200909 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100910 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
911 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
912 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
913 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200914
Gilles Peskine5197c662020-08-26 17:03:24 +0200915 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100916 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
917 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
918 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
919 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200920
Gilles Peskine5197c662020-08-26 17:03:24 +0200921 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100922 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
923 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
924 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
925 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200926
Gilles Peskine449bd832023-01-11 14:50:10 +0100927 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
928 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
929 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
930 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +0000931
Gilles Peskine449bd832023-01-11 14:50:10 +0100932 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500933
Gilles Peskine449bd832023-01-11 14:50:10 +0100934 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200935}
936#endif /* !MBEDTLS_AES_DECRYPT_ALT */
937
938/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000939 * AES-ECB block encryption/decryption
940 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100941int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
942 int mode,
943 const unsigned char input[16],
944 unsigned char output[16])
Paul Bakker5121ce52009-01-03 21:22:43 +0000945{
Gilles Peskine449bd832023-01-11 14:50:10 +0100946 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +0100947 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100948 }
Manuel Pégourié-Gonnard1aca2602018-12-12 12:56:55 +0100949
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200950#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Gilles Peskine449bd832023-01-11 14:50:10 +0100951 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
952 return mbedtls_aesni_crypt_ecb(ctx, mode, input, output);
953 }
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +0100954#endif
955
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200956#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Gilles Peskine449bd832023-01-11 14:50:10 +0100957 if (aes_padlock_ace > 0) {
958 if (mbedtls_padlock_xcryptecb(ctx, mode, input, output) == 0) {
959 return 0;
960 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000961
962 // If padlock data misaligned, we just fall back to
963 // unaccelerated mode
964 //
Paul Bakker5121ce52009-01-03 21:22:43 +0000965 }
966#endif
967
Gilles Peskine449bd832023-01-11 14:50:10 +0100968 if (mode == MBEDTLS_AES_ENCRYPT) {
969 return mbedtls_internal_aes_encrypt(ctx, input, output);
970 } else {
971 return mbedtls_internal_aes_decrypt(ctx, input, output);
972 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000973}
974
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200975#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000976/*
977 * AES-CBC buffer encryption/decryption
978 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100979int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
980 int mode,
981 size_t length,
982 unsigned char iv[16],
983 const unsigned char *input,
984 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +0000985{
Gilles Peskine7820a572021-07-07 21:08:28 +0200986 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +0000987 unsigned char temp[16];
988
Gilles Peskine449bd832023-01-11 14:50:10 +0100989 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +0100990 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100991 }
Manuel Pégourié-Gonnard3178d1a2018-12-12 13:05:00 +0100992
Gilles Peskine449bd832023-01-11 14:50:10 +0100993 if (length % 16) {
994 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
995 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000996
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200997#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Gilles Peskine449bd832023-01-11 14:50:10 +0100998 if (aes_padlock_ace > 0) {
999 if (mbedtls_padlock_xcryptcbc(ctx, mode, length, iv, input, output) == 0) {
1000 return 0;
1001 }
Paul Bakker9af723c2014-05-01 13:03:14 +02001002
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001003 // If padlock data misaligned, we just fall back to
1004 // unaccelerated mode
1005 //
Paul Bakker5121ce52009-01-03 21:22:43 +00001006 }
1007#endif
1008
Gilles Peskine449bd832023-01-11 14:50:10 +01001009 if (mode == MBEDTLS_AES_DECRYPT) {
1010 while (length > 0) {
1011 memcpy(temp, input, 16);
1012 ret = mbedtls_aes_crypt_ecb(ctx, mode, input, output);
1013 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001014 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001015 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001016
Gilles Peskine449bd832023-01-11 14:50:10 +01001017 mbedtls_xor(output, output, iv, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001018
Gilles Peskine449bd832023-01-11 14:50:10 +01001019 memcpy(iv, temp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001020
1021 input += 16;
1022 output += 16;
1023 length -= 16;
1024 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001025 } else {
1026 while (length > 0) {
1027 mbedtls_xor(output, input, iv, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001028
Gilles Peskine449bd832023-01-11 14:50:10 +01001029 ret = mbedtls_aes_crypt_ecb(ctx, mode, output, output);
1030 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001031 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001032 }
1033 memcpy(iv, output, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001034
1035 input += 16;
1036 output += 16;
1037 length -= 16;
1038 }
1039 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001040 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001041
Gilles Peskine7820a572021-07-07 21:08:28 +02001042exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001043 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001044}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001045#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001046
Aorimn5f778012016-06-09 23:22:58 +02001047#if defined(MBEDTLS_CIPHER_MODE_XTS)
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001048
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001049typedef unsigned char mbedtls_be128[16];
1050
1051/*
1052 * GF(2^128) multiplication function
1053 *
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001054 * This function multiplies a field element by x in the polynomial field
1055 * representation. It uses 64-bit word operations to gain speed but compensates
Shaun Case8b0ecbc2021-12-20 21:14:10 -08001056 * for machine endianness and hence works correctly on both big and little
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001057 * endian machines.
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001058 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001059static void mbedtls_gf128mul_x_ble(unsigned char r[16],
1060 const unsigned char x[16])
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001061{
1062 uint64_t a, b, ra, rb;
1063
Gilles Peskine449bd832023-01-11 14:50:10 +01001064 a = MBEDTLS_GET_UINT64_LE(x, 0);
1065 b = MBEDTLS_GET_UINT64_LE(x, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001066
Gilles Peskine449bd832023-01-11 14:50:10 +01001067 ra = (a << 1) ^ 0x0087 >> (8 - ((b >> 63) << 3));
1068 rb = (a >> 63) | (b << 1);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001069
Gilles Peskine449bd832023-01-11 14:50:10 +01001070 MBEDTLS_PUT_UINT64_LE(ra, r, 0);
1071 MBEDTLS_PUT_UINT64_LE(rb, r, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001072}
1073
Aorimn5f778012016-06-09 23:22:58 +02001074/*
1075 * AES-XTS buffer encryption/decryption
1076 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001077int mbedtls_aes_crypt_xts(mbedtls_aes_xts_context *ctx,
1078 int mode,
1079 size_t length,
1080 const unsigned char data_unit[16],
1081 const unsigned char *input,
1082 unsigned char *output)
Aorimn5f778012016-06-09 23:22:58 +02001083{
Janos Follath24eed8d2019-11-22 13:21:35 +00001084 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amerod82cd862018-04-28 15:02:45 +01001085 size_t blocks = length / 16;
1086 size_t leftover = length % 16;
1087 unsigned char tweak[16];
1088 unsigned char prev_tweak[16];
1089 unsigned char tmp[16];
Aorimn5f778012016-06-09 23:22:58 +02001090
Gilles Peskine449bd832023-01-11 14:50:10 +01001091 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001092 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001093 }
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01001094
Jaeden Amero8381fcb2018-10-11 12:06:15 +01001095 /* Data units must be at least 16 bytes long. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001096 if (length < 16) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001097 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001098 }
Aorimn5f778012016-06-09 23:22:58 +02001099
Jaeden Ameroa74faba2018-10-11 12:07:43 +01001100 /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001101 if (length > (1 << 20) * 16) {
Jaeden Amero0a8b0202018-05-30 15:36:06 +01001102 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001103 }
Aorimn5f778012016-06-09 23:22:58 +02001104
Jaeden Amerod82cd862018-04-28 15:02:45 +01001105 /* Compute the tweak. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001106 ret = mbedtls_aes_crypt_ecb(&ctx->tweak, MBEDTLS_AES_ENCRYPT,
1107 data_unit, tweak);
1108 if (ret != 0) {
1109 return ret;
1110 }
Aorimn5f778012016-06-09 23:22:58 +02001111
Gilles Peskine449bd832023-01-11 14:50:10 +01001112 while (blocks--) {
1113 if (leftover && (mode == MBEDTLS_AES_DECRYPT) && blocks == 0) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001114 /* We are on the last block in a decrypt operation that has
1115 * leftover bytes, so we need to use the next tweak for this block,
Tom Cosgrove1797b052022-12-04 17:19:59 +00001116 * and this tweak for the leftover bytes. Save the current tweak for
Jaeden Amerod82cd862018-04-28 15:02:45 +01001117 * the leftovers and then update the current tweak for use on this,
1118 * the last full block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001119 memcpy(prev_tweak, tweak, sizeof(tweak));
1120 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001121 }
1122
Gilles Peskine449bd832023-01-11 14:50:10 +01001123 mbedtls_xor(tmp, input, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001124
Gilles Peskine449bd832023-01-11 14:50:10 +01001125 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1126 if (ret != 0) {
1127 return ret;
1128 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001129
Gilles Peskine449bd832023-01-11 14:50:10 +01001130 mbedtls_xor(output, tmp, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001131
1132 /* Update the tweak for the next block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001133 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001134
1135 output += 16;
1136 input += 16;
Aorimn5f778012016-06-09 23:22:58 +02001137 }
1138
Gilles Peskine449bd832023-01-11 14:50:10 +01001139 if (leftover) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001140 /* If we are on the leftover bytes in a decrypt operation, we need to
1141 * use the previous tweak for these bytes (as saved in prev_tweak). */
1142 unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
Aorimn5f778012016-06-09 23:22:58 +02001143
Jaeden Amerod82cd862018-04-28 15:02:45 +01001144 /* We are now on the final part of the data unit, which doesn't divide
1145 * evenly by 16. It's time for ciphertext stealing. */
1146 size_t i;
1147 unsigned char *prev_output = output - 16;
Aorimn5f778012016-06-09 23:22:58 +02001148
Jaeden Amerod82cd862018-04-28 15:02:45 +01001149 /* Copy ciphertext bytes from the previous block to our output for each
Dave Rodgman069e7f42022-11-24 19:37:26 +00001150 * byte of ciphertext we won't steal. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001151 for (i = 0; i < leftover; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001152 output[i] = prev_output[i];
Aorimn5f778012016-06-09 23:22:58 +02001153 }
Aorimn5f778012016-06-09 23:22:58 +02001154
Dave Rodgman069e7f42022-11-24 19:37:26 +00001155 /* Copy the remainder of the input for this final round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001156 mbedtls_xor(tmp, input, t, leftover);
Dave Rodgmana8cf6072022-11-22 15:02:54 +00001157
Jaeden Amerod82cd862018-04-28 15:02:45 +01001158 /* Copy ciphertext bytes from the previous block for input in this
1159 * round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001160 mbedtls_xor(tmp + i, prev_output + i, t + i, 16 - i);
Aorimn5f778012016-06-09 23:22:58 +02001161
Gilles Peskine449bd832023-01-11 14:50:10 +01001162 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1163 if (ret != 0) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001164 return ret;
Gilles Peskine449bd832023-01-11 14:50:10 +01001165 }
Aorimn5f778012016-06-09 23:22:58 +02001166
Jaeden Amerod82cd862018-04-28 15:02:45 +01001167 /* Write the result back to the previous block, overriding the previous
1168 * output we copied. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001169 mbedtls_xor(prev_output, tmp, t, 16);
Aorimn5f778012016-06-09 23:22:58 +02001170 }
1171
Gilles Peskine449bd832023-01-11 14:50:10 +01001172 return 0;
Aorimn5f778012016-06-09 23:22:58 +02001173}
1174#endif /* MBEDTLS_CIPHER_MODE_XTS */
1175
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001176#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001177/*
1178 * AES-CFB128 buffer encryption/decryption
1179 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001180int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx,
1181 int mode,
1182 size_t length,
1183 size_t *iv_off,
1184 unsigned char iv[16],
1185 const unsigned char *input,
1186 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001187{
Paul Bakker27fdf462011-06-09 13:55:13 +00001188 int c;
Gilles Peskine7820a572021-07-07 21:08:28 +02001189 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001190 size_t n;
1191
Gilles Peskine449bd832023-01-11 14:50:10 +01001192 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001193 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001194 }
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001195
1196 n = *iv_off;
Paul Bakker5121ce52009-01-03 21:22:43 +00001197
Gilles Peskine449bd832023-01-11 14:50:10 +01001198 if (n > 15) {
1199 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1200 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001201
Gilles Peskine449bd832023-01-11 14:50:10 +01001202 if (mode == MBEDTLS_AES_DECRYPT) {
1203 while (length--) {
1204 if (n == 0) {
1205 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1206 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001207 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001208 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001209 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001210
1211 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001212 *output++ = (unsigned char) (c ^ iv[n]);
Paul Bakker5121ce52009-01-03 21:22:43 +00001213 iv[n] = (unsigned char) c;
1214
Gilles Peskine449bd832023-01-11 14:50:10 +01001215 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001216 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001217 } else {
1218 while (length--) {
1219 if (n == 0) {
1220 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1221 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001222 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001223 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001224 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001225
Gilles Peskine449bd832023-01-11 14:50:10 +01001226 iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++);
Paul Bakker5121ce52009-01-03 21:22:43 +00001227
Gilles Peskine449bd832023-01-11 14:50:10 +01001228 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001229 }
1230 }
1231
1232 *iv_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001233 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001234
Gilles Peskine7820a572021-07-07 21:08:28 +02001235exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001236 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001237}
Paul Bakker556efba2014-01-24 15:38:12 +01001238
1239/*
1240 * AES-CFB8 buffer encryption/decryption
1241 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001242int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx,
1243 int mode,
1244 size_t length,
1245 unsigned char iv[16],
1246 const unsigned char *input,
1247 unsigned char *output)
Paul Bakker556efba2014-01-24 15:38:12 +01001248{
Gilles Peskine7820a572021-07-07 21:08:28 +02001249 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker556efba2014-01-24 15:38:12 +01001250 unsigned char c;
1251 unsigned char ov[17];
1252
Gilles Peskine449bd832023-01-11 14:50:10 +01001253 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001254 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001255 }
1256 while (length--) {
1257 memcpy(ov, iv, 16);
1258 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1259 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001260 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001261 }
Paul Bakker556efba2014-01-24 15:38:12 +01001262
Gilles Peskine449bd832023-01-11 14:50:10 +01001263 if (mode == MBEDTLS_AES_DECRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001264 ov[16] = *input;
Gilles Peskine449bd832023-01-11 14:50:10 +01001265 }
Paul Bakker556efba2014-01-24 15:38:12 +01001266
Gilles Peskine449bd832023-01-11 14:50:10 +01001267 c = *output++ = (unsigned char) (iv[0] ^ *input++);
Paul Bakker556efba2014-01-24 15:38:12 +01001268
Gilles Peskine449bd832023-01-11 14:50:10 +01001269 if (mode == MBEDTLS_AES_ENCRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001270 ov[16] = c;
Gilles Peskine449bd832023-01-11 14:50:10 +01001271 }
Paul Bakker556efba2014-01-24 15:38:12 +01001272
Gilles Peskine449bd832023-01-11 14:50:10 +01001273 memcpy(iv, ov + 1, 16);
Paul Bakker556efba2014-01-24 15:38:12 +01001274 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001275 ret = 0;
Paul Bakker556efba2014-01-24 15:38:12 +01001276
Gilles Peskine7820a572021-07-07 21:08:28 +02001277exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001278 return ret;
Paul Bakker556efba2014-01-24 15:38:12 +01001279}
Simon Butcher76a5b222018-04-22 22:57:27 +01001280#endif /* MBEDTLS_CIPHER_MODE_CFB */
1281
1282#if defined(MBEDTLS_CIPHER_MODE_OFB)
1283/*
1284 * AES-OFB (Output Feedback Mode) buffer encryption/decryption
1285 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001286int mbedtls_aes_crypt_ofb(mbedtls_aes_context *ctx,
1287 size_t length,
1288 size_t *iv_off,
1289 unsigned char iv[16],
1290 const unsigned char *input,
1291 unsigned char *output)
Simon Butcher76a5b222018-04-22 22:57:27 +01001292{
Simon Butcherad4e4932018-04-29 00:43:47 +01001293 int ret = 0;
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001294 size_t n;
1295
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001296 n = *iv_off;
Simon Butcher76a5b222018-04-22 22:57:27 +01001297
Gilles Peskine449bd832023-01-11 14:50:10 +01001298 if (n > 15) {
1299 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1300 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001301
Gilles Peskine449bd832023-01-11 14:50:10 +01001302 while (length--) {
1303 if (n == 0) {
1304 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1305 if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001306 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001307 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001308 }
Simon Butcher76a5b222018-04-22 22:57:27 +01001309 *output++ = *input++ ^ iv[n];
1310
Gilles Peskine449bd832023-01-11 14:50:10 +01001311 n = (n + 1) & 0x0F;
Simon Butcher76a5b222018-04-22 22:57:27 +01001312 }
1313
1314 *iv_off = n;
1315
Simon Butcherad4e4932018-04-29 00:43:47 +01001316exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001317 return ret;
Simon Butcher76a5b222018-04-22 22:57:27 +01001318}
1319#endif /* MBEDTLS_CIPHER_MODE_OFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001320
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001321#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001322/*
1323 * AES-CTR buffer encryption/decryption
1324 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001325int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
1326 size_t length,
1327 size_t *nc_off,
1328 unsigned char nonce_counter[16],
1329 unsigned char stream_block[16],
1330 const unsigned char *input,
1331 unsigned char *output)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001332{
Paul Bakker369e14b2012-04-18 14:16:09 +00001333 int c, i;
Gilles Peskine7820a572021-07-07 21:08:28 +02001334 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001335 size_t n;
1336
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001337 n = *nc_off;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001338
Gilles Peskine449bd832023-01-11 14:50:10 +01001339 if (n > 0x0F) {
1340 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1341 }
Mohammad Azim Khan3f7f8172017-11-23 17:49:05 +00001342
Gilles Peskine449bd832023-01-11 14:50:10 +01001343 while (length--) {
1344 if (n == 0) {
1345 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block);
1346 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001347 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001348 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001349
Gilles Peskine449bd832023-01-11 14:50:10 +01001350 for (i = 16; i > 0; i--) {
1351 if (++nonce_counter[i - 1] != 0) {
Paul Bakker369e14b2012-04-18 14:16:09 +00001352 break;
Gilles Peskine449bd832023-01-11 14:50:10 +01001353 }
1354 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001355 }
1356 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001357 *output++ = (unsigned char) (c ^ stream_block[n]);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001358
Gilles Peskine449bd832023-01-11 14:50:10 +01001359 n = (n + 1) & 0x0F;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001360 }
1361
1362 *nc_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001363 ret = 0;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001364
Gilles Peskine7820a572021-07-07 21:08:28 +02001365exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001366 return ret;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001367}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001368#endif /* MBEDTLS_CIPHER_MODE_CTR */
Manuel Pégourié-Gonnard1ec220b2014-03-10 11:20:17 +01001369
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001370#endif /* !MBEDTLS_AES_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001371
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001372#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001373/*
1374 * AES test vectors from:
1375 *
1376 * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
1377 */
1378static const unsigned char aes_test_ecb_dec[3][16] =
1379{
1380 { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
1381 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
1382 { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
1383 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
1384 { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
1385 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
1386};
1387
1388static const unsigned char aes_test_ecb_enc[3][16] =
1389{
1390 { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
1391 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
1392 { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
1393 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
1394 { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
1395 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
1396};
1397
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001398#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001399static const unsigned char aes_test_cbc_dec[3][16] =
1400{
1401 { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
1402 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
1403 { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
1404 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
1405 { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
1406 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
1407};
1408
1409static const unsigned char aes_test_cbc_enc[3][16] =
1410{
1411 { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
1412 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
1413 { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
1414 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
1415 { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
1416 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
1417};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001418#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001419
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001420#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001421/*
1422 * AES-CFB128 test vectors from:
1423 *
1424 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
1425 */
1426static const unsigned char aes_test_cfb128_key[3][32] =
1427{
1428 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1429 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
1430 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1431 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1432 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1433 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1434 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1435 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1436 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
1437};
1438
1439static const unsigned char aes_test_cfb128_iv[16] =
1440{
1441 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1442 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1443};
1444
1445static const unsigned char aes_test_cfb128_pt[64] =
1446{
1447 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1448 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1449 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1450 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1451 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1452 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1453 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1454 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1455};
1456
1457static const unsigned char aes_test_cfb128_ct[3][64] =
1458{
1459 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1460 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1461 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F,
1462 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B,
1463 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40,
1464 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF,
1465 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E,
1466 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 },
1467 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1468 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1469 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21,
1470 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A,
1471 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1,
1472 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9,
1473 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0,
1474 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF },
1475 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1476 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1477 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8,
1478 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B,
1479 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92,
1480 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9,
1481 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8,
1482 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 }
1483};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001484#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001485
Simon Butcherad4e4932018-04-29 00:43:47 +01001486#if defined(MBEDTLS_CIPHER_MODE_OFB)
1487/*
1488 * AES-OFB test vectors from:
1489 *
Simon Butcher5db13622018-06-04 22:11:25 +01001490 * https://csrc.nist.gov/publications/detail/sp/800-38a/final
Simon Butcherad4e4932018-04-29 00:43:47 +01001491 */
1492static const unsigned char aes_test_ofb_key[3][32] =
1493{
1494 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1495 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
1496 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1497 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1498 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1499 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1500 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1501 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1502 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
1503};
1504
1505static const unsigned char aes_test_ofb_iv[16] =
1506{
1507 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1508 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1509};
1510
1511static const unsigned char aes_test_ofb_pt[64] =
1512{
1513 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1514 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1515 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1516 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1517 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1518 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1519 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1520 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1521};
1522
1523static const unsigned char aes_test_ofb_ct[3][64] =
1524{
1525 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1526 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1527 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
1528 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
1529 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
1530 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
1531 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
1532 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e },
1533 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1534 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1535 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
1536 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
1537 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f,
1538 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
1539 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e,
1540 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a },
1541 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1542 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1543 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
1544 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
1545 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed,
1546 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
1547 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8,
1548 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 }
1549};
1550#endif /* MBEDTLS_CIPHER_MODE_OFB */
1551
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001552#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001553/*
1554 * AES-CTR test vectors from:
1555 *
1556 * http://www.faqs.org/rfcs/rfc3686.html
1557 */
1558
1559static const unsigned char aes_test_ctr_key[3][16] =
1560{
1561 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
1562 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
1563 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
1564 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
1565 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
1566 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
1567};
1568
1569static const unsigned char aes_test_ctr_nonce_counter[3][16] =
1570{
1571 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
1572 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
1573 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
1574 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
1575 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
1576 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
1577};
1578
1579static const unsigned char aes_test_ctr_pt[3][48] =
1580{
1581 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
1582 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
1583
1584 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1585 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1586 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1587 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
1588
1589 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1590 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1591 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1592 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
1593 0x20, 0x21, 0x22, 0x23 }
1594};
1595
1596static const unsigned char aes_test_ctr_ct[3][48] =
1597{
1598 { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79,
1599 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 },
1600 { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9,
1601 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88,
1602 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8,
1603 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 },
1604 { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
1605 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
1606 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
1607 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
1608 0x25, 0xB2, 0x07, 0x2F }
1609};
1610
1611static const int aes_test_ctr_len[3] =
Gilles Peskine449bd832023-01-11 14:50:10 +01001612{ 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001613#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00001614
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001615#if defined(MBEDTLS_CIPHER_MODE_XTS)
1616/*
1617 * AES-XTS test vectors from:
1618 *
1619 * IEEE P1619/D16 Annex B
1620 * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf
1621 * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf)
1622 */
1623static const unsigned char aes_test_xts_key[][32] =
1624{
1625 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1626 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1627 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1628 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1629 { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1630 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1631 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1632 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1633 { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
1634 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
1635 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1636 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1637};
1638
1639static const unsigned char aes_test_xts_pt32[][32] =
1640{
1641 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1642 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1643 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1644 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1645 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1646 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1647 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1648 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1649 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1650 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1651 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1652 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1653};
1654
1655static const unsigned char aes_test_xts_ct32[][32] =
1656{
1657 { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec,
1658 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92,
1659 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85,
1660 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e },
1661 { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e,
1662 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b,
1663 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4,
1664 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 },
1665 { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a,
1666 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2,
1667 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53,
1668 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 },
1669};
1670
1671static const unsigned char aes_test_xts_data_unit[][16] =
1672{
Gilles Peskine449bd832023-01-11 14:50:10 +01001673 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1674 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1675 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1676 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1677 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1678 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001679};
1680
1681#endif /* MBEDTLS_CIPHER_MODE_XTS */
1682
Paul Bakker5121ce52009-01-03 21:22:43 +00001683/*
1684 * Checkup routine
1685 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001686int mbedtls_aes_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +00001687{
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001688 int ret = 0, i, j, u, mode;
1689 unsigned int keybits;
Paul Bakker5121ce52009-01-03 21:22:43 +00001690 unsigned char key[32];
1691 unsigned char buf[64];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001692 const unsigned char *aes_tests;
Andrzej Kurek252283f2022-09-27 07:54:16 -04001693#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1694 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001695 unsigned char iv[16];
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03001696#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001697#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +02001698 unsigned char prv[16];
1699#endif
Simon Butcher2ff0e522018-06-14 09:57:07 +01001700#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1701 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker27fdf462011-06-09 13:55:13 +00001702 size_t offset;
Paul Bakkere91d01e2011-04-19 15:55:50 +00001703#endif
Simon Butcher66a89032018-06-15 18:20:29 +01001704#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS)
Paul Bakkere91d01e2011-04-19 15:55:50 +00001705 int len;
Simon Butcher66a89032018-06-15 18:20:29 +01001706#endif
1707#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001708 unsigned char nonce_counter[16];
1709 unsigned char stream_block[16];
1710#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001711 mbedtls_aes_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001712
Gilles Peskine449bd832023-01-11 14:50:10 +01001713 memset(key, 0, 32);
1714 mbedtls_aes_init(&ctx);
Paul Bakker5121ce52009-01-03 21:22:43 +00001715
1716 /*
1717 * ECB mode
1718 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001719 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +00001720 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001721 keybits = 128 + u * 64;
1722 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001723
Gilles Peskine449bd832023-01-11 14:50:10 +01001724 if (verbose != 0) {
1725 mbedtls_printf(" AES-ECB-%3u (%s): ", keybits,
1726 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00001727 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001728
1729 memset(buf, 0, 16);
1730
1731 if (mode == MBEDTLS_AES_DECRYPT) {
1732 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1733 aes_tests = aes_test_ecb_dec[u];
1734 } else {
1735 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001736 aes_tests = aes_test_ecb_enc[u];
1737 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001738
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01001739 /*
1740 * AES-192 is an optional feature that may be unavailable when
1741 * there is an alternative underlying implementation i.e. when
1742 * MBEDTLS_AES_ALT is defined.
1743 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001744 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1745 mbedtls_printf("skipped\n");
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001746 continue;
Gilles Peskine449bd832023-01-11 14:50:10 +01001747 } else if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001748 goto exit;
1749 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001750
Gilles Peskine449bd832023-01-11 14:50:10 +01001751 for (j = 0; j < 10000; j++) {
1752 ret = mbedtls_aes_crypt_ecb(&ctx, mode, buf, buf);
1753 if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001754 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001755 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001756 }
1757
Gilles Peskine449bd832023-01-11 14:50:10 +01001758 if (memcmp(buf, aes_tests, 16) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001759 ret = 1;
1760 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001761 }
1762
Gilles Peskine449bd832023-01-11 14:50:10 +01001763 if (verbose != 0) {
1764 mbedtls_printf("passed\n");
1765 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001766 }
1767
Gilles Peskine449bd832023-01-11 14:50:10 +01001768 if (verbose != 0) {
1769 mbedtls_printf("\n");
1770 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001771
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001772#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001773 /*
1774 * CBC mode
1775 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001776 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +00001777 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001778 keybits = 128 + u * 64;
1779 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001780
Gilles Peskine449bd832023-01-11 14:50:10 +01001781 if (verbose != 0) {
1782 mbedtls_printf(" AES-CBC-%3u (%s): ", keybits,
1783 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00001784 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001785
1786 memset(iv, 0, 16);
1787 memset(prv, 0, 16);
1788 memset(buf, 0, 16);
1789
1790 if (mode == MBEDTLS_AES_DECRYPT) {
1791 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1792 aes_tests = aes_test_cbc_dec[u];
1793 } else {
1794 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001795 aes_tests = aes_test_cbc_enc[u];
1796 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001797
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01001798 /*
1799 * AES-192 is an optional feature that may be unavailable when
1800 * there is an alternative underlying implementation i.e. when
1801 * MBEDTLS_AES_ALT is defined.
1802 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001803 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1804 mbedtls_printf("skipped\n");
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001805 continue;
Gilles Peskine449bd832023-01-11 14:50:10 +01001806 } else if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001807 goto exit;
1808 }
1809
Gilles Peskine449bd832023-01-11 14:50:10 +01001810 for (j = 0; j < 10000; j++) {
1811 if (mode == MBEDTLS_AES_ENCRYPT) {
Paul Bakker5121ce52009-01-03 21:22:43 +00001812 unsigned char tmp[16];
1813
Gilles Peskine449bd832023-01-11 14:50:10 +01001814 memcpy(tmp, prv, 16);
1815 memcpy(prv, buf, 16);
1816 memcpy(buf, tmp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001817 }
1818
Gilles Peskine449bd832023-01-11 14:50:10 +01001819 ret = mbedtls_aes_crypt_cbc(&ctx, mode, 16, iv, buf, buf);
1820 if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001821 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001822 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001823
1824 }
1825
Gilles Peskine449bd832023-01-11 14:50:10 +01001826 if (memcmp(buf, aes_tests, 16) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001827 ret = 1;
1828 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001829 }
1830
Gilles Peskine449bd832023-01-11 14:50:10 +01001831 if (verbose != 0) {
1832 mbedtls_printf("passed\n");
1833 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001834 }
1835
Gilles Peskine449bd832023-01-11 14:50:10 +01001836 if (verbose != 0) {
1837 mbedtls_printf("\n");
1838 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001839#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001840
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001841#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001842 /*
1843 * CFB128 mode
1844 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001845 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +00001846 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001847 keybits = 128 + u * 64;
1848 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001849
Gilles Peskine449bd832023-01-11 14:50:10 +01001850 if (verbose != 0) {
1851 mbedtls_printf(" AES-CFB128-%3u (%s): ", keybits,
1852 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
1853 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001854
Gilles Peskine449bd832023-01-11 14:50:10 +01001855 memcpy(iv, aes_test_cfb128_iv, 16);
1856 memcpy(key, aes_test_cfb128_key[u], keybits / 8);
Paul Bakker5121ce52009-01-03 21:22:43 +00001857
1858 offset = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +01001859 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01001860 /*
1861 * AES-192 is an optional feature that may be unavailable when
1862 * there is an alternative underlying implementation i.e. when
1863 * MBEDTLS_AES_ALT is defined.
1864 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001865 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1866 mbedtls_printf("skipped\n");
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001867 continue;
Gilles Peskine449bd832023-01-11 14:50:10 +01001868 } else if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001869 goto exit;
1870 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001871
Gilles Peskine449bd832023-01-11 14:50:10 +01001872 if (mode == MBEDTLS_AES_DECRYPT) {
1873 memcpy(buf, aes_test_cfb128_ct[u], 64);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001874 aes_tests = aes_test_cfb128_pt;
Gilles Peskine449bd832023-01-11 14:50:10 +01001875 } else {
1876 memcpy(buf, aes_test_cfb128_pt, 64);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001877 aes_tests = aes_test_cfb128_ct[u];
1878 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001879
Gilles Peskine449bd832023-01-11 14:50:10 +01001880 ret = mbedtls_aes_crypt_cfb128(&ctx, mode, 64, &offset, iv, buf, buf);
1881 if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001882 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001883 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001884
Gilles Peskine449bd832023-01-11 14:50:10 +01001885 if (memcmp(buf, aes_tests, 64) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001886 ret = 1;
1887 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001888 }
1889
Gilles Peskine449bd832023-01-11 14:50:10 +01001890 if (verbose != 0) {
1891 mbedtls_printf("passed\n");
1892 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001893 }
1894
Gilles Peskine449bd832023-01-11 14:50:10 +01001895 if (verbose != 0) {
1896 mbedtls_printf("\n");
1897 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001898#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001899
Simon Butcherad4e4932018-04-29 00:43:47 +01001900#if defined(MBEDTLS_CIPHER_MODE_OFB)
1901 /*
1902 * OFB mode
1903 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001904 for (i = 0; i < 6; i++) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001905 u = i >> 1;
1906 keybits = 128 + u * 64;
1907 mode = i & 1;
1908
Gilles Peskine449bd832023-01-11 14:50:10 +01001909 if (verbose != 0) {
1910 mbedtls_printf(" AES-OFB-%3u (%s): ", keybits,
1911 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
1912 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001913
Gilles Peskine449bd832023-01-11 14:50:10 +01001914 memcpy(iv, aes_test_ofb_iv, 16);
1915 memcpy(key, aes_test_ofb_key[u], keybits / 8);
Simon Butcherad4e4932018-04-29 00:43:47 +01001916
1917 offset = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +01001918 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Simon Butcherad4e4932018-04-29 00:43:47 +01001919 /*
1920 * AES-192 is an optional feature that may be unavailable when
1921 * there is an alternative underlying implementation i.e. when
1922 * MBEDTLS_AES_ALT is defined.
1923 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001924 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1925 mbedtls_printf("skipped\n");
Simon Butcherad4e4932018-04-29 00:43:47 +01001926 continue;
Gilles Peskine449bd832023-01-11 14:50:10 +01001927 } else if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001928 goto exit;
1929 }
1930
Gilles Peskine449bd832023-01-11 14:50:10 +01001931 if (mode == MBEDTLS_AES_DECRYPT) {
1932 memcpy(buf, aes_test_ofb_ct[u], 64);
Simon Butcherad4e4932018-04-29 00:43:47 +01001933 aes_tests = aes_test_ofb_pt;
Gilles Peskine449bd832023-01-11 14:50:10 +01001934 } else {
1935 memcpy(buf, aes_test_ofb_pt, 64);
Simon Butcherad4e4932018-04-29 00:43:47 +01001936 aes_tests = aes_test_ofb_ct[u];
1937 }
1938
Gilles Peskine449bd832023-01-11 14:50:10 +01001939 ret = mbedtls_aes_crypt_ofb(&ctx, 64, &offset, iv, buf, buf);
1940 if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001941 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001942 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001943
Gilles Peskine449bd832023-01-11 14:50:10 +01001944 if (memcmp(buf, aes_tests, 64) != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001945 ret = 1;
1946 goto exit;
1947 }
1948
Gilles Peskine449bd832023-01-11 14:50:10 +01001949 if (verbose != 0) {
1950 mbedtls_printf("passed\n");
1951 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001952 }
1953
Gilles Peskine449bd832023-01-11 14:50:10 +01001954 if (verbose != 0) {
1955 mbedtls_printf("\n");
1956 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001957#endif /* MBEDTLS_CIPHER_MODE_OFB */
1958
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001959#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001960 /*
1961 * CTR mode
1962 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001963 for (i = 0; i < 6; i++) {
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001964 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001965 mode = i & 1;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001966
Gilles Peskine449bd832023-01-11 14:50:10 +01001967 if (verbose != 0) {
1968 mbedtls_printf(" AES-CTR-128 (%s): ",
1969 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
1970 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001971
Gilles Peskine449bd832023-01-11 14:50:10 +01001972 memcpy(nonce_counter, aes_test_ctr_nonce_counter[u], 16);
1973 memcpy(key, aes_test_ctr_key[u], 16);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001974
1975 offset = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +01001976 if ((ret = mbedtls_aes_setkey_enc(&ctx, key, 128)) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001977 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001978 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001979
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001980 len = aes_test_ctr_len[u];
1981
Gilles Peskine449bd832023-01-11 14:50:10 +01001982 if (mode == MBEDTLS_AES_DECRYPT) {
1983 memcpy(buf, aes_test_ctr_ct[u], len);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001984 aes_tests = aes_test_ctr_pt[u];
Gilles Peskine449bd832023-01-11 14:50:10 +01001985 } else {
1986 memcpy(buf, aes_test_ctr_pt[u], len);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001987 aes_tests = aes_test_ctr_ct[u];
1988 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001989
Gilles Peskine449bd832023-01-11 14:50:10 +01001990 ret = mbedtls_aes_crypt_ctr(&ctx, len, &offset, nonce_counter,
1991 stream_block, buf, buf);
1992 if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001993 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001994 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001995
Gilles Peskine449bd832023-01-11 14:50:10 +01001996 if (memcmp(buf, aes_tests, len) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001997 ret = 1;
1998 goto exit;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001999 }
2000
Gilles Peskine449bd832023-01-11 14:50:10 +01002001 if (verbose != 0) {
2002 mbedtls_printf("passed\n");
2003 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002004 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002005
Gilles Peskine449bd832023-01-11 14:50:10 +01002006 if (verbose != 0) {
2007 mbedtls_printf("\n");
2008 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002009#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00002010
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002011#if defined(MBEDTLS_CIPHER_MODE_XTS)
2012 {
Gilles Peskine449bd832023-01-11 14:50:10 +01002013 static const int num_tests =
2014 sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key);
2015 mbedtls_aes_xts_context ctx_xts;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002016
Gilles Peskine449bd832023-01-11 14:50:10 +01002017 /*
2018 * XTS mode
2019 */
2020 mbedtls_aes_xts_init(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002021
Gilles Peskine449bd832023-01-11 14:50:10 +01002022 for (i = 0; i < num_tests << 1; i++) {
2023 const unsigned char *data_unit;
2024 u = i >> 1;
2025 mode = i & 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002026
Gilles Peskine449bd832023-01-11 14:50:10 +01002027 if (verbose != 0) {
2028 mbedtls_printf(" AES-XTS-128 (%s): ",
2029 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2030 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002031
Gilles Peskine449bd832023-01-11 14:50:10 +01002032 memset(key, 0, sizeof(key));
2033 memcpy(key, aes_test_xts_key[u], 32);
2034 data_unit = aes_test_xts_data_unit[u];
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002035
Gilles Peskine449bd832023-01-11 14:50:10 +01002036 len = sizeof(*aes_test_xts_ct32);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002037
Gilles Peskine449bd832023-01-11 14:50:10 +01002038 if (mode == MBEDTLS_AES_DECRYPT) {
2039 ret = mbedtls_aes_xts_setkey_dec(&ctx_xts, key, 256);
2040 if (ret != 0) {
2041 goto exit;
2042 }
2043 memcpy(buf, aes_test_xts_ct32[u], len);
2044 aes_tests = aes_test_xts_pt32[u];
2045 } else {
2046 ret = mbedtls_aes_xts_setkey_enc(&ctx_xts, key, 256);
2047 if (ret != 0) {
2048 goto exit;
2049 }
2050 memcpy(buf, aes_test_xts_pt32[u], len);
2051 aes_tests = aes_test_xts_ct32[u];
2052 }
2053
2054
2055 ret = mbedtls_aes_crypt_xts(&ctx_xts, mode, len, data_unit,
2056 buf, buf);
2057 if (ret != 0) {
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002058 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002059 }
2060
2061 if (memcmp(buf, aes_tests, len) != 0) {
2062 ret = 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002063 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002064 }
2065
2066 if (verbose != 0) {
2067 mbedtls_printf("passed\n");
2068 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002069 }
2070
Gilles Peskine449bd832023-01-11 14:50:10 +01002071 if (verbose != 0) {
2072 mbedtls_printf("\n");
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002073 }
2074
Gilles Peskine449bd832023-01-11 14:50:10 +01002075 mbedtls_aes_xts_free(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002076 }
2077#endif /* MBEDTLS_CIPHER_MODE_XTS */
2078
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002079 ret = 0;
2080
2081exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01002082 if (ret != 0 && verbose != 0) {
2083 mbedtls_printf("failed\n");
2084 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002085
Gilles Peskine449bd832023-01-11 14:50:10 +01002086 mbedtls_aes_free(&ctx);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002087
Gilles Peskine449bd832023-01-11 14:50:10 +01002088 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002089}
2090
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002091#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002092
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002093#endif /* MBEDTLS_AES_C */