blob: 566e74715febaadb97e0f97bb76596a2dc75a1df [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
Paul Bakker5121ce52009-01-03 21:22:43 +000042
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000043#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010044
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020045#if !defined(MBEDTLS_AES_ALT)
Paul Bakker90995b52013-06-24 19:20:35 +020046
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020047#if defined(MBEDTLS_PADLOCK_C) && \
Gilles Peskine449bd832023-01-11 14:50:10 +010048 (defined(MBEDTLS_HAVE_X86) || defined(MBEDTLS_PADLOCK_ALIGN16))
Paul Bakker048d04e2012-02-12 17:31:04 +000049static int aes_padlock_ace = -1;
50#endif
51
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020052#if defined(MBEDTLS_AES_ROM_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +000053/*
54 * Forward S-box
55 */
56static const unsigned char FSb[256] =
57{
58 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
59 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
60 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
61 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
62 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
63 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
64 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
65 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
66 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
67 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
68 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
69 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
70 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
71 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
72 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
73 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
74 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
75 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
76 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
77 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
78 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
79 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
80 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
81 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
82 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
83 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
84 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
85 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
86 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
87 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
88 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
89 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
90};
91
92/*
93 * Forward tables
94 */
95#define FT \
96\
Gilles Peskine449bd832023-01-11 14:50:10 +010097 V(A5, 63, 63, C6), V(84, 7C, 7C, F8), V(99, 77, 77, EE), V(8D, 7B, 7B, F6), \
98 V(0D, F2, F2, FF), V(BD, 6B, 6B, D6), V(B1, 6F, 6F, DE), V(54, C5, C5, 91), \
99 V(50, 30, 30, 60), V(03, 01, 01, 02), V(A9, 67, 67, CE), V(7D, 2B, 2B, 56), \
100 V(19, FE, FE, E7), V(62, D7, D7, B5), V(E6, AB, AB, 4D), V(9A, 76, 76, EC), \
101 V(45, CA, CA, 8F), V(9D, 82, 82, 1F), V(40, C9, C9, 89), V(87, 7D, 7D, FA), \
102 V(15, FA, FA, EF), V(EB, 59, 59, B2), V(C9, 47, 47, 8E), V(0B, F0, F0, FB), \
103 V(EC, AD, AD, 41), V(67, D4, D4, B3), V(FD, A2, A2, 5F), V(EA, AF, AF, 45), \
104 V(BF, 9C, 9C, 23), V(F7, A4, A4, 53), V(96, 72, 72, E4), V(5B, C0, C0, 9B), \
105 V(C2, B7, B7, 75), V(1C, FD, FD, E1), V(AE, 93, 93, 3D), V(6A, 26, 26, 4C), \
106 V(5A, 36, 36, 6C), V(41, 3F, 3F, 7E), V(02, F7, F7, F5), V(4F, CC, CC, 83), \
107 V(5C, 34, 34, 68), V(F4, A5, A5, 51), V(34, E5, E5, D1), V(08, F1, F1, F9), \
108 V(93, 71, 71, E2), V(73, D8, D8, AB), V(53, 31, 31, 62), V(3F, 15, 15, 2A), \
109 V(0C, 04, 04, 08), V(52, C7, C7, 95), V(65, 23, 23, 46), V(5E, C3, C3, 9D), \
110 V(28, 18, 18, 30), V(A1, 96, 96, 37), V(0F, 05, 05, 0A), V(B5, 9A, 9A, 2F), \
111 V(09, 07, 07, 0E), V(36, 12, 12, 24), V(9B, 80, 80, 1B), V(3D, E2, E2, DF), \
112 V(26, EB, EB, CD), V(69, 27, 27, 4E), V(CD, B2, B2, 7F), V(9F, 75, 75, EA), \
113 V(1B, 09, 09, 12), V(9E, 83, 83, 1D), V(74, 2C, 2C, 58), V(2E, 1A, 1A, 34), \
114 V(2D, 1B, 1B, 36), V(B2, 6E, 6E, DC), V(EE, 5A, 5A, B4), V(FB, A0, A0, 5B), \
115 V(F6, 52, 52, A4), V(4D, 3B, 3B, 76), V(61, D6, D6, B7), V(CE, B3, B3, 7D), \
116 V(7B, 29, 29, 52), V(3E, E3, E3, DD), V(71, 2F, 2F, 5E), V(97, 84, 84, 13), \
117 V(F5, 53, 53, A6), V(68, D1, D1, B9), V(00, 00, 00, 00), V(2C, ED, ED, C1), \
118 V(60, 20, 20, 40), V(1F, FC, FC, E3), V(C8, B1, B1, 79), V(ED, 5B, 5B, B6), \
119 V(BE, 6A, 6A, D4), V(46, CB, CB, 8D), V(D9, BE, BE, 67), V(4B, 39, 39, 72), \
120 V(DE, 4A, 4A, 94), V(D4, 4C, 4C, 98), V(E8, 58, 58, B0), V(4A, CF, CF, 85), \
121 V(6B, D0, D0, BB), V(2A, EF, EF, C5), V(E5, AA, AA, 4F), V(16, FB, FB, ED), \
122 V(C5, 43, 43, 86), V(D7, 4D, 4D, 9A), V(55, 33, 33, 66), V(94, 85, 85, 11), \
123 V(CF, 45, 45, 8A), V(10, F9, F9, E9), V(06, 02, 02, 04), V(81, 7F, 7F, FE), \
124 V(F0, 50, 50, A0), V(44, 3C, 3C, 78), V(BA, 9F, 9F, 25), V(E3, A8, A8, 4B), \
125 V(F3, 51, 51, A2), V(FE, A3, A3, 5D), V(C0, 40, 40, 80), V(8A, 8F, 8F, 05), \
126 V(AD, 92, 92, 3F), V(BC, 9D, 9D, 21), V(48, 38, 38, 70), V(04, F5, F5, F1), \
127 V(DF, BC, BC, 63), V(C1, B6, B6, 77), V(75, DA, DA, AF), V(63, 21, 21, 42), \
128 V(30, 10, 10, 20), V(1A, FF, FF, E5), V(0E, F3, F3, FD), V(6D, D2, D2, BF), \
129 V(4C, CD, CD, 81), V(14, 0C, 0C, 18), V(35, 13, 13, 26), V(2F, EC, EC, C3), \
130 V(E1, 5F, 5F, BE), V(A2, 97, 97, 35), V(CC, 44, 44, 88), V(39, 17, 17, 2E), \
131 V(57, C4, C4, 93), V(F2, A7, A7, 55), V(82, 7E, 7E, FC), V(47, 3D, 3D, 7A), \
132 V(AC, 64, 64, C8), V(E7, 5D, 5D, BA), V(2B, 19, 19, 32), V(95, 73, 73, E6), \
133 V(A0, 60, 60, C0), V(98, 81, 81, 19), V(D1, 4F, 4F, 9E), V(7F, DC, DC, A3), \
134 V(66, 22, 22, 44), V(7E, 2A, 2A, 54), V(AB, 90, 90, 3B), V(83, 88, 88, 0B), \
135 V(CA, 46, 46, 8C), V(29, EE, EE, C7), V(D3, B8, B8, 6B), V(3C, 14, 14, 28), \
136 V(79, DE, DE, A7), V(E2, 5E, 5E, BC), V(1D, 0B, 0B, 16), V(76, DB, DB, AD), \
137 V(3B, E0, E0, DB), V(56, 32, 32, 64), V(4E, 3A, 3A, 74), V(1E, 0A, 0A, 14), \
138 V(DB, 49, 49, 92), V(0A, 06, 06, 0C), V(6C, 24, 24, 48), V(E4, 5C, 5C, B8), \
139 V(5D, C2, C2, 9F), V(6E, D3, D3, BD), V(EF, AC, AC, 43), V(A6, 62, 62, C4), \
140 V(A8, 91, 91, 39), V(A4, 95, 95, 31), V(37, E4, E4, D3), V(8B, 79, 79, F2), \
141 V(32, E7, E7, D5), V(43, C8, C8, 8B), V(59, 37, 37, 6E), V(B7, 6D, 6D, DA), \
142 V(8C, 8D, 8D, 01), V(64, D5, D5, B1), V(D2, 4E, 4E, 9C), V(E0, A9, A9, 49), \
143 V(B4, 6C, 6C, D8), V(FA, 56, 56, AC), V(07, F4, F4, F3), V(25, EA, EA, CF), \
144 V(AF, 65, 65, CA), V(8E, 7A, 7A, F4), V(E9, AE, AE, 47), V(18, 08, 08, 10), \
145 V(D5, BA, BA, 6F), V(88, 78, 78, F0), V(6F, 25, 25, 4A), V(72, 2E, 2E, 5C), \
146 V(24, 1C, 1C, 38), V(F1, A6, A6, 57), V(C7, B4, B4, 73), V(51, C6, C6, 97), \
147 V(23, E8, E8, CB), V(7C, DD, DD, A1), V(9C, 74, 74, E8), V(21, 1F, 1F, 3E), \
148 V(DD, 4B, 4B, 96), V(DC, BD, BD, 61), V(86, 8B, 8B, 0D), V(85, 8A, 8A, 0F), \
149 V(90, 70, 70, E0), V(42, 3E, 3E, 7C), V(C4, B5, B5, 71), V(AA, 66, 66, CC), \
150 V(D8, 48, 48, 90), V(05, 03, 03, 06), V(01, F6, F6, F7), V(12, 0E, 0E, 1C), \
151 V(A3, 61, 61, C2), V(5F, 35, 35, 6A), V(F9, 57, 57, AE), V(D0, B9, B9, 69), \
152 V(91, 86, 86, 17), V(58, C1, C1, 99), V(27, 1D, 1D, 3A), V(B9, 9E, 9E, 27), \
153 V(38, E1, E1, D9), V(13, F8, F8, EB), V(B3, 98, 98, 2B), V(33, 11, 11, 22), \
154 V(BB, 69, 69, D2), V(70, D9, D9, A9), V(89, 8E, 8E, 07), V(A7, 94, 94, 33), \
155 V(B6, 9B, 9B, 2D), V(22, 1E, 1E, 3C), V(92, 87, 87, 15), V(20, E9, E9, C9), \
156 V(49, CE, CE, 87), V(FF, 55, 55, AA), V(78, 28, 28, 50), V(7A, DF, DF, A5), \
157 V(8F, 8C, 8C, 03), V(F8, A1, A1, 59), V(80, 89, 89, 09), V(17, 0D, 0D, 1A), \
158 V(DA, BF, BF, 65), V(31, E6, E6, D7), V(C6, 42, 42, 84), V(B8, 68, 68, D0), \
159 V(C3, 41, 41, 82), V(B0, 99, 99, 29), V(77, 2D, 2D, 5A), V(11, 0F, 0F, 1E), \
160 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 +0000161
Gilles Peskine449bd832023-01-11 14:50:10 +0100162#define V(a, b, c, d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000163static const uint32_t FT0[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000164#undef V
165
Hanno Beckerad049a92017-06-19 16:31:54 +0100166#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200167
Gilles Peskine449bd832023-01-11 14:50:10 +0100168#define V(a, b, c, d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000169static const uint32_t FT1[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000170#undef V
171
Gilles Peskine449bd832023-01-11 14:50:10 +0100172#define V(a, b, c, d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000173static const uint32_t FT2[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000174#undef V
175
Gilles Peskine449bd832023-01-11 14:50:10 +0100176#define V(a, b, c, d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000177static const uint32_t FT3[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000178#undef V
179
Hanno Becker177d3cf2017-06-07 15:52:48 +0100180#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200181
Paul Bakker5121ce52009-01-03 21:22:43 +0000182#undef FT
183
184/*
185 * Reverse S-box
186 */
187static const unsigned char RSb[256] =
188{
189 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
190 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
191 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
192 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
193 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
194 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
195 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
196 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
197 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
198 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
199 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
200 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
201 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
202 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
203 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
204 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
205 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
206 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
207 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
208 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
209 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
210 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
211 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
212 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
213 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
214 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
215 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
216 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
217 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
218 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
219 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
220 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
221};
222
223/*
224 * Reverse tables
225 */
226#define RT \
227\
Gilles Peskine449bd832023-01-11 14:50:10 +0100228 V(50, A7, F4, 51), V(53, 65, 41, 7E), V(C3, A4, 17, 1A), V(96, 5E, 27, 3A), \
229 V(CB, 6B, AB, 3B), V(F1, 45, 9D, 1F), V(AB, 58, FA, AC), V(93, 03, E3, 4B), \
230 V(55, FA, 30, 20), V(F6, 6D, 76, AD), V(91, 76, CC, 88), V(25, 4C, 02, F5), \
231 V(FC, D7, E5, 4F), V(D7, CB, 2A, C5), V(80, 44, 35, 26), V(8F, A3, 62, B5), \
232 V(49, 5A, B1, DE), V(67, 1B, BA, 25), V(98, 0E, EA, 45), V(E1, C0, FE, 5D), \
233 V(02, 75, 2F, C3), V(12, F0, 4C, 81), V(A3, 97, 46, 8D), V(C6, F9, D3, 6B), \
234 V(E7, 5F, 8F, 03), V(95, 9C, 92, 15), V(EB, 7A, 6D, BF), V(DA, 59, 52, 95), \
235 V(2D, 83, BE, D4), V(D3, 21, 74, 58), V(29, 69, E0, 49), V(44, C8, C9, 8E), \
236 V(6A, 89, C2, 75), V(78, 79, 8E, F4), V(6B, 3E, 58, 99), V(DD, 71, B9, 27), \
237 V(B6, 4F, E1, BE), V(17, AD, 88, F0), V(66, AC, 20, C9), V(B4, 3A, CE, 7D), \
238 V(18, 4A, DF, 63), V(82, 31, 1A, E5), V(60, 33, 51, 97), V(45, 7F, 53, 62), \
239 V(E0, 77, 64, B1), V(84, AE, 6B, BB), V(1C, A0, 81, FE), V(94, 2B, 08, F9), \
240 V(58, 68, 48, 70), V(19, FD, 45, 8F), V(87, 6C, DE, 94), V(B7, F8, 7B, 52), \
241 V(23, D3, 73, AB), V(E2, 02, 4B, 72), V(57, 8F, 1F, E3), V(2A, AB, 55, 66), \
242 V(07, 28, EB, B2), V(03, C2, B5, 2F), V(9A, 7B, C5, 86), V(A5, 08, 37, D3), \
243 V(F2, 87, 28, 30), V(B2, A5, BF, 23), V(BA, 6A, 03, 02), V(5C, 82, 16, ED), \
244 V(2B, 1C, CF, 8A), V(92, B4, 79, A7), V(F0, F2, 07, F3), V(A1, E2, 69, 4E), \
245 V(CD, F4, DA, 65), V(D5, BE, 05, 06), V(1F, 62, 34, D1), V(8A, FE, A6, C4), \
246 V(9D, 53, 2E, 34), V(A0, 55, F3, A2), V(32, E1, 8A, 05), V(75, EB, F6, A4), \
247 V(39, EC, 83, 0B), V(AA, EF, 60, 40), V(06, 9F, 71, 5E), V(51, 10, 6E, BD), \
248 V(F9, 8A, 21, 3E), V(3D, 06, DD, 96), V(AE, 05, 3E, DD), V(46, BD, E6, 4D), \
249 V(B5, 8D, 54, 91), V(05, 5D, C4, 71), V(6F, D4, 06, 04), V(FF, 15, 50, 60), \
250 V(24, FB, 98, 19), V(97, E9, BD, D6), V(CC, 43, 40, 89), V(77, 9E, D9, 67), \
251 V(BD, 42, E8, B0), V(88, 8B, 89, 07), V(38, 5B, 19, E7), V(DB, EE, C8, 79), \
252 V(47, 0A, 7C, A1), V(E9, 0F, 42, 7C), V(C9, 1E, 84, F8), V(00, 00, 00, 00), \
253 V(83, 86, 80, 09), V(48, ED, 2B, 32), V(AC, 70, 11, 1E), V(4E, 72, 5A, 6C), \
254 V(FB, FF, 0E, FD), V(56, 38, 85, 0F), V(1E, D5, AE, 3D), V(27, 39, 2D, 36), \
255 V(64, D9, 0F, 0A), V(21, A6, 5C, 68), V(D1, 54, 5B, 9B), V(3A, 2E, 36, 24), \
256 V(B1, 67, 0A, 0C), V(0F, E7, 57, 93), V(D2, 96, EE, B4), V(9E, 91, 9B, 1B), \
257 V(4F, C5, C0, 80), V(A2, 20, DC, 61), V(69, 4B, 77, 5A), V(16, 1A, 12, 1C), \
258 V(0A, BA, 93, E2), V(E5, 2A, A0, C0), V(43, E0, 22, 3C), V(1D, 17, 1B, 12), \
259 V(0B, 0D, 09, 0E), V(AD, C7, 8B, F2), V(B9, A8, B6, 2D), V(C8, A9, 1E, 14), \
260 V(85, 19, F1, 57), V(4C, 07, 75, AF), V(BB, DD, 99, EE), V(FD, 60, 7F, A3), \
261 V(9F, 26, 01, F7), V(BC, F5, 72, 5C), V(C5, 3B, 66, 44), V(34, 7E, FB, 5B), \
262 V(76, 29, 43, 8B), V(DC, C6, 23, CB), V(68, FC, ED, B6), V(63, F1, E4, B8), \
263 V(CA, DC, 31, D7), V(10, 85, 63, 42), V(40, 22, 97, 13), V(20, 11, C6, 84), \
264 V(7D, 24, 4A, 85), V(F8, 3D, BB, D2), V(11, 32, F9, AE), V(6D, A1, 29, C7), \
265 V(4B, 2F, 9E, 1D), V(F3, 30, B2, DC), V(EC, 52, 86, 0D), V(D0, E3, C1, 77), \
266 V(6C, 16, B3, 2B), V(99, B9, 70, A9), V(FA, 48, 94, 11), V(22, 64, E9, 47), \
267 V(C4, 8C, FC, A8), V(1A, 3F, F0, A0), V(D8, 2C, 7D, 56), V(EF, 90, 33, 22), \
268 V(C7, 4E, 49, 87), V(C1, D1, 38, D9), V(FE, A2, CA, 8C), V(36, 0B, D4, 98), \
269 V(CF, 81, F5, A6), V(28, DE, 7A, A5), V(26, 8E, B7, DA), V(A4, BF, AD, 3F), \
270 V(E4, 9D, 3A, 2C), V(0D, 92, 78, 50), V(9B, CC, 5F, 6A), V(62, 46, 7E, 54), \
271 V(C2, 13, 8D, F6), V(E8, B8, D8, 90), V(5E, F7, 39, 2E), V(F5, AF, C3, 82), \
272 V(BE, 80, 5D, 9F), V(7C, 93, D0, 69), V(A9, 2D, D5, 6F), V(B3, 12, 25, CF), \
273 V(3B, 99, AC, C8), V(A7, 7D, 18, 10), V(6E, 63, 9C, E8), V(7B, BB, 3B, DB), \
274 V(09, 78, 26, CD), V(F4, 18, 59, 6E), V(01, B7, 9A, EC), V(A8, 9A, 4F, 83), \
275 V(65, 6E, 95, E6), V(7E, E6, FF, AA), V(08, CF, BC, 21), V(E6, E8, 15, EF), \
276 V(D9, 9B, E7, BA), V(CE, 36, 6F, 4A), V(D4, 09, 9F, EA), V(D6, 7C, B0, 29), \
277 V(AF, B2, A4, 31), V(31, 23, 3F, 2A), V(30, 94, A5, C6), V(C0, 66, A2, 35), \
278 V(37, BC, 4E, 74), V(A6, CA, 82, FC), V(B0, D0, 90, E0), V(15, D8, A7, 33), \
279 V(4A, 98, 04, F1), V(F7, DA, EC, 41), V(0E, 50, CD, 7F), V(2F, F6, 91, 17), \
280 V(8D, D6, 4D, 76), V(4D, B0, EF, 43), V(54, 4D, AA, CC), V(DF, 04, 96, E4), \
281 V(E3, B5, D1, 9E), V(1B, 88, 6A, 4C), V(B8, 1F, 2C, C1), V(7F, 51, 65, 46), \
282 V(04, EA, 5E, 9D), V(5D, 35, 8C, 01), V(73, 74, 87, FA), V(2E, 41, 0B, FB), \
283 V(5A, 1D, 67, B3), V(52, D2, DB, 92), V(33, 56, 10, E9), V(13, 47, D6, 6D), \
284 V(8C, 61, D7, 9A), V(7A, 0C, A1, 37), V(8E, 14, F8, 59), V(89, 3C, 13, EB), \
285 V(EE, 27, A9, CE), V(35, C9, 61, B7), V(ED, E5, 1C, E1), V(3C, B1, 47, 7A), \
286 V(59, DF, D2, 9C), V(3F, 73, F2, 55), V(79, CE, 14, 18), V(BF, 37, C7, 73), \
287 V(EA, CD, F7, 53), V(5B, AA, FD, 5F), V(14, 6F, 3D, DF), V(86, DB, 44, 78), \
288 V(81, F3, AF, CA), V(3E, C4, 68, B9), V(2C, 34, 24, 38), V(5F, 40, A3, C2), \
289 V(72, C3, 1D, 16), V(0C, 25, E2, BC), V(8B, 49, 3C, 28), V(41, 95, 0D, FF), \
290 V(71, 01, A8, 39), V(DE, B3, 0C, 08), V(9C, E4, B4, D8), V(90, C1, 56, 64), \
291 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 +0000292
Gilles Peskine449bd832023-01-11 14:50:10 +0100293#define V(a, b, c, d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000294static const uint32_t RT0[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000295#undef V
296
Hanno Beckerad049a92017-06-19 16:31:54 +0100297#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200298
Gilles Peskine449bd832023-01-11 14:50:10 +0100299#define V(a, b, c, d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000300static const uint32_t RT1[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000301#undef V
302
Gilles Peskine449bd832023-01-11 14:50:10 +0100303#define V(a, b, c, d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000304static const uint32_t RT2[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000305#undef V
306
Gilles Peskine449bd832023-01-11 14:50:10 +0100307#define V(a, b, c, d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000308static const uint32_t RT3[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000309#undef V
310
Hanno Becker177d3cf2017-06-07 15:52:48 +0100311#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200312
Paul Bakker5121ce52009-01-03 21:22:43 +0000313#undef RT
314
315/*
316 * Round constants
317 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000318static const uint32_t RCON[10] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000319{
320 0x00000001, 0x00000002, 0x00000004, 0x00000008,
321 0x00000010, 0x00000020, 0x00000040, 0x00000080,
322 0x0000001B, 0x00000036
323};
324
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200325#else /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000326
327/*
328 * Forward S-box & tables
329 */
330static unsigned char FSb[256];
Paul Bakker9af723c2014-05-01 13:03:14 +0200331static uint32_t FT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100332#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker9af723c2014-05-01 13:03:14 +0200333static uint32_t FT1[256];
334static uint32_t FT2[256];
335static uint32_t FT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100336#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000337
338/*
339 * Reverse S-box & tables
340 */
341static unsigned char RSb[256];
Paul Bakker5c2364c2012-10-01 14:41:15 +0000342static uint32_t RT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100343#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker5c2364c2012-10-01 14:41:15 +0000344static uint32_t RT1[256];
345static uint32_t RT2[256];
346static uint32_t RT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100347#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000348
349/*
350 * Round constants
351 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000352static uint32_t RCON[10];
Paul Bakker5121ce52009-01-03 21:22:43 +0000353
354/*
355 * Tables generation code
356 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100357#define ROTL8(x) (((x) << 8) & 0xFFFFFFFF) | ((x) >> 24)
358#define XTIME(x) (((x) << 1) ^ (((x) & 0x80) ? 0x1B : 0x00))
359#define MUL(x, y) (((x) && (y)) ? pow[(log[(x)]+log[(y)]) % 255] : 0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000360
361static int aes_init_done = 0;
362
Gilles Peskine449bd832023-01-11 14:50:10 +0100363static void aes_gen_tables(void)
Paul Bakker5121ce52009-01-03 21:22:43 +0000364{
365 int i, x, y, z;
366 int pow[256];
367 int log[256];
368
369 /*
370 * compute pow and log tables over GF(2^8)
371 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100372 for (i = 0, x = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000373 pow[i] = x;
374 log[x] = i;
Gilles Peskine449bd832023-01-11 14:50:10 +0100375 x = MBEDTLS_BYTE_0(x ^ XTIME(x));
Paul Bakker5121ce52009-01-03 21:22:43 +0000376 }
377
378 /*
379 * calculate the round constants
380 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100381 for (i = 0, x = 1; i < 10; i++) {
Paul Bakker5c2364c2012-10-01 14:41:15 +0000382 RCON[i] = (uint32_t) x;
Gilles Peskine449bd832023-01-11 14:50:10 +0100383 x = MBEDTLS_BYTE_0(XTIME(x));
Paul Bakker5121ce52009-01-03 21:22:43 +0000384 }
385
386 /*
387 * generate the forward and reverse S-boxes
388 */
389 FSb[0x00] = 0x63;
390 RSb[0x63] = 0x00;
391
Gilles Peskine449bd832023-01-11 14:50:10 +0100392 for (i = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000393 x = pow[255 - log[i]];
394
Gilles Peskine449bd832023-01-11 14:50:10 +0100395 y = x; y = MBEDTLS_BYTE_0((y << 1) | (y >> 7));
396 x ^= y; y = MBEDTLS_BYTE_0((y << 1) | (y >> 7));
397 x ^= y; y = MBEDTLS_BYTE_0((y << 1) | (y >> 7));
398 x ^= y; y = MBEDTLS_BYTE_0((y << 1) | (y >> 7));
Paul Bakker5121ce52009-01-03 21:22:43 +0000399 x ^= y ^ 0x63;
400
401 FSb[i] = (unsigned char) x;
402 RSb[x] = (unsigned char) i;
403 }
404
405 /*
406 * generate the forward and reverse tables
407 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100408 for (i = 0; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000409 x = FSb[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100410 y = MBEDTLS_BYTE_0(XTIME(x));
411 z = MBEDTLS_BYTE_0(y ^ x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000412
Gilles Peskine449bd832023-01-11 14:50:10 +0100413 FT0[i] = ((uint32_t) y) ^
414 ((uint32_t) x << 8) ^
415 ((uint32_t) x << 16) ^
416 ((uint32_t) z << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000417
Hanno Beckerad049a92017-06-19 16:31:54 +0100418#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100419 FT1[i] = ROTL8(FT0[i]);
420 FT2[i] = ROTL8(FT1[i]);
421 FT3[i] = ROTL8(FT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100422#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000423
424 x = RSb[i];
425
Gilles Peskine449bd832023-01-11 14:50:10 +0100426 RT0[i] = ((uint32_t) MUL(0x0E, x)) ^
427 ((uint32_t) MUL(0x09, x) << 8) ^
428 ((uint32_t) MUL(0x0D, x) << 16) ^
429 ((uint32_t) MUL(0x0B, x) << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000430
Hanno Beckerad049a92017-06-19 16:31:54 +0100431#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100432 RT1[i] = ROTL8(RT0[i]);
433 RT2[i] = ROTL8(RT1[i]);
434 RT3[i] = ROTL8(RT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100435#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000436 }
437}
438
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200439#undef ROTL8
440
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200441#endif /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000442
Hanno Beckerad049a92017-06-19 16:31:54 +0100443#if defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200444
Gilles Peskine449bd832023-01-11 14:50:10 +0100445#define ROTL8(x) ((uint32_t) ((x) << 8) + (uint32_t) ((x) >> 24))
446#define ROTL16(x) ((uint32_t) ((x) << 16) + (uint32_t) ((x) >> 16))
447#define ROTL24(x) ((uint32_t) ((x) << 24) + (uint32_t) ((x) >> 8))
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200448
449#define AES_RT0(idx) RT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100450#define AES_RT1(idx) ROTL8(RT0[idx])
451#define AES_RT2(idx) ROTL16(RT0[idx])
452#define AES_RT3(idx) ROTL24(RT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200453
454#define AES_FT0(idx) FT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100455#define AES_FT1(idx) ROTL8(FT0[idx])
456#define AES_FT2(idx) ROTL16(FT0[idx])
457#define AES_FT3(idx) ROTL24(FT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200458
Hanno Becker177d3cf2017-06-07 15:52:48 +0100459#else /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200460
461#define AES_RT0(idx) RT0[idx]
462#define AES_RT1(idx) RT1[idx]
463#define AES_RT2(idx) RT2[idx]
464#define AES_RT3(idx) RT3[idx]
465
466#define AES_FT0(idx) FT0[idx]
467#define AES_FT1(idx) FT1[idx]
468#define AES_FT2(idx) FT2[idx]
469#define AES_FT3(idx) FT3[idx]
470
Hanno Becker177d3cf2017-06-07 15:52:48 +0100471#endif /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200472
Gilles Peskine449bd832023-01-11 14:50:10 +0100473void mbedtls_aes_init(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200474{
Gilles Peskine449bd832023-01-11 14:50:10 +0100475 memset(ctx, 0, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200476}
477
Gilles Peskine449bd832023-01-11 14:50:10 +0100478void mbedtls_aes_free(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200479{
Gilles Peskine449bd832023-01-11 14:50:10 +0100480 if (ctx == NULL) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200481 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100482 }
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200483
Gilles Peskine449bd832023-01-11 14:50:10 +0100484 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200485}
486
Jaeden Amero9366feb2018-05-29 18:55:17 +0100487#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100488void mbedtls_aes_xts_init(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100489{
Gilles Peskine449bd832023-01-11 14:50:10 +0100490 mbedtls_aes_init(&ctx->crypt);
491 mbedtls_aes_init(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100492}
493
Gilles Peskine449bd832023-01-11 14:50:10 +0100494void mbedtls_aes_xts_free(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100495{
Gilles Peskine449bd832023-01-11 14:50:10 +0100496 if (ctx == NULL) {
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100497 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100498 }
Simon Butcher5201e412018-12-06 17:40:14 +0000499
Gilles Peskine449bd832023-01-11 14:50:10 +0100500 mbedtls_aes_free(&ctx->crypt);
501 mbedtls_aes_free(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100502}
503#endif /* MBEDTLS_CIPHER_MODE_XTS */
504
Paul Bakker5121ce52009-01-03 21:22:43 +0000505/*
506 * AES key schedule (encryption)
507 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200508#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100509int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
510 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000511{
Paul Bakker23986e52011-04-24 08:57:21 +0000512 unsigned int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000513 uint32_t *RK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000514
Gilles Peskine449bd832023-01-11 14:50:10 +0100515 switch (keybits) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000516 case 128: ctx->nr = 10; break;
517 case 192: ctx->nr = 12; break;
518 case 256: ctx->nr = 14; break;
Gilles Peskine449bd832023-01-11 14:50:10 +0100519 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Paul Bakker5121ce52009-01-03 21:22:43 +0000520 }
521
Simon Butcher5201e412018-12-06 17:40:14 +0000522#if !defined(MBEDTLS_AES_ROM_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100523 if (aes_init_done == 0) {
Simon Butcher5201e412018-12-06 17:40:14 +0000524 aes_gen_tables();
525 aes_init_done = 1;
Simon Butcher5201e412018-12-06 17:40:14 +0000526 }
527#endif
528
Werner Lewis7656a372022-06-13 12:28:20 +0100529 ctx->rk_offset = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200530#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_PADLOCK_ALIGN16)
Gilles Peskine449bd832023-01-11 14:50:10 +0100531 if (aes_padlock_ace == -1) {
532 aes_padlock_ace = mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE);
533 }
Paul Bakker048d04e2012-02-12 17:31:04 +0000534
Gilles Peskine449bd832023-01-11 14:50:10 +0100535 if (aes_padlock_ace) {
536 ctx->rk_offset = MBEDTLS_PADLOCK_ALIGN16(ctx->buf) - ctx->buf;
537 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000538#endif
Werner Lewisdd76ef32022-05-30 12:00:21 +0100539 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000540
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200541#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Gilles Peskine449bd832023-01-11 14:50:10 +0100542 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
543 return mbedtls_aesni_setkey_enc((unsigned char *) RK, key, keybits);
544 }
Manuel Pégourié-Gonnard47a35362013-12-28 20:45:04 +0100545#endif
546
Gilles Peskine449bd832023-01-11 14:50:10 +0100547 for (i = 0; i < (keybits >> 5); i++) {
548 RK[i] = MBEDTLS_GET_UINT32_LE(key, i << 2);
Paul Bakker5121ce52009-01-03 21:22:43 +0000549 }
550
Gilles Peskine449bd832023-01-11 14:50:10 +0100551 switch (ctx->nr) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000552 case 10:
553
Gilles Peskine449bd832023-01-11 14:50:10 +0100554 for (i = 0; i < 10; i++, RK += 4) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000555 RK[4] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100556 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[3])]) ^
557 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[3])] << 8) ^
558 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[3])] << 16) ^
559 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[3])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000560
561 RK[5] = RK[1] ^ RK[4];
562 RK[6] = RK[2] ^ RK[5];
563 RK[7] = RK[3] ^ RK[6];
564 }
565 break;
566
567 case 12:
568
Gilles Peskine449bd832023-01-11 14:50:10 +0100569 for (i = 0; i < 8; i++, RK += 6) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000570 RK[6] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100571 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[5])]) ^
572 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[5])] << 8) ^
573 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[5])] << 16) ^
574 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[5])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000575
576 RK[7] = RK[1] ^ RK[6];
577 RK[8] = RK[2] ^ RK[7];
578 RK[9] = RK[3] ^ RK[8];
579 RK[10] = RK[4] ^ RK[9];
580 RK[11] = RK[5] ^ RK[10];
581 }
582 break;
583
584 case 14:
585
Gilles Peskine449bd832023-01-11 14:50:10 +0100586 for (i = 0; i < 7; i++, RK += 8) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000587 RK[8] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100588 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[7])]) ^
589 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[7])] << 8) ^
590 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[7])] << 16) ^
591 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[7])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000592
593 RK[9] = RK[1] ^ RK[8];
594 RK[10] = RK[2] ^ RK[9];
595 RK[11] = RK[3] ^ RK[10];
596
597 RK[12] = RK[4] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100598 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[11])]) ^
599 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[11])] << 8) ^
600 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[11])] << 16) ^
601 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[11])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000602
603 RK[13] = RK[5] ^ RK[12];
604 RK[14] = RK[6] ^ RK[13];
605 RK[15] = RK[7] ^ RK[14];
606 }
607 break;
Paul Bakker5121ce52009-01-03 21:22:43 +0000608 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000609
Gilles Peskine449bd832023-01-11 14:50:10 +0100610 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000611}
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200612#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000613
614/*
615 * AES key schedule (decryption)
616 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200617#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100618int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
619 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000620{
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200621 int i, j, ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200622 mbedtls_aes_context cty;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000623 uint32_t *RK;
624 uint32_t *SK;
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200625
Gilles Peskine449bd832023-01-11 14:50:10 +0100626 mbedtls_aes_init(&cty);
Paul Bakker5121ce52009-01-03 21:22:43 +0000627
Werner Lewis7656a372022-06-13 12:28:20 +0100628 ctx->rk_offset = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200629#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_PADLOCK_ALIGN16)
Gilles Peskine449bd832023-01-11 14:50:10 +0100630 if (aes_padlock_ace == -1) {
631 aes_padlock_ace = mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE);
632 }
Paul Bakker048d04e2012-02-12 17:31:04 +0000633
Gilles Peskine449bd832023-01-11 14:50:10 +0100634 if (aes_padlock_ace) {
635 ctx->rk_offset = MBEDTLS_PADLOCK_ALIGN16(ctx->buf) - ctx->buf;
636 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000637#endif
Werner Lewisdd76ef32022-05-30 12:00:21 +0100638 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000639
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200640 /* Also checks keybits */
Gilles Peskine449bd832023-01-11 14:50:10 +0100641 if ((ret = mbedtls_aes_setkey_enc(&cty, key, keybits)) != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200642 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100643 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000644
Manuel Pégourié-Gonnardafd5a082014-05-28 21:52:59 +0200645 ctx->nr = cty.nr;
646
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200647#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Gilles Peskine449bd832023-01-11 14:50:10 +0100648 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
649 mbedtls_aesni_inverse_key((unsigned char *) RK,
650 (const unsigned char *) (cty.buf + cty.rk_offset), ctx->nr);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200651 goto exit;
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100652 }
653#endif
654
Werner Lewisdd76ef32022-05-30 12:00:21 +0100655 SK = cty.buf + cty.rk_offset + cty.nr * 4;
Paul Bakker5121ce52009-01-03 21:22:43 +0000656
657 *RK++ = *SK++;
658 *RK++ = *SK++;
659 *RK++ = *SK++;
660 *RK++ = *SK++;
661
Gilles Peskine449bd832023-01-11 14:50:10 +0100662 for (i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8) {
663 for (j = 0; j < 4; j++, SK++) {
664 *RK++ = AES_RT0(FSb[MBEDTLS_BYTE_0(*SK)]) ^
665 AES_RT1(FSb[MBEDTLS_BYTE_1(*SK)]) ^
666 AES_RT2(FSb[MBEDTLS_BYTE_2(*SK)]) ^
667 AES_RT3(FSb[MBEDTLS_BYTE_3(*SK)]);
Paul Bakker5121ce52009-01-03 21:22:43 +0000668 }
669 }
670
671 *RK++ = *SK++;
672 *RK++ = *SK++;
673 *RK++ = *SK++;
674 *RK++ = *SK++;
675
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200676exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100677 mbedtls_aes_free(&cty);
Paul Bakker2b222c82009-07-27 21:03:45 +0000678
Gilles Peskine449bd832023-01-11 14:50:10 +0100679 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000680}
gabor-mezei-arm95db3012020-10-26 11:35:23 +0100681#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */
Jaeden Amero9366feb2018-05-29 18:55:17 +0100682
683#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100684static int mbedtls_aes_xts_decode_keys(const unsigned char *key,
685 unsigned int keybits,
686 const unsigned char **key1,
687 unsigned int *key1bits,
688 const unsigned char **key2,
689 unsigned int *key2bits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100690{
691 const unsigned int half_keybits = keybits / 2;
692 const unsigned int half_keybytes = half_keybits / 8;
693
Gilles Peskine449bd832023-01-11 14:50:10 +0100694 switch (keybits) {
Jaeden Amero9366feb2018-05-29 18:55:17 +0100695 case 256: break;
696 case 512: break;
Gilles Peskine449bd832023-01-11 14:50:10 +0100697 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100698 }
699
700 *key1bits = half_keybits;
701 *key2bits = half_keybits;
702 *key1 = &key[0];
703 *key2 = &key[half_keybytes];
704
705 return 0;
706}
707
Gilles Peskine449bd832023-01-11 14:50:10 +0100708int mbedtls_aes_xts_setkey_enc(mbedtls_aes_xts_context *ctx,
709 const unsigned char *key,
710 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100711{
Janos Follath24eed8d2019-11-22 13:21:35 +0000712 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100713 const unsigned char *key1, *key2;
714 unsigned int key1bits, key2bits;
715
Gilles Peskine449bd832023-01-11 14:50:10 +0100716 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
717 &key2, &key2bits);
718 if (ret != 0) {
719 return ret;
720 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100721
722 /* Set the tweak key. Always set tweak key for the encryption mode. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100723 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
724 if (ret != 0) {
725 return ret;
726 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100727
728 /* Set crypt key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100729 return mbedtls_aes_setkey_enc(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100730}
731
Gilles Peskine449bd832023-01-11 14:50:10 +0100732int mbedtls_aes_xts_setkey_dec(mbedtls_aes_xts_context *ctx,
733 const unsigned char *key,
734 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100735{
Janos Follath24eed8d2019-11-22 13:21:35 +0000736 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100737 const unsigned char *key1, *key2;
738 unsigned int key1bits, key2bits;
739
Gilles Peskine449bd832023-01-11 14:50:10 +0100740 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
741 &key2, &key2bits);
742 if (ret != 0) {
743 return ret;
744 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100745
746 /* Set the tweak key. Always set tweak key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100747 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
748 if (ret != 0) {
749 return ret;
750 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100751
752 /* Set crypt key for decryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100753 return mbedtls_aes_setkey_dec(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100754}
755#endif /* MBEDTLS_CIPHER_MODE_XTS */
756
Gilles Peskine449bd832023-01-11 14:50:10 +0100757#define AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Joe Subbianicd84d762021-07-08 14:59:52 +0100758 do \
759 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100760 (X0) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y0)) ^ \
761 AES_FT1(MBEDTLS_BYTE_1(Y1)) ^ \
762 AES_FT2(MBEDTLS_BYTE_2(Y2)) ^ \
763 AES_FT3(MBEDTLS_BYTE_3(Y3)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100764 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100765 (X1) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y1)) ^ \
766 AES_FT1(MBEDTLS_BYTE_1(Y2)) ^ \
767 AES_FT2(MBEDTLS_BYTE_2(Y3)) ^ \
768 AES_FT3(MBEDTLS_BYTE_3(Y0)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100769 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100770 (X2) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y2)) ^ \
771 AES_FT1(MBEDTLS_BYTE_1(Y3)) ^ \
772 AES_FT2(MBEDTLS_BYTE_2(Y0)) ^ \
773 AES_FT3(MBEDTLS_BYTE_3(Y1)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100774 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100775 (X3) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y3)) ^ \
776 AES_FT1(MBEDTLS_BYTE_1(Y0)) ^ \
777 AES_FT2(MBEDTLS_BYTE_2(Y1)) ^ \
778 AES_FT3(MBEDTLS_BYTE_3(Y2)); \
779 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000780
Gilles Peskine449bd832023-01-11 14:50:10 +0100781#define AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100782 do \
783 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100784 (X0) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y0)) ^ \
785 AES_RT1(MBEDTLS_BYTE_1(Y3)) ^ \
786 AES_RT2(MBEDTLS_BYTE_2(Y2)) ^ \
787 AES_RT3(MBEDTLS_BYTE_3(Y1)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100788 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100789 (X1) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y1)) ^ \
790 AES_RT1(MBEDTLS_BYTE_1(Y0)) ^ \
791 AES_RT2(MBEDTLS_BYTE_2(Y3)) ^ \
792 AES_RT3(MBEDTLS_BYTE_3(Y2)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100793 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100794 (X2) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y2)) ^ \
795 AES_RT1(MBEDTLS_BYTE_1(Y1)) ^ \
796 AES_RT2(MBEDTLS_BYTE_2(Y0)) ^ \
797 AES_RT3(MBEDTLS_BYTE_3(Y3)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100798 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100799 (X3) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y3)) ^ \
800 AES_RT1(MBEDTLS_BYTE_1(Y2)) ^ \
801 AES_RT2(MBEDTLS_BYTE_2(Y1)) ^ \
802 AES_RT3(MBEDTLS_BYTE_3(Y0)); \
803 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000804
805/*
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200806 * AES-ECB block encryption
807 */
808#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100809int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx,
810 const unsigned char input[16],
811 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200812{
813 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100814 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100815 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200816 uint32_t X[4];
817 uint32_t Y[4];
818 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200819
Gilles Peskine449bd832023-01-11 14:50:10 +0100820 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
821 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
822 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
823 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200824
Gilles Peskine449bd832023-01-11 14:50:10 +0100825 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
826 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]);
827 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 +0200828 }
829
Gilles Peskine449bd832023-01-11 14:50:10 +0100830 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 +0200831
Gilles Peskine5197c662020-08-26 17:03:24 +0200832 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100833 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
834 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
835 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
836 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200837
Gilles Peskine5197c662020-08-26 17:03:24 +0200838 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100839 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
840 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
841 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
842 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200843
Gilles Peskine5197c662020-08-26 17:03:24 +0200844 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100845 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
846 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
847 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
848 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200849
Gilles Peskine5197c662020-08-26 17:03:24 +0200850 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100851 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
852 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
853 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
854 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200855
Gilles Peskine449bd832023-01-11 14:50:10 +0100856 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
857 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
858 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
859 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +0000860
Gilles Peskine449bd832023-01-11 14:50:10 +0100861 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500862
Gilles Peskine449bd832023-01-11 14:50:10 +0100863 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200864}
865#endif /* !MBEDTLS_AES_ENCRYPT_ALT */
866
867/*
868 * AES-ECB block decryption
869 */
870#if !defined(MBEDTLS_AES_DECRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100871int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
872 const unsigned char input[16],
873 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200874{
875 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100876 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100877 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200878 uint32_t X[4];
879 uint32_t Y[4];
880 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200881
Gilles Peskine449bd832023-01-11 14:50:10 +0100882 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
883 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
884 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
885 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200886
Gilles Peskine449bd832023-01-11 14:50:10 +0100887 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
888 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]);
889 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 +0200890 }
891
Gilles Peskine449bd832023-01-11 14:50:10 +0100892 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 +0200893
Gilles Peskine5197c662020-08-26 17:03:24 +0200894 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100895 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
896 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
897 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
898 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200899
Gilles Peskine5197c662020-08-26 17:03:24 +0200900 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100901 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
902 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
903 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
904 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200905
Gilles Peskine5197c662020-08-26 17:03:24 +0200906 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100907 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
908 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
909 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
910 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200911
Gilles Peskine5197c662020-08-26 17:03:24 +0200912 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100913 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
914 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
915 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
916 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200917
Gilles Peskine449bd832023-01-11 14:50:10 +0100918 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
919 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
920 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
921 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +0000922
Gilles Peskine449bd832023-01-11 14:50:10 +0100923 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500924
Gilles Peskine449bd832023-01-11 14:50:10 +0100925 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200926}
927#endif /* !MBEDTLS_AES_DECRYPT_ALT */
928
929/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000930 * AES-ECB block encryption/decryption
931 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100932int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
933 int mode,
934 const unsigned char input[16],
935 unsigned char output[16])
Paul Bakker5121ce52009-01-03 21:22:43 +0000936{
Gilles Peskine449bd832023-01-11 14:50:10 +0100937 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +0100938 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100939 }
Manuel Pégourié-Gonnard1aca2602018-12-12 12:56:55 +0100940
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200941#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Gilles Peskine449bd832023-01-11 14:50:10 +0100942 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
943 return mbedtls_aesni_crypt_ecb(ctx, mode, input, output);
944 }
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +0100945#endif
946
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200947#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Gilles Peskine449bd832023-01-11 14:50:10 +0100948 if (aes_padlock_ace > 0) {
949 if (mbedtls_padlock_xcryptecb(ctx, mode, input, output) == 0) {
950 return 0;
951 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000952
953 // If padlock data misaligned, we just fall back to
954 // unaccelerated mode
955 //
Paul Bakker5121ce52009-01-03 21:22:43 +0000956 }
957#endif
958
Gilles Peskine449bd832023-01-11 14:50:10 +0100959 if (mode == MBEDTLS_AES_ENCRYPT) {
960 return mbedtls_internal_aes_encrypt(ctx, input, output);
961 } else {
962 return mbedtls_internal_aes_decrypt(ctx, input, output);
963 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000964}
965
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200966#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000967/*
968 * AES-CBC buffer encryption/decryption
969 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100970int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
971 int mode,
972 size_t length,
973 unsigned char iv[16],
974 const unsigned char *input,
975 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +0000976{
Gilles Peskine7820a572021-07-07 21:08:28 +0200977 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +0000978 unsigned char temp[16];
979
Gilles Peskine449bd832023-01-11 14:50:10 +0100980 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +0100981 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100982 }
Manuel Pégourié-Gonnard3178d1a2018-12-12 13:05:00 +0100983
Gilles Peskine449bd832023-01-11 14:50:10 +0100984 if (length % 16) {
985 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
986 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000987
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200988#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Gilles Peskine449bd832023-01-11 14:50:10 +0100989 if (aes_padlock_ace > 0) {
990 if (mbedtls_padlock_xcryptcbc(ctx, mode, length, iv, input, output) == 0) {
991 return 0;
992 }
Paul Bakker9af723c2014-05-01 13:03:14 +0200993
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000994 // If padlock data misaligned, we just fall back to
995 // unaccelerated mode
996 //
Paul Bakker5121ce52009-01-03 21:22:43 +0000997 }
998#endif
999
Gilles Peskine449bd832023-01-11 14:50:10 +01001000 if (mode == MBEDTLS_AES_DECRYPT) {
1001 while (length > 0) {
1002 memcpy(temp, input, 16);
1003 ret = mbedtls_aes_crypt_ecb(ctx, mode, input, output);
1004 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001005 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001006 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001007
Gilles Peskine449bd832023-01-11 14:50:10 +01001008 mbedtls_xor(output, output, iv, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001009
Gilles Peskine449bd832023-01-11 14:50:10 +01001010 memcpy(iv, temp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001011
1012 input += 16;
1013 output += 16;
1014 length -= 16;
1015 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001016 } else {
1017 while (length > 0) {
1018 mbedtls_xor(output, input, iv, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001019
Gilles Peskine449bd832023-01-11 14:50:10 +01001020 ret = mbedtls_aes_crypt_ecb(ctx, mode, output, output);
1021 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001022 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001023 }
1024 memcpy(iv, output, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001025
1026 input += 16;
1027 output += 16;
1028 length -= 16;
1029 }
1030 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001031 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001032
Gilles Peskine7820a572021-07-07 21:08:28 +02001033exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001034 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001035}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001036#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001037
Aorimn5f778012016-06-09 23:22:58 +02001038#if defined(MBEDTLS_CIPHER_MODE_XTS)
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001039
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001040typedef unsigned char mbedtls_be128[16];
1041
1042/*
1043 * GF(2^128) multiplication function
1044 *
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001045 * This function multiplies a field element by x in the polynomial field
1046 * representation. It uses 64-bit word operations to gain speed but compensates
Shaun Case8b0ecbc2021-12-20 21:14:10 -08001047 * for machine endianness and hence works correctly on both big and little
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001048 * endian machines.
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001049 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001050static void mbedtls_gf128mul_x_ble(unsigned char r[16],
1051 const unsigned char x[16])
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001052{
1053 uint64_t a, b, ra, rb;
1054
Gilles Peskine449bd832023-01-11 14:50:10 +01001055 a = MBEDTLS_GET_UINT64_LE(x, 0);
1056 b = MBEDTLS_GET_UINT64_LE(x, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001057
Gilles Peskine449bd832023-01-11 14:50:10 +01001058 ra = (a << 1) ^ 0x0087 >> (8 - ((b >> 63) << 3));
1059 rb = (a >> 63) | (b << 1);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001060
Gilles Peskine449bd832023-01-11 14:50:10 +01001061 MBEDTLS_PUT_UINT64_LE(ra, r, 0);
1062 MBEDTLS_PUT_UINT64_LE(rb, r, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001063}
1064
Aorimn5f778012016-06-09 23:22:58 +02001065/*
1066 * AES-XTS buffer encryption/decryption
1067 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001068int mbedtls_aes_crypt_xts(mbedtls_aes_xts_context *ctx,
1069 int mode,
1070 size_t length,
1071 const unsigned char data_unit[16],
1072 const unsigned char *input,
1073 unsigned char *output)
Aorimn5f778012016-06-09 23:22:58 +02001074{
Janos Follath24eed8d2019-11-22 13:21:35 +00001075 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amerod82cd862018-04-28 15:02:45 +01001076 size_t blocks = length / 16;
1077 size_t leftover = length % 16;
1078 unsigned char tweak[16];
1079 unsigned char prev_tweak[16];
1080 unsigned char tmp[16];
Aorimn5f778012016-06-09 23:22:58 +02001081
Gilles Peskine449bd832023-01-11 14:50:10 +01001082 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001083 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001084 }
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01001085
Jaeden Amero8381fcb2018-10-11 12:06:15 +01001086 /* Data units must be at least 16 bytes long. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001087 if (length < 16) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001088 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001089 }
Aorimn5f778012016-06-09 23:22:58 +02001090
Jaeden Ameroa74faba2018-10-11 12:07:43 +01001091 /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001092 if (length > (1 << 20) * 16) {
Jaeden Amero0a8b0202018-05-30 15:36:06 +01001093 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001094 }
Aorimn5f778012016-06-09 23:22:58 +02001095
Jaeden Amerod82cd862018-04-28 15:02:45 +01001096 /* Compute the tweak. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001097 ret = mbedtls_aes_crypt_ecb(&ctx->tweak, MBEDTLS_AES_ENCRYPT,
1098 data_unit, tweak);
1099 if (ret != 0) {
1100 return ret;
1101 }
Aorimn5f778012016-06-09 23:22:58 +02001102
Gilles Peskine449bd832023-01-11 14:50:10 +01001103 while (blocks--) {
1104 if (leftover && (mode == MBEDTLS_AES_DECRYPT) && blocks == 0) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001105 /* We are on the last block in a decrypt operation that has
1106 * leftover bytes, so we need to use the next tweak for this block,
Tom Cosgrove1797b052022-12-04 17:19:59 +00001107 * and this tweak for the leftover bytes. Save the current tweak for
Jaeden Amerod82cd862018-04-28 15:02:45 +01001108 * the leftovers and then update the current tweak for use on this,
1109 * the last full block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001110 memcpy(prev_tweak, tweak, sizeof(tweak));
1111 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001112 }
1113
Gilles Peskine449bd832023-01-11 14:50:10 +01001114 mbedtls_xor(tmp, input, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001115
Gilles Peskine449bd832023-01-11 14:50:10 +01001116 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1117 if (ret != 0) {
1118 return ret;
1119 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001120
Gilles Peskine449bd832023-01-11 14:50:10 +01001121 mbedtls_xor(output, tmp, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001122
1123 /* Update the tweak for the next block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001124 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001125
1126 output += 16;
1127 input += 16;
Aorimn5f778012016-06-09 23:22:58 +02001128 }
1129
Gilles Peskine449bd832023-01-11 14:50:10 +01001130 if (leftover) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001131 /* If we are on the leftover bytes in a decrypt operation, we need to
1132 * use the previous tweak for these bytes (as saved in prev_tweak). */
1133 unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
Aorimn5f778012016-06-09 23:22:58 +02001134
Jaeden Amerod82cd862018-04-28 15:02:45 +01001135 /* We are now on the final part of the data unit, which doesn't divide
1136 * evenly by 16. It's time for ciphertext stealing. */
1137 size_t i;
1138 unsigned char *prev_output = output - 16;
Aorimn5f778012016-06-09 23:22:58 +02001139
Jaeden Amerod82cd862018-04-28 15:02:45 +01001140 /* Copy ciphertext bytes from the previous block to our output for each
Dave Rodgman069e7f42022-11-24 19:37:26 +00001141 * byte of ciphertext we won't steal. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001142 for (i = 0; i < leftover; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001143 output[i] = prev_output[i];
Aorimn5f778012016-06-09 23:22:58 +02001144 }
Aorimn5f778012016-06-09 23:22:58 +02001145
Dave Rodgman069e7f42022-11-24 19:37:26 +00001146 /* Copy the remainder of the input for this final round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001147 mbedtls_xor(tmp, input, t, leftover);
Dave Rodgmana8cf6072022-11-22 15:02:54 +00001148
Jaeden Amerod82cd862018-04-28 15:02:45 +01001149 /* Copy ciphertext bytes from the previous block for input in this
1150 * round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001151 mbedtls_xor(tmp + i, prev_output + i, t + i, 16 - i);
Aorimn5f778012016-06-09 23:22:58 +02001152
Gilles Peskine449bd832023-01-11 14:50:10 +01001153 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1154 if (ret != 0) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001155 return ret;
Gilles Peskine449bd832023-01-11 14:50:10 +01001156 }
Aorimn5f778012016-06-09 23:22:58 +02001157
Jaeden Amerod82cd862018-04-28 15:02:45 +01001158 /* Write the result back to the previous block, overriding the previous
1159 * output we copied. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001160 mbedtls_xor(prev_output, tmp, t, 16);
Aorimn5f778012016-06-09 23:22:58 +02001161 }
1162
Gilles Peskine449bd832023-01-11 14:50:10 +01001163 return 0;
Aorimn5f778012016-06-09 23:22:58 +02001164}
1165#endif /* MBEDTLS_CIPHER_MODE_XTS */
1166
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001167#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001168/*
1169 * AES-CFB128 buffer encryption/decryption
1170 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001171int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx,
1172 int mode,
1173 size_t length,
1174 size_t *iv_off,
1175 unsigned char iv[16],
1176 const unsigned char *input,
1177 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001178{
Paul Bakker27fdf462011-06-09 13:55:13 +00001179 int c;
Gilles Peskine7820a572021-07-07 21:08:28 +02001180 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001181 size_t n;
1182
Gilles Peskine449bd832023-01-11 14:50:10 +01001183 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001184 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001185 }
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001186
1187 n = *iv_off;
Paul Bakker5121ce52009-01-03 21:22:43 +00001188
Gilles Peskine449bd832023-01-11 14:50:10 +01001189 if (n > 15) {
1190 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1191 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001192
Gilles Peskine449bd832023-01-11 14:50:10 +01001193 if (mode == MBEDTLS_AES_DECRYPT) {
1194 while (length--) {
1195 if (n == 0) {
1196 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1197 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001198 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001199 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001200 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001201
1202 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001203 *output++ = (unsigned char) (c ^ iv[n]);
Paul Bakker5121ce52009-01-03 21:22:43 +00001204 iv[n] = (unsigned char) c;
1205
Gilles Peskine449bd832023-01-11 14:50:10 +01001206 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001207 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001208 } else {
1209 while (length--) {
1210 if (n == 0) {
1211 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1212 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001213 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001214 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001215 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001216
Gilles Peskine449bd832023-01-11 14:50:10 +01001217 iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++);
Paul Bakker5121ce52009-01-03 21:22:43 +00001218
Gilles Peskine449bd832023-01-11 14:50:10 +01001219 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001220 }
1221 }
1222
1223 *iv_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001224 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001225
Gilles Peskine7820a572021-07-07 21:08:28 +02001226exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001227 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001228}
Paul Bakker556efba2014-01-24 15:38:12 +01001229
1230/*
1231 * AES-CFB8 buffer encryption/decryption
1232 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001233int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx,
1234 int mode,
1235 size_t length,
1236 unsigned char iv[16],
1237 const unsigned char *input,
1238 unsigned char *output)
Paul Bakker556efba2014-01-24 15:38:12 +01001239{
Gilles Peskine7820a572021-07-07 21:08:28 +02001240 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker556efba2014-01-24 15:38:12 +01001241 unsigned char c;
1242 unsigned char ov[17];
1243
Gilles Peskine449bd832023-01-11 14:50:10 +01001244 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001245 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001246 }
1247 while (length--) {
1248 memcpy(ov, iv, 16);
1249 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1250 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001251 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001252 }
Paul Bakker556efba2014-01-24 15:38:12 +01001253
Gilles Peskine449bd832023-01-11 14:50:10 +01001254 if (mode == MBEDTLS_AES_DECRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001255 ov[16] = *input;
Gilles Peskine449bd832023-01-11 14:50:10 +01001256 }
Paul Bakker556efba2014-01-24 15:38:12 +01001257
Gilles Peskine449bd832023-01-11 14:50:10 +01001258 c = *output++ = (unsigned char) (iv[0] ^ *input++);
Paul Bakker556efba2014-01-24 15:38:12 +01001259
Gilles Peskine449bd832023-01-11 14:50:10 +01001260 if (mode == MBEDTLS_AES_ENCRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001261 ov[16] = c;
Gilles Peskine449bd832023-01-11 14:50:10 +01001262 }
Paul Bakker556efba2014-01-24 15:38:12 +01001263
Gilles Peskine449bd832023-01-11 14:50:10 +01001264 memcpy(iv, ov + 1, 16);
Paul Bakker556efba2014-01-24 15:38:12 +01001265 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001266 ret = 0;
Paul Bakker556efba2014-01-24 15:38:12 +01001267
Gilles Peskine7820a572021-07-07 21:08:28 +02001268exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001269 return ret;
Paul Bakker556efba2014-01-24 15:38:12 +01001270}
Simon Butcher76a5b222018-04-22 22:57:27 +01001271#endif /* MBEDTLS_CIPHER_MODE_CFB */
1272
1273#if defined(MBEDTLS_CIPHER_MODE_OFB)
1274/*
1275 * AES-OFB (Output Feedback Mode) buffer encryption/decryption
1276 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001277int mbedtls_aes_crypt_ofb(mbedtls_aes_context *ctx,
1278 size_t length,
1279 size_t *iv_off,
1280 unsigned char iv[16],
1281 const unsigned char *input,
1282 unsigned char *output)
Simon Butcher76a5b222018-04-22 22:57:27 +01001283{
Simon Butcherad4e4932018-04-29 00:43:47 +01001284 int ret = 0;
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001285 size_t n;
1286
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001287 n = *iv_off;
Simon Butcher76a5b222018-04-22 22:57:27 +01001288
Gilles Peskine449bd832023-01-11 14:50:10 +01001289 if (n > 15) {
1290 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1291 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001292
Gilles Peskine449bd832023-01-11 14:50:10 +01001293 while (length--) {
1294 if (n == 0) {
1295 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1296 if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001297 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001298 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001299 }
Simon Butcher76a5b222018-04-22 22:57:27 +01001300 *output++ = *input++ ^ iv[n];
1301
Gilles Peskine449bd832023-01-11 14:50:10 +01001302 n = (n + 1) & 0x0F;
Simon Butcher76a5b222018-04-22 22:57:27 +01001303 }
1304
1305 *iv_off = n;
1306
Simon Butcherad4e4932018-04-29 00:43:47 +01001307exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001308 return ret;
Simon Butcher76a5b222018-04-22 22:57:27 +01001309}
1310#endif /* MBEDTLS_CIPHER_MODE_OFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001311
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001312#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001313/*
1314 * AES-CTR buffer encryption/decryption
1315 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001316int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
1317 size_t length,
1318 size_t *nc_off,
1319 unsigned char nonce_counter[16],
1320 unsigned char stream_block[16],
1321 const unsigned char *input,
1322 unsigned char *output)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001323{
Paul Bakker369e14b2012-04-18 14:16:09 +00001324 int c, i;
Gilles Peskine7820a572021-07-07 21:08:28 +02001325 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001326 size_t n;
1327
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001328 n = *nc_off;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001329
Gilles Peskine449bd832023-01-11 14:50:10 +01001330 if (n > 0x0F) {
1331 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1332 }
Mohammad Azim Khan3f7f8172017-11-23 17:49:05 +00001333
Gilles Peskine449bd832023-01-11 14:50:10 +01001334 while (length--) {
1335 if (n == 0) {
1336 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block);
1337 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001338 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001339 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001340
Gilles Peskine449bd832023-01-11 14:50:10 +01001341 for (i = 16; i > 0; i--) {
1342 if (++nonce_counter[i - 1] != 0) {
Paul Bakker369e14b2012-04-18 14:16:09 +00001343 break;
Gilles Peskine449bd832023-01-11 14:50:10 +01001344 }
1345 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001346 }
1347 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001348 *output++ = (unsigned char) (c ^ stream_block[n]);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001349
Gilles Peskine449bd832023-01-11 14:50:10 +01001350 n = (n + 1) & 0x0F;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001351 }
1352
1353 *nc_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001354 ret = 0;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001355
Gilles Peskine7820a572021-07-07 21:08:28 +02001356exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001357 return ret;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001358}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001359#endif /* MBEDTLS_CIPHER_MODE_CTR */
Manuel Pégourié-Gonnard1ec220b2014-03-10 11:20:17 +01001360
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001361#endif /* !MBEDTLS_AES_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001362
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001363#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001364/*
1365 * AES test vectors from:
1366 *
1367 * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
1368 */
1369static const unsigned char aes_test_ecb_dec[3][16] =
1370{
1371 { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
1372 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
1373 { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
1374 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
1375 { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
1376 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
1377};
1378
1379static const unsigned char aes_test_ecb_enc[3][16] =
1380{
1381 { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
1382 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
1383 { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
1384 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
1385 { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
1386 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
1387};
1388
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001389#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001390static const unsigned char aes_test_cbc_dec[3][16] =
1391{
1392 { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
1393 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
1394 { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
1395 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
1396 { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
1397 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
1398};
1399
1400static const unsigned char aes_test_cbc_enc[3][16] =
1401{
1402 { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
1403 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
1404 { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
1405 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
1406 { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
1407 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
1408};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001409#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001410
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001411#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001412/*
1413 * AES-CFB128 test vectors from:
1414 *
1415 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
1416 */
1417static const unsigned char aes_test_cfb128_key[3][32] =
1418{
1419 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1420 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
1421 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1422 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1423 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1424 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1425 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1426 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1427 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
1428};
1429
1430static const unsigned char aes_test_cfb128_iv[16] =
1431{
1432 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1433 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1434};
1435
1436static const unsigned char aes_test_cfb128_pt[64] =
1437{
1438 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1439 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1440 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1441 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1442 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1443 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1444 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1445 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1446};
1447
1448static const unsigned char aes_test_cfb128_ct[3][64] =
1449{
1450 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1451 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1452 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F,
1453 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B,
1454 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40,
1455 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF,
1456 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E,
1457 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 },
1458 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1459 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1460 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21,
1461 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A,
1462 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1,
1463 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9,
1464 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0,
1465 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF },
1466 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1467 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1468 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8,
1469 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B,
1470 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92,
1471 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9,
1472 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8,
1473 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 }
1474};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001475#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001476
Simon Butcherad4e4932018-04-29 00:43:47 +01001477#if defined(MBEDTLS_CIPHER_MODE_OFB)
1478/*
1479 * AES-OFB test vectors from:
1480 *
Simon Butcher5db13622018-06-04 22:11:25 +01001481 * https://csrc.nist.gov/publications/detail/sp/800-38a/final
Simon Butcherad4e4932018-04-29 00:43:47 +01001482 */
1483static const unsigned char aes_test_ofb_key[3][32] =
1484{
1485 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1486 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
1487 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1488 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1489 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1490 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1491 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1492 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1493 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
1494};
1495
1496static const unsigned char aes_test_ofb_iv[16] =
1497{
1498 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1499 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1500};
1501
1502static const unsigned char aes_test_ofb_pt[64] =
1503{
1504 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1505 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1506 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1507 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1508 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1509 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1510 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1511 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1512};
1513
1514static const unsigned char aes_test_ofb_ct[3][64] =
1515{
1516 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1517 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1518 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
1519 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
1520 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
1521 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
1522 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
1523 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e },
1524 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1525 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1526 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
1527 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
1528 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f,
1529 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
1530 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e,
1531 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a },
1532 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1533 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1534 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
1535 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
1536 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed,
1537 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
1538 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8,
1539 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 }
1540};
1541#endif /* MBEDTLS_CIPHER_MODE_OFB */
1542
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001543#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001544/*
1545 * AES-CTR test vectors from:
1546 *
1547 * http://www.faqs.org/rfcs/rfc3686.html
1548 */
1549
1550static const unsigned char aes_test_ctr_key[3][16] =
1551{
1552 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
1553 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
1554 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
1555 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
1556 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
1557 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
1558};
1559
1560static const unsigned char aes_test_ctr_nonce_counter[3][16] =
1561{
1562 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
1563 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
1564 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
1565 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
1566 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
1567 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
1568};
1569
1570static const unsigned char aes_test_ctr_pt[3][48] =
1571{
1572 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
1573 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
1574
1575 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1576 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1577 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1578 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
1579
1580 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1581 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1582 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1583 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
1584 0x20, 0x21, 0x22, 0x23 }
1585};
1586
1587static const unsigned char aes_test_ctr_ct[3][48] =
1588{
1589 { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79,
1590 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 },
1591 { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9,
1592 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88,
1593 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8,
1594 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 },
1595 { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
1596 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
1597 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
1598 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
1599 0x25, 0xB2, 0x07, 0x2F }
1600};
1601
1602static const int aes_test_ctr_len[3] =
Gilles Peskine449bd832023-01-11 14:50:10 +01001603{ 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001604#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00001605
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001606#if defined(MBEDTLS_CIPHER_MODE_XTS)
1607/*
1608 * AES-XTS test vectors from:
1609 *
1610 * IEEE P1619/D16 Annex B
1611 * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf
1612 * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf)
1613 */
1614static const unsigned char aes_test_xts_key[][32] =
1615{
1616 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1617 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1618 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1619 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1620 { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1621 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1622 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1623 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1624 { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
1625 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
1626 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1627 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1628};
1629
1630static const unsigned char aes_test_xts_pt32[][32] =
1631{
1632 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1633 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1634 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1635 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1636 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1637 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1638 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1639 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1640 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1641 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1642 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1643 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1644};
1645
1646static const unsigned char aes_test_xts_ct32[][32] =
1647{
1648 { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec,
1649 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92,
1650 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85,
1651 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e },
1652 { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e,
1653 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b,
1654 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4,
1655 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 },
1656 { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a,
1657 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2,
1658 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53,
1659 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 },
1660};
1661
1662static const unsigned char aes_test_xts_data_unit[][16] =
1663{
Gilles Peskine449bd832023-01-11 14:50:10 +01001664 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1665 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1666 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1667 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1668 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1669 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001670};
1671
1672#endif /* MBEDTLS_CIPHER_MODE_XTS */
1673
Paul Bakker5121ce52009-01-03 21:22:43 +00001674/*
1675 * Checkup routine
1676 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001677int mbedtls_aes_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +00001678{
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001679 int ret = 0, i, j, u, mode;
1680 unsigned int keybits;
Paul Bakker5121ce52009-01-03 21:22:43 +00001681 unsigned char key[32];
1682 unsigned char buf[64];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001683 const unsigned char *aes_tests;
Andrzej Kurek252283f2022-09-27 07:54:16 -04001684#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1685 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001686 unsigned char iv[16];
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03001687#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001688#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +02001689 unsigned char prv[16];
1690#endif
Simon Butcher2ff0e522018-06-14 09:57:07 +01001691#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1692 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker27fdf462011-06-09 13:55:13 +00001693 size_t offset;
Paul Bakkere91d01e2011-04-19 15:55:50 +00001694#endif
Simon Butcher66a89032018-06-15 18:20:29 +01001695#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS)
Paul Bakkere91d01e2011-04-19 15:55:50 +00001696 int len;
Simon Butcher66a89032018-06-15 18:20:29 +01001697#endif
1698#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001699 unsigned char nonce_counter[16];
1700 unsigned char stream_block[16];
1701#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001702 mbedtls_aes_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001703
Gilles Peskine449bd832023-01-11 14:50:10 +01001704 memset(key, 0, 32);
1705 mbedtls_aes_init(&ctx);
Paul Bakker5121ce52009-01-03 21:22:43 +00001706
1707 /*
1708 * ECB mode
1709 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001710 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +00001711 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001712 keybits = 128 + u * 64;
1713 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001714
Gilles Peskine449bd832023-01-11 14:50:10 +01001715 if (verbose != 0) {
1716 mbedtls_printf(" AES-ECB-%3u (%s): ", keybits,
1717 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00001718 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001719
1720 memset(buf, 0, 16);
1721
1722 if (mode == MBEDTLS_AES_DECRYPT) {
1723 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1724 aes_tests = aes_test_ecb_dec[u];
1725 } else {
1726 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001727 aes_tests = aes_test_ecb_enc[u];
1728 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001729
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01001730 /*
1731 * AES-192 is an optional feature that may be unavailable when
1732 * there is an alternative underlying implementation i.e. when
1733 * MBEDTLS_AES_ALT is defined.
1734 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001735 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1736 mbedtls_printf("skipped\n");
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001737 continue;
Gilles Peskine449bd832023-01-11 14:50:10 +01001738 } else if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001739 goto exit;
1740 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001741
Gilles Peskine449bd832023-01-11 14:50:10 +01001742 for (j = 0; j < 10000; j++) {
1743 ret = mbedtls_aes_crypt_ecb(&ctx, mode, buf, buf);
1744 if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001745 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001746 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001747 }
1748
Gilles Peskine449bd832023-01-11 14:50:10 +01001749 if (memcmp(buf, aes_tests, 16) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001750 ret = 1;
1751 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001752 }
1753
Gilles Peskine449bd832023-01-11 14:50:10 +01001754 if (verbose != 0) {
1755 mbedtls_printf("passed\n");
1756 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001757 }
1758
Gilles Peskine449bd832023-01-11 14:50:10 +01001759 if (verbose != 0) {
1760 mbedtls_printf("\n");
1761 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001762
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001763#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001764 /*
1765 * CBC mode
1766 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001767 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +00001768 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001769 keybits = 128 + u * 64;
1770 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001771
Gilles Peskine449bd832023-01-11 14:50:10 +01001772 if (verbose != 0) {
1773 mbedtls_printf(" AES-CBC-%3u (%s): ", keybits,
1774 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00001775 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001776
1777 memset(iv, 0, 16);
1778 memset(prv, 0, 16);
1779 memset(buf, 0, 16);
1780
1781 if (mode == MBEDTLS_AES_DECRYPT) {
1782 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1783 aes_tests = aes_test_cbc_dec[u];
1784 } else {
1785 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001786 aes_tests = aes_test_cbc_enc[u];
1787 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001788
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01001789 /*
1790 * AES-192 is an optional feature that may be unavailable when
1791 * there is an alternative underlying implementation i.e. when
1792 * MBEDTLS_AES_ALT is defined.
1793 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001794 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1795 mbedtls_printf("skipped\n");
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001796 continue;
Gilles Peskine449bd832023-01-11 14:50:10 +01001797 } else if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001798 goto exit;
1799 }
1800
Gilles Peskine449bd832023-01-11 14:50:10 +01001801 for (j = 0; j < 10000; j++) {
1802 if (mode == MBEDTLS_AES_ENCRYPT) {
Paul Bakker5121ce52009-01-03 21:22:43 +00001803 unsigned char tmp[16];
1804
Gilles Peskine449bd832023-01-11 14:50:10 +01001805 memcpy(tmp, prv, 16);
1806 memcpy(prv, buf, 16);
1807 memcpy(buf, tmp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001808 }
1809
Gilles Peskine449bd832023-01-11 14:50:10 +01001810 ret = mbedtls_aes_crypt_cbc(&ctx, mode, 16, iv, buf, buf);
1811 if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001812 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001813 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001814
1815 }
1816
Gilles Peskine449bd832023-01-11 14:50:10 +01001817 if (memcmp(buf, aes_tests, 16) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001818 ret = 1;
1819 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001820 }
1821
Gilles Peskine449bd832023-01-11 14:50:10 +01001822 if (verbose != 0) {
1823 mbedtls_printf("passed\n");
1824 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001825 }
1826
Gilles Peskine449bd832023-01-11 14:50:10 +01001827 if (verbose != 0) {
1828 mbedtls_printf("\n");
1829 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001830#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001831
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001832#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001833 /*
1834 * CFB128 mode
1835 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001836 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +00001837 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001838 keybits = 128 + u * 64;
1839 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001840
Gilles Peskine449bd832023-01-11 14:50:10 +01001841 if (verbose != 0) {
1842 mbedtls_printf(" AES-CFB128-%3u (%s): ", keybits,
1843 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
1844 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001845
Gilles Peskine449bd832023-01-11 14:50:10 +01001846 memcpy(iv, aes_test_cfb128_iv, 16);
1847 memcpy(key, aes_test_cfb128_key[u], keybits / 8);
Paul Bakker5121ce52009-01-03 21:22:43 +00001848
1849 offset = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +01001850 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01001851 /*
1852 * AES-192 is an optional feature that may be unavailable when
1853 * there is an alternative underlying implementation i.e. when
1854 * MBEDTLS_AES_ALT is defined.
1855 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001856 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1857 mbedtls_printf("skipped\n");
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001858 continue;
Gilles Peskine449bd832023-01-11 14:50:10 +01001859 } else if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001860 goto exit;
1861 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001862
Gilles Peskine449bd832023-01-11 14:50:10 +01001863 if (mode == MBEDTLS_AES_DECRYPT) {
1864 memcpy(buf, aes_test_cfb128_ct[u], 64);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001865 aes_tests = aes_test_cfb128_pt;
Gilles Peskine449bd832023-01-11 14:50:10 +01001866 } else {
1867 memcpy(buf, aes_test_cfb128_pt, 64);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001868 aes_tests = aes_test_cfb128_ct[u];
1869 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001870
Gilles Peskine449bd832023-01-11 14:50:10 +01001871 ret = mbedtls_aes_crypt_cfb128(&ctx, mode, 64, &offset, iv, buf, buf);
1872 if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001873 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001874 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001875
Gilles Peskine449bd832023-01-11 14:50:10 +01001876 if (memcmp(buf, aes_tests, 64) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001877 ret = 1;
1878 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001879 }
1880
Gilles Peskine449bd832023-01-11 14:50:10 +01001881 if (verbose != 0) {
1882 mbedtls_printf("passed\n");
1883 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001884 }
1885
Gilles Peskine449bd832023-01-11 14:50:10 +01001886 if (verbose != 0) {
1887 mbedtls_printf("\n");
1888 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001889#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001890
Simon Butcherad4e4932018-04-29 00:43:47 +01001891#if defined(MBEDTLS_CIPHER_MODE_OFB)
1892 /*
1893 * OFB mode
1894 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001895 for (i = 0; i < 6; i++) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001896 u = i >> 1;
1897 keybits = 128 + u * 64;
1898 mode = i & 1;
1899
Gilles Peskine449bd832023-01-11 14:50:10 +01001900 if (verbose != 0) {
1901 mbedtls_printf(" AES-OFB-%3u (%s): ", keybits,
1902 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
1903 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001904
Gilles Peskine449bd832023-01-11 14:50:10 +01001905 memcpy(iv, aes_test_ofb_iv, 16);
1906 memcpy(key, aes_test_ofb_key[u], keybits / 8);
Simon Butcherad4e4932018-04-29 00:43:47 +01001907
1908 offset = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +01001909 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Simon Butcherad4e4932018-04-29 00:43:47 +01001910 /*
1911 * AES-192 is an optional feature that may be unavailable when
1912 * there is an alternative underlying implementation i.e. when
1913 * MBEDTLS_AES_ALT is defined.
1914 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001915 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1916 mbedtls_printf("skipped\n");
Simon Butcherad4e4932018-04-29 00:43:47 +01001917 continue;
Gilles Peskine449bd832023-01-11 14:50:10 +01001918 } else if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001919 goto exit;
1920 }
1921
Gilles Peskine449bd832023-01-11 14:50:10 +01001922 if (mode == MBEDTLS_AES_DECRYPT) {
1923 memcpy(buf, aes_test_ofb_ct[u], 64);
Simon Butcherad4e4932018-04-29 00:43:47 +01001924 aes_tests = aes_test_ofb_pt;
Gilles Peskine449bd832023-01-11 14:50:10 +01001925 } else {
1926 memcpy(buf, aes_test_ofb_pt, 64);
Simon Butcherad4e4932018-04-29 00:43:47 +01001927 aes_tests = aes_test_ofb_ct[u];
1928 }
1929
Gilles Peskine449bd832023-01-11 14:50:10 +01001930 ret = mbedtls_aes_crypt_ofb(&ctx, 64, &offset, iv, buf, buf);
1931 if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001932 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001933 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001934
Gilles Peskine449bd832023-01-11 14:50:10 +01001935 if (memcmp(buf, aes_tests, 64) != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001936 ret = 1;
1937 goto exit;
1938 }
1939
Gilles Peskine449bd832023-01-11 14:50:10 +01001940 if (verbose != 0) {
1941 mbedtls_printf("passed\n");
1942 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001943 }
1944
Gilles Peskine449bd832023-01-11 14:50:10 +01001945 if (verbose != 0) {
1946 mbedtls_printf("\n");
1947 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001948#endif /* MBEDTLS_CIPHER_MODE_OFB */
1949
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001950#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001951 /*
1952 * CTR mode
1953 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001954 for (i = 0; i < 6; i++) {
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001955 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001956 mode = i & 1;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001957
Gilles Peskine449bd832023-01-11 14:50:10 +01001958 if (verbose != 0) {
1959 mbedtls_printf(" AES-CTR-128 (%s): ",
1960 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
1961 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001962
Gilles Peskine449bd832023-01-11 14:50:10 +01001963 memcpy(nonce_counter, aes_test_ctr_nonce_counter[u], 16);
1964 memcpy(key, aes_test_ctr_key[u], 16);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001965
1966 offset = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +01001967 if ((ret = mbedtls_aes_setkey_enc(&ctx, key, 128)) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001968 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001969 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001970
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001971 len = aes_test_ctr_len[u];
1972
Gilles Peskine449bd832023-01-11 14:50:10 +01001973 if (mode == MBEDTLS_AES_DECRYPT) {
1974 memcpy(buf, aes_test_ctr_ct[u], len);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001975 aes_tests = aes_test_ctr_pt[u];
Gilles Peskine449bd832023-01-11 14:50:10 +01001976 } else {
1977 memcpy(buf, aes_test_ctr_pt[u], len);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001978 aes_tests = aes_test_ctr_ct[u];
1979 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001980
Gilles Peskine449bd832023-01-11 14:50:10 +01001981 ret = mbedtls_aes_crypt_ctr(&ctx, len, &offset, nonce_counter,
1982 stream_block, buf, buf);
1983 if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001984 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001985 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001986
Gilles Peskine449bd832023-01-11 14:50:10 +01001987 if (memcmp(buf, aes_tests, len) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001988 ret = 1;
1989 goto exit;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001990 }
1991
Gilles Peskine449bd832023-01-11 14:50:10 +01001992 if (verbose != 0) {
1993 mbedtls_printf("passed\n");
1994 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001995 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001996
Gilles Peskine449bd832023-01-11 14:50:10 +01001997 if (verbose != 0) {
1998 mbedtls_printf("\n");
1999 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002000#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00002001
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002002#if defined(MBEDTLS_CIPHER_MODE_XTS)
2003 {
Gilles Peskine449bd832023-01-11 14:50:10 +01002004 static const int num_tests =
2005 sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key);
2006 mbedtls_aes_xts_context ctx_xts;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002007
Gilles Peskine449bd832023-01-11 14:50:10 +01002008 /*
2009 * XTS mode
2010 */
2011 mbedtls_aes_xts_init(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002012
Gilles Peskine449bd832023-01-11 14:50:10 +01002013 for (i = 0; i < num_tests << 1; i++) {
2014 const unsigned char *data_unit;
2015 u = i >> 1;
2016 mode = i & 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002017
Gilles Peskine449bd832023-01-11 14:50:10 +01002018 if (verbose != 0) {
2019 mbedtls_printf(" AES-XTS-128 (%s): ",
2020 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2021 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002022
Gilles Peskine449bd832023-01-11 14:50:10 +01002023 memset(key, 0, sizeof(key));
2024 memcpy(key, aes_test_xts_key[u], 32);
2025 data_unit = aes_test_xts_data_unit[u];
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002026
Gilles Peskine449bd832023-01-11 14:50:10 +01002027 len = sizeof(*aes_test_xts_ct32);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002028
Gilles Peskine449bd832023-01-11 14:50:10 +01002029 if (mode == MBEDTLS_AES_DECRYPT) {
2030 ret = mbedtls_aes_xts_setkey_dec(&ctx_xts, key, 256);
2031 if (ret != 0) {
2032 goto exit;
2033 }
2034 memcpy(buf, aes_test_xts_ct32[u], len);
2035 aes_tests = aes_test_xts_pt32[u];
2036 } else {
2037 ret = mbedtls_aes_xts_setkey_enc(&ctx_xts, key, 256);
2038 if (ret != 0) {
2039 goto exit;
2040 }
2041 memcpy(buf, aes_test_xts_pt32[u], len);
2042 aes_tests = aes_test_xts_ct32[u];
2043 }
2044
2045
2046 ret = mbedtls_aes_crypt_xts(&ctx_xts, mode, len, data_unit,
2047 buf, buf);
2048 if (ret != 0) {
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002049 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002050 }
2051
2052 if (memcmp(buf, aes_tests, len) != 0) {
2053 ret = 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002054 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002055 }
2056
2057 if (verbose != 0) {
2058 mbedtls_printf("passed\n");
2059 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002060 }
2061
Gilles Peskine449bd832023-01-11 14:50:10 +01002062 if (verbose != 0) {
2063 mbedtls_printf("\n");
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002064 }
2065
Gilles Peskine449bd832023-01-11 14:50:10 +01002066 mbedtls_aes_xts_free(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002067 }
2068#endif /* MBEDTLS_CIPHER_MODE_XTS */
2069
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002070 ret = 0;
2071
2072exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01002073 if (ret != 0 && verbose != 0) {
2074 mbedtls_printf("failed\n");
2075 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002076
Gilles Peskine449bd832023-01-11 14:50:10 +01002077 mbedtls_aes_free(&ctx);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002078
Gilles Peskine449bd832023-01-11 14:50:10 +01002079 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002080}
2081
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002082#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002083
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002084#endif /* MBEDTLS_AES_C */