blob: 6306fecf84b28237219cbee405469c3c53480bf1 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * FIPS-197 compliant AES implementation
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Paul Bakker5121ce52009-01-03 21:22:43 +000018 */
19/*
20 * The AES block cipher was designed by Vincent Rijmen and Joan Daemen.
21 *
22 * http://csrc.nist.gov/encryption/aes/rijndael/Rijndael.pdf
23 * http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
24 */
25
Gilles Peskinedb09ef62020-06-03 01:43:33 +020026#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000027
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020028#if defined(MBEDTLS_AES_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000029
Rich Evans00ab4702015-02-06 13:43:58 +000030#include <string.h>
31
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000032#include "mbedtls/aes.h"
Ron Eldor9924bdc2018-10-04 10:59:13 +030033#include "mbedtls/platform.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050034#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000035#include "mbedtls/error.h"
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020036#if defined(MBEDTLS_PADLOCK_C)
Chris Jones16dbaeb2021-03-09 17:47:55 +000037#include "padlock.h"
Paul Bakker67820bd2012-06-04 12:47:23 +000038#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020039#if defined(MBEDTLS_AESNI_C)
Chris Jones187782f2021-03-09 17:28:35 +000040#include "aesni.h"
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +010041#endif
Jerry Yu3f2fb712023-01-10 17:05:42 +080042#if defined(MBEDTLS_AESCE_C)
43#include "aesce.h"
44#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000045
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000046#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010047
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020048#if !defined(MBEDTLS_AES_ALT)
Paul Bakker90995b52013-06-24 19:20:35 +020049
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020050#if defined(MBEDTLS_PADLOCK_C) && \
Gilles Peskine449bd832023-01-11 14:50:10 +010051 (defined(MBEDTLS_HAVE_X86) || defined(MBEDTLS_PADLOCK_ALIGN16))
Paul Bakker048d04e2012-02-12 17:31:04 +000052static int aes_padlock_ace = -1;
53#endif
54
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020055#if defined(MBEDTLS_AES_ROM_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +000056/*
57 * Forward S-box
58 */
59static const unsigned char FSb[256] =
60{
61 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
62 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
63 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
64 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
65 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
66 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
67 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
68 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
69 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
70 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
71 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
72 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
73 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
74 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
75 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
76 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
77 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
78 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
79 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
80 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
81 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
82 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
83 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
84 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
85 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
86 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
87 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
88 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
89 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
90 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
91 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
92 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
93};
94
95/*
96 * Forward tables
97 */
98#define FT \
99\
Gilles Peskine449bd832023-01-11 14:50:10 +0100100 V(A5, 63, 63, C6), V(84, 7C, 7C, F8), V(99, 77, 77, EE), V(8D, 7B, 7B, F6), \
101 V(0D, F2, F2, FF), V(BD, 6B, 6B, D6), V(B1, 6F, 6F, DE), V(54, C5, C5, 91), \
102 V(50, 30, 30, 60), V(03, 01, 01, 02), V(A9, 67, 67, CE), V(7D, 2B, 2B, 56), \
103 V(19, FE, FE, E7), V(62, D7, D7, B5), V(E6, AB, AB, 4D), V(9A, 76, 76, EC), \
104 V(45, CA, CA, 8F), V(9D, 82, 82, 1F), V(40, C9, C9, 89), V(87, 7D, 7D, FA), \
105 V(15, FA, FA, EF), V(EB, 59, 59, B2), V(C9, 47, 47, 8E), V(0B, F0, F0, FB), \
106 V(EC, AD, AD, 41), V(67, D4, D4, B3), V(FD, A2, A2, 5F), V(EA, AF, AF, 45), \
107 V(BF, 9C, 9C, 23), V(F7, A4, A4, 53), V(96, 72, 72, E4), V(5B, C0, C0, 9B), \
108 V(C2, B7, B7, 75), V(1C, FD, FD, E1), V(AE, 93, 93, 3D), V(6A, 26, 26, 4C), \
109 V(5A, 36, 36, 6C), V(41, 3F, 3F, 7E), V(02, F7, F7, F5), V(4F, CC, CC, 83), \
110 V(5C, 34, 34, 68), V(F4, A5, A5, 51), V(34, E5, E5, D1), V(08, F1, F1, F9), \
111 V(93, 71, 71, E2), V(73, D8, D8, AB), V(53, 31, 31, 62), V(3F, 15, 15, 2A), \
112 V(0C, 04, 04, 08), V(52, C7, C7, 95), V(65, 23, 23, 46), V(5E, C3, C3, 9D), \
113 V(28, 18, 18, 30), V(A1, 96, 96, 37), V(0F, 05, 05, 0A), V(B5, 9A, 9A, 2F), \
114 V(09, 07, 07, 0E), V(36, 12, 12, 24), V(9B, 80, 80, 1B), V(3D, E2, E2, DF), \
115 V(26, EB, EB, CD), V(69, 27, 27, 4E), V(CD, B2, B2, 7F), V(9F, 75, 75, EA), \
116 V(1B, 09, 09, 12), V(9E, 83, 83, 1D), V(74, 2C, 2C, 58), V(2E, 1A, 1A, 34), \
117 V(2D, 1B, 1B, 36), V(B2, 6E, 6E, DC), V(EE, 5A, 5A, B4), V(FB, A0, A0, 5B), \
118 V(F6, 52, 52, A4), V(4D, 3B, 3B, 76), V(61, D6, D6, B7), V(CE, B3, B3, 7D), \
119 V(7B, 29, 29, 52), V(3E, E3, E3, DD), V(71, 2F, 2F, 5E), V(97, 84, 84, 13), \
120 V(F5, 53, 53, A6), V(68, D1, D1, B9), V(00, 00, 00, 00), V(2C, ED, ED, C1), \
121 V(60, 20, 20, 40), V(1F, FC, FC, E3), V(C8, B1, B1, 79), V(ED, 5B, 5B, B6), \
122 V(BE, 6A, 6A, D4), V(46, CB, CB, 8D), V(D9, BE, BE, 67), V(4B, 39, 39, 72), \
123 V(DE, 4A, 4A, 94), V(D4, 4C, 4C, 98), V(E8, 58, 58, B0), V(4A, CF, CF, 85), \
124 V(6B, D0, D0, BB), V(2A, EF, EF, C5), V(E5, AA, AA, 4F), V(16, FB, FB, ED), \
125 V(C5, 43, 43, 86), V(D7, 4D, 4D, 9A), V(55, 33, 33, 66), V(94, 85, 85, 11), \
126 V(CF, 45, 45, 8A), V(10, F9, F9, E9), V(06, 02, 02, 04), V(81, 7F, 7F, FE), \
127 V(F0, 50, 50, A0), V(44, 3C, 3C, 78), V(BA, 9F, 9F, 25), V(E3, A8, A8, 4B), \
128 V(F3, 51, 51, A2), V(FE, A3, A3, 5D), V(C0, 40, 40, 80), V(8A, 8F, 8F, 05), \
129 V(AD, 92, 92, 3F), V(BC, 9D, 9D, 21), V(48, 38, 38, 70), V(04, F5, F5, F1), \
130 V(DF, BC, BC, 63), V(C1, B6, B6, 77), V(75, DA, DA, AF), V(63, 21, 21, 42), \
131 V(30, 10, 10, 20), V(1A, FF, FF, E5), V(0E, F3, F3, FD), V(6D, D2, D2, BF), \
132 V(4C, CD, CD, 81), V(14, 0C, 0C, 18), V(35, 13, 13, 26), V(2F, EC, EC, C3), \
133 V(E1, 5F, 5F, BE), V(A2, 97, 97, 35), V(CC, 44, 44, 88), V(39, 17, 17, 2E), \
134 V(57, C4, C4, 93), V(F2, A7, A7, 55), V(82, 7E, 7E, FC), V(47, 3D, 3D, 7A), \
135 V(AC, 64, 64, C8), V(E7, 5D, 5D, BA), V(2B, 19, 19, 32), V(95, 73, 73, E6), \
136 V(A0, 60, 60, C0), V(98, 81, 81, 19), V(D1, 4F, 4F, 9E), V(7F, DC, DC, A3), \
137 V(66, 22, 22, 44), V(7E, 2A, 2A, 54), V(AB, 90, 90, 3B), V(83, 88, 88, 0B), \
138 V(CA, 46, 46, 8C), V(29, EE, EE, C7), V(D3, B8, B8, 6B), V(3C, 14, 14, 28), \
139 V(79, DE, DE, A7), V(E2, 5E, 5E, BC), V(1D, 0B, 0B, 16), V(76, DB, DB, AD), \
140 V(3B, E0, E0, DB), V(56, 32, 32, 64), V(4E, 3A, 3A, 74), V(1E, 0A, 0A, 14), \
141 V(DB, 49, 49, 92), V(0A, 06, 06, 0C), V(6C, 24, 24, 48), V(E4, 5C, 5C, B8), \
142 V(5D, C2, C2, 9F), V(6E, D3, D3, BD), V(EF, AC, AC, 43), V(A6, 62, 62, C4), \
143 V(A8, 91, 91, 39), V(A4, 95, 95, 31), V(37, E4, E4, D3), V(8B, 79, 79, F2), \
144 V(32, E7, E7, D5), V(43, C8, C8, 8B), V(59, 37, 37, 6E), V(B7, 6D, 6D, DA), \
145 V(8C, 8D, 8D, 01), V(64, D5, D5, B1), V(D2, 4E, 4E, 9C), V(E0, A9, A9, 49), \
146 V(B4, 6C, 6C, D8), V(FA, 56, 56, AC), V(07, F4, F4, F3), V(25, EA, EA, CF), \
147 V(AF, 65, 65, CA), V(8E, 7A, 7A, F4), V(E9, AE, AE, 47), V(18, 08, 08, 10), \
148 V(D5, BA, BA, 6F), V(88, 78, 78, F0), V(6F, 25, 25, 4A), V(72, 2E, 2E, 5C), \
149 V(24, 1C, 1C, 38), V(F1, A6, A6, 57), V(C7, B4, B4, 73), V(51, C6, C6, 97), \
150 V(23, E8, E8, CB), V(7C, DD, DD, A1), V(9C, 74, 74, E8), V(21, 1F, 1F, 3E), \
151 V(DD, 4B, 4B, 96), V(DC, BD, BD, 61), V(86, 8B, 8B, 0D), V(85, 8A, 8A, 0F), \
152 V(90, 70, 70, E0), V(42, 3E, 3E, 7C), V(C4, B5, B5, 71), V(AA, 66, 66, CC), \
153 V(D8, 48, 48, 90), V(05, 03, 03, 06), V(01, F6, F6, F7), V(12, 0E, 0E, 1C), \
154 V(A3, 61, 61, C2), V(5F, 35, 35, 6A), V(F9, 57, 57, AE), V(D0, B9, B9, 69), \
155 V(91, 86, 86, 17), V(58, C1, C1, 99), V(27, 1D, 1D, 3A), V(B9, 9E, 9E, 27), \
156 V(38, E1, E1, D9), V(13, F8, F8, EB), V(B3, 98, 98, 2B), V(33, 11, 11, 22), \
157 V(BB, 69, 69, D2), V(70, D9, D9, A9), V(89, 8E, 8E, 07), V(A7, 94, 94, 33), \
158 V(B6, 9B, 9B, 2D), V(22, 1E, 1E, 3C), V(92, 87, 87, 15), V(20, E9, E9, C9), \
159 V(49, CE, CE, 87), V(FF, 55, 55, AA), V(78, 28, 28, 50), V(7A, DF, DF, A5), \
160 V(8F, 8C, 8C, 03), V(F8, A1, A1, 59), V(80, 89, 89, 09), V(17, 0D, 0D, 1A), \
161 V(DA, BF, BF, 65), V(31, E6, E6, D7), V(C6, 42, 42, 84), V(B8, 68, 68, D0), \
162 V(C3, 41, 41, 82), V(B0, 99, 99, 29), V(77, 2D, 2D, 5A), V(11, 0F, 0F, 1E), \
163 V(CB, B0, B0, 7B), V(FC, 54, 54, A8), V(D6, BB, BB, 6D), V(3A, 16, 16, 2C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000164
Gilles Peskine449bd832023-01-11 14:50:10 +0100165#define V(a, b, c, d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000166static const uint32_t FT0[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000167#undef V
168
Hanno Beckerad049a92017-06-19 16:31:54 +0100169#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200170
Gilles Peskine449bd832023-01-11 14:50:10 +0100171#define V(a, b, c, d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000172static const uint32_t FT1[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000173#undef V
174
Gilles Peskine449bd832023-01-11 14:50:10 +0100175#define V(a, b, c, d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000176static const uint32_t FT2[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000177#undef V
178
Gilles Peskine449bd832023-01-11 14:50:10 +0100179#define V(a, b, c, d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000180static const uint32_t FT3[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000181#undef V
182
Hanno Becker177d3cf2017-06-07 15:52:48 +0100183#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200184
Paul Bakker5121ce52009-01-03 21:22:43 +0000185#undef FT
186
187/*
188 * Reverse S-box
189 */
190static const unsigned char RSb[256] =
191{
192 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
193 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
194 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
195 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
196 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
197 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
198 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
199 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
200 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
201 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
202 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
203 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
204 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
205 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
206 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
207 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
208 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
209 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
210 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
211 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
212 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
213 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
214 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
215 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
216 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
217 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
218 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
219 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
220 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
221 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
222 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
223 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
224};
225
226/*
227 * Reverse tables
228 */
229#define RT \
230\
Gilles Peskine449bd832023-01-11 14:50:10 +0100231 V(50, A7, F4, 51), V(53, 65, 41, 7E), V(C3, A4, 17, 1A), V(96, 5E, 27, 3A), \
232 V(CB, 6B, AB, 3B), V(F1, 45, 9D, 1F), V(AB, 58, FA, AC), V(93, 03, E3, 4B), \
233 V(55, FA, 30, 20), V(F6, 6D, 76, AD), V(91, 76, CC, 88), V(25, 4C, 02, F5), \
234 V(FC, D7, E5, 4F), V(D7, CB, 2A, C5), V(80, 44, 35, 26), V(8F, A3, 62, B5), \
235 V(49, 5A, B1, DE), V(67, 1B, BA, 25), V(98, 0E, EA, 45), V(E1, C0, FE, 5D), \
236 V(02, 75, 2F, C3), V(12, F0, 4C, 81), V(A3, 97, 46, 8D), V(C6, F9, D3, 6B), \
237 V(E7, 5F, 8F, 03), V(95, 9C, 92, 15), V(EB, 7A, 6D, BF), V(DA, 59, 52, 95), \
238 V(2D, 83, BE, D4), V(D3, 21, 74, 58), V(29, 69, E0, 49), V(44, C8, C9, 8E), \
239 V(6A, 89, C2, 75), V(78, 79, 8E, F4), V(6B, 3E, 58, 99), V(DD, 71, B9, 27), \
240 V(B6, 4F, E1, BE), V(17, AD, 88, F0), V(66, AC, 20, C9), V(B4, 3A, CE, 7D), \
241 V(18, 4A, DF, 63), V(82, 31, 1A, E5), V(60, 33, 51, 97), V(45, 7F, 53, 62), \
242 V(E0, 77, 64, B1), V(84, AE, 6B, BB), V(1C, A0, 81, FE), V(94, 2B, 08, F9), \
243 V(58, 68, 48, 70), V(19, FD, 45, 8F), V(87, 6C, DE, 94), V(B7, F8, 7B, 52), \
244 V(23, D3, 73, AB), V(E2, 02, 4B, 72), V(57, 8F, 1F, E3), V(2A, AB, 55, 66), \
245 V(07, 28, EB, B2), V(03, C2, B5, 2F), V(9A, 7B, C5, 86), V(A5, 08, 37, D3), \
246 V(F2, 87, 28, 30), V(B2, A5, BF, 23), V(BA, 6A, 03, 02), V(5C, 82, 16, ED), \
247 V(2B, 1C, CF, 8A), V(92, B4, 79, A7), V(F0, F2, 07, F3), V(A1, E2, 69, 4E), \
248 V(CD, F4, DA, 65), V(D5, BE, 05, 06), V(1F, 62, 34, D1), V(8A, FE, A6, C4), \
249 V(9D, 53, 2E, 34), V(A0, 55, F3, A2), V(32, E1, 8A, 05), V(75, EB, F6, A4), \
250 V(39, EC, 83, 0B), V(AA, EF, 60, 40), V(06, 9F, 71, 5E), V(51, 10, 6E, BD), \
251 V(F9, 8A, 21, 3E), V(3D, 06, DD, 96), V(AE, 05, 3E, DD), V(46, BD, E6, 4D), \
252 V(B5, 8D, 54, 91), V(05, 5D, C4, 71), V(6F, D4, 06, 04), V(FF, 15, 50, 60), \
253 V(24, FB, 98, 19), V(97, E9, BD, D6), V(CC, 43, 40, 89), V(77, 9E, D9, 67), \
254 V(BD, 42, E8, B0), V(88, 8B, 89, 07), V(38, 5B, 19, E7), V(DB, EE, C8, 79), \
255 V(47, 0A, 7C, A1), V(E9, 0F, 42, 7C), V(C9, 1E, 84, F8), V(00, 00, 00, 00), \
256 V(83, 86, 80, 09), V(48, ED, 2B, 32), V(AC, 70, 11, 1E), V(4E, 72, 5A, 6C), \
257 V(FB, FF, 0E, FD), V(56, 38, 85, 0F), V(1E, D5, AE, 3D), V(27, 39, 2D, 36), \
258 V(64, D9, 0F, 0A), V(21, A6, 5C, 68), V(D1, 54, 5B, 9B), V(3A, 2E, 36, 24), \
259 V(B1, 67, 0A, 0C), V(0F, E7, 57, 93), V(D2, 96, EE, B4), V(9E, 91, 9B, 1B), \
260 V(4F, C5, C0, 80), V(A2, 20, DC, 61), V(69, 4B, 77, 5A), V(16, 1A, 12, 1C), \
261 V(0A, BA, 93, E2), V(E5, 2A, A0, C0), V(43, E0, 22, 3C), V(1D, 17, 1B, 12), \
262 V(0B, 0D, 09, 0E), V(AD, C7, 8B, F2), V(B9, A8, B6, 2D), V(C8, A9, 1E, 14), \
263 V(85, 19, F1, 57), V(4C, 07, 75, AF), V(BB, DD, 99, EE), V(FD, 60, 7F, A3), \
264 V(9F, 26, 01, F7), V(BC, F5, 72, 5C), V(C5, 3B, 66, 44), V(34, 7E, FB, 5B), \
265 V(76, 29, 43, 8B), V(DC, C6, 23, CB), V(68, FC, ED, B6), V(63, F1, E4, B8), \
266 V(CA, DC, 31, D7), V(10, 85, 63, 42), V(40, 22, 97, 13), V(20, 11, C6, 84), \
267 V(7D, 24, 4A, 85), V(F8, 3D, BB, D2), V(11, 32, F9, AE), V(6D, A1, 29, C7), \
268 V(4B, 2F, 9E, 1D), V(F3, 30, B2, DC), V(EC, 52, 86, 0D), V(D0, E3, C1, 77), \
269 V(6C, 16, B3, 2B), V(99, B9, 70, A9), V(FA, 48, 94, 11), V(22, 64, E9, 47), \
270 V(C4, 8C, FC, A8), V(1A, 3F, F0, A0), V(D8, 2C, 7D, 56), V(EF, 90, 33, 22), \
271 V(C7, 4E, 49, 87), V(C1, D1, 38, D9), V(FE, A2, CA, 8C), V(36, 0B, D4, 98), \
272 V(CF, 81, F5, A6), V(28, DE, 7A, A5), V(26, 8E, B7, DA), V(A4, BF, AD, 3F), \
273 V(E4, 9D, 3A, 2C), V(0D, 92, 78, 50), V(9B, CC, 5F, 6A), V(62, 46, 7E, 54), \
274 V(C2, 13, 8D, F6), V(E8, B8, D8, 90), V(5E, F7, 39, 2E), V(F5, AF, C3, 82), \
275 V(BE, 80, 5D, 9F), V(7C, 93, D0, 69), V(A9, 2D, D5, 6F), V(B3, 12, 25, CF), \
276 V(3B, 99, AC, C8), V(A7, 7D, 18, 10), V(6E, 63, 9C, E8), V(7B, BB, 3B, DB), \
277 V(09, 78, 26, CD), V(F4, 18, 59, 6E), V(01, B7, 9A, EC), V(A8, 9A, 4F, 83), \
278 V(65, 6E, 95, E6), V(7E, E6, FF, AA), V(08, CF, BC, 21), V(E6, E8, 15, EF), \
279 V(D9, 9B, E7, BA), V(CE, 36, 6F, 4A), V(D4, 09, 9F, EA), V(D6, 7C, B0, 29), \
280 V(AF, B2, A4, 31), V(31, 23, 3F, 2A), V(30, 94, A5, C6), V(C0, 66, A2, 35), \
281 V(37, BC, 4E, 74), V(A6, CA, 82, FC), V(B0, D0, 90, E0), V(15, D8, A7, 33), \
282 V(4A, 98, 04, F1), V(F7, DA, EC, 41), V(0E, 50, CD, 7F), V(2F, F6, 91, 17), \
283 V(8D, D6, 4D, 76), V(4D, B0, EF, 43), V(54, 4D, AA, CC), V(DF, 04, 96, E4), \
284 V(E3, B5, D1, 9E), V(1B, 88, 6A, 4C), V(B8, 1F, 2C, C1), V(7F, 51, 65, 46), \
285 V(04, EA, 5E, 9D), V(5D, 35, 8C, 01), V(73, 74, 87, FA), V(2E, 41, 0B, FB), \
286 V(5A, 1D, 67, B3), V(52, D2, DB, 92), V(33, 56, 10, E9), V(13, 47, D6, 6D), \
287 V(8C, 61, D7, 9A), V(7A, 0C, A1, 37), V(8E, 14, F8, 59), V(89, 3C, 13, EB), \
288 V(EE, 27, A9, CE), V(35, C9, 61, B7), V(ED, E5, 1C, E1), V(3C, B1, 47, 7A), \
289 V(59, DF, D2, 9C), V(3F, 73, F2, 55), V(79, CE, 14, 18), V(BF, 37, C7, 73), \
290 V(EA, CD, F7, 53), V(5B, AA, FD, 5F), V(14, 6F, 3D, DF), V(86, DB, 44, 78), \
291 V(81, F3, AF, CA), V(3E, C4, 68, B9), V(2C, 34, 24, 38), V(5F, 40, A3, C2), \
292 V(72, C3, 1D, 16), V(0C, 25, E2, BC), V(8B, 49, 3C, 28), V(41, 95, 0D, FF), \
293 V(71, 01, A8, 39), V(DE, B3, 0C, 08), V(9C, E4, B4, D8), V(90, C1, 56, 64), \
294 V(61, 84, CB, 7B), V(70, B6, 32, D5), V(74, 5C, 6C, 48), V(42, 57, B8, D0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000295
Gilles Peskine449bd832023-01-11 14:50:10 +0100296#define V(a, b, c, d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000297static const uint32_t RT0[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000298#undef V
299
Hanno Beckerad049a92017-06-19 16:31:54 +0100300#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200301
Gilles Peskine449bd832023-01-11 14:50:10 +0100302#define V(a, b, c, d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000303static const uint32_t RT1[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000304#undef V
305
Gilles Peskine449bd832023-01-11 14:50:10 +0100306#define V(a, b, c, d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000307static const uint32_t RT2[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000308#undef V
309
Gilles Peskine449bd832023-01-11 14:50:10 +0100310#define V(a, b, c, d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000311static const uint32_t RT3[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000312#undef V
313
Hanno Becker177d3cf2017-06-07 15:52:48 +0100314#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200315
Paul Bakker5121ce52009-01-03 21:22:43 +0000316#undef RT
317
318/*
319 * Round constants
320 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000321static const uint32_t RCON[10] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000322{
323 0x00000001, 0x00000002, 0x00000004, 0x00000008,
324 0x00000010, 0x00000020, 0x00000040, 0x00000080,
325 0x0000001B, 0x00000036
326};
327
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200328#else /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000329
330/*
331 * Forward S-box & tables
332 */
333static unsigned char FSb[256];
Paul Bakker9af723c2014-05-01 13:03:14 +0200334static uint32_t FT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100335#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker9af723c2014-05-01 13:03:14 +0200336static uint32_t FT1[256];
337static uint32_t FT2[256];
338static uint32_t FT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100339#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000340
341/*
342 * Reverse S-box & tables
343 */
344static unsigned char RSb[256];
Paul Bakker5c2364c2012-10-01 14:41:15 +0000345static uint32_t RT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100346#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker5c2364c2012-10-01 14:41:15 +0000347static uint32_t RT1[256];
348static uint32_t RT2[256];
349static uint32_t RT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100350#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000351
352/*
353 * Round constants
354 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000355static uint32_t RCON[10];
Paul Bakker5121ce52009-01-03 21:22:43 +0000356
357/*
358 * Tables generation code
359 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100360#define ROTL8(x) (((x) << 8) & 0xFFFFFFFF) | ((x) >> 24)
361#define XTIME(x) (((x) << 1) ^ (((x) & 0x80) ? 0x1B : 0x00))
362#define MUL(x, y) (((x) && (y)) ? pow[(log[(x)]+log[(y)]) % 255] : 0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000363
364static int aes_init_done = 0;
365
Gilles Peskine449bd832023-01-11 14:50:10 +0100366static void aes_gen_tables(void)
Paul Bakker5121ce52009-01-03 21:22:43 +0000367{
368 int i, x, y, z;
369 int pow[256];
370 int log[256];
371
372 /*
373 * compute pow and log tables over GF(2^8)
374 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100375 for (i = 0, x = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000376 pow[i] = x;
377 log[x] = i;
Gilles Peskine449bd832023-01-11 14:50:10 +0100378 x = MBEDTLS_BYTE_0(x ^ XTIME(x));
Paul Bakker5121ce52009-01-03 21:22:43 +0000379 }
380
381 /*
382 * calculate the round constants
383 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100384 for (i = 0, x = 1; i < 10; i++) {
Paul Bakker5c2364c2012-10-01 14:41:15 +0000385 RCON[i] = (uint32_t) x;
Gilles Peskine449bd832023-01-11 14:50:10 +0100386 x = MBEDTLS_BYTE_0(XTIME(x));
Paul Bakker5121ce52009-01-03 21:22:43 +0000387 }
388
389 /*
390 * generate the forward and reverse S-boxes
391 */
392 FSb[0x00] = 0x63;
393 RSb[0x63] = 0x00;
394
Gilles Peskine449bd832023-01-11 14:50:10 +0100395 for (i = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000396 x = pow[255 - log[i]];
397
Gilles Peskine449bd832023-01-11 14:50:10 +0100398 y = x; y = MBEDTLS_BYTE_0((y << 1) | (y >> 7));
399 x ^= y; y = MBEDTLS_BYTE_0((y << 1) | (y >> 7));
400 x ^= y; y = MBEDTLS_BYTE_0((y << 1) | (y >> 7));
401 x ^= y; y = MBEDTLS_BYTE_0((y << 1) | (y >> 7));
Paul Bakker5121ce52009-01-03 21:22:43 +0000402 x ^= y ^ 0x63;
403
404 FSb[i] = (unsigned char) x;
405 RSb[x] = (unsigned char) i;
406 }
407
408 /*
409 * generate the forward and reverse tables
410 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100411 for (i = 0; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000412 x = FSb[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100413 y = MBEDTLS_BYTE_0(XTIME(x));
414 z = MBEDTLS_BYTE_0(y ^ x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000415
Gilles Peskine449bd832023-01-11 14:50:10 +0100416 FT0[i] = ((uint32_t) y) ^
417 ((uint32_t) x << 8) ^
418 ((uint32_t) x << 16) ^
419 ((uint32_t) z << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000420
Hanno Beckerad049a92017-06-19 16:31:54 +0100421#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100422 FT1[i] = ROTL8(FT0[i]);
423 FT2[i] = ROTL8(FT1[i]);
424 FT3[i] = ROTL8(FT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100425#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000426
427 x = RSb[i];
428
Gilles Peskine449bd832023-01-11 14:50:10 +0100429 RT0[i] = ((uint32_t) MUL(0x0E, x)) ^
430 ((uint32_t) MUL(0x09, x) << 8) ^
431 ((uint32_t) MUL(0x0D, x) << 16) ^
432 ((uint32_t) MUL(0x0B, x) << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000433
Hanno Beckerad049a92017-06-19 16:31:54 +0100434#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100435 RT1[i] = ROTL8(RT0[i]);
436 RT2[i] = ROTL8(RT1[i]);
437 RT3[i] = ROTL8(RT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100438#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000439 }
440}
441
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200442#undef ROTL8
443
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200444#endif /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000445
Hanno Beckerad049a92017-06-19 16:31:54 +0100446#if defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200447
Gilles Peskine449bd832023-01-11 14:50:10 +0100448#define ROTL8(x) ((uint32_t) ((x) << 8) + (uint32_t) ((x) >> 24))
449#define ROTL16(x) ((uint32_t) ((x) << 16) + (uint32_t) ((x) >> 16))
450#define ROTL24(x) ((uint32_t) ((x) << 24) + (uint32_t) ((x) >> 8))
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200451
452#define AES_RT0(idx) RT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100453#define AES_RT1(idx) ROTL8(RT0[idx])
454#define AES_RT2(idx) ROTL16(RT0[idx])
455#define AES_RT3(idx) ROTL24(RT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200456
457#define AES_FT0(idx) FT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100458#define AES_FT1(idx) ROTL8(FT0[idx])
459#define AES_FT2(idx) ROTL16(FT0[idx])
460#define AES_FT3(idx) ROTL24(FT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200461
Hanno Becker177d3cf2017-06-07 15:52:48 +0100462#else /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200463
464#define AES_RT0(idx) RT0[idx]
465#define AES_RT1(idx) RT1[idx]
466#define AES_RT2(idx) RT2[idx]
467#define AES_RT3(idx) RT3[idx]
468
469#define AES_FT0(idx) FT0[idx]
470#define AES_FT1(idx) FT1[idx]
471#define AES_FT2(idx) FT2[idx]
472#define AES_FT3(idx) FT3[idx]
473
Hanno Becker177d3cf2017-06-07 15:52:48 +0100474#endif /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200475
Gilles Peskine449bd832023-01-11 14:50:10 +0100476void mbedtls_aes_init(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200477{
Gilles Peskine449bd832023-01-11 14:50:10 +0100478 memset(ctx, 0, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200479}
480
Gilles Peskine449bd832023-01-11 14:50:10 +0100481void mbedtls_aes_free(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200482{
Gilles Peskine449bd832023-01-11 14:50:10 +0100483 if (ctx == NULL) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200484 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100485 }
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200486
Gilles Peskine449bd832023-01-11 14:50:10 +0100487 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200488}
489
Jaeden Amero9366feb2018-05-29 18:55:17 +0100490#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100491void mbedtls_aes_xts_init(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100492{
Gilles Peskine449bd832023-01-11 14:50:10 +0100493 mbedtls_aes_init(&ctx->crypt);
494 mbedtls_aes_init(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100495}
496
Gilles Peskine449bd832023-01-11 14:50:10 +0100497void mbedtls_aes_xts_free(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100498{
Gilles Peskine449bd832023-01-11 14:50:10 +0100499 if (ctx == NULL) {
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100500 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100501 }
Simon Butcher5201e412018-12-06 17:40:14 +0000502
Gilles Peskine449bd832023-01-11 14:50:10 +0100503 mbedtls_aes_free(&ctx->crypt);
504 mbedtls_aes_free(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100505}
506#endif /* MBEDTLS_CIPHER_MODE_XTS */
507
Paul Bakker5121ce52009-01-03 21:22:43 +0000508/*
509 * AES key schedule (encryption)
510 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200511#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100512int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
513 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000514{
Paul Bakker23986e52011-04-24 08:57:21 +0000515 unsigned int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000516 uint32_t *RK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000517
Gilles Peskine449bd832023-01-11 14:50:10 +0100518 switch (keybits) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000519 case 128: ctx->nr = 10; break;
520 case 192: ctx->nr = 12; break;
521 case 256: ctx->nr = 14; break;
Gilles Peskine449bd832023-01-11 14:50:10 +0100522 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Paul Bakker5121ce52009-01-03 21:22:43 +0000523 }
524
Simon Butcher5201e412018-12-06 17:40:14 +0000525#if !defined(MBEDTLS_AES_ROM_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100526 if (aes_init_done == 0) {
Simon Butcher5201e412018-12-06 17:40:14 +0000527 aes_gen_tables();
528 aes_init_done = 1;
Simon Butcher5201e412018-12-06 17:40:14 +0000529 }
530#endif
531
Werner Lewis7656a372022-06-13 12:28:20 +0100532 ctx->rk_offset = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200533#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_PADLOCK_ALIGN16)
Gilles Peskine449bd832023-01-11 14:50:10 +0100534 if (aes_padlock_ace == -1) {
535 aes_padlock_ace = mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE);
536 }
Paul Bakker048d04e2012-02-12 17:31:04 +0000537
Gilles Peskine449bd832023-01-11 14:50:10 +0100538 if (aes_padlock_ace) {
539 ctx->rk_offset = MBEDTLS_PADLOCK_ALIGN16(ctx->buf) - ctx->buf;
540 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000541#endif
Werner Lewisdd76ef32022-05-30 12:00:21 +0100542 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000543
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200544#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Gilles Peskine449bd832023-01-11 14:50:10 +0100545 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
546 return mbedtls_aesni_setkey_enc((unsigned char *) RK, key, keybits);
547 }
Manuel Pégourié-Gonnard47a35362013-12-28 20:45:04 +0100548#endif
549
Jerry Yu3f2fb712023-01-10 17:05:42 +0800550#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
551 if (mbedtls_aesce_has_support()) {
552 return mbedtls_aesce_setkey_enc((unsigned char *) RK, key, keybits);
553 }
554#endif
555
Gilles Peskine449bd832023-01-11 14:50:10 +0100556 for (i = 0; i < (keybits >> 5); i++) {
557 RK[i] = MBEDTLS_GET_UINT32_LE(key, i << 2);
Paul Bakker5121ce52009-01-03 21:22:43 +0000558 }
559
Gilles Peskine449bd832023-01-11 14:50:10 +0100560 switch (ctx->nr) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000561 case 10:
562
Gilles Peskine449bd832023-01-11 14:50:10 +0100563 for (i = 0; i < 10; i++, RK += 4) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000564 RK[4] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100565 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[3])]) ^
566 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[3])] << 8) ^
567 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[3])] << 16) ^
568 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[3])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000569
570 RK[5] = RK[1] ^ RK[4];
571 RK[6] = RK[2] ^ RK[5];
572 RK[7] = RK[3] ^ RK[6];
573 }
574 break;
575
576 case 12:
577
Gilles Peskine449bd832023-01-11 14:50:10 +0100578 for (i = 0; i < 8; i++, RK += 6) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000579 RK[6] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100580 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[5])]) ^
581 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[5])] << 8) ^
582 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[5])] << 16) ^
583 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[5])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000584
585 RK[7] = RK[1] ^ RK[6];
586 RK[8] = RK[2] ^ RK[7];
587 RK[9] = RK[3] ^ RK[8];
588 RK[10] = RK[4] ^ RK[9];
589 RK[11] = RK[5] ^ RK[10];
590 }
591 break;
592
593 case 14:
594
Gilles Peskine449bd832023-01-11 14:50:10 +0100595 for (i = 0; i < 7; i++, RK += 8) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000596 RK[8] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100597 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[7])]) ^
598 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[7])] << 8) ^
599 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[7])] << 16) ^
600 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[7])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000601
602 RK[9] = RK[1] ^ RK[8];
603 RK[10] = RK[2] ^ RK[9];
604 RK[11] = RK[3] ^ RK[10];
605
606 RK[12] = RK[4] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100607 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[11])]) ^
608 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[11])] << 8) ^
609 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[11])] << 16) ^
610 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[11])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000611
612 RK[13] = RK[5] ^ RK[12];
613 RK[14] = RK[6] ^ RK[13];
614 RK[15] = RK[7] ^ RK[14];
615 }
616 break;
Paul Bakker5121ce52009-01-03 21:22:43 +0000617 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000618
Gilles Peskine449bd832023-01-11 14:50:10 +0100619 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000620}
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200621#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000622
623/*
624 * AES key schedule (decryption)
625 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200626#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100627int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
628 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000629{
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200630 int i, j, ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200631 mbedtls_aes_context cty;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000632 uint32_t *RK;
633 uint32_t *SK;
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200634
Gilles Peskine449bd832023-01-11 14:50:10 +0100635 mbedtls_aes_init(&cty);
Paul Bakker5121ce52009-01-03 21:22:43 +0000636
Werner Lewis7656a372022-06-13 12:28:20 +0100637 ctx->rk_offset = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200638#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_PADLOCK_ALIGN16)
Gilles Peskine449bd832023-01-11 14:50:10 +0100639 if (aes_padlock_ace == -1) {
640 aes_padlock_ace = mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE);
641 }
Paul Bakker048d04e2012-02-12 17:31:04 +0000642
Gilles Peskine449bd832023-01-11 14:50:10 +0100643 if (aes_padlock_ace) {
644 ctx->rk_offset = MBEDTLS_PADLOCK_ALIGN16(ctx->buf) - ctx->buf;
645 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000646#endif
Werner Lewisdd76ef32022-05-30 12:00:21 +0100647 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000648
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200649 /* Also checks keybits */
Gilles Peskine449bd832023-01-11 14:50:10 +0100650 if ((ret = mbedtls_aes_setkey_enc(&cty, key, keybits)) != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200651 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100652 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000653
Manuel Pégourié-Gonnardafd5a082014-05-28 21:52:59 +0200654 ctx->nr = cty.nr;
655
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200656#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Gilles Peskine449bd832023-01-11 14:50:10 +0100657 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
658 mbedtls_aesni_inverse_key((unsigned char *) RK,
659 (const unsigned char *) (cty.buf + cty.rk_offset), ctx->nr);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200660 goto exit;
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100661 }
662#endif
663
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
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200960#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
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
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200966#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Gilles Peskine449bd832023-01-11 14:50:10 +0100967 if (aes_padlock_ace > 0) {
968 if (mbedtls_padlock_xcryptecb(ctx, mode, input, output) == 0) {
969 return 0;
970 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000971
972 // If padlock data misaligned, we just fall back to
973 // unaccelerated mode
974 //
Paul Bakker5121ce52009-01-03 21:22:43 +0000975 }
976#endif
977
Gilles Peskine449bd832023-01-11 14:50:10 +0100978 if (mode == MBEDTLS_AES_ENCRYPT) {
979 return mbedtls_internal_aes_encrypt(ctx, input, output);
980 } else {
981 return mbedtls_internal_aes_decrypt(ctx, input, output);
982 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000983}
984
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200985#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000986/*
987 * AES-CBC buffer encryption/decryption
988 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100989int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
990 int mode,
991 size_t length,
992 unsigned char iv[16],
993 const unsigned char *input,
994 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +0000995{
Gilles Peskine7820a572021-07-07 21:08:28 +0200996 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +0000997 unsigned char temp[16];
998
Gilles Peskine449bd832023-01-11 14:50:10 +0100999 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001000 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001001 }
Manuel Pégourié-Gonnard3178d1a2018-12-12 13:05:00 +01001002
Gilles Peskine449bd832023-01-11 14:50:10 +01001003 if (length % 16) {
1004 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
1005 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001006
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001007#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Gilles Peskine449bd832023-01-11 14:50:10 +01001008 if (aes_padlock_ace > 0) {
1009 if (mbedtls_padlock_xcryptcbc(ctx, mode, length, iv, input, output) == 0) {
1010 return 0;
1011 }
Paul Bakker9af723c2014-05-01 13:03:14 +02001012
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001013 // If padlock data misaligned, we just fall back to
1014 // unaccelerated mode
1015 //
Paul Bakker5121ce52009-01-03 21:22:43 +00001016 }
1017#endif
1018
Gilles Peskine449bd832023-01-11 14:50:10 +01001019 if (mode == MBEDTLS_AES_DECRYPT) {
1020 while (length > 0) {
1021 memcpy(temp, input, 16);
1022 ret = mbedtls_aes_crypt_ecb(ctx, mode, input, output);
1023 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001024 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001025 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001026
Gilles Peskine449bd832023-01-11 14:50:10 +01001027 mbedtls_xor(output, output, iv, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001028
Gilles Peskine449bd832023-01-11 14:50:10 +01001029 memcpy(iv, temp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001030
1031 input += 16;
1032 output += 16;
1033 length -= 16;
1034 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001035 } else {
1036 while (length > 0) {
1037 mbedtls_xor(output, input, iv, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001038
Gilles Peskine449bd832023-01-11 14:50:10 +01001039 ret = mbedtls_aes_crypt_ecb(ctx, mode, output, output);
1040 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001041 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001042 }
1043 memcpy(iv, output, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001044
1045 input += 16;
1046 output += 16;
1047 length -= 16;
1048 }
1049 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001050 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001051
Gilles Peskine7820a572021-07-07 21:08:28 +02001052exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001053 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001054}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001055#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001056
Aorimn5f778012016-06-09 23:22:58 +02001057#if defined(MBEDTLS_CIPHER_MODE_XTS)
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001058
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001059typedef unsigned char mbedtls_be128[16];
1060
1061/*
1062 * GF(2^128) multiplication function
1063 *
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001064 * This function multiplies a field element by x in the polynomial field
1065 * representation. It uses 64-bit word operations to gain speed but compensates
Shaun Case8b0ecbc2021-12-20 21:14:10 -08001066 * for machine endianness and hence works correctly on both big and little
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001067 * endian machines.
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001068 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001069static void mbedtls_gf128mul_x_ble(unsigned char r[16],
1070 const unsigned char x[16])
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001071{
1072 uint64_t a, b, ra, rb;
1073
Gilles Peskine449bd832023-01-11 14:50:10 +01001074 a = MBEDTLS_GET_UINT64_LE(x, 0);
1075 b = MBEDTLS_GET_UINT64_LE(x, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001076
Gilles Peskine449bd832023-01-11 14:50:10 +01001077 ra = (a << 1) ^ 0x0087 >> (8 - ((b >> 63) << 3));
1078 rb = (a >> 63) | (b << 1);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001079
Gilles Peskine449bd832023-01-11 14:50:10 +01001080 MBEDTLS_PUT_UINT64_LE(ra, r, 0);
1081 MBEDTLS_PUT_UINT64_LE(rb, r, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001082}
1083
Aorimn5f778012016-06-09 23:22:58 +02001084/*
1085 * AES-XTS buffer encryption/decryption
1086 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001087int mbedtls_aes_crypt_xts(mbedtls_aes_xts_context *ctx,
1088 int mode,
1089 size_t length,
1090 const unsigned char data_unit[16],
1091 const unsigned char *input,
1092 unsigned char *output)
Aorimn5f778012016-06-09 23:22:58 +02001093{
Janos Follath24eed8d2019-11-22 13:21:35 +00001094 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amerod82cd862018-04-28 15:02:45 +01001095 size_t blocks = length / 16;
1096 size_t leftover = length % 16;
1097 unsigned char tweak[16];
1098 unsigned char prev_tweak[16];
1099 unsigned char tmp[16];
Aorimn5f778012016-06-09 23:22:58 +02001100
Gilles Peskine449bd832023-01-11 14:50:10 +01001101 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001102 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001103 }
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01001104
Jaeden Amero8381fcb2018-10-11 12:06:15 +01001105 /* Data units must be at least 16 bytes long. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001106 if (length < 16) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001107 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001108 }
Aorimn5f778012016-06-09 23:22:58 +02001109
Jaeden Ameroa74faba2018-10-11 12:07:43 +01001110 /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001111 if (length > (1 << 20) * 16) {
Jaeden Amero0a8b0202018-05-30 15:36:06 +01001112 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001113 }
Aorimn5f778012016-06-09 23:22:58 +02001114
Jaeden Amerod82cd862018-04-28 15:02:45 +01001115 /* Compute the tweak. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001116 ret = mbedtls_aes_crypt_ecb(&ctx->tweak, MBEDTLS_AES_ENCRYPT,
1117 data_unit, tweak);
1118 if (ret != 0) {
1119 return ret;
1120 }
Aorimn5f778012016-06-09 23:22:58 +02001121
Gilles Peskine449bd832023-01-11 14:50:10 +01001122 while (blocks--) {
1123 if (leftover && (mode == MBEDTLS_AES_DECRYPT) && blocks == 0) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001124 /* We are on the last block in a decrypt operation that has
1125 * leftover bytes, so we need to use the next tweak for this block,
Tom Cosgrove1797b052022-12-04 17:19:59 +00001126 * and this tweak for the leftover bytes. Save the current tweak for
Jaeden Amerod82cd862018-04-28 15:02:45 +01001127 * the leftovers and then update the current tweak for use on this,
1128 * the last full block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001129 memcpy(prev_tweak, tweak, sizeof(tweak));
1130 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001131 }
1132
Gilles Peskine449bd832023-01-11 14:50:10 +01001133 mbedtls_xor(tmp, input, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001134
Gilles Peskine449bd832023-01-11 14:50:10 +01001135 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1136 if (ret != 0) {
1137 return ret;
1138 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001139
Gilles Peskine449bd832023-01-11 14:50:10 +01001140 mbedtls_xor(output, tmp, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001141
1142 /* Update the tweak for the next block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001143 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001144
1145 output += 16;
1146 input += 16;
Aorimn5f778012016-06-09 23:22:58 +02001147 }
1148
Gilles Peskine449bd832023-01-11 14:50:10 +01001149 if (leftover) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001150 /* If we are on the leftover bytes in a decrypt operation, we need to
1151 * use the previous tweak for these bytes (as saved in prev_tweak). */
1152 unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
Aorimn5f778012016-06-09 23:22:58 +02001153
Jaeden Amerod82cd862018-04-28 15:02:45 +01001154 /* We are now on the final part of the data unit, which doesn't divide
1155 * evenly by 16. It's time for ciphertext stealing. */
1156 size_t i;
1157 unsigned char *prev_output = output - 16;
Aorimn5f778012016-06-09 23:22:58 +02001158
Jaeden Amerod82cd862018-04-28 15:02:45 +01001159 /* Copy ciphertext bytes from the previous block to our output for each
Dave Rodgman069e7f42022-11-24 19:37:26 +00001160 * byte of ciphertext we won't steal. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001161 for (i = 0; i < leftover; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001162 output[i] = prev_output[i];
Aorimn5f778012016-06-09 23:22:58 +02001163 }
Aorimn5f778012016-06-09 23:22:58 +02001164
Dave Rodgman069e7f42022-11-24 19:37:26 +00001165 /* Copy the remainder of the input for this final round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001166 mbedtls_xor(tmp, input, t, leftover);
Dave Rodgmana8cf6072022-11-22 15:02:54 +00001167
Jaeden Amerod82cd862018-04-28 15:02:45 +01001168 /* Copy ciphertext bytes from the previous block for input in this
1169 * round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001170 mbedtls_xor(tmp + i, prev_output + i, t + i, 16 - i);
Aorimn5f778012016-06-09 23:22:58 +02001171
Gilles Peskine449bd832023-01-11 14:50:10 +01001172 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1173 if (ret != 0) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001174 return ret;
Gilles Peskine449bd832023-01-11 14:50:10 +01001175 }
Aorimn5f778012016-06-09 23:22:58 +02001176
Jaeden Amerod82cd862018-04-28 15:02:45 +01001177 /* Write the result back to the previous block, overriding the previous
1178 * output we copied. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001179 mbedtls_xor(prev_output, tmp, t, 16);
Aorimn5f778012016-06-09 23:22:58 +02001180 }
1181
Gilles Peskine449bd832023-01-11 14:50:10 +01001182 return 0;
Aorimn5f778012016-06-09 23:22:58 +02001183}
1184#endif /* MBEDTLS_CIPHER_MODE_XTS */
1185
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001186#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001187/*
1188 * AES-CFB128 buffer encryption/decryption
1189 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001190int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx,
1191 int mode,
1192 size_t length,
1193 size_t *iv_off,
1194 unsigned char iv[16],
1195 const unsigned char *input,
1196 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001197{
Paul Bakker27fdf462011-06-09 13:55:13 +00001198 int c;
Gilles Peskine7820a572021-07-07 21:08:28 +02001199 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001200 size_t n;
1201
Gilles Peskine449bd832023-01-11 14:50:10 +01001202 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001203 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001204 }
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001205
1206 n = *iv_off;
Paul Bakker5121ce52009-01-03 21:22:43 +00001207
Gilles Peskine449bd832023-01-11 14:50:10 +01001208 if (n > 15) {
1209 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1210 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001211
Gilles Peskine449bd832023-01-11 14:50:10 +01001212 if (mode == MBEDTLS_AES_DECRYPT) {
1213 while (length--) {
1214 if (n == 0) {
1215 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1216 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001217 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001218 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001219 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001220
1221 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001222 *output++ = (unsigned char) (c ^ iv[n]);
Paul Bakker5121ce52009-01-03 21:22:43 +00001223 iv[n] = (unsigned char) c;
1224
Gilles Peskine449bd832023-01-11 14:50:10 +01001225 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001226 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001227 } else {
1228 while (length--) {
1229 if (n == 0) {
1230 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1231 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001232 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001233 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001234 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001235
Gilles Peskine449bd832023-01-11 14:50:10 +01001236 iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++);
Paul Bakker5121ce52009-01-03 21:22:43 +00001237
Gilles Peskine449bd832023-01-11 14:50:10 +01001238 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001239 }
1240 }
1241
1242 *iv_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001243 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001244
Gilles Peskine7820a572021-07-07 21:08:28 +02001245exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001246 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001247}
Paul Bakker556efba2014-01-24 15:38:12 +01001248
1249/*
1250 * AES-CFB8 buffer encryption/decryption
1251 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001252int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx,
1253 int mode,
1254 size_t length,
1255 unsigned char iv[16],
1256 const unsigned char *input,
1257 unsigned char *output)
Paul Bakker556efba2014-01-24 15:38:12 +01001258{
Gilles Peskine7820a572021-07-07 21:08:28 +02001259 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker556efba2014-01-24 15:38:12 +01001260 unsigned char c;
1261 unsigned char ov[17];
1262
Gilles Peskine449bd832023-01-11 14:50:10 +01001263 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001264 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001265 }
1266 while (length--) {
1267 memcpy(ov, iv, 16);
1268 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1269 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001270 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001271 }
Paul Bakker556efba2014-01-24 15:38:12 +01001272
Gilles Peskine449bd832023-01-11 14:50:10 +01001273 if (mode == MBEDTLS_AES_DECRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001274 ov[16] = *input;
Gilles Peskine449bd832023-01-11 14:50:10 +01001275 }
Paul Bakker556efba2014-01-24 15:38:12 +01001276
Gilles Peskine449bd832023-01-11 14:50:10 +01001277 c = *output++ = (unsigned char) (iv[0] ^ *input++);
Paul Bakker556efba2014-01-24 15:38:12 +01001278
Gilles Peskine449bd832023-01-11 14:50:10 +01001279 if (mode == MBEDTLS_AES_ENCRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001280 ov[16] = c;
Gilles Peskine449bd832023-01-11 14:50:10 +01001281 }
Paul Bakker556efba2014-01-24 15:38:12 +01001282
Gilles Peskine449bd832023-01-11 14:50:10 +01001283 memcpy(iv, ov + 1, 16);
Paul Bakker556efba2014-01-24 15:38:12 +01001284 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001285 ret = 0;
Paul Bakker556efba2014-01-24 15:38:12 +01001286
Gilles Peskine7820a572021-07-07 21:08:28 +02001287exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001288 return ret;
Paul Bakker556efba2014-01-24 15:38:12 +01001289}
Simon Butcher76a5b222018-04-22 22:57:27 +01001290#endif /* MBEDTLS_CIPHER_MODE_CFB */
1291
1292#if defined(MBEDTLS_CIPHER_MODE_OFB)
1293/*
1294 * AES-OFB (Output Feedback Mode) buffer encryption/decryption
1295 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001296int mbedtls_aes_crypt_ofb(mbedtls_aes_context *ctx,
1297 size_t length,
1298 size_t *iv_off,
1299 unsigned char iv[16],
1300 const unsigned char *input,
1301 unsigned char *output)
Simon Butcher76a5b222018-04-22 22:57:27 +01001302{
Simon Butcherad4e4932018-04-29 00:43:47 +01001303 int ret = 0;
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001304 size_t n;
1305
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001306 n = *iv_off;
Simon Butcher76a5b222018-04-22 22:57:27 +01001307
Gilles Peskine449bd832023-01-11 14:50:10 +01001308 if (n > 15) {
1309 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1310 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001311
Gilles Peskine449bd832023-01-11 14:50:10 +01001312 while (length--) {
1313 if (n == 0) {
1314 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1315 if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001316 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001317 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001318 }
Simon Butcher76a5b222018-04-22 22:57:27 +01001319 *output++ = *input++ ^ iv[n];
1320
Gilles Peskine449bd832023-01-11 14:50:10 +01001321 n = (n + 1) & 0x0F;
Simon Butcher76a5b222018-04-22 22:57:27 +01001322 }
1323
1324 *iv_off = n;
1325
Simon Butcherad4e4932018-04-29 00:43:47 +01001326exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001327 return ret;
Simon Butcher76a5b222018-04-22 22:57:27 +01001328}
1329#endif /* MBEDTLS_CIPHER_MODE_OFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001330
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001331#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001332/*
1333 * AES-CTR buffer encryption/decryption
1334 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001335int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
1336 size_t length,
1337 size_t *nc_off,
1338 unsigned char nonce_counter[16],
1339 unsigned char stream_block[16],
1340 const unsigned char *input,
1341 unsigned char *output)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001342{
Paul Bakker369e14b2012-04-18 14:16:09 +00001343 int c, i;
Gilles Peskine7820a572021-07-07 21:08:28 +02001344 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001345 size_t n;
1346
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001347 n = *nc_off;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001348
Gilles Peskine449bd832023-01-11 14:50:10 +01001349 if (n > 0x0F) {
1350 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1351 }
Mohammad Azim Khan3f7f8172017-11-23 17:49:05 +00001352
Gilles Peskine449bd832023-01-11 14:50:10 +01001353 while (length--) {
1354 if (n == 0) {
1355 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block);
1356 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001357 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001358 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001359
Gilles Peskine449bd832023-01-11 14:50:10 +01001360 for (i = 16; i > 0; i--) {
1361 if (++nonce_counter[i - 1] != 0) {
Paul Bakker369e14b2012-04-18 14:16:09 +00001362 break;
Gilles Peskine449bd832023-01-11 14:50:10 +01001363 }
1364 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001365 }
1366 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001367 *output++ = (unsigned char) (c ^ stream_block[n]);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001368
Gilles Peskine449bd832023-01-11 14:50:10 +01001369 n = (n + 1) & 0x0F;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001370 }
1371
1372 *nc_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001373 ret = 0;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001374
Gilles Peskine7820a572021-07-07 21:08:28 +02001375exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001376 return ret;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001377}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001378#endif /* MBEDTLS_CIPHER_MODE_CTR */
Manuel Pégourié-Gonnard1ec220b2014-03-10 11:20:17 +01001379
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001380#endif /* !MBEDTLS_AES_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001381
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001382#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001383/*
1384 * AES test vectors from:
1385 *
1386 * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
1387 */
1388static const unsigned char aes_test_ecb_dec[3][16] =
1389{
1390 { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
1391 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
1392 { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
1393 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
1394 { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
1395 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
1396};
1397
1398static const unsigned char aes_test_ecb_enc[3][16] =
1399{
1400 { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
1401 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
1402 { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
1403 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
1404 { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
1405 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
1406};
1407
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001408#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001409static const unsigned char aes_test_cbc_dec[3][16] =
1410{
1411 { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
1412 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
1413 { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
1414 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
1415 { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
1416 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
1417};
1418
1419static const unsigned char aes_test_cbc_enc[3][16] =
1420{
1421 { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
1422 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
1423 { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
1424 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
1425 { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
1426 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
1427};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001428#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001429
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001430#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001431/*
1432 * AES-CFB128 test vectors from:
1433 *
1434 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
1435 */
1436static const unsigned char aes_test_cfb128_key[3][32] =
1437{
1438 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1439 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
1440 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1441 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1442 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1443 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1444 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1445 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1446 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
1447};
1448
1449static const unsigned char aes_test_cfb128_iv[16] =
1450{
1451 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1452 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1453};
1454
1455static const unsigned char aes_test_cfb128_pt[64] =
1456{
1457 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1458 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1459 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1460 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1461 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1462 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1463 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1464 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1465};
1466
1467static const unsigned char aes_test_cfb128_ct[3][64] =
1468{
1469 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1470 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1471 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F,
1472 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B,
1473 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40,
1474 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF,
1475 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E,
1476 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 },
1477 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1478 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1479 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21,
1480 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A,
1481 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1,
1482 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9,
1483 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0,
1484 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF },
1485 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1486 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1487 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8,
1488 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B,
1489 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92,
1490 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9,
1491 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8,
1492 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 }
1493};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001494#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001495
Simon Butcherad4e4932018-04-29 00:43:47 +01001496#if defined(MBEDTLS_CIPHER_MODE_OFB)
1497/*
1498 * AES-OFB test vectors from:
1499 *
Simon Butcher5db13622018-06-04 22:11:25 +01001500 * https://csrc.nist.gov/publications/detail/sp/800-38a/final
Simon Butcherad4e4932018-04-29 00:43:47 +01001501 */
1502static const unsigned char aes_test_ofb_key[3][32] =
1503{
1504 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1505 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
1506 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1507 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1508 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1509 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1510 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1511 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1512 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
1513};
1514
1515static const unsigned char aes_test_ofb_iv[16] =
1516{
1517 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1518 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1519};
1520
1521static const unsigned char aes_test_ofb_pt[64] =
1522{
1523 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1524 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1525 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1526 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1527 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1528 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1529 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1530 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1531};
1532
1533static const unsigned char aes_test_ofb_ct[3][64] =
1534{
1535 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1536 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1537 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
1538 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
1539 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
1540 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
1541 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
1542 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e },
1543 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1544 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1545 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
1546 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
1547 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f,
1548 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
1549 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e,
1550 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a },
1551 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1552 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1553 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
1554 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
1555 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed,
1556 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
1557 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8,
1558 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 }
1559};
1560#endif /* MBEDTLS_CIPHER_MODE_OFB */
1561
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001562#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001563/*
1564 * AES-CTR test vectors from:
1565 *
1566 * http://www.faqs.org/rfcs/rfc3686.html
1567 */
1568
1569static const unsigned char aes_test_ctr_key[3][16] =
1570{
1571 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
1572 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
1573 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
1574 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
1575 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
1576 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
1577};
1578
1579static const unsigned char aes_test_ctr_nonce_counter[3][16] =
1580{
1581 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
1582 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
1583 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
1584 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
1585 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
1586 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
1587};
1588
1589static const unsigned char aes_test_ctr_pt[3][48] =
1590{
1591 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
1592 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
1593
1594 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1595 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1596 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1597 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
1598
1599 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1600 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1601 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1602 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
1603 0x20, 0x21, 0x22, 0x23 }
1604};
1605
1606static const unsigned char aes_test_ctr_ct[3][48] =
1607{
1608 { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79,
1609 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 },
1610 { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9,
1611 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88,
1612 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8,
1613 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 },
1614 { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
1615 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
1616 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
1617 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
1618 0x25, 0xB2, 0x07, 0x2F }
1619};
1620
1621static const int aes_test_ctr_len[3] =
Gilles Peskine449bd832023-01-11 14:50:10 +01001622{ 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001623#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00001624
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001625#if defined(MBEDTLS_CIPHER_MODE_XTS)
1626/*
1627 * AES-XTS test vectors from:
1628 *
1629 * IEEE P1619/D16 Annex B
1630 * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf
1631 * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf)
1632 */
1633static const unsigned char aes_test_xts_key[][32] =
1634{
1635 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1636 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1637 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1638 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1639 { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1640 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1641 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1642 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1643 { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
1644 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
1645 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1646 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1647};
1648
1649static const unsigned char aes_test_xts_pt32[][32] =
1650{
1651 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1652 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1653 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1654 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1655 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1656 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1657 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1658 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1659 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1660 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1661 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1662 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1663};
1664
1665static const unsigned char aes_test_xts_ct32[][32] =
1666{
1667 { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec,
1668 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92,
1669 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85,
1670 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e },
1671 { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e,
1672 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b,
1673 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4,
1674 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 },
1675 { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a,
1676 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2,
1677 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53,
1678 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 },
1679};
1680
1681static const unsigned char aes_test_xts_data_unit[][16] =
1682{
Gilles Peskine449bd832023-01-11 14:50:10 +01001683 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1684 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1685 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1686 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1687 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1688 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001689};
1690
1691#endif /* MBEDTLS_CIPHER_MODE_XTS */
1692
Paul Bakker5121ce52009-01-03 21:22:43 +00001693/*
1694 * Checkup routine
1695 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001696int mbedtls_aes_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +00001697{
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001698 int ret = 0, i, j, u, mode;
1699 unsigned int keybits;
Paul Bakker5121ce52009-01-03 21:22:43 +00001700 unsigned char key[32];
1701 unsigned char buf[64];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001702 const unsigned char *aes_tests;
Andrzej Kurek252283f2022-09-27 07:54:16 -04001703#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1704 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001705 unsigned char iv[16];
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03001706#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001707#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +02001708 unsigned char prv[16];
1709#endif
Simon Butcher2ff0e522018-06-14 09:57:07 +01001710#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1711 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker27fdf462011-06-09 13:55:13 +00001712 size_t offset;
Paul Bakkere91d01e2011-04-19 15:55:50 +00001713#endif
Simon Butcher66a89032018-06-15 18:20:29 +01001714#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS)
Paul Bakkere91d01e2011-04-19 15:55:50 +00001715 int len;
Simon Butcher66a89032018-06-15 18:20:29 +01001716#endif
1717#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001718 unsigned char nonce_counter[16];
1719 unsigned char stream_block[16];
1720#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001721 mbedtls_aes_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001722
Gilles Peskine449bd832023-01-11 14:50:10 +01001723 memset(key, 0, 32);
1724 mbedtls_aes_init(&ctx);
Paul Bakker5121ce52009-01-03 21:22:43 +00001725
1726 /*
1727 * ECB mode
1728 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001729 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +00001730 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001731 keybits = 128 + u * 64;
1732 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001733
Gilles Peskine449bd832023-01-11 14:50:10 +01001734 if (verbose != 0) {
1735 mbedtls_printf(" AES-ECB-%3u (%s): ", keybits,
1736 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00001737 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001738
1739 memset(buf, 0, 16);
1740
1741 if (mode == MBEDTLS_AES_DECRYPT) {
1742 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1743 aes_tests = aes_test_ecb_dec[u];
1744 } else {
1745 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001746 aes_tests = aes_test_ecb_enc[u];
1747 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001748
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01001749 /*
1750 * AES-192 is an optional feature that may be unavailable when
1751 * there is an alternative underlying implementation i.e. when
1752 * MBEDTLS_AES_ALT is defined.
1753 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001754 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1755 mbedtls_printf("skipped\n");
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001756 continue;
Gilles Peskine449bd832023-01-11 14:50:10 +01001757 } else if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001758 goto exit;
1759 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001760
Gilles Peskine449bd832023-01-11 14:50:10 +01001761 for (j = 0; j < 10000; j++) {
1762 ret = mbedtls_aes_crypt_ecb(&ctx, mode, buf, buf);
1763 if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001764 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001765 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001766 }
1767
Gilles Peskine449bd832023-01-11 14:50:10 +01001768 if (memcmp(buf, aes_tests, 16) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001769 ret = 1;
1770 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001771 }
1772
Gilles Peskine449bd832023-01-11 14:50:10 +01001773 if (verbose != 0) {
1774 mbedtls_printf("passed\n");
1775 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001776 }
1777
Gilles Peskine449bd832023-01-11 14:50:10 +01001778 if (verbose != 0) {
1779 mbedtls_printf("\n");
1780 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001781
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001782#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001783 /*
1784 * CBC mode
1785 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001786 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +00001787 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001788 keybits = 128 + u * 64;
1789 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001790
Gilles Peskine449bd832023-01-11 14:50:10 +01001791 if (verbose != 0) {
1792 mbedtls_printf(" AES-CBC-%3u (%s): ", keybits,
1793 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00001794 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001795
1796 memset(iv, 0, 16);
1797 memset(prv, 0, 16);
1798 memset(buf, 0, 16);
1799
1800 if (mode == MBEDTLS_AES_DECRYPT) {
1801 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1802 aes_tests = aes_test_cbc_dec[u];
1803 } else {
1804 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001805 aes_tests = aes_test_cbc_enc[u];
1806 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001807
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01001808 /*
1809 * AES-192 is an optional feature that may be unavailable when
1810 * there is an alternative underlying implementation i.e. when
1811 * MBEDTLS_AES_ALT is defined.
1812 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001813 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1814 mbedtls_printf("skipped\n");
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001815 continue;
Gilles Peskine449bd832023-01-11 14:50:10 +01001816 } else if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001817 goto exit;
1818 }
1819
Gilles Peskine449bd832023-01-11 14:50:10 +01001820 for (j = 0; j < 10000; j++) {
1821 if (mode == MBEDTLS_AES_ENCRYPT) {
Paul Bakker5121ce52009-01-03 21:22:43 +00001822 unsigned char tmp[16];
1823
Gilles Peskine449bd832023-01-11 14:50:10 +01001824 memcpy(tmp, prv, 16);
1825 memcpy(prv, buf, 16);
1826 memcpy(buf, tmp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001827 }
1828
Gilles Peskine449bd832023-01-11 14:50:10 +01001829 ret = mbedtls_aes_crypt_cbc(&ctx, mode, 16, iv, buf, buf);
1830 if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001831 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001832 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001833
1834 }
1835
Gilles Peskine449bd832023-01-11 14:50:10 +01001836 if (memcmp(buf, aes_tests, 16) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001837 ret = 1;
1838 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001839 }
1840
Gilles Peskine449bd832023-01-11 14:50:10 +01001841 if (verbose != 0) {
1842 mbedtls_printf("passed\n");
1843 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001844 }
1845
Gilles Peskine449bd832023-01-11 14:50:10 +01001846 if (verbose != 0) {
1847 mbedtls_printf("\n");
1848 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001849#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001850
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001851#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001852 /*
1853 * CFB128 mode
1854 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001855 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +00001856 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001857 keybits = 128 + u * 64;
1858 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001859
Gilles Peskine449bd832023-01-11 14:50:10 +01001860 if (verbose != 0) {
1861 mbedtls_printf(" AES-CFB128-%3u (%s): ", keybits,
1862 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
1863 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001864
Gilles Peskine449bd832023-01-11 14:50:10 +01001865 memcpy(iv, aes_test_cfb128_iv, 16);
1866 memcpy(key, aes_test_cfb128_key[u], keybits / 8);
Paul Bakker5121ce52009-01-03 21:22:43 +00001867
1868 offset = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +01001869 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01001870 /*
1871 * AES-192 is an optional feature that may be unavailable when
1872 * there is an alternative underlying implementation i.e. when
1873 * MBEDTLS_AES_ALT is defined.
1874 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001875 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1876 mbedtls_printf("skipped\n");
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001877 continue;
Gilles Peskine449bd832023-01-11 14:50:10 +01001878 } else if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001879 goto exit;
1880 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001881
Gilles Peskine449bd832023-01-11 14:50:10 +01001882 if (mode == MBEDTLS_AES_DECRYPT) {
1883 memcpy(buf, aes_test_cfb128_ct[u], 64);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001884 aes_tests = aes_test_cfb128_pt;
Gilles Peskine449bd832023-01-11 14:50:10 +01001885 } else {
1886 memcpy(buf, aes_test_cfb128_pt, 64);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001887 aes_tests = aes_test_cfb128_ct[u];
1888 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001889
Gilles Peskine449bd832023-01-11 14:50:10 +01001890 ret = mbedtls_aes_crypt_cfb128(&ctx, mode, 64, &offset, iv, buf, buf);
1891 if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001892 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001893 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001894
Gilles Peskine449bd832023-01-11 14:50:10 +01001895 if (memcmp(buf, aes_tests, 64) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001896 ret = 1;
1897 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001898 }
1899
Gilles Peskine449bd832023-01-11 14:50:10 +01001900 if (verbose != 0) {
1901 mbedtls_printf("passed\n");
1902 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001903 }
1904
Gilles Peskine449bd832023-01-11 14:50:10 +01001905 if (verbose != 0) {
1906 mbedtls_printf("\n");
1907 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001908#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001909
Simon Butcherad4e4932018-04-29 00:43:47 +01001910#if defined(MBEDTLS_CIPHER_MODE_OFB)
1911 /*
1912 * OFB mode
1913 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001914 for (i = 0; i < 6; i++) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001915 u = i >> 1;
1916 keybits = 128 + u * 64;
1917 mode = i & 1;
1918
Gilles Peskine449bd832023-01-11 14:50:10 +01001919 if (verbose != 0) {
1920 mbedtls_printf(" AES-OFB-%3u (%s): ", keybits,
1921 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
1922 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001923
Gilles Peskine449bd832023-01-11 14:50:10 +01001924 memcpy(iv, aes_test_ofb_iv, 16);
1925 memcpy(key, aes_test_ofb_key[u], keybits / 8);
Simon Butcherad4e4932018-04-29 00:43:47 +01001926
1927 offset = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +01001928 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Simon Butcherad4e4932018-04-29 00:43:47 +01001929 /*
1930 * AES-192 is an optional feature that may be unavailable when
1931 * there is an alternative underlying implementation i.e. when
1932 * MBEDTLS_AES_ALT is defined.
1933 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001934 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1935 mbedtls_printf("skipped\n");
Simon Butcherad4e4932018-04-29 00:43:47 +01001936 continue;
Gilles Peskine449bd832023-01-11 14:50:10 +01001937 } else if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001938 goto exit;
1939 }
1940
Gilles Peskine449bd832023-01-11 14:50:10 +01001941 if (mode == MBEDTLS_AES_DECRYPT) {
1942 memcpy(buf, aes_test_ofb_ct[u], 64);
Simon Butcherad4e4932018-04-29 00:43:47 +01001943 aes_tests = aes_test_ofb_pt;
Gilles Peskine449bd832023-01-11 14:50:10 +01001944 } else {
1945 memcpy(buf, aes_test_ofb_pt, 64);
Simon Butcherad4e4932018-04-29 00:43:47 +01001946 aes_tests = aes_test_ofb_ct[u];
1947 }
1948
Gilles Peskine449bd832023-01-11 14:50:10 +01001949 ret = mbedtls_aes_crypt_ofb(&ctx, 64, &offset, iv, buf, buf);
1950 if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001951 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001952 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001953
Gilles Peskine449bd832023-01-11 14:50:10 +01001954 if (memcmp(buf, aes_tests, 64) != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001955 ret = 1;
1956 goto exit;
1957 }
1958
Gilles Peskine449bd832023-01-11 14:50:10 +01001959 if (verbose != 0) {
1960 mbedtls_printf("passed\n");
1961 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001962 }
1963
Gilles Peskine449bd832023-01-11 14:50:10 +01001964 if (verbose != 0) {
1965 mbedtls_printf("\n");
1966 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001967#endif /* MBEDTLS_CIPHER_MODE_OFB */
1968
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001969#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001970 /*
1971 * CTR mode
1972 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001973 for (i = 0; i < 6; i++) {
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001974 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001975 mode = i & 1;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001976
Gilles Peskine449bd832023-01-11 14:50:10 +01001977 if (verbose != 0) {
1978 mbedtls_printf(" AES-CTR-128 (%s): ",
1979 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
1980 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001981
Gilles Peskine449bd832023-01-11 14:50:10 +01001982 memcpy(nonce_counter, aes_test_ctr_nonce_counter[u], 16);
1983 memcpy(key, aes_test_ctr_key[u], 16);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001984
1985 offset = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +01001986 if ((ret = mbedtls_aes_setkey_enc(&ctx, key, 128)) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001987 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001988 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001989
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001990 len = aes_test_ctr_len[u];
1991
Gilles Peskine449bd832023-01-11 14:50:10 +01001992 if (mode == MBEDTLS_AES_DECRYPT) {
1993 memcpy(buf, aes_test_ctr_ct[u], len);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001994 aes_tests = aes_test_ctr_pt[u];
Gilles Peskine449bd832023-01-11 14:50:10 +01001995 } else {
1996 memcpy(buf, aes_test_ctr_pt[u], len);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001997 aes_tests = aes_test_ctr_ct[u];
1998 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001999
Gilles Peskine449bd832023-01-11 14:50:10 +01002000 ret = mbedtls_aes_crypt_ctr(&ctx, len, &offset, nonce_counter,
2001 stream_block, buf, buf);
2002 if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002003 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002004 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002005
Gilles Peskine449bd832023-01-11 14:50:10 +01002006 if (memcmp(buf, aes_tests, len) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002007 ret = 1;
2008 goto exit;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002009 }
2010
Gilles Peskine449bd832023-01-11 14:50:10 +01002011 if (verbose != 0) {
2012 mbedtls_printf("passed\n");
2013 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002014 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002015
Gilles Peskine449bd832023-01-11 14:50:10 +01002016 if (verbose != 0) {
2017 mbedtls_printf("\n");
2018 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002019#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00002020
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002021#if defined(MBEDTLS_CIPHER_MODE_XTS)
2022 {
Gilles Peskine449bd832023-01-11 14:50:10 +01002023 static const int num_tests =
2024 sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key);
2025 mbedtls_aes_xts_context ctx_xts;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002026
Gilles Peskine449bd832023-01-11 14:50:10 +01002027 /*
2028 * XTS mode
2029 */
2030 mbedtls_aes_xts_init(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002031
Gilles Peskine449bd832023-01-11 14:50:10 +01002032 for (i = 0; i < num_tests << 1; i++) {
2033 const unsigned char *data_unit;
2034 u = i >> 1;
2035 mode = i & 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002036
Gilles Peskine449bd832023-01-11 14:50:10 +01002037 if (verbose != 0) {
2038 mbedtls_printf(" AES-XTS-128 (%s): ",
2039 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2040 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002041
Gilles Peskine449bd832023-01-11 14:50:10 +01002042 memset(key, 0, sizeof(key));
2043 memcpy(key, aes_test_xts_key[u], 32);
2044 data_unit = aes_test_xts_data_unit[u];
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002045
Gilles Peskine449bd832023-01-11 14:50:10 +01002046 len = sizeof(*aes_test_xts_ct32);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002047
Gilles Peskine449bd832023-01-11 14:50:10 +01002048 if (mode == MBEDTLS_AES_DECRYPT) {
2049 ret = mbedtls_aes_xts_setkey_dec(&ctx_xts, key, 256);
2050 if (ret != 0) {
2051 goto exit;
2052 }
2053 memcpy(buf, aes_test_xts_ct32[u], len);
2054 aes_tests = aes_test_xts_pt32[u];
2055 } else {
2056 ret = mbedtls_aes_xts_setkey_enc(&ctx_xts, key, 256);
2057 if (ret != 0) {
2058 goto exit;
2059 }
2060 memcpy(buf, aes_test_xts_pt32[u], len);
2061 aes_tests = aes_test_xts_ct32[u];
2062 }
2063
2064
2065 ret = mbedtls_aes_crypt_xts(&ctx_xts, mode, len, data_unit,
2066 buf, buf);
2067 if (ret != 0) {
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002068 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002069 }
2070
2071 if (memcmp(buf, aes_tests, len) != 0) {
2072 ret = 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002073 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002074 }
2075
2076 if (verbose != 0) {
2077 mbedtls_printf("passed\n");
2078 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002079 }
2080
Gilles Peskine449bd832023-01-11 14:50:10 +01002081 if (verbose != 0) {
2082 mbedtls_printf("\n");
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002083 }
2084
Gilles Peskine449bd832023-01-11 14:50:10 +01002085 mbedtls_aes_xts_free(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002086 }
2087#endif /* MBEDTLS_CIPHER_MODE_XTS */
2088
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002089 ret = 0;
2090
2091exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01002092 if (ret != 0 && verbose != 0) {
2093 mbedtls_printf("failed\n");
2094 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002095
Gilles Peskine449bd832023-01-11 14:50:10 +01002096 mbedtls_aes_free(&ctx);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002097
Gilles Peskine449bd832023-01-11 14:50:10 +01002098 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002099}
2100
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002101#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002102
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002103#endif /* MBEDTLS_AES_C */