blob: e41810a54df09abd2beb64acc7700b176136c4b4 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * FIPS-197 compliant AES implementation
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Paul Bakker5121ce52009-01-03 21:22:43 +000018 */
19/*
20 * The AES block cipher was designed by Vincent Rijmen and Joan Daemen.
21 *
22 * http://csrc.nist.gov/encryption/aes/rijndael/Rijndael.pdf
23 * http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
24 */
25
Gilles Peskinedb09ef62020-06-03 01:43:33 +020026#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000027
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020028#if defined(MBEDTLS_AES_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000029
Rich Evans00ab4702015-02-06 13:43:58 +000030#include <string.h>
31
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000032#include "mbedtls/aes.h"
Ron Eldor9924bdc2018-10-04 10:59:13 +030033#include "mbedtls/platform.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050034#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000035#include "mbedtls/error.h"
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020036#if defined(MBEDTLS_PADLOCK_C)
Chris Jones16dbaeb2021-03-09 17:47:55 +000037#include "padlock.h"
Paul Bakker67820bd2012-06-04 12:47:23 +000038#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020039#if defined(MBEDTLS_AESNI_C)
Chris Jones187782f2021-03-09 17:28:35 +000040#include "aesni.h"
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +010041#endif
Jerry Yu3f2fb712023-01-10 17:05:42 +080042#if defined(MBEDTLS_AESCE_C)
43#include "aesce.h"
44#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000045
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000046#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010047
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020048#if !defined(MBEDTLS_AES_ALT)
Paul Bakker90995b52013-06-24 19:20:35 +020049
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020050#if defined(MBEDTLS_PADLOCK_C) && \
Gilles Peskine449bd832023-01-11 14:50:10 +010051 (defined(MBEDTLS_HAVE_X86) || defined(MBEDTLS_PADLOCK_ALIGN16))
Paul Bakker048d04e2012-02-12 17:31:04 +000052static int aes_padlock_ace = -1;
53#endif
54
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020055#if defined(MBEDTLS_AES_ROM_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +000056/*
57 * Forward S-box
58 */
59static const unsigned char FSb[256] =
60{
61 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
62 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
63 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
64 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
65 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
66 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
67 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
68 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
69 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
70 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
71 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
72 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
73 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
74 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
75 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
76 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
77 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
78 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
79 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
80 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
81 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
82 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
83 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
84 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
85 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
86 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
87 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
88 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
89 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
90 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
91 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
92 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
93};
94
95/*
96 * Forward tables
97 */
98#define FT \
99\
Gilles Peskine449bd832023-01-11 14:50:10 +0100100 V(A5, 63, 63, C6), V(84, 7C, 7C, F8), V(99, 77, 77, EE), V(8D, 7B, 7B, F6), \
101 V(0D, F2, F2, FF), V(BD, 6B, 6B, D6), V(B1, 6F, 6F, DE), V(54, C5, C5, 91), \
102 V(50, 30, 30, 60), V(03, 01, 01, 02), V(A9, 67, 67, CE), V(7D, 2B, 2B, 56), \
103 V(19, FE, FE, E7), V(62, D7, D7, B5), V(E6, AB, AB, 4D), V(9A, 76, 76, EC), \
104 V(45, CA, CA, 8F), V(9D, 82, 82, 1F), V(40, C9, C9, 89), V(87, 7D, 7D, FA), \
105 V(15, FA, FA, EF), V(EB, 59, 59, B2), V(C9, 47, 47, 8E), V(0B, F0, F0, FB), \
106 V(EC, AD, AD, 41), V(67, D4, D4, B3), V(FD, A2, A2, 5F), V(EA, AF, AF, 45), \
107 V(BF, 9C, 9C, 23), V(F7, A4, A4, 53), V(96, 72, 72, E4), V(5B, C0, C0, 9B), \
108 V(C2, B7, B7, 75), V(1C, FD, FD, E1), V(AE, 93, 93, 3D), V(6A, 26, 26, 4C), \
109 V(5A, 36, 36, 6C), V(41, 3F, 3F, 7E), V(02, F7, F7, F5), V(4F, CC, CC, 83), \
110 V(5C, 34, 34, 68), V(F4, A5, A5, 51), V(34, E5, E5, D1), V(08, F1, F1, F9), \
111 V(93, 71, 71, E2), V(73, D8, D8, AB), V(53, 31, 31, 62), V(3F, 15, 15, 2A), \
112 V(0C, 04, 04, 08), V(52, C7, C7, 95), V(65, 23, 23, 46), V(5E, C3, C3, 9D), \
113 V(28, 18, 18, 30), V(A1, 96, 96, 37), V(0F, 05, 05, 0A), V(B5, 9A, 9A, 2F), \
114 V(09, 07, 07, 0E), V(36, 12, 12, 24), V(9B, 80, 80, 1B), V(3D, E2, E2, DF), \
115 V(26, EB, EB, CD), V(69, 27, 27, 4E), V(CD, B2, B2, 7F), V(9F, 75, 75, EA), \
116 V(1B, 09, 09, 12), V(9E, 83, 83, 1D), V(74, 2C, 2C, 58), V(2E, 1A, 1A, 34), \
117 V(2D, 1B, 1B, 36), V(B2, 6E, 6E, DC), V(EE, 5A, 5A, B4), V(FB, A0, A0, 5B), \
118 V(F6, 52, 52, A4), V(4D, 3B, 3B, 76), V(61, D6, D6, B7), V(CE, B3, B3, 7D), \
119 V(7B, 29, 29, 52), V(3E, E3, E3, DD), V(71, 2F, 2F, 5E), V(97, 84, 84, 13), \
120 V(F5, 53, 53, A6), V(68, D1, D1, B9), V(00, 00, 00, 00), V(2C, ED, ED, C1), \
121 V(60, 20, 20, 40), V(1F, FC, FC, E3), V(C8, B1, B1, 79), V(ED, 5B, 5B, B6), \
122 V(BE, 6A, 6A, D4), V(46, CB, CB, 8D), V(D9, BE, BE, 67), V(4B, 39, 39, 72), \
123 V(DE, 4A, 4A, 94), V(D4, 4C, 4C, 98), V(E8, 58, 58, B0), V(4A, CF, CF, 85), \
124 V(6B, D0, D0, BB), V(2A, EF, EF, C5), V(E5, AA, AA, 4F), V(16, FB, FB, ED), \
125 V(C5, 43, 43, 86), V(D7, 4D, 4D, 9A), V(55, 33, 33, 66), V(94, 85, 85, 11), \
126 V(CF, 45, 45, 8A), V(10, F9, F9, E9), V(06, 02, 02, 04), V(81, 7F, 7F, FE), \
127 V(F0, 50, 50, A0), V(44, 3C, 3C, 78), V(BA, 9F, 9F, 25), V(E3, A8, A8, 4B), \
128 V(F3, 51, 51, A2), V(FE, A3, A3, 5D), V(C0, 40, 40, 80), V(8A, 8F, 8F, 05), \
129 V(AD, 92, 92, 3F), V(BC, 9D, 9D, 21), V(48, 38, 38, 70), V(04, F5, F5, F1), \
130 V(DF, BC, BC, 63), V(C1, B6, B6, 77), V(75, DA, DA, AF), V(63, 21, 21, 42), \
131 V(30, 10, 10, 20), V(1A, FF, FF, E5), V(0E, F3, F3, FD), V(6D, D2, D2, BF), \
132 V(4C, CD, CD, 81), V(14, 0C, 0C, 18), V(35, 13, 13, 26), V(2F, EC, EC, C3), \
133 V(E1, 5F, 5F, BE), V(A2, 97, 97, 35), V(CC, 44, 44, 88), V(39, 17, 17, 2E), \
134 V(57, C4, C4, 93), V(F2, A7, A7, 55), V(82, 7E, 7E, FC), V(47, 3D, 3D, 7A), \
135 V(AC, 64, 64, C8), V(E7, 5D, 5D, BA), V(2B, 19, 19, 32), V(95, 73, 73, E6), \
136 V(A0, 60, 60, C0), V(98, 81, 81, 19), V(D1, 4F, 4F, 9E), V(7F, DC, DC, A3), \
137 V(66, 22, 22, 44), V(7E, 2A, 2A, 54), V(AB, 90, 90, 3B), V(83, 88, 88, 0B), \
138 V(CA, 46, 46, 8C), V(29, EE, EE, C7), V(D3, B8, B8, 6B), V(3C, 14, 14, 28), \
139 V(79, DE, DE, A7), V(E2, 5E, 5E, BC), V(1D, 0B, 0B, 16), V(76, DB, DB, AD), \
140 V(3B, E0, E0, DB), V(56, 32, 32, 64), V(4E, 3A, 3A, 74), V(1E, 0A, 0A, 14), \
141 V(DB, 49, 49, 92), V(0A, 06, 06, 0C), V(6C, 24, 24, 48), V(E4, 5C, 5C, B8), \
142 V(5D, C2, C2, 9F), V(6E, D3, D3, BD), V(EF, AC, AC, 43), V(A6, 62, 62, C4), \
143 V(A8, 91, 91, 39), V(A4, 95, 95, 31), V(37, E4, E4, D3), V(8B, 79, 79, F2), \
144 V(32, E7, E7, D5), V(43, C8, C8, 8B), V(59, 37, 37, 6E), V(B7, 6D, 6D, DA), \
145 V(8C, 8D, 8D, 01), V(64, D5, D5, B1), V(D2, 4E, 4E, 9C), V(E0, A9, A9, 49), \
146 V(B4, 6C, 6C, D8), V(FA, 56, 56, AC), V(07, F4, F4, F3), V(25, EA, EA, CF), \
147 V(AF, 65, 65, CA), V(8E, 7A, 7A, F4), V(E9, AE, AE, 47), V(18, 08, 08, 10), \
148 V(D5, BA, BA, 6F), V(88, 78, 78, F0), V(6F, 25, 25, 4A), V(72, 2E, 2E, 5C), \
149 V(24, 1C, 1C, 38), V(F1, A6, A6, 57), V(C7, B4, B4, 73), V(51, C6, C6, 97), \
150 V(23, E8, E8, CB), V(7C, DD, DD, A1), V(9C, 74, 74, E8), V(21, 1F, 1F, 3E), \
151 V(DD, 4B, 4B, 96), V(DC, BD, BD, 61), V(86, 8B, 8B, 0D), V(85, 8A, 8A, 0F), \
152 V(90, 70, 70, E0), V(42, 3E, 3E, 7C), V(C4, B5, B5, 71), V(AA, 66, 66, CC), \
153 V(D8, 48, 48, 90), V(05, 03, 03, 06), V(01, F6, F6, F7), V(12, 0E, 0E, 1C), \
154 V(A3, 61, 61, C2), V(5F, 35, 35, 6A), V(F9, 57, 57, AE), V(D0, B9, B9, 69), \
155 V(91, 86, 86, 17), V(58, C1, C1, 99), V(27, 1D, 1D, 3A), V(B9, 9E, 9E, 27), \
156 V(38, E1, E1, D9), V(13, F8, F8, EB), V(B3, 98, 98, 2B), V(33, 11, 11, 22), \
157 V(BB, 69, 69, D2), V(70, D9, D9, A9), V(89, 8E, 8E, 07), V(A7, 94, 94, 33), \
158 V(B6, 9B, 9B, 2D), V(22, 1E, 1E, 3C), V(92, 87, 87, 15), V(20, E9, E9, C9), \
159 V(49, CE, CE, 87), V(FF, 55, 55, AA), V(78, 28, 28, 50), V(7A, DF, DF, A5), \
160 V(8F, 8C, 8C, 03), V(F8, A1, A1, 59), V(80, 89, 89, 09), V(17, 0D, 0D, 1A), \
161 V(DA, BF, BF, 65), V(31, E6, E6, D7), V(C6, 42, 42, 84), V(B8, 68, 68, D0), \
162 V(C3, 41, 41, 82), V(B0, 99, 99, 29), V(77, 2D, 2D, 5A), V(11, 0F, 0F, 1E), \
163 V(CB, B0, B0, 7B), V(FC, 54, 54, A8), V(D6, BB, BB, 6D), V(3A, 16, 16, 2C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000164
Gilles Peskine449bd832023-01-11 14:50:10 +0100165#define V(a, b, c, d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000166static const uint32_t FT0[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000167#undef V
168
Hanno Beckerad049a92017-06-19 16:31:54 +0100169#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200170
Gilles Peskine449bd832023-01-11 14:50:10 +0100171#define V(a, b, c, d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000172static const uint32_t FT1[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000173#undef V
174
Gilles Peskine449bd832023-01-11 14:50:10 +0100175#define V(a, b, c, d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000176static const uint32_t FT2[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000177#undef V
178
Gilles Peskine449bd832023-01-11 14:50:10 +0100179#define V(a, b, c, d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000180static const uint32_t FT3[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000181#undef V
182
Hanno Becker177d3cf2017-06-07 15:52:48 +0100183#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200184
Paul Bakker5121ce52009-01-03 21:22:43 +0000185#undef FT
186
187/*
188 * Reverse S-box
189 */
190static const unsigned char RSb[256] =
191{
192 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
193 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
194 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
195 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
196 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
197 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
198 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
199 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
200 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
201 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
202 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
203 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
204 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
205 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
206 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
207 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
208 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
209 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
210 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
211 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
212 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
213 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
214 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
215 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
216 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
217 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
218 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
219 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
220 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
221 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
222 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
223 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
224};
225
226/*
227 * Reverse tables
228 */
229#define RT \
230\
Gilles Peskine449bd832023-01-11 14:50:10 +0100231 V(50, A7, F4, 51), V(53, 65, 41, 7E), V(C3, A4, 17, 1A), V(96, 5E, 27, 3A), \
232 V(CB, 6B, AB, 3B), V(F1, 45, 9D, 1F), V(AB, 58, FA, AC), V(93, 03, E3, 4B), \
233 V(55, FA, 30, 20), V(F6, 6D, 76, AD), V(91, 76, CC, 88), V(25, 4C, 02, F5), \
234 V(FC, D7, E5, 4F), V(D7, CB, 2A, C5), V(80, 44, 35, 26), V(8F, A3, 62, B5), \
235 V(49, 5A, B1, DE), V(67, 1B, BA, 25), V(98, 0E, EA, 45), V(E1, C0, FE, 5D), \
236 V(02, 75, 2F, C3), V(12, F0, 4C, 81), V(A3, 97, 46, 8D), V(C6, F9, D3, 6B), \
237 V(E7, 5F, 8F, 03), V(95, 9C, 92, 15), V(EB, 7A, 6D, BF), V(DA, 59, 52, 95), \
238 V(2D, 83, BE, D4), V(D3, 21, 74, 58), V(29, 69, E0, 49), V(44, C8, C9, 8E), \
239 V(6A, 89, C2, 75), V(78, 79, 8E, F4), V(6B, 3E, 58, 99), V(DD, 71, B9, 27), \
240 V(B6, 4F, E1, BE), V(17, AD, 88, F0), V(66, AC, 20, C9), V(B4, 3A, CE, 7D), \
241 V(18, 4A, DF, 63), V(82, 31, 1A, E5), V(60, 33, 51, 97), V(45, 7F, 53, 62), \
242 V(E0, 77, 64, B1), V(84, AE, 6B, BB), V(1C, A0, 81, FE), V(94, 2B, 08, F9), \
243 V(58, 68, 48, 70), V(19, FD, 45, 8F), V(87, 6C, DE, 94), V(B7, F8, 7B, 52), \
244 V(23, D3, 73, AB), V(E2, 02, 4B, 72), V(57, 8F, 1F, E3), V(2A, AB, 55, 66), \
245 V(07, 28, EB, B2), V(03, C2, B5, 2F), V(9A, 7B, C5, 86), V(A5, 08, 37, D3), \
246 V(F2, 87, 28, 30), V(B2, A5, BF, 23), V(BA, 6A, 03, 02), V(5C, 82, 16, ED), \
247 V(2B, 1C, CF, 8A), V(92, B4, 79, A7), V(F0, F2, 07, F3), V(A1, E2, 69, 4E), \
248 V(CD, F4, DA, 65), V(D5, BE, 05, 06), V(1F, 62, 34, D1), V(8A, FE, A6, C4), \
249 V(9D, 53, 2E, 34), V(A0, 55, F3, A2), V(32, E1, 8A, 05), V(75, EB, F6, A4), \
250 V(39, EC, 83, 0B), V(AA, EF, 60, 40), V(06, 9F, 71, 5E), V(51, 10, 6E, BD), \
251 V(F9, 8A, 21, 3E), V(3D, 06, DD, 96), V(AE, 05, 3E, DD), V(46, BD, E6, 4D), \
252 V(B5, 8D, 54, 91), V(05, 5D, C4, 71), V(6F, D4, 06, 04), V(FF, 15, 50, 60), \
253 V(24, FB, 98, 19), V(97, E9, BD, D6), V(CC, 43, 40, 89), V(77, 9E, D9, 67), \
254 V(BD, 42, E8, B0), V(88, 8B, 89, 07), V(38, 5B, 19, E7), V(DB, EE, C8, 79), \
255 V(47, 0A, 7C, A1), V(E9, 0F, 42, 7C), V(C9, 1E, 84, F8), V(00, 00, 00, 00), \
256 V(83, 86, 80, 09), V(48, ED, 2B, 32), V(AC, 70, 11, 1E), V(4E, 72, 5A, 6C), \
257 V(FB, FF, 0E, FD), V(56, 38, 85, 0F), V(1E, D5, AE, 3D), V(27, 39, 2D, 36), \
258 V(64, D9, 0F, 0A), V(21, A6, 5C, 68), V(D1, 54, 5B, 9B), V(3A, 2E, 36, 24), \
259 V(B1, 67, 0A, 0C), V(0F, E7, 57, 93), V(D2, 96, EE, B4), V(9E, 91, 9B, 1B), \
260 V(4F, C5, C0, 80), V(A2, 20, DC, 61), V(69, 4B, 77, 5A), V(16, 1A, 12, 1C), \
261 V(0A, BA, 93, E2), V(E5, 2A, A0, C0), V(43, E0, 22, 3C), V(1D, 17, 1B, 12), \
262 V(0B, 0D, 09, 0E), V(AD, C7, 8B, F2), V(B9, A8, B6, 2D), V(C8, A9, 1E, 14), \
263 V(85, 19, F1, 57), V(4C, 07, 75, AF), V(BB, DD, 99, EE), V(FD, 60, 7F, A3), \
264 V(9F, 26, 01, F7), V(BC, F5, 72, 5C), V(C5, 3B, 66, 44), V(34, 7E, FB, 5B), \
265 V(76, 29, 43, 8B), V(DC, C6, 23, CB), V(68, FC, ED, B6), V(63, F1, E4, B8), \
266 V(CA, DC, 31, D7), V(10, 85, 63, 42), V(40, 22, 97, 13), V(20, 11, C6, 84), \
267 V(7D, 24, 4A, 85), V(F8, 3D, BB, D2), V(11, 32, F9, AE), V(6D, A1, 29, C7), \
268 V(4B, 2F, 9E, 1D), V(F3, 30, B2, DC), V(EC, 52, 86, 0D), V(D0, E3, C1, 77), \
269 V(6C, 16, B3, 2B), V(99, B9, 70, A9), V(FA, 48, 94, 11), V(22, 64, E9, 47), \
270 V(C4, 8C, FC, A8), V(1A, 3F, F0, A0), V(D8, 2C, 7D, 56), V(EF, 90, 33, 22), \
271 V(C7, 4E, 49, 87), V(C1, D1, 38, D9), V(FE, A2, CA, 8C), V(36, 0B, D4, 98), \
272 V(CF, 81, F5, A6), V(28, DE, 7A, A5), V(26, 8E, B7, DA), V(A4, BF, AD, 3F), \
273 V(E4, 9D, 3A, 2C), V(0D, 92, 78, 50), V(9B, CC, 5F, 6A), V(62, 46, 7E, 54), \
274 V(C2, 13, 8D, F6), V(E8, B8, D8, 90), V(5E, F7, 39, 2E), V(F5, AF, C3, 82), \
275 V(BE, 80, 5D, 9F), V(7C, 93, D0, 69), V(A9, 2D, D5, 6F), V(B3, 12, 25, CF), \
276 V(3B, 99, AC, C8), V(A7, 7D, 18, 10), V(6E, 63, 9C, E8), V(7B, BB, 3B, DB), \
277 V(09, 78, 26, CD), V(F4, 18, 59, 6E), V(01, B7, 9A, EC), V(A8, 9A, 4F, 83), \
278 V(65, 6E, 95, E6), V(7E, E6, FF, AA), V(08, CF, BC, 21), V(E6, E8, 15, EF), \
279 V(D9, 9B, E7, BA), V(CE, 36, 6F, 4A), V(D4, 09, 9F, EA), V(D6, 7C, B0, 29), \
280 V(AF, B2, A4, 31), V(31, 23, 3F, 2A), V(30, 94, A5, C6), V(C0, 66, A2, 35), \
281 V(37, BC, 4E, 74), V(A6, CA, 82, FC), V(B0, D0, 90, E0), V(15, D8, A7, 33), \
282 V(4A, 98, 04, F1), V(F7, DA, EC, 41), V(0E, 50, CD, 7F), V(2F, F6, 91, 17), \
283 V(8D, D6, 4D, 76), V(4D, B0, EF, 43), V(54, 4D, AA, CC), V(DF, 04, 96, E4), \
284 V(E3, B5, D1, 9E), V(1B, 88, 6A, 4C), V(B8, 1F, 2C, C1), V(7F, 51, 65, 46), \
285 V(04, EA, 5E, 9D), V(5D, 35, 8C, 01), V(73, 74, 87, FA), V(2E, 41, 0B, FB), \
286 V(5A, 1D, 67, B3), V(52, D2, DB, 92), V(33, 56, 10, E9), V(13, 47, D6, 6D), \
287 V(8C, 61, D7, 9A), V(7A, 0C, A1, 37), V(8E, 14, F8, 59), V(89, 3C, 13, EB), \
288 V(EE, 27, A9, CE), V(35, C9, 61, B7), V(ED, E5, 1C, E1), V(3C, B1, 47, 7A), \
289 V(59, DF, D2, 9C), V(3F, 73, F2, 55), V(79, CE, 14, 18), V(BF, 37, C7, 73), \
290 V(EA, CD, F7, 53), V(5B, AA, FD, 5F), V(14, 6F, 3D, DF), V(86, DB, 44, 78), \
291 V(81, F3, AF, CA), V(3E, C4, 68, B9), V(2C, 34, 24, 38), V(5F, 40, A3, C2), \
292 V(72, C3, 1D, 16), V(0C, 25, E2, BC), V(8B, 49, 3C, 28), V(41, 95, 0D, FF), \
293 V(71, 01, A8, 39), V(DE, B3, 0C, 08), V(9C, E4, B4, D8), V(90, C1, 56, 64), \
294 V(61, 84, CB, 7B), V(70, B6, 32, D5), V(74, 5C, 6C, 48), V(42, 57, B8, D0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000295
Gilles Peskine449bd832023-01-11 14:50:10 +0100296#define V(a, b, c, d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000297static const uint32_t RT0[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000298#undef V
299
Hanno Beckerad049a92017-06-19 16:31:54 +0100300#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200301
Gilles Peskine449bd832023-01-11 14:50:10 +0100302#define V(a, b, c, d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000303static const uint32_t RT1[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000304#undef V
305
Gilles Peskine449bd832023-01-11 14:50:10 +0100306#define V(a, b, c, d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000307static const uint32_t RT2[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000308#undef V
309
Gilles Peskine449bd832023-01-11 14:50:10 +0100310#define V(a, b, c, d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000311static const uint32_t RT3[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000312#undef V
313
Hanno Becker177d3cf2017-06-07 15:52:48 +0100314#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200315
Paul Bakker5121ce52009-01-03 21:22:43 +0000316#undef RT
317
318/*
319 * Round constants
320 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000321static const uint32_t RCON[10] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000322{
323 0x00000001, 0x00000002, 0x00000004, 0x00000008,
324 0x00000010, 0x00000020, 0x00000040, 0x00000080,
325 0x0000001B, 0x00000036
326};
327
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200328#else /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000329
330/*
331 * Forward S-box & tables
332 */
333static unsigned char FSb[256];
Paul Bakker9af723c2014-05-01 13:03:14 +0200334static uint32_t FT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100335#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker9af723c2014-05-01 13:03:14 +0200336static uint32_t FT1[256];
337static uint32_t FT2[256];
338static uint32_t FT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100339#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000340
341/*
342 * Reverse S-box & tables
343 */
344static unsigned char RSb[256];
Paul Bakker5c2364c2012-10-01 14:41:15 +0000345static uint32_t RT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100346#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker5c2364c2012-10-01 14:41:15 +0000347static uint32_t RT1[256];
348static uint32_t RT2[256];
349static uint32_t RT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100350#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000351
352/*
353 * Round constants
354 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000355static uint32_t RCON[10];
Paul Bakker5121ce52009-01-03 21:22:43 +0000356
357/*
358 * Tables generation code
359 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100360#define ROTL8(x) (((x) << 8) & 0xFFFFFFFF) | ((x) >> 24)
361#define XTIME(x) (((x) << 1) ^ (((x) & 0x80) ? 0x1B : 0x00))
362#define MUL(x, y) (((x) && (y)) ? pow[(log[(x)]+log[(y)]) % 255] : 0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000363
364static int aes_init_done = 0;
365
Gilles Peskine449bd832023-01-11 14:50:10 +0100366static void aes_gen_tables(void)
Paul Bakker5121ce52009-01-03 21:22:43 +0000367{
368 int i, x, y, z;
369 int pow[256];
370 int log[256];
371
372 /*
373 * compute pow and log tables over GF(2^8)
374 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100375 for (i = 0, x = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000376 pow[i] = x;
377 log[x] = i;
Gilles Peskine449bd832023-01-11 14:50:10 +0100378 x = MBEDTLS_BYTE_0(x ^ XTIME(x));
Paul Bakker5121ce52009-01-03 21:22:43 +0000379 }
380
381 /*
382 * calculate the round constants
383 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100384 for (i = 0, x = 1; i < 10; i++) {
Paul Bakker5c2364c2012-10-01 14:41:15 +0000385 RCON[i] = (uint32_t) x;
Gilles Peskine449bd832023-01-11 14:50:10 +0100386 x = MBEDTLS_BYTE_0(XTIME(x));
Paul Bakker5121ce52009-01-03 21:22:43 +0000387 }
388
389 /*
390 * generate the forward and reverse S-boxes
391 */
392 FSb[0x00] = 0x63;
393 RSb[0x63] = 0x00;
394
Gilles Peskine449bd832023-01-11 14:50:10 +0100395 for (i = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000396 x = pow[255 - log[i]];
397
Gilles Peskine449bd832023-01-11 14:50:10 +0100398 y = x; y = MBEDTLS_BYTE_0((y << 1) | (y >> 7));
399 x ^= y; y = MBEDTLS_BYTE_0((y << 1) | (y >> 7));
400 x ^= y; y = MBEDTLS_BYTE_0((y << 1) | (y >> 7));
401 x ^= y; y = MBEDTLS_BYTE_0((y << 1) | (y >> 7));
Paul Bakker5121ce52009-01-03 21:22:43 +0000402 x ^= y ^ 0x63;
403
404 FSb[i] = (unsigned char) x;
405 RSb[x] = (unsigned char) i;
406 }
407
408 /*
409 * generate the forward and reverse tables
410 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100411 for (i = 0; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000412 x = FSb[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100413 y = MBEDTLS_BYTE_0(XTIME(x));
414 z = MBEDTLS_BYTE_0(y ^ x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000415
Gilles Peskine449bd832023-01-11 14:50:10 +0100416 FT0[i] = ((uint32_t) y) ^
417 ((uint32_t) x << 8) ^
418 ((uint32_t) x << 16) ^
419 ((uint32_t) z << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000420
Hanno Beckerad049a92017-06-19 16:31:54 +0100421#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100422 FT1[i] = ROTL8(FT0[i]);
423 FT2[i] = ROTL8(FT1[i]);
424 FT3[i] = ROTL8(FT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100425#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000426
427 x = RSb[i];
428
Gilles Peskine449bd832023-01-11 14:50:10 +0100429 RT0[i] = ((uint32_t) MUL(0x0E, x)) ^
430 ((uint32_t) MUL(0x09, x) << 8) ^
431 ((uint32_t) MUL(0x0D, x) << 16) ^
432 ((uint32_t) MUL(0x0B, x) << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000433
Hanno Beckerad049a92017-06-19 16:31:54 +0100434#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100435 RT1[i] = ROTL8(RT0[i]);
436 RT2[i] = ROTL8(RT1[i]);
437 RT3[i] = ROTL8(RT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100438#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000439 }
440}
441
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200442#undef ROTL8
443
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200444#endif /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000445
Hanno Beckerad049a92017-06-19 16:31:54 +0100446#if defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200447
Gilles Peskine449bd832023-01-11 14:50:10 +0100448#define ROTL8(x) ((uint32_t) ((x) << 8) + (uint32_t) ((x) >> 24))
449#define ROTL16(x) ((uint32_t) ((x) << 16) + (uint32_t) ((x) >> 16))
450#define ROTL24(x) ((uint32_t) ((x) << 24) + (uint32_t) ((x) >> 8))
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200451
452#define AES_RT0(idx) RT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100453#define AES_RT1(idx) ROTL8(RT0[idx])
454#define AES_RT2(idx) ROTL16(RT0[idx])
455#define AES_RT3(idx) ROTL24(RT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200456
457#define AES_FT0(idx) FT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100458#define AES_FT1(idx) ROTL8(FT0[idx])
459#define AES_FT2(idx) ROTL16(FT0[idx])
460#define AES_FT3(idx) ROTL24(FT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200461
Hanno Becker177d3cf2017-06-07 15:52:48 +0100462#else /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200463
464#define AES_RT0(idx) RT0[idx]
465#define AES_RT1(idx) RT1[idx]
466#define AES_RT2(idx) RT2[idx]
467#define AES_RT3(idx) RT3[idx]
468
469#define AES_FT0(idx) FT0[idx]
470#define AES_FT1(idx) FT1[idx]
471#define AES_FT2(idx) FT2[idx]
472#define AES_FT3(idx) FT3[idx]
473
Hanno Becker177d3cf2017-06-07 15:52:48 +0100474#endif /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200475
Gilles Peskine449bd832023-01-11 14:50:10 +0100476void mbedtls_aes_init(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200477{
Gilles Peskine449bd832023-01-11 14:50:10 +0100478 memset(ctx, 0, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200479}
480
Gilles Peskine449bd832023-01-11 14:50:10 +0100481void mbedtls_aes_free(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200482{
Gilles Peskine449bd832023-01-11 14:50:10 +0100483 if (ctx == NULL) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200484 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100485 }
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200486
Gilles Peskine449bd832023-01-11 14:50:10 +0100487 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200488}
489
Jaeden Amero9366feb2018-05-29 18:55:17 +0100490#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100491void mbedtls_aes_xts_init(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100492{
Gilles Peskine449bd832023-01-11 14:50:10 +0100493 mbedtls_aes_init(&ctx->crypt);
494 mbedtls_aes_init(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100495}
496
Gilles Peskine449bd832023-01-11 14:50:10 +0100497void mbedtls_aes_xts_free(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100498{
Gilles Peskine449bd832023-01-11 14:50:10 +0100499 if (ctx == NULL) {
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100500 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100501 }
Simon Butcher5201e412018-12-06 17:40:14 +0000502
Gilles Peskine449bd832023-01-11 14:50:10 +0100503 mbedtls_aes_free(&ctx->crypt);
504 mbedtls_aes_free(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100505}
506#endif /* MBEDTLS_CIPHER_MODE_XTS */
507
Paul Bakker5121ce52009-01-03 21:22:43 +0000508/*
509 * AES key schedule (encryption)
510 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200511#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100512int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
513 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000514{
Paul Bakker23986e52011-04-24 08:57:21 +0000515 unsigned int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000516 uint32_t *RK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000517
Gilles Peskine449bd832023-01-11 14:50:10 +0100518 switch (keybits) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000519 case 128: ctx->nr = 10; break;
520 case 192: ctx->nr = 12; break;
521 case 256: ctx->nr = 14; break;
Gilles Peskine449bd832023-01-11 14:50:10 +0100522 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Paul Bakker5121ce52009-01-03 21:22:43 +0000523 }
524
Simon Butcher5201e412018-12-06 17:40:14 +0000525#if !defined(MBEDTLS_AES_ROM_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100526 if (aes_init_done == 0) {
Simon Butcher5201e412018-12-06 17:40:14 +0000527 aes_gen_tables();
528 aes_init_done = 1;
Simon Butcher5201e412018-12-06 17:40:14 +0000529 }
530#endif
531
Werner Lewis7656a372022-06-13 12:28:20 +0100532 ctx->rk_offset = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200533#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_PADLOCK_ALIGN16)
Gilles Peskine449bd832023-01-11 14:50:10 +0100534 if (aes_padlock_ace == -1) {
535 aes_padlock_ace = mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE);
536 }
Paul Bakker048d04e2012-02-12 17:31:04 +0000537
Gilles Peskine449bd832023-01-11 14:50:10 +0100538 if (aes_padlock_ace) {
539 ctx->rk_offset = MBEDTLS_PADLOCK_ALIGN16(ctx->buf) - ctx->buf;
540 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000541#endif
Werner Lewisdd76ef32022-05-30 12:00:21 +0100542 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000543
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100544#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100545 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
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
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100656#if defined(MBEDTLS_AESNI_HAVE_CODE)
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
Jerry Yue096da12023-01-10 17:07:01 +0800664#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
665 if (mbedtls_aesce_has_support()) {
666 mbedtls_aesce_inverse_key(
667 (unsigned char *) RK,
668 (const unsigned char *) (cty.buf + cty.rk_offset),
669 ctx->nr);
670 goto exit;
671 }
672#endif
673
Werner Lewisdd76ef32022-05-30 12:00:21 +0100674 SK = cty.buf + cty.rk_offset + cty.nr * 4;
Paul Bakker5121ce52009-01-03 21:22:43 +0000675
676 *RK++ = *SK++;
677 *RK++ = *SK++;
678 *RK++ = *SK++;
679 *RK++ = *SK++;
680
Gilles Peskine449bd832023-01-11 14:50:10 +0100681 for (i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8) {
682 for (j = 0; j < 4; j++, SK++) {
683 *RK++ = AES_RT0(FSb[MBEDTLS_BYTE_0(*SK)]) ^
684 AES_RT1(FSb[MBEDTLS_BYTE_1(*SK)]) ^
685 AES_RT2(FSb[MBEDTLS_BYTE_2(*SK)]) ^
686 AES_RT3(FSb[MBEDTLS_BYTE_3(*SK)]);
Paul Bakker5121ce52009-01-03 21:22:43 +0000687 }
688 }
689
690 *RK++ = *SK++;
691 *RK++ = *SK++;
692 *RK++ = *SK++;
693 *RK++ = *SK++;
694
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200695exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100696 mbedtls_aes_free(&cty);
Paul Bakker2b222c82009-07-27 21:03:45 +0000697
Gilles Peskine449bd832023-01-11 14:50:10 +0100698 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000699}
gabor-mezei-arm95db3012020-10-26 11:35:23 +0100700#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */
Jaeden Amero9366feb2018-05-29 18:55:17 +0100701
702#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100703static int mbedtls_aes_xts_decode_keys(const unsigned char *key,
704 unsigned int keybits,
705 const unsigned char **key1,
706 unsigned int *key1bits,
707 const unsigned char **key2,
708 unsigned int *key2bits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100709{
710 const unsigned int half_keybits = keybits / 2;
711 const unsigned int half_keybytes = half_keybits / 8;
712
Gilles Peskine449bd832023-01-11 14:50:10 +0100713 switch (keybits) {
Jaeden Amero9366feb2018-05-29 18:55:17 +0100714 case 256: break;
715 case 512: break;
Gilles Peskine449bd832023-01-11 14:50:10 +0100716 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100717 }
718
719 *key1bits = half_keybits;
720 *key2bits = half_keybits;
721 *key1 = &key[0];
722 *key2 = &key[half_keybytes];
723
724 return 0;
725}
726
Gilles Peskine449bd832023-01-11 14:50:10 +0100727int mbedtls_aes_xts_setkey_enc(mbedtls_aes_xts_context *ctx,
728 const unsigned char *key,
729 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100730{
Janos Follath24eed8d2019-11-22 13:21:35 +0000731 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100732 const unsigned char *key1, *key2;
733 unsigned int key1bits, key2bits;
734
Gilles Peskine449bd832023-01-11 14:50:10 +0100735 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
736 &key2, &key2bits);
737 if (ret != 0) {
738 return ret;
739 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100740
741 /* Set the tweak key. Always set tweak key for the encryption mode. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100742 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
743 if (ret != 0) {
744 return ret;
745 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100746
747 /* Set crypt key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100748 return mbedtls_aes_setkey_enc(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100749}
750
Gilles Peskine449bd832023-01-11 14:50:10 +0100751int mbedtls_aes_xts_setkey_dec(mbedtls_aes_xts_context *ctx,
752 const unsigned char *key,
753 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100754{
Janos Follath24eed8d2019-11-22 13:21:35 +0000755 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100756 const unsigned char *key1, *key2;
757 unsigned int key1bits, key2bits;
758
Gilles Peskine449bd832023-01-11 14:50:10 +0100759 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
760 &key2, &key2bits);
761 if (ret != 0) {
762 return ret;
763 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100764
765 /* Set the tweak key. Always set tweak key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100766 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
767 if (ret != 0) {
768 return ret;
769 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100770
771 /* Set crypt key for decryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100772 return mbedtls_aes_setkey_dec(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100773}
774#endif /* MBEDTLS_CIPHER_MODE_XTS */
775
Gilles Peskine449bd832023-01-11 14:50:10 +0100776#define AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Joe Subbianicd84d762021-07-08 14:59:52 +0100777 do \
778 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100779 (X0) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y0)) ^ \
780 AES_FT1(MBEDTLS_BYTE_1(Y1)) ^ \
781 AES_FT2(MBEDTLS_BYTE_2(Y2)) ^ \
782 AES_FT3(MBEDTLS_BYTE_3(Y3)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100783 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100784 (X1) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y1)) ^ \
785 AES_FT1(MBEDTLS_BYTE_1(Y2)) ^ \
786 AES_FT2(MBEDTLS_BYTE_2(Y3)) ^ \
787 AES_FT3(MBEDTLS_BYTE_3(Y0)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100788 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100789 (X2) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y2)) ^ \
790 AES_FT1(MBEDTLS_BYTE_1(Y3)) ^ \
791 AES_FT2(MBEDTLS_BYTE_2(Y0)) ^ \
792 AES_FT3(MBEDTLS_BYTE_3(Y1)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100793 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100794 (X3) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y3)) ^ \
795 AES_FT1(MBEDTLS_BYTE_1(Y0)) ^ \
796 AES_FT2(MBEDTLS_BYTE_2(Y1)) ^ \
797 AES_FT3(MBEDTLS_BYTE_3(Y2)); \
798 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000799
Gilles Peskine449bd832023-01-11 14:50:10 +0100800#define AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100801 do \
802 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100803 (X0) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y0)) ^ \
804 AES_RT1(MBEDTLS_BYTE_1(Y3)) ^ \
805 AES_RT2(MBEDTLS_BYTE_2(Y2)) ^ \
806 AES_RT3(MBEDTLS_BYTE_3(Y1)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100807 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100808 (X1) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y1)) ^ \
809 AES_RT1(MBEDTLS_BYTE_1(Y0)) ^ \
810 AES_RT2(MBEDTLS_BYTE_2(Y3)) ^ \
811 AES_RT3(MBEDTLS_BYTE_3(Y2)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100812 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100813 (X2) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y2)) ^ \
814 AES_RT1(MBEDTLS_BYTE_1(Y1)) ^ \
815 AES_RT2(MBEDTLS_BYTE_2(Y0)) ^ \
816 AES_RT3(MBEDTLS_BYTE_3(Y3)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100817 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100818 (X3) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y3)) ^ \
819 AES_RT1(MBEDTLS_BYTE_1(Y2)) ^ \
820 AES_RT2(MBEDTLS_BYTE_2(Y1)) ^ \
821 AES_RT3(MBEDTLS_BYTE_3(Y0)); \
822 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000823
824/*
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200825 * AES-ECB block encryption
826 */
827#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100828int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx,
829 const unsigned char input[16],
830 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200831{
832 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100833 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100834 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200835 uint32_t X[4];
836 uint32_t Y[4];
837 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200838
Gilles Peskine449bd832023-01-11 14:50:10 +0100839 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
840 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
841 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
842 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200843
Gilles Peskine449bd832023-01-11 14:50:10 +0100844 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
845 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]);
846 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 +0200847 }
848
Gilles Peskine449bd832023-01-11 14:50:10 +0100849 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 +0200850
Gilles Peskine5197c662020-08-26 17:03:24 +0200851 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100852 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
853 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
854 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
855 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200856
Gilles Peskine5197c662020-08-26 17:03:24 +0200857 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100858 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
859 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
860 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
861 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200862
Gilles Peskine5197c662020-08-26 17:03:24 +0200863 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100864 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
865 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
866 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
867 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200868
Gilles Peskine5197c662020-08-26 17:03:24 +0200869 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100870 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
871 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
872 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
873 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200874
Gilles Peskine449bd832023-01-11 14:50:10 +0100875 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
876 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
877 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
878 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +0000879
Gilles Peskine449bd832023-01-11 14:50:10 +0100880 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500881
Gilles Peskine449bd832023-01-11 14:50:10 +0100882 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200883}
884#endif /* !MBEDTLS_AES_ENCRYPT_ALT */
885
886/*
887 * AES-ECB block decryption
888 */
889#if !defined(MBEDTLS_AES_DECRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100890int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
891 const unsigned char input[16],
892 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200893{
894 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100895 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100896 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200897 uint32_t X[4];
898 uint32_t Y[4];
899 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200900
Gilles Peskine449bd832023-01-11 14:50:10 +0100901 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
902 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
903 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
904 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200905
Gilles Peskine449bd832023-01-11 14:50:10 +0100906 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
907 AES_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]);
908 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 +0200909 }
910
Gilles Peskine449bd832023-01-11 14:50:10 +0100911 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 +0200912
Gilles Peskine5197c662020-08-26 17:03:24 +0200913 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100914 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
915 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
916 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
917 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200918
Gilles Peskine5197c662020-08-26 17:03:24 +0200919 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100920 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
921 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
922 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
923 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200924
Gilles Peskine5197c662020-08-26 17:03:24 +0200925 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100926 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
927 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
928 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
929 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200930
Gilles Peskine5197c662020-08-26 17:03:24 +0200931 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100932 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
933 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
934 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
935 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200936
Gilles Peskine449bd832023-01-11 14:50:10 +0100937 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
938 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
939 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
940 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +0000941
Gilles Peskine449bd832023-01-11 14:50:10 +0100942 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500943
Gilles Peskine449bd832023-01-11 14:50:10 +0100944 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200945}
946#endif /* !MBEDTLS_AES_DECRYPT_ALT */
947
948/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000949 * AES-ECB block encryption/decryption
950 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100951int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
952 int mode,
953 const unsigned char input[16],
954 unsigned char output[16])
Paul Bakker5121ce52009-01-03 21:22:43 +0000955{
Gilles Peskine449bd832023-01-11 14:50:10 +0100956 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +0100957 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100958 }
Manuel Pégourié-Gonnard1aca2602018-12-12 12:56:55 +0100959
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100960#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100961 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
962 return mbedtls_aesni_crypt_ecb(ctx, mode, input, output);
963 }
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +0100964#endif
965
Jerry Yu2bb3d812023-01-10 17:38:26 +0800966#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
967 if (mbedtls_aesce_has_support()) {
968 return mbedtls_aesce_crypt_ecb(ctx, mode, input, output);
969 }
970#endif
971
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200972#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Gilles Peskine449bd832023-01-11 14:50:10 +0100973 if (aes_padlock_ace > 0) {
974 if (mbedtls_padlock_xcryptecb(ctx, mode, input, output) == 0) {
975 return 0;
976 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000977
978 // If padlock data misaligned, we just fall back to
979 // unaccelerated mode
980 //
Paul Bakker5121ce52009-01-03 21:22:43 +0000981 }
982#endif
983
Gilles Peskine449bd832023-01-11 14:50:10 +0100984 if (mode == MBEDTLS_AES_ENCRYPT) {
985 return mbedtls_internal_aes_encrypt(ctx, input, output);
986 } else {
987 return mbedtls_internal_aes_decrypt(ctx, input, output);
988 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000989}
990
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200991#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000992/*
993 * AES-CBC buffer encryption/decryption
994 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100995int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
996 int mode,
997 size_t length,
998 unsigned char iv[16],
999 const unsigned char *input,
1000 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001001{
Gilles Peskine7820a572021-07-07 21:08:28 +02001002 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +00001003 unsigned char temp[16];
1004
Gilles Peskine449bd832023-01-11 14:50:10 +01001005 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001006 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001007 }
Manuel Pégourié-Gonnard3178d1a2018-12-12 13:05:00 +01001008
Gilles Peskine449bd832023-01-11 14:50:10 +01001009 if (length % 16) {
1010 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
1011 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001012
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001013#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Gilles Peskine449bd832023-01-11 14:50:10 +01001014 if (aes_padlock_ace > 0) {
1015 if (mbedtls_padlock_xcryptcbc(ctx, mode, length, iv, input, output) == 0) {
1016 return 0;
1017 }
Paul Bakker9af723c2014-05-01 13:03:14 +02001018
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001019 // If padlock data misaligned, we just fall back to
1020 // unaccelerated mode
1021 //
Paul Bakker5121ce52009-01-03 21:22:43 +00001022 }
1023#endif
1024
Gilles Peskine449bd832023-01-11 14:50:10 +01001025 if (mode == MBEDTLS_AES_DECRYPT) {
1026 while (length > 0) {
1027 memcpy(temp, input, 16);
1028 ret = mbedtls_aes_crypt_ecb(ctx, mode, input, output);
1029 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001030 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001031 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001032
Gilles Peskine449bd832023-01-11 14:50:10 +01001033 mbedtls_xor(output, output, iv, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001034
Gilles Peskine449bd832023-01-11 14:50:10 +01001035 memcpy(iv, temp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001036
1037 input += 16;
1038 output += 16;
1039 length -= 16;
1040 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001041 } else {
1042 while (length > 0) {
1043 mbedtls_xor(output, input, iv, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001044
Gilles Peskine449bd832023-01-11 14:50:10 +01001045 ret = mbedtls_aes_crypt_ecb(ctx, mode, output, output);
1046 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001047 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001048 }
1049 memcpy(iv, output, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001050
1051 input += 16;
1052 output += 16;
1053 length -= 16;
1054 }
1055 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001056 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001057
Gilles Peskine7820a572021-07-07 21:08:28 +02001058exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001059 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001060}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001061#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001062
Aorimn5f778012016-06-09 23:22:58 +02001063#if defined(MBEDTLS_CIPHER_MODE_XTS)
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001064
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001065typedef unsigned char mbedtls_be128[16];
1066
1067/*
1068 * GF(2^128) multiplication function
1069 *
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001070 * This function multiplies a field element by x in the polynomial field
1071 * representation. It uses 64-bit word operations to gain speed but compensates
Shaun Case8b0ecbc2021-12-20 21:14:10 -08001072 * for machine endianness and hence works correctly on both big and little
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001073 * endian machines.
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001074 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001075static void mbedtls_gf128mul_x_ble(unsigned char r[16],
1076 const unsigned char x[16])
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001077{
1078 uint64_t a, b, ra, rb;
1079
Gilles Peskine449bd832023-01-11 14:50:10 +01001080 a = MBEDTLS_GET_UINT64_LE(x, 0);
1081 b = MBEDTLS_GET_UINT64_LE(x, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001082
Gilles Peskine449bd832023-01-11 14:50:10 +01001083 ra = (a << 1) ^ 0x0087 >> (8 - ((b >> 63) << 3));
1084 rb = (a >> 63) | (b << 1);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001085
Gilles Peskine449bd832023-01-11 14:50:10 +01001086 MBEDTLS_PUT_UINT64_LE(ra, r, 0);
1087 MBEDTLS_PUT_UINT64_LE(rb, r, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001088}
1089
Aorimn5f778012016-06-09 23:22:58 +02001090/*
1091 * AES-XTS buffer encryption/decryption
1092 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001093int mbedtls_aes_crypt_xts(mbedtls_aes_xts_context *ctx,
1094 int mode,
1095 size_t length,
1096 const unsigned char data_unit[16],
1097 const unsigned char *input,
1098 unsigned char *output)
Aorimn5f778012016-06-09 23:22:58 +02001099{
Janos Follath24eed8d2019-11-22 13:21:35 +00001100 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amerod82cd862018-04-28 15:02:45 +01001101 size_t blocks = length / 16;
1102 size_t leftover = length % 16;
1103 unsigned char tweak[16];
1104 unsigned char prev_tweak[16];
1105 unsigned char tmp[16];
Aorimn5f778012016-06-09 23:22:58 +02001106
Gilles Peskine449bd832023-01-11 14:50:10 +01001107 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001108 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001109 }
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01001110
Jaeden Amero8381fcb2018-10-11 12:06:15 +01001111 /* Data units must be at least 16 bytes long. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001112 if (length < 16) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001113 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001114 }
Aorimn5f778012016-06-09 23:22:58 +02001115
Jaeden Ameroa74faba2018-10-11 12:07:43 +01001116 /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001117 if (length > (1 << 20) * 16) {
Jaeden Amero0a8b0202018-05-30 15:36:06 +01001118 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001119 }
Aorimn5f778012016-06-09 23:22:58 +02001120
Jaeden Amerod82cd862018-04-28 15:02:45 +01001121 /* Compute the tweak. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001122 ret = mbedtls_aes_crypt_ecb(&ctx->tweak, MBEDTLS_AES_ENCRYPT,
1123 data_unit, tweak);
1124 if (ret != 0) {
1125 return ret;
1126 }
Aorimn5f778012016-06-09 23:22:58 +02001127
Gilles Peskine449bd832023-01-11 14:50:10 +01001128 while (blocks--) {
1129 if (leftover && (mode == MBEDTLS_AES_DECRYPT) && blocks == 0) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001130 /* We are on the last block in a decrypt operation that has
1131 * leftover bytes, so we need to use the next tweak for this block,
Tom Cosgrove1797b052022-12-04 17:19:59 +00001132 * and this tweak for the leftover bytes. Save the current tweak for
Jaeden Amerod82cd862018-04-28 15:02:45 +01001133 * the leftovers and then update the current tweak for use on this,
1134 * the last full block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001135 memcpy(prev_tweak, tweak, sizeof(tweak));
1136 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001137 }
1138
Gilles Peskine449bd832023-01-11 14:50:10 +01001139 mbedtls_xor(tmp, input, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001140
Gilles Peskine449bd832023-01-11 14:50:10 +01001141 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1142 if (ret != 0) {
1143 return ret;
1144 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001145
Gilles Peskine449bd832023-01-11 14:50:10 +01001146 mbedtls_xor(output, tmp, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001147
1148 /* Update the tweak for the next block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001149 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001150
1151 output += 16;
1152 input += 16;
Aorimn5f778012016-06-09 23:22:58 +02001153 }
1154
Gilles Peskine449bd832023-01-11 14:50:10 +01001155 if (leftover) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001156 /* If we are on the leftover bytes in a decrypt operation, we need to
1157 * use the previous tweak for these bytes (as saved in prev_tweak). */
1158 unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
Aorimn5f778012016-06-09 23:22:58 +02001159
Jaeden Amerod82cd862018-04-28 15:02:45 +01001160 /* We are now on the final part of the data unit, which doesn't divide
1161 * evenly by 16. It's time for ciphertext stealing. */
1162 size_t i;
1163 unsigned char *prev_output = output - 16;
Aorimn5f778012016-06-09 23:22:58 +02001164
Jaeden Amerod82cd862018-04-28 15:02:45 +01001165 /* Copy ciphertext bytes from the previous block to our output for each
Dave Rodgman069e7f42022-11-24 19:37:26 +00001166 * byte of ciphertext we won't steal. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001167 for (i = 0; i < leftover; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001168 output[i] = prev_output[i];
Aorimn5f778012016-06-09 23:22:58 +02001169 }
Aorimn5f778012016-06-09 23:22:58 +02001170
Dave Rodgman069e7f42022-11-24 19:37:26 +00001171 /* Copy the remainder of the input for this final round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001172 mbedtls_xor(tmp, input, t, leftover);
Dave Rodgmana8cf6072022-11-22 15:02:54 +00001173
Jaeden Amerod82cd862018-04-28 15:02:45 +01001174 /* Copy ciphertext bytes from the previous block for input in this
1175 * round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001176 mbedtls_xor(tmp + i, prev_output + i, t + i, 16 - i);
Aorimn5f778012016-06-09 23:22:58 +02001177
Gilles Peskine449bd832023-01-11 14:50:10 +01001178 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1179 if (ret != 0) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001180 return ret;
Gilles Peskine449bd832023-01-11 14:50:10 +01001181 }
Aorimn5f778012016-06-09 23:22:58 +02001182
Jaeden Amerod82cd862018-04-28 15:02:45 +01001183 /* Write the result back to the previous block, overriding the previous
1184 * output we copied. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001185 mbedtls_xor(prev_output, tmp, t, 16);
Aorimn5f778012016-06-09 23:22:58 +02001186 }
1187
Gilles Peskine449bd832023-01-11 14:50:10 +01001188 return 0;
Aorimn5f778012016-06-09 23:22:58 +02001189}
1190#endif /* MBEDTLS_CIPHER_MODE_XTS */
1191
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001192#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001193/*
1194 * AES-CFB128 buffer encryption/decryption
1195 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001196int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx,
1197 int mode,
1198 size_t length,
1199 size_t *iv_off,
1200 unsigned char iv[16],
1201 const unsigned char *input,
1202 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001203{
Paul Bakker27fdf462011-06-09 13:55:13 +00001204 int c;
Gilles Peskine7820a572021-07-07 21:08:28 +02001205 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001206 size_t n;
1207
Gilles Peskine449bd832023-01-11 14:50:10 +01001208 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001209 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001210 }
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001211
1212 n = *iv_off;
Paul Bakker5121ce52009-01-03 21:22:43 +00001213
Gilles Peskine449bd832023-01-11 14:50:10 +01001214 if (n > 15) {
1215 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1216 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001217
Gilles Peskine449bd832023-01-11 14:50:10 +01001218 if (mode == MBEDTLS_AES_DECRYPT) {
1219 while (length--) {
1220 if (n == 0) {
1221 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1222 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001223 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001224 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001225 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001226
1227 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001228 *output++ = (unsigned char) (c ^ iv[n]);
Paul Bakker5121ce52009-01-03 21:22:43 +00001229 iv[n] = (unsigned char) c;
1230
Gilles Peskine449bd832023-01-11 14:50:10 +01001231 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001232 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001233 } else {
1234 while (length--) {
1235 if (n == 0) {
1236 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1237 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001238 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001239 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001240 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001241
Gilles Peskine449bd832023-01-11 14:50:10 +01001242 iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++);
Paul Bakker5121ce52009-01-03 21:22:43 +00001243
Gilles Peskine449bd832023-01-11 14:50:10 +01001244 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001245 }
1246 }
1247
1248 *iv_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001249 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001250
Gilles Peskine7820a572021-07-07 21:08:28 +02001251exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001252 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001253}
Paul Bakker556efba2014-01-24 15:38:12 +01001254
1255/*
1256 * AES-CFB8 buffer encryption/decryption
1257 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001258int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx,
1259 int mode,
1260 size_t length,
1261 unsigned char iv[16],
1262 const unsigned char *input,
1263 unsigned char *output)
Paul Bakker556efba2014-01-24 15:38:12 +01001264{
Gilles Peskine7820a572021-07-07 21:08:28 +02001265 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker556efba2014-01-24 15:38:12 +01001266 unsigned char c;
1267 unsigned char ov[17];
1268
Gilles Peskine449bd832023-01-11 14:50:10 +01001269 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001270 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001271 }
1272 while (length--) {
1273 memcpy(ov, iv, 16);
1274 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1275 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001276 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001277 }
Paul Bakker556efba2014-01-24 15:38:12 +01001278
Gilles Peskine449bd832023-01-11 14:50:10 +01001279 if (mode == MBEDTLS_AES_DECRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001280 ov[16] = *input;
Gilles Peskine449bd832023-01-11 14:50:10 +01001281 }
Paul Bakker556efba2014-01-24 15:38:12 +01001282
Gilles Peskine449bd832023-01-11 14:50:10 +01001283 c = *output++ = (unsigned char) (iv[0] ^ *input++);
Paul Bakker556efba2014-01-24 15:38:12 +01001284
Gilles Peskine449bd832023-01-11 14:50:10 +01001285 if (mode == MBEDTLS_AES_ENCRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001286 ov[16] = c;
Gilles Peskine449bd832023-01-11 14:50:10 +01001287 }
Paul Bakker556efba2014-01-24 15:38:12 +01001288
Gilles Peskine449bd832023-01-11 14:50:10 +01001289 memcpy(iv, ov + 1, 16);
Paul Bakker556efba2014-01-24 15:38:12 +01001290 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001291 ret = 0;
Paul Bakker556efba2014-01-24 15:38:12 +01001292
Gilles Peskine7820a572021-07-07 21:08:28 +02001293exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001294 return ret;
Paul Bakker556efba2014-01-24 15:38:12 +01001295}
Simon Butcher76a5b222018-04-22 22:57:27 +01001296#endif /* MBEDTLS_CIPHER_MODE_CFB */
1297
1298#if defined(MBEDTLS_CIPHER_MODE_OFB)
1299/*
1300 * AES-OFB (Output Feedback Mode) buffer encryption/decryption
1301 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001302int mbedtls_aes_crypt_ofb(mbedtls_aes_context *ctx,
1303 size_t length,
1304 size_t *iv_off,
1305 unsigned char iv[16],
1306 const unsigned char *input,
1307 unsigned char *output)
Simon Butcher76a5b222018-04-22 22:57:27 +01001308{
Simon Butcherad4e4932018-04-29 00:43:47 +01001309 int ret = 0;
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001310 size_t n;
1311
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001312 n = *iv_off;
Simon Butcher76a5b222018-04-22 22:57:27 +01001313
Gilles Peskine449bd832023-01-11 14:50:10 +01001314 if (n > 15) {
1315 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1316 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001317
Gilles Peskine449bd832023-01-11 14:50:10 +01001318 while (length--) {
1319 if (n == 0) {
1320 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1321 if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001322 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001323 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001324 }
Simon Butcher76a5b222018-04-22 22:57:27 +01001325 *output++ = *input++ ^ iv[n];
1326
Gilles Peskine449bd832023-01-11 14:50:10 +01001327 n = (n + 1) & 0x0F;
Simon Butcher76a5b222018-04-22 22:57:27 +01001328 }
1329
1330 *iv_off = n;
1331
Simon Butcherad4e4932018-04-29 00:43:47 +01001332exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001333 return ret;
Simon Butcher76a5b222018-04-22 22:57:27 +01001334}
1335#endif /* MBEDTLS_CIPHER_MODE_OFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001336
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001337#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001338/*
1339 * AES-CTR buffer encryption/decryption
1340 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001341int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
1342 size_t length,
1343 size_t *nc_off,
1344 unsigned char nonce_counter[16],
1345 unsigned char stream_block[16],
1346 const unsigned char *input,
1347 unsigned char *output)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001348{
Paul Bakker369e14b2012-04-18 14:16:09 +00001349 int c, i;
Gilles Peskine7820a572021-07-07 21:08:28 +02001350 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001351 size_t n;
1352
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001353 n = *nc_off;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001354
Gilles Peskine449bd832023-01-11 14:50:10 +01001355 if (n > 0x0F) {
1356 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1357 }
Mohammad Azim Khan3f7f8172017-11-23 17:49:05 +00001358
Gilles Peskine449bd832023-01-11 14:50:10 +01001359 while (length--) {
1360 if (n == 0) {
1361 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block);
1362 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001363 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001364 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001365
Gilles Peskine449bd832023-01-11 14:50:10 +01001366 for (i = 16; i > 0; i--) {
1367 if (++nonce_counter[i - 1] != 0) {
Paul Bakker369e14b2012-04-18 14:16:09 +00001368 break;
Gilles Peskine449bd832023-01-11 14:50:10 +01001369 }
1370 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001371 }
1372 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001373 *output++ = (unsigned char) (c ^ stream_block[n]);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001374
Gilles Peskine449bd832023-01-11 14:50:10 +01001375 n = (n + 1) & 0x0F;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001376 }
1377
1378 *nc_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001379 ret = 0;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001380
Gilles Peskine7820a572021-07-07 21:08:28 +02001381exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001382 return ret;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001383}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001384#endif /* MBEDTLS_CIPHER_MODE_CTR */
Manuel Pégourié-Gonnard1ec220b2014-03-10 11:20:17 +01001385
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001386#endif /* !MBEDTLS_AES_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001387
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001388#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001389/*
1390 * AES test vectors from:
1391 *
1392 * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
1393 */
1394static const unsigned char aes_test_ecb_dec[3][16] =
1395{
1396 { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
1397 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
1398 { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
1399 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
1400 { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
1401 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
1402};
1403
1404static const unsigned char aes_test_ecb_enc[3][16] =
1405{
1406 { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
1407 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
1408 { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
1409 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
1410 { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
1411 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
1412};
1413
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001414#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001415static const unsigned char aes_test_cbc_dec[3][16] =
1416{
1417 { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
1418 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
1419 { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
1420 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
1421 { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
1422 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
1423};
1424
1425static const unsigned char aes_test_cbc_enc[3][16] =
1426{
1427 { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
1428 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
1429 { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
1430 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
1431 { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
1432 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
1433};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001434#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001435
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001436#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001437/*
1438 * AES-CFB128 test vectors from:
1439 *
1440 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
1441 */
1442static const unsigned char aes_test_cfb128_key[3][32] =
1443{
1444 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1445 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
1446 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1447 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1448 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1449 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1450 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1451 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1452 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
1453};
1454
1455static const unsigned char aes_test_cfb128_iv[16] =
1456{
1457 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1458 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1459};
1460
1461static const unsigned char aes_test_cfb128_pt[64] =
1462{
1463 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1464 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1465 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1466 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1467 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1468 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1469 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1470 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1471};
1472
1473static const unsigned char aes_test_cfb128_ct[3][64] =
1474{
1475 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1476 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1477 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F,
1478 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B,
1479 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40,
1480 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF,
1481 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E,
1482 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 },
1483 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1484 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1485 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21,
1486 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A,
1487 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1,
1488 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9,
1489 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0,
1490 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF },
1491 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1492 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1493 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8,
1494 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B,
1495 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92,
1496 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9,
1497 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8,
1498 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 }
1499};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001500#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001501
Simon Butcherad4e4932018-04-29 00:43:47 +01001502#if defined(MBEDTLS_CIPHER_MODE_OFB)
1503/*
1504 * AES-OFB test vectors from:
1505 *
Simon Butcher5db13622018-06-04 22:11:25 +01001506 * https://csrc.nist.gov/publications/detail/sp/800-38a/final
Simon Butcherad4e4932018-04-29 00:43:47 +01001507 */
1508static const unsigned char aes_test_ofb_key[3][32] =
1509{
1510 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1511 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
1512 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1513 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1514 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1515 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1516 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1517 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1518 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
1519};
1520
1521static const unsigned char aes_test_ofb_iv[16] =
1522{
1523 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1524 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1525};
1526
1527static const unsigned char aes_test_ofb_pt[64] =
1528{
1529 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1530 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1531 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1532 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1533 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1534 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1535 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1536 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1537};
1538
1539static const unsigned char aes_test_ofb_ct[3][64] =
1540{
1541 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1542 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1543 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
1544 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
1545 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
1546 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
1547 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
1548 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e },
1549 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1550 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1551 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
1552 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
1553 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f,
1554 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
1555 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e,
1556 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a },
1557 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1558 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1559 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
1560 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
1561 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed,
1562 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
1563 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8,
1564 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 }
1565};
1566#endif /* MBEDTLS_CIPHER_MODE_OFB */
1567
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001568#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001569/*
1570 * AES-CTR test vectors from:
1571 *
1572 * http://www.faqs.org/rfcs/rfc3686.html
1573 */
1574
1575static const unsigned char aes_test_ctr_key[3][16] =
1576{
1577 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
1578 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
1579 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
1580 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
1581 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
1582 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
1583};
1584
1585static const unsigned char aes_test_ctr_nonce_counter[3][16] =
1586{
1587 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
1588 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
1589 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
1590 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
1591 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
1592 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
1593};
1594
1595static const unsigned char aes_test_ctr_pt[3][48] =
1596{
1597 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
1598 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
1599
1600 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1601 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1602 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1603 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
1604
1605 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1606 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1607 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1608 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
1609 0x20, 0x21, 0x22, 0x23 }
1610};
1611
1612static const unsigned char aes_test_ctr_ct[3][48] =
1613{
1614 { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79,
1615 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 },
1616 { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9,
1617 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88,
1618 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8,
1619 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 },
1620 { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
1621 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
1622 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
1623 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
1624 0x25, 0xB2, 0x07, 0x2F }
1625};
1626
1627static const int aes_test_ctr_len[3] =
Gilles Peskine449bd832023-01-11 14:50:10 +01001628{ 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001629#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00001630
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001631#if defined(MBEDTLS_CIPHER_MODE_XTS)
1632/*
1633 * AES-XTS test vectors from:
1634 *
1635 * IEEE P1619/D16 Annex B
1636 * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf
1637 * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf)
1638 */
1639static const unsigned char aes_test_xts_key[][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 { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1646 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1647 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1648 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1649 { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
1650 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
1651 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1652 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1653};
1654
1655static const unsigned char aes_test_xts_pt32[][32] =
1656{
1657 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1658 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1659 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1660 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1661 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1662 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1663 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1664 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1665 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1666 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1667 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1668 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1669};
1670
1671static const unsigned char aes_test_xts_ct32[][32] =
1672{
1673 { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec,
1674 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92,
1675 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85,
1676 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e },
1677 { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e,
1678 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b,
1679 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4,
1680 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 },
1681 { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a,
1682 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2,
1683 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53,
1684 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 },
1685};
1686
1687static const unsigned char aes_test_xts_data_unit[][16] =
1688{
Gilles Peskine449bd832023-01-11 14:50:10 +01001689 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1690 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1691 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1692 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1693 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1694 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001695};
1696
1697#endif /* MBEDTLS_CIPHER_MODE_XTS */
1698
Paul Bakker5121ce52009-01-03 21:22:43 +00001699/*
1700 * Checkup routine
1701 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001702int mbedtls_aes_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +00001703{
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001704 int ret = 0, i, j, u, mode;
1705 unsigned int keybits;
Paul Bakker5121ce52009-01-03 21:22:43 +00001706 unsigned char key[32];
1707 unsigned char buf[64];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001708 const unsigned char *aes_tests;
Andrzej Kurek252283f2022-09-27 07:54:16 -04001709#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1710 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001711 unsigned char iv[16];
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03001712#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001713#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +02001714 unsigned char prv[16];
1715#endif
Simon Butcher2ff0e522018-06-14 09:57:07 +01001716#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1717 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker27fdf462011-06-09 13:55:13 +00001718 size_t offset;
Paul Bakkere91d01e2011-04-19 15:55:50 +00001719#endif
Simon Butcher66a89032018-06-15 18:20:29 +01001720#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS)
Paul Bakkere91d01e2011-04-19 15:55:50 +00001721 int len;
Simon Butcher66a89032018-06-15 18:20:29 +01001722#endif
1723#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001724 unsigned char nonce_counter[16];
1725 unsigned char stream_block[16];
1726#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001727 mbedtls_aes_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001728
Gilles Peskine449bd832023-01-11 14:50:10 +01001729 memset(key, 0, 32);
1730 mbedtls_aes_init(&ctx);
Paul Bakker5121ce52009-01-03 21:22:43 +00001731
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001732 if (verbose != 0) {
1733#if defined(MBEDTLS_AES_ALT)
1734 mbedtls_printf(" AES note: alternative implementation.\n");
1735#else /* MBEDTLS_AES_ALT */
1736#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
1737 if (mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE)) {
1738 mbedtls_printf(" AES note: using VIA Padlock.\n");
1739 } else
1740#endif
1741#if defined(MBEDTLS_AESNI_HAVE_CODE)
1742 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1743 mbedtls_printf(" AES note: using AESNI.\n");
1744 } else
1745#endif
1746#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
1747 if (mbedtls_aesce_has_support()) {
1748 mbedtls_printf(" AES note: using AESCE.\n");
1749 } else
1750#endif
1751 mbedtls_printf(" AES note: built-in implementation.\n");
1752#endif /* MBEDTLS_AES_ALT */
1753 }
1754
Paul Bakker5121ce52009-01-03 21:22:43 +00001755 /*
1756 * ECB mode
1757 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001758 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +00001759 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001760 keybits = 128 + u * 64;
1761 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001762
Gilles Peskine449bd832023-01-11 14:50:10 +01001763 if (verbose != 0) {
1764 mbedtls_printf(" AES-ECB-%3u (%s): ", keybits,
1765 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00001766 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001767
1768 memset(buf, 0, 16);
1769
1770 if (mode == MBEDTLS_AES_DECRYPT) {
1771 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1772 aes_tests = aes_test_ecb_dec[u];
1773 } else {
1774 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001775 aes_tests = aes_test_ecb_enc[u];
1776 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001777
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01001778 /*
1779 * AES-192 is an optional feature that may be unavailable when
1780 * there is an alternative underlying implementation i.e. when
1781 * MBEDTLS_AES_ALT is defined.
1782 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001783 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1784 mbedtls_printf("skipped\n");
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001785 continue;
Gilles Peskine449bd832023-01-11 14:50:10 +01001786 } else if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001787 goto exit;
1788 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001789
Gilles Peskine449bd832023-01-11 14:50:10 +01001790 for (j = 0; j < 10000; j++) {
1791 ret = mbedtls_aes_crypt_ecb(&ctx, mode, buf, buf);
1792 if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001793 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001794 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001795 }
1796
Gilles Peskine449bd832023-01-11 14:50:10 +01001797 if (memcmp(buf, aes_tests, 16) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001798 ret = 1;
1799 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001800 }
1801
Gilles Peskine449bd832023-01-11 14:50:10 +01001802 if (verbose != 0) {
1803 mbedtls_printf("passed\n");
1804 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001805 }
1806
Gilles Peskine449bd832023-01-11 14:50:10 +01001807 if (verbose != 0) {
1808 mbedtls_printf("\n");
1809 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001810
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001811#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001812 /*
1813 * CBC mode
1814 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001815 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +00001816 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001817 keybits = 128 + u * 64;
1818 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001819
Gilles Peskine449bd832023-01-11 14:50:10 +01001820 if (verbose != 0) {
1821 mbedtls_printf(" AES-CBC-%3u (%s): ", keybits,
1822 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00001823 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001824
1825 memset(iv, 0, 16);
1826 memset(prv, 0, 16);
1827 memset(buf, 0, 16);
1828
1829 if (mode == MBEDTLS_AES_DECRYPT) {
1830 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1831 aes_tests = aes_test_cbc_dec[u];
1832 } else {
1833 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001834 aes_tests = aes_test_cbc_enc[u];
1835 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001836
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01001837 /*
1838 * AES-192 is an optional feature that may be unavailable when
1839 * there is an alternative underlying implementation i.e. when
1840 * MBEDTLS_AES_ALT is defined.
1841 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001842 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1843 mbedtls_printf("skipped\n");
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001844 continue;
Gilles Peskine449bd832023-01-11 14:50:10 +01001845 } else if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001846 goto exit;
1847 }
1848
Gilles Peskine449bd832023-01-11 14:50:10 +01001849 for (j = 0; j < 10000; j++) {
1850 if (mode == MBEDTLS_AES_ENCRYPT) {
Paul Bakker5121ce52009-01-03 21:22:43 +00001851 unsigned char tmp[16];
1852
Gilles Peskine449bd832023-01-11 14:50:10 +01001853 memcpy(tmp, prv, 16);
1854 memcpy(prv, buf, 16);
1855 memcpy(buf, tmp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001856 }
1857
Gilles Peskine449bd832023-01-11 14:50:10 +01001858 ret = mbedtls_aes_crypt_cbc(&ctx, mode, 16, iv, buf, buf);
1859 if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001860 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001861 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001862
1863 }
1864
Gilles Peskine449bd832023-01-11 14:50:10 +01001865 if (memcmp(buf, aes_tests, 16) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001866 ret = 1;
1867 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001868 }
1869
Gilles Peskine449bd832023-01-11 14:50:10 +01001870 if (verbose != 0) {
1871 mbedtls_printf("passed\n");
1872 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001873 }
1874
Gilles Peskine449bd832023-01-11 14:50:10 +01001875 if (verbose != 0) {
1876 mbedtls_printf("\n");
1877 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001878#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001879
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001880#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001881 /*
1882 * CFB128 mode
1883 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001884 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +00001885 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001886 keybits = 128 + u * 64;
1887 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001888
Gilles Peskine449bd832023-01-11 14:50:10 +01001889 if (verbose != 0) {
1890 mbedtls_printf(" AES-CFB128-%3u (%s): ", keybits,
1891 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
1892 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001893
Gilles Peskine449bd832023-01-11 14:50:10 +01001894 memcpy(iv, aes_test_cfb128_iv, 16);
1895 memcpy(key, aes_test_cfb128_key[u], keybits / 8);
Paul Bakker5121ce52009-01-03 21:22:43 +00001896
1897 offset = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +01001898 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01001899 /*
1900 * AES-192 is an optional feature that may be unavailable when
1901 * there is an alternative underlying implementation i.e. when
1902 * MBEDTLS_AES_ALT is defined.
1903 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001904 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1905 mbedtls_printf("skipped\n");
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001906 continue;
Gilles Peskine449bd832023-01-11 14:50:10 +01001907 } else if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001908 goto exit;
1909 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001910
Gilles Peskine449bd832023-01-11 14:50:10 +01001911 if (mode == MBEDTLS_AES_DECRYPT) {
1912 memcpy(buf, aes_test_cfb128_ct[u], 64);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001913 aes_tests = aes_test_cfb128_pt;
Gilles Peskine449bd832023-01-11 14:50:10 +01001914 } else {
1915 memcpy(buf, aes_test_cfb128_pt, 64);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001916 aes_tests = aes_test_cfb128_ct[u];
1917 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001918
Gilles Peskine449bd832023-01-11 14:50:10 +01001919 ret = mbedtls_aes_crypt_cfb128(&ctx, mode, 64, &offset, iv, buf, buf);
1920 if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001921 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001922 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001923
Gilles Peskine449bd832023-01-11 14:50:10 +01001924 if (memcmp(buf, aes_tests, 64) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001925 ret = 1;
1926 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001927 }
1928
Gilles Peskine449bd832023-01-11 14:50:10 +01001929 if (verbose != 0) {
1930 mbedtls_printf("passed\n");
1931 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001932 }
1933
Gilles Peskine449bd832023-01-11 14:50:10 +01001934 if (verbose != 0) {
1935 mbedtls_printf("\n");
1936 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001937#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001938
Simon Butcherad4e4932018-04-29 00:43:47 +01001939#if defined(MBEDTLS_CIPHER_MODE_OFB)
1940 /*
1941 * OFB mode
1942 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001943 for (i = 0; i < 6; i++) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001944 u = i >> 1;
1945 keybits = 128 + u * 64;
1946 mode = i & 1;
1947
Gilles Peskine449bd832023-01-11 14:50:10 +01001948 if (verbose != 0) {
1949 mbedtls_printf(" AES-OFB-%3u (%s): ", keybits,
1950 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
1951 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001952
Gilles Peskine449bd832023-01-11 14:50:10 +01001953 memcpy(iv, aes_test_ofb_iv, 16);
1954 memcpy(key, aes_test_ofb_key[u], keybits / 8);
Simon Butcherad4e4932018-04-29 00:43:47 +01001955
1956 offset = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +01001957 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Simon Butcherad4e4932018-04-29 00:43:47 +01001958 /*
1959 * AES-192 is an optional feature that may be unavailable when
1960 * there is an alternative underlying implementation i.e. when
1961 * MBEDTLS_AES_ALT is defined.
1962 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001963 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1964 mbedtls_printf("skipped\n");
Simon Butcherad4e4932018-04-29 00:43:47 +01001965 continue;
Gilles Peskine449bd832023-01-11 14:50:10 +01001966 } else if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001967 goto exit;
1968 }
1969
Gilles Peskine449bd832023-01-11 14:50:10 +01001970 if (mode == MBEDTLS_AES_DECRYPT) {
1971 memcpy(buf, aes_test_ofb_ct[u], 64);
Simon Butcherad4e4932018-04-29 00:43:47 +01001972 aes_tests = aes_test_ofb_pt;
Gilles Peskine449bd832023-01-11 14:50:10 +01001973 } else {
1974 memcpy(buf, aes_test_ofb_pt, 64);
Simon Butcherad4e4932018-04-29 00:43:47 +01001975 aes_tests = aes_test_ofb_ct[u];
1976 }
1977
Gilles Peskine449bd832023-01-11 14:50:10 +01001978 ret = mbedtls_aes_crypt_ofb(&ctx, 64, &offset, iv, buf, buf);
1979 if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001980 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001981 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001982
Gilles Peskine449bd832023-01-11 14:50:10 +01001983 if (memcmp(buf, aes_tests, 64) != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001984 ret = 1;
1985 goto exit;
1986 }
1987
Gilles Peskine449bd832023-01-11 14:50:10 +01001988 if (verbose != 0) {
1989 mbedtls_printf("passed\n");
1990 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001991 }
1992
Gilles Peskine449bd832023-01-11 14:50:10 +01001993 if (verbose != 0) {
1994 mbedtls_printf("\n");
1995 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001996#endif /* MBEDTLS_CIPHER_MODE_OFB */
1997
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001998#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001999 /*
2000 * CTR mode
2001 */
Gilles Peskine449bd832023-01-11 14:50:10 +01002002 for (i = 0; i < 6; i++) {
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002003 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002004 mode = i & 1;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002005
Gilles Peskine449bd832023-01-11 14:50:10 +01002006 if (verbose != 0) {
2007 mbedtls_printf(" AES-CTR-128 (%s): ",
2008 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2009 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002010
Gilles Peskine449bd832023-01-11 14:50:10 +01002011 memcpy(nonce_counter, aes_test_ctr_nonce_counter[u], 16);
2012 memcpy(key, aes_test_ctr_key[u], 16);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002013
2014 offset = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +01002015 if ((ret = mbedtls_aes_setkey_enc(&ctx, key, 128)) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002016 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002017 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002018
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002019 len = aes_test_ctr_len[u];
2020
Gilles Peskine449bd832023-01-11 14:50:10 +01002021 if (mode == MBEDTLS_AES_DECRYPT) {
2022 memcpy(buf, aes_test_ctr_ct[u], len);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002023 aes_tests = aes_test_ctr_pt[u];
Gilles Peskine449bd832023-01-11 14:50:10 +01002024 } else {
2025 memcpy(buf, aes_test_ctr_pt[u], len);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002026 aes_tests = aes_test_ctr_ct[u];
2027 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002028
Gilles Peskine449bd832023-01-11 14:50:10 +01002029 ret = mbedtls_aes_crypt_ctr(&ctx, len, &offset, nonce_counter,
2030 stream_block, buf, buf);
2031 if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002032 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002033 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002034
Gilles Peskine449bd832023-01-11 14:50:10 +01002035 if (memcmp(buf, aes_tests, len) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002036 ret = 1;
2037 goto exit;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002038 }
2039
Gilles Peskine449bd832023-01-11 14:50:10 +01002040 if (verbose != 0) {
2041 mbedtls_printf("passed\n");
2042 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002043 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002044
Gilles Peskine449bd832023-01-11 14:50:10 +01002045 if (verbose != 0) {
2046 mbedtls_printf("\n");
2047 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002048#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00002049
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002050#if defined(MBEDTLS_CIPHER_MODE_XTS)
2051 {
Gilles Peskine449bd832023-01-11 14:50:10 +01002052 static const int num_tests =
2053 sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key);
2054 mbedtls_aes_xts_context ctx_xts;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002055
Gilles Peskine449bd832023-01-11 14:50:10 +01002056 /*
2057 * XTS mode
2058 */
2059 mbedtls_aes_xts_init(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002060
Gilles Peskine449bd832023-01-11 14:50:10 +01002061 for (i = 0; i < num_tests << 1; i++) {
2062 const unsigned char *data_unit;
2063 u = i >> 1;
2064 mode = i & 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002065
Gilles Peskine449bd832023-01-11 14:50:10 +01002066 if (verbose != 0) {
2067 mbedtls_printf(" AES-XTS-128 (%s): ",
2068 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2069 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002070
Gilles Peskine449bd832023-01-11 14:50:10 +01002071 memset(key, 0, sizeof(key));
2072 memcpy(key, aes_test_xts_key[u], 32);
2073 data_unit = aes_test_xts_data_unit[u];
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002074
Gilles Peskine449bd832023-01-11 14:50:10 +01002075 len = sizeof(*aes_test_xts_ct32);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002076
Gilles Peskine449bd832023-01-11 14:50:10 +01002077 if (mode == MBEDTLS_AES_DECRYPT) {
2078 ret = mbedtls_aes_xts_setkey_dec(&ctx_xts, key, 256);
2079 if (ret != 0) {
2080 goto exit;
2081 }
2082 memcpy(buf, aes_test_xts_ct32[u], len);
2083 aes_tests = aes_test_xts_pt32[u];
2084 } else {
2085 ret = mbedtls_aes_xts_setkey_enc(&ctx_xts, key, 256);
2086 if (ret != 0) {
2087 goto exit;
2088 }
2089 memcpy(buf, aes_test_xts_pt32[u], len);
2090 aes_tests = aes_test_xts_ct32[u];
2091 }
2092
2093
2094 ret = mbedtls_aes_crypt_xts(&ctx_xts, mode, len, data_unit,
2095 buf, buf);
2096 if (ret != 0) {
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002097 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002098 }
2099
2100 if (memcmp(buf, aes_tests, len) != 0) {
2101 ret = 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002102 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002103 }
2104
2105 if (verbose != 0) {
2106 mbedtls_printf("passed\n");
2107 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002108 }
2109
Gilles Peskine449bd832023-01-11 14:50:10 +01002110 if (verbose != 0) {
2111 mbedtls_printf("\n");
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002112 }
2113
Gilles Peskine449bd832023-01-11 14:50:10 +01002114 mbedtls_aes_xts_free(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002115 }
2116#endif /* MBEDTLS_CIPHER_MODE_XTS */
2117
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002118 ret = 0;
2119
2120exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01002121 if (ret != 0 && verbose != 0) {
2122 mbedtls_printf("failed\n");
2123 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002124
Gilles Peskine449bd832023-01-11 14:50:10 +01002125 mbedtls_aes_free(&ctx);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002126
Gilles Peskine449bd832023-01-11 14:50:10 +01002127 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002128}
2129
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002130#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002131
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002132#endif /* MBEDTLS_AES_C */