blob: a64b2a5ded84ddb0f35dd267543b4ede7e34b569 [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)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000037#include "mbedtls/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)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000040#include "mbedtls/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é-Gonnard0e9cddb2018-12-10 16:37:51 +010047/* Parameter validation macros based on platform_util.h */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010048#define AES_VALIDATE_RET(cond) \
49 MBEDTLS_INTERNAL_VALIDATE_RET(cond, MBEDTLS_ERR_AES_BAD_INPUT_DATA)
50#define AES_VALIDATE(cond) \
51 MBEDTLS_INTERNAL_VALIDATE(cond)
Manuel Pégourié-Gonnard0e9cddb2018-12-10 16:37:51 +010052
Gilles Peskine30c356c2023-03-16 14:58:46 +010053#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Paul Bakker048d04e2012-02-12 17:31:04 +000054static int aes_padlock_ace = -1;
55#endif
56
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020057#if defined(MBEDTLS_AES_ROM_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +000058/*
59 * Forward S-box
60 */
Dave Rodgman584b62f2023-06-27 21:03:31 +010061#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
62 !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +000063static const unsigned char FSb[256] =
64{
65 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
66 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
67 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
68 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
69 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
70 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
71 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
72 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
73 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
74 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
75 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
76 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
77 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
78 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
79 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
80 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
81 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
82 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
83 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
84 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
85 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
86 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
87 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
88 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
89 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
90 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
91 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
92 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
93 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
94 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
95 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
96 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
97};
Dave Rodgman1d0033e2023-06-29 12:07:11 +010098#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
99 !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000100
101/*
102 * Forward tables
103 */
104#define FT \
105\
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100106 V(A5, 63, 63, C6), V(84, 7C, 7C, F8), V(99, 77, 77, EE), V(8D, 7B, 7B, F6), \
107 V(0D, F2, F2, FF), V(BD, 6B, 6B, D6), V(B1, 6F, 6F, DE), V(54, C5, C5, 91), \
108 V(50, 30, 30, 60), V(03, 01, 01, 02), V(A9, 67, 67, CE), V(7D, 2B, 2B, 56), \
109 V(19, FE, FE, E7), V(62, D7, D7, B5), V(E6, AB, AB, 4D), V(9A, 76, 76, EC), \
110 V(45, CA, CA, 8F), V(9D, 82, 82, 1F), V(40, C9, C9, 89), V(87, 7D, 7D, FA), \
111 V(15, FA, FA, EF), V(EB, 59, 59, B2), V(C9, 47, 47, 8E), V(0B, F0, F0, FB), \
112 V(EC, AD, AD, 41), V(67, D4, D4, B3), V(FD, A2, A2, 5F), V(EA, AF, AF, 45), \
113 V(BF, 9C, 9C, 23), V(F7, A4, A4, 53), V(96, 72, 72, E4), V(5B, C0, C0, 9B), \
114 V(C2, B7, B7, 75), V(1C, FD, FD, E1), V(AE, 93, 93, 3D), V(6A, 26, 26, 4C), \
115 V(5A, 36, 36, 6C), V(41, 3F, 3F, 7E), V(02, F7, F7, F5), V(4F, CC, CC, 83), \
116 V(5C, 34, 34, 68), V(F4, A5, A5, 51), V(34, E5, E5, D1), V(08, F1, F1, F9), \
117 V(93, 71, 71, E2), V(73, D8, D8, AB), V(53, 31, 31, 62), V(3F, 15, 15, 2A), \
118 V(0C, 04, 04, 08), V(52, C7, C7, 95), V(65, 23, 23, 46), V(5E, C3, C3, 9D), \
119 V(28, 18, 18, 30), V(A1, 96, 96, 37), V(0F, 05, 05, 0A), V(B5, 9A, 9A, 2F), \
120 V(09, 07, 07, 0E), V(36, 12, 12, 24), V(9B, 80, 80, 1B), V(3D, E2, E2, DF), \
121 V(26, EB, EB, CD), V(69, 27, 27, 4E), V(CD, B2, B2, 7F), V(9F, 75, 75, EA), \
122 V(1B, 09, 09, 12), V(9E, 83, 83, 1D), V(74, 2C, 2C, 58), V(2E, 1A, 1A, 34), \
123 V(2D, 1B, 1B, 36), V(B2, 6E, 6E, DC), V(EE, 5A, 5A, B4), V(FB, A0, A0, 5B), \
124 V(F6, 52, 52, A4), V(4D, 3B, 3B, 76), V(61, D6, D6, B7), V(CE, B3, B3, 7D), \
125 V(7B, 29, 29, 52), V(3E, E3, E3, DD), V(71, 2F, 2F, 5E), V(97, 84, 84, 13), \
126 V(F5, 53, 53, A6), V(68, D1, D1, B9), V(00, 00, 00, 00), V(2C, ED, ED, C1), \
127 V(60, 20, 20, 40), V(1F, FC, FC, E3), V(C8, B1, B1, 79), V(ED, 5B, 5B, B6), \
128 V(BE, 6A, 6A, D4), V(46, CB, CB, 8D), V(D9, BE, BE, 67), V(4B, 39, 39, 72), \
129 V(DE, 4A, 4A, 94), V(D4, 4C, 4C, 98), V(E8, 58, 58, B0), V(4A, CF, CF, 85), \
130 V(6B, D0, D0, BB), V(2A, EF, EF, C5), V(E5, AA, AA, 4F), V(16, FB, FB, ED), \
131 V(C5, 43, 43, 86), V(D7, 4D, 4D, 9A), V(55, 33, 33, 66), V(94, 85, 85, 11), \
132 V(CF, 45, 45, 8A), V(10, F9, F9, E9), V(06, 02, 02, 04), V(81, 7F, 7F, FE), \
133 V(F0, 50, 50, A0), V(44, 3C, 3C, 78), V(BA, 9F, 9F, 25), V(E3, A8, A8, 4B), \
134 V(F3, 51, 51, A2), V(FE, A3, A3, 5D), V(C0, 40, 40, 80), V(8A, 8F, 8F, 05), \
135 V(AD, 92, 92, 3F), V(BC, 9D, 9D, 21), V(48, 38, 38, 70), V(04, F5, F5, F1), \
136 V(DF, BC, BC, 63), V(C1, B6, B6, 77), V(75, DA, DA, AF), V(63, 21, 21, 42), \
137 V(30, 10, 10, 20), V(1A, FF, FF, E5), V(0E, F3, F3, FD), V(6D, D2, D2, BF), \
138 V(4C, CD, CD, 81), V(14, 0C, 0C, 18), V(35, 13, 13, 26), V(2F, EC, EC, C3), \
139 V(E1, 5F, 5F, BE), V(A2, 97, 97, 35), V(CC, 44, 44, 88), V(39, 17, 17, 2E), \
140 V(57, C4, C4, 93), V(F2, A7, A7, 55), V(82, 7E, 7E, FC), V(47, 3D, 3D, 7A), \
141 V(AC, 64, 64, C8), V(E7, 5D, 5D, BA), V(2B, 19, 19, 32), V(95, 73, 73, E6), \
142 V(A0, 60, 60, C0), V(98, 81, 81, 19), V(D1, 4F, 4F, 9E), V(7F, DC, DC, A3), \
143 V(66, 22, 22, 44), V(7E, 2A, 2A, 54), V(AB, 90, 90, 3B), V(83, 88, 88, 0B), \
144 V(CA, 46, 46, 8C), V(29, EE, EE, C7), V(D3, B8, B8, 6B), V(3C, 14, 14, 28), \
145 V(79, DE, DE, A7), V(E2, 5E, 5E, BC), V(1D, 0B, 0B, 16), V(76, DB, DB, AD), \
146 V(3B, E0, E0, DB), V(56, 32, 32, 64), V(4E, 3A, 3A, 74), V(1E, 0A, 0A, 14), \
147 V(DB, 49, 49, 92), V(0A, 06, 06, 0C), V(6C, 24, 24, 48), V(E4, 5C, 5C, B8), \
148 V(5D, C2, C2, 9F), V(6E, D3, D3, BD), V(EF, AC, AC, 43), V(A6, 62, 62, C4), \
149 V(A8, 91, 91, 39), V(A4, 95, 95, 31), V(37, E4, E4, D3), V(8B, 79, 79, F2), \
150 V(32, E7, E7, D5), V(43, C8, C8, 8B), V(59, 37, 37, 6E), V(B7, 6D, 6D, DA), \
151 V(8C, 8D, 8D, 01), V(64, D5, D5, B1), V(D2, 4E, 4E, 9C), V(E0, A9, A9, 49), \
152 V(B4, 6C, 6C, D8), V(FA, 56, 56, AC), V(07, F4, F4, F3), V(25, EA, EA, CF), \
153 V(AF, 65, 65, CA), V(8E, 7A, 7A, F4), V(E9, AE, AE, 47), V(18, 08, 08, 10), \
154 V(D5, BA, BA, 6F), V(88, 78, 78, F0), V(6F, 25, 25, 4A), V(72, 2E, 2E, 5C), \
155 V(24, 1C, 1C, 38), V(F1, A6, A6, 57), V(C7, B4, B4, 73), V(51, C6, C6, 97), \
156 V(23, E8, E8, CB), V(7C, DD, DD, A1), V(9C, 74, 74, E8), V(21, 1F, 1F, 3E), \
157 V(DD, 4B, 4B, 96), V(DC, BD, BD, 61), V(86, 8B, 8B, 0D), V(85, 8A, 8A, 0F), \
158 V(90, 70, 70, E0), V(42, 3E, 3E, 7C), V(C4, B5, B5, 71), V(AA, 66, 66, CC), \
159 V(D8, 48, 48, 90), V(05, 03, 03, 06), V(01, F6, F6, F7), V(12, 0E, 0E, 1C), \
160 V(A3, 61, 61, C2), V(5F, 35, 35, 6A), V(F9, 57, 57, AE), V(D0, B9, B9, 69), \
161 V(91, 86, 86, 17), V(58, C1, C1, 99), V(27, 1D, 1D, 3A), V(B9, 9E, 9E, 27), \
162 V(38, E1, E1, D9), V(13, F8, F8, EB), V(B3, 98, 98, 2B), V(33, 11, 11, 22), \
163 V(BB, 69, 69, D2), V(70, D9, D9, A9), V(89, 8E, 8E, 07), V(A7, 94, 94, 33), \
164 V(B6, 9B, 9B, 2D), V(22, 1E, 1E, 3C), V(92, 87, 87, 15), V(20, E9, E9, C9), \
165 V(49, CE, CE, 87), V(FF, 55, 55, AA), V(78, 28, 28, 50), V(7A, DF, DF, A5), \
166 V(8F, 8C, 8C, 03), V(F8, A1, A1, 59), V(80, 89, 89, 09), V(17, 0D, 0D, 1A), \
167 V(DA, BF, BF, 65), V(31, E6, E6, D7), V(C6, 42, 42, 84), V(B8, 68, 68, D0), \
168 V(C3, 41, 41, 82), V(B0, 99, 99, 29), V(77, 2D, 2D, 5A), V(11, 0F, 0F, 1E), \
169 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 +0000170
Dave Rodgman5c047d92023-06-27 19:20:27 +0100171#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100172#define V(a, b, c, d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000173static const uint32_t FT0[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000174#undef V
175
Hanno Beckerad049a92017-06-19 16:31:54 +0100176#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200177
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100178#define V(a, b, c, d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000179static const uint32_t FT1[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000180#undef V
181
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100182#define V(a, b, c, d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000183static const uint32_t FT2[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000184#undef V
185
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100186#define V(a, b, c, d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000187static const uint32_t FT3[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000188#undef V
189
Hanno Becker177d3cf2017-06-07 15:52:48 +0100190#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200191
Dave Rodgman1ce92e42023-06-29 12:01:24 +0100192#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) */
193
Paul Bakker5121ce52009-01-03 21:22:43 +0000194#undef FT
195
Dave Rodgman5c047d92023-06-27 19:20:27 +0100196#if !defined(MBEDTLS_AES_DECRYPT_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000197/*
198 * Reverse S-box
199 */
200static const unsigned char RSb[256] =
201{
202 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
203 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
204 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
205 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
206 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
207 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
208 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
209 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
210 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
211 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
212 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
213 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
214 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
215 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
216 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
217 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
218 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
219 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
220 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
221 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
222 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
223 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
224 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
225 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
226 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
227 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
228 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
229 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
230 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
231 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
232 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
233 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
234};
Dave Rodgmana4a33732023-06-29 11:58:04 +0100235#endif /* defined(MBEDTLS_AES_DECRYPT_ALT)) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000236
237/*
238 * Reverse tables
239 */
240#define RT \
241\
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100242 V(50, A7, F4, 51), V(53, 65, 41, 7E), V(C3, A4, 17, 1A), V(96, 5E, 27, 3A), \
243 V(CB, 6B, AB, 3B), V(F1, 45, 9D, 1F), V(AB, 58, FA, AC), V(93, 03, E3, 4B), \
244 V(55, FA, 30, 20), V(F6, 6D, 76, AD), V(91, 76, CC, 88), V(25, 4C, 02, F5), \
245 V(FC, D7, E5, 4F), V(D7, CB, 2A, C5), V(80, 44, 35, 26), V(8F, A3, 62, B5), \
246 V(49, 5A, B1, DE), V(67, 1B, BA, 25), V(98, 0E, EA, 45), V(E1, C0, FE, 5D), \
247 V(02, 75, 2F, C3), V(12, F0, 4C, 81), V(A3, 97, 46, 8D), V(C6, F9, D3, 6B), \
248 V(E7, 5F, 8F, 03), V(95, 9C, 92, 15), V(EB, 7A, 6D, BF), V(DA, 59, 52, 95), \
249 V(2D, 83, BE, D4), V(D3, 21, 74, 58), V(29, 69, E0, 49), V(44, C8, C9, 8E), \
250 V(6A, 89, C2, 75), V(78, 79, 8E, F4), V(6B, 3E, 58, 99), V(DD, 71, B9, 27), \
251 V(B6, 4F, E1, BE), V(17, AD, 88, F0), V(66, AC, 20, C9), V(B4, 3A, CE, 7D), \
252 V(18, 4A, DF, 63), V(82, 31, 1A, E5), V(60, 33, 51, 97), V(45, 7F, 53, 62), \
253 V(E0, 77, 64, B1), V(84, AE, 6B, BB), V(1C, A0, 81, FE), V(94, 2B, 08, F9), \
254 V(58, 68, 48, 70), V(19, FD, 45, 8F), V(87, 6C, DE, 94), V(B7, F8, 7B, 52), \
255 V(23, D3, 73, AB), V(E2, 02, 4B, 72), V(57, 8F, 1F, E3), V(2A, AB, 55, 66), \
256 V(07, 28, EB, B2), V(03, C2, B5, 2F), V(9A, 7B, C5, 86), V(A5, 08, 37, D3), \
257 V(F2, 87, 28, 30), V(B2, A5, BF, 23), V(BA, 6A, 03, 02), V(5C, 82, 16, ED), \
258 V(2B, 1C, CF, 8A), V(92, B4, 79, A7), V(F0, F2, 07, F3), V(A1, E2, 69, 4E), \
259 V(CD, F4, DA, 65), V(D5, BE, 05, 06), V(1F, 62, 34, D1), V(8A, FE, A6, C4), \
260 V(9D, 53, 2E, 34), V(A0, 55, F3, A2), V(32, E1, 8A, 05), V(75, EB, F6, A4), \
261 V(39, EC, 83, 0B), V(AA, EF, 60, 40), V(06, 9F, 71, 5E), V(51, 10, 6E, BD), \
262 V(F9, 8A, 21, 3E), V(3D, 06, DD, 96), V(AE, 05, 3E, DD), V(46, BD, E6, 4D), \
263 V(B5, 8D, 54, 91), V(05, 5D, C4, 71), V(6F, D4, 06, 04), V(FF, 15, 50, 60), \
264 V(24, FB, 98, 19), V(97, E9, BD, D6), V(CC, 43, 40, 89), V(77, 9E, D9, 67), \
265 V(BD, 42, E8, B0), V(88, 8B, 89, 07), V(38, 5B, 19, E7), V(DB, EE, C8, 79), \
266 V(47, 0A, 7C, A1), V(E9, 0F, 42, 7C), V(C9, 1E, 84, F8), V(00, 00, 00, 00), \
267 V(83, 86, 80, 09), V(48, ED, 2B, 32), V(AC, 70, 11, 1E), V(4E, 72, 5A, 6C), \
268 V(FB, FF, 0E, FD), V(56, 38, 85, 0F), V(1E, D5, AE, 3D), V(27, 39, 2D, 36), \
269 V(64, D9, 0F, 0A), V(21, A6, 5C, 68), V(D1, 54, 5B, 9B), V(3A, 2E, 36, 24), \
270 V(B1, 67, 0A, 0C), V(0F, E7, 57, 93), V(D2, 96, EE, B4), V(9E, 91, 9B, 1B), \
271 V(4F, C5, C0, 80), V(A2, 20, DC, 61), V(69, 4B, 77, 5A), V(16, 1A, 12, 1C), \
272 V(0A, BA, 93, E2), V(E5, 2A, A0, C0), V(43, E0, 22, 3C), V(1D, 17, 1B, 12), \
273 V(0B, 0D, 09, 0E), V(AD, C7, 8B, F2), V(B9, A8, B6, 2D), V(C8, A9, 1E, 14), \
274 V(85, 19, F1, 57), V(4C, 07, 75, AF), V(BB, DD, 99, EE), V(FD, 60, 7F, A3), \
275 V(9F, 26, 01, F7), V(BC, F5, 72, 5C), V(C5, 3B, 66, 44), V(34, 7E, FB, 5B), \
276 V(76, 29, 43, 8B), V(DC, C6, 23, CB), V(68, FC, ED, B6), V(63, F1, E4, B8), \
277 V(CA, DC, 31, D7), V(10, 85, 63, 42), V(40, 22, 97, 13), V(20, 11, C6, 84), \
278 V(7D, 24, 4A, 85), V(F8, 3D, BB, D2), V(11, 32, F9, AE), V(6D, A1, 29, C7), \
279 V(4B, 2F, 9E, 1D), V(F3, 30, B2, DC), V(EC, 52, 86, 0D), V(D0, E3, C1, 77), \
280 V(6C, 16, B3, 2B), V(99, B9, 70, A9), V(FA, 48, 94, 11), V(22, 64, E9, 47), \
281 V(C4, 8C, FC, A8), V(1A, 3F, F0, A0), V(D8, 2C, 7D, 56), V(EF, 90, 33, 22), \
282 V(C7, 4E, 49, 87), V(C1, D1, 38, D9), V(FE, A2, CA, 8C), V(36, 0B, D4, 98), \
283 V(CF, 81, F5, A6), V(28, DE, 7A, A5), V(26, 8E, B7, DA), V(A4, BF, AD, 3F), \
284 V(E4, 9D, 3A, 2C), V(0D, 92, 78, 50), V(9B, CC, 5F, 6A), V(62, 46, 7E, 54), \
285 V(C2, 13, 8D, F6), V(E8, B8, D8, 90), V(5E, F7, 39, 2E), V(F5, AF, C3, 82), \
286 V(BE, 80, 5D, 9F), V(7C, 93, D0, 69), V(A9, 2D, D5, 6F), V(B3, 12, 25, CF), \
287 V(3B, 99, AC, C8), V(A7, 7D, 18, 10), V(6E, 63, 9C, E8), V(7B, BB, 3B, DB), \
288 V(09, 78, 26, CD), V(F4, 18, 59, 6E), V(01, B7, 9A, EC), V(A8, 9A, 4F, 83), \
289 V(65, 6E, 95, E6), V(7E, E6, FF, AA), V(08, CF, BC, 21), V(E6, E8, 15, EF), \
290 V(D9, 9B, E7, BA), V(CE, 36, 6F, 4A), V(D4, 09, 9F, EA), V(D6, 7C, B0, 29), \
291 V(AF, B2, A4, 31), V(31, 23, 3F, 2A), V(30, 94, A5, C6), V(C0, 66, A2, 35), \
292 V(37, BC, 4E, 74), V(A6, CA, 82, FC), V(B0, D0, 90, E0), V(15, D8, A7, 33), \
293 V(4A, 98, 04, F1), V(F7, DA, EC, 41), V(0E, 50, CD, 7F), V(2F, F6, 91, 17), \
294 V(8D, D6, 4D, 76), V(4D, B0, EF, 43), V(54, 4D, AA, CC), V(DF, 04, 96, E4), \
295 V(E3, B5, D1, 9E), V(1B, 88, 6A, 4C), V(B8, 1F, 2C, C1), V(7F, 51, 65, 46), \
296 V(04, EA, 5E, 9D), V(5D, 35, 8C, 01), V(73, 74, 87, FA), V(2E, 41, 0B, FB), \
297 V(5A, 1D, 67, B3), V(52, D2, DB, 92), V(33, 56, 10, E9), V(13, 47, D6, 6D), \
298 V(8C, 61, D7, 9A), V(7A, 0C, A1, 37), V(8E, 14, F8, 59), V(89, 3C, 13, EB), \
299 V(EE, 27, A9, CE), V(35, C9, 61, B7), V(ED, E5, 1C, E1), V(3C, B1, 47, 7A), \
300 V(59, DF, D2, 9C), V(3F, 73, F2, 55), V(79, CE, 14, 18), V(BF, 37, C7, 73), \
301 V(EA, CD, F7, 53), V(5B, AA, FD, 5F), V(14, 6F, 3D, DF), V(86, DB, 44, 78), \
302 V(81, F3, AF, CA), V(3E, C4, 68, B9), V(2C, 34, 24, 38), V(5F, 40, A3, C2), \
303 V(72, C3, 1D, 16), V(0C, 25, E2, BC), V(8B, 49, 3C, 28), V(41, 95, 0D, FF), \
304 V(71, 01, A8, 39), V(DE, B3, 0C, 08), V(9C, E4, B4, D8), V(90, C1, 56, 64), \
305 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 +0000306
Dave Rodgman5c047d92023-06-27 19:20:27 +0100307#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
308
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100309#define V(a, b, c, d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000310static const uint32_t RT0[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000311#undef V
312
Hanno Beckerad049a92017-06-19 16:31:54 +0100313#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200314
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100315#define V(a, b, c, d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000316static const uint32_t RT1[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000317#undef V
318
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100319#define V(a, b, c, d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000320static const uint32_t RT2[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000321#undef V
322
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100323#define V(a, b, c, d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000324static const uint32_t RT3[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000325#undef V
326
Dave Rodgman9d3b6332023-06-27 20:41:51 +0100327#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Dave Rodgman5c047d92023-06-27 19:20:27 +0100328
Hanno Becker177d3cf2017-06-07 15:52:48 +0100329#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200330
Paul Bakker5121ce52009-01-03 21:22:43 +0000331#undef RT
332
Dave Rodgman36c8e582023-06-27 18:31:24 +0100333#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000334/*
335 * Round constants
336 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000337static const uint32_t RCON[10] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000338{
339 0x00000001, 0x00000002, 0x00000004, 0x00000008,
340 0x00000010, 0x00000020, 0x00000040, 0x00000080,
341 0x0000001B, 0x00000036
342};
Dave Rodgman36c8e582023-06-27 18:31:24 +0100343#endif /* !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000344
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200345#else /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000346
347/*
348 * Forward S-box & tables
349 */
Dave Rodgman584b62f2023-06-27 21:03:31 +0100350#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
351 !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000352static unsigned char FSb[256];
Dave Rodgman1d0033e2023-06-29 12:07:11 +0100353#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
354 !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Dave Rodgman5c047d92023-06-27 19:20:27 +0100355#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker9af723c2014-05-01 13:03:14 +0200356static uint32_t FT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100357#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker9af723c2014-05-01 13:03:14 +0200358static uint32_t FT1[256];
359static uint32_t FT2[256];
360static uint32_t FT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100361#endif /* !MBEDTLS_AES_FEWER_TABLES */
Dave Rodgman5c047d92023-06-27 19:20:27 +0100362#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000363
364/*
365 * Reverse S-box & tables
366 */
Dave Rodgmandbae1842023-06-27 18:27:31 +0100367#if !(defined(MBEDTLS_AES_SETKEY_ENC_ALT) && defined(MBEDTLS_AES_DECRYPT_ALT))
Paul Bakker5121ce52009-01-03 21:22:43 +0000368static unsigned char RSb[256];
Dave Rodgman1d0033e2023-06-29 12:07:11 +0100369#endif /* !(defined(MBEDTLS_AES_SETKEY_ENC_ALT) && defined(MBEDTLS_AES_DECRYPT_ALT)) */
Dave Rodgman5c047d92023-06-27 19:20:27 +0100370
371#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Paul Bakker5c2364c2012-10-01 14:41:15 +0000372static uint32_t RT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100373#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker5c2364c2012-10-01 14:41:15 +0000374static uint32_t RT1[256];
375static uint32_t RT2[256];
376static uint32_t RT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100377#endif /* !MBEDTLS_AES_FEWER_TABLES */
Dave Rodgmana4a33732023-06-29 11:58:04 +0100378#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000379
Dave Rodgman1e6f7702023-06-27 18:16:13 +0100380#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000381/*
382 * Round constants
383 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000384static uint32_t RCON[10];
Paul Bakker5121ce52009-01-03 21:22:43 +0000385
386/*
387 * Tables generation code
388 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100389#define ROTL8(x) (((x) << 8) & 0xFFFFFFFF) | ((x) >> 24)
390#define XTIME(x) (((x) << 1) ^ (((x) & 0x80) ? 0x1B : 0x00))
391#define MUL(x, y) (((x) && (y)) ? pow[(log[(x)]+log[(y)]) % 255] : 0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000392
393static int aes_init_done = 0;
394
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100395static void aes_gen_tables(void)
Paul Bakker5121ce52009-01-03 21:22:43 +0000396{
397 int i, x, y, z;
398 int pow[256];
399 int log[256];
400
401 /*
402 * compute pow and log tables over GF(2^8)
403 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100404 for (i = 0, x = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000405 pow[i] = x;
406 log[x] = i;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100407 x = MBEDTLS_BYTE_0(x ^ XTIME(x));
Paul Bakker5121ce52009-01-03 21:22:43 +0000408 }
409
410 /*
411 * calculate the round constants
412 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100413 for (i = 0, x = 1; i < 10; i++) {
Paul Bakker5c2364c2012-10-01 14:41:15 +0000414 RCON[i] = (uint32_t) x;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100415 x = MBEDTLS_BYTE_0(XTIME(x));
Paul Bakker5121ce52009-01-03 21:22:43 +0000416 }
417
418 /*
419 * generate the forward and reverse S-boxes
420 */
421 FSb[0x00] = 0x63;
422 RSb[0x63] = 0x00;
423
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100424 for (i = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000425 x = pow[255 - log[i]];
426
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100427 y = x; y = MBEDTLS_BYTE_0((y << 1) | (y >> 7));
428 x ^= y; y = MBEDTLS_BYTE_0((y << 1) | (y >> 7));
429 x ^= y; y = MBEDTLS_BYTE_0((y << 1) | (y >> 7));
430 x ^= y; y = MBEDTLS_BYTE_0((y << 1) | (y >> 7));
Paul Bakker5121ce52009-01-03 21:22:43 +0000431 x ^= y ^ 0x63;
432
433 FSb[i] = (unsigned char) x;
434 RSb[x] = (unsigned char) i;
435 }
436
437 /*
438 * generate the forward and reverse tables
439 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100440 for (i = 0; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000441 x = FSb[i];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100442 y = MBEDTLS_BYTE_0(XTIME(x));
443 z = MBEDTLS_BYTE_0(y ^ x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000444
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100445 FT0[i] = ((uint32_t) y) ^
446 ((uint32_t) x << 8) ^
447 ((uint32_t) x << 16) ^
448 ((uint32_t) z << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000449
Hanno Beckerad049a92017-06-19 16:31:54 +0100450#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100451 FT1[i] = ROTL8(FT0[i]);
452 FT2[i] = ROTL8(FT1[i]);
453 FT3[i] = ROTL8(FT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100454#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000455
456 x = RSb[i];
457
Dave Rodgman5c047d92023-06-27 19:20:27 +0100458#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100459 RT0[i] = ((uint32_t) MUL(0x0E, x)) ^
460 ((uint32_t) MUL(0x09, x) << 8) ^
461 ((uint32_t) MUL(0x0D, x) << 16) ^
462 ((uint32_t) MUL(0x0B, x) << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000463
Hanno Beckerad049a92017-06-19 16:31:54 +0100464#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100465 RT1[i] = ROTL8(RT0[i]);
466 RT2[i] = ROTL8(RT1[i]);
467 RT3[i] = ROTL8(RT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100468#endif /* !MBEDTLS_AES_FEWER_TABLES */
Dave Rodgman5c047d92023-06-27 19:20:27 +0100469#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000470 }
471}
472
Dave Rodgman1e6f7702023-06-27 18:16:13 +0100473#endif /* !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
474
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200475#undef ROTL8
476
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200477#endif /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000478
Hanno Beckerad049a92017-06-19 16:31:54 +0100479#if defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200480
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100481#define ROTL8(x) ((uint32_t) ((x) << 8) + (uint32_t) ((x) >> 24))
482#define ROTL16(x) ((uint32_t) ((x) << 16) + (uint32_t) ((x) >> 16))
483#define ROTL24(x) ((uint32_t) ((x) << 24) + (uint32_t) ((x) >> 8))
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200484
485#define AES_RT0(idx) RT0[idx]
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100486#define AES_RT1(idx) ROTL8(RT0[idx])
487#define AES_RT2(idx) ROTL16(RT0[idx])
488#define AES_RT3(idx) ROTL24(RT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200489
490#define AES_FT0(idx) FT0[idx]
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100491#define AES_FT1(idx) ROTL8(FT0[idx])
492#define AES_FT2(idx) ROTL16(FT0[idx])
493#define AES_FT3(idx) ROTL24(FT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200494
Hanno Becker177d3cf2017-06-07 15:52:48 +0100495#else /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200496
497#define AES_RT0(idx) RT0[idx]
498#define AES_RT1(idx) RT1[idx]
499#define AES_RT2(idx) RT2[idx]
500#define AES_RT3(idx) RT3[idx]
501
502#define AES_FT0(idx) FT0[idx]
503#define AES_FT1(idx) FT1[idx]
504#define AES_FT2(idx) FT2[idx]
505#define AES_FT3(idx) FT3[idx]
506
Hanno Becker177d3cf2017-06-07 15:52:48 +0100507#endif /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200508
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100509void mbedtls_aes_init(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200510{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100511 AES_VALIDATE(ctx != NULL);
Simon Butcher5201e412018-12-06 17:40:14 +0000512
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100513 memset(ctx, 0, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200514}
515
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100516void mbedtls_aes_free(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200517{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100518 if (ctx == NULL) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200519 return;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100520 }
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200521
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100522 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200523}
524
Jaeden Amero9366feb2018-05-29 18:55:17 +0100525#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100526void mbedtls_aes_xts_init(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100527{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100528 AES_VALIDATE(ctx != NULL);
Simon Butcher5201e412018-12-06 17:40:14 +0000529
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100530 mbedtls_aes_init(&ctx->crypt);
531 mbedtls_aes_init(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100532}
533
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100534void mbedtls_aes_xts_free(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100535{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100536 if (ctx == NULL) {
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100537 return;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100538 }
Simon Butcher5201e412018-12-06 17:40:14 +0000539
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100540 mbedtls_aes_free(&ctx->crypt);
541 mbedtls_aes_free(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100542}
543#endif /* MBEDTLS_CIPHER_MODE_XTS */
544
Gilles Peskineb71d4022023-03-16 17:14:59 +0100545/* Some implementations need the round keys to be aligned.
546 * Return an offset to be added to buf, such that (buf + offset) is
547 * correctly aligned.
548 * Note that the offset is in units of elements of buf, i.e. 32-bit words,
549 * i.e. an offset of 1 means 4 bytes and so on.
550 */
551#if (defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)) || \
Gilles Peskine6dec5412023-03-16 17:21:33 +0100552 (defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2)
Gilles Peskineb71d4022023-03-16 17:14:59 +0100553#define MAY_NEED_TO_ALIGN
554#endif
Dave Rodgman9b20aea2023-06-27 18:22:34 +0100555
Dave Rodgman584b62f2023-06-27 21:03:31 +0100556#if defined(MAY_NEED_TO_ALIGN) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) || \
557 !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskineb71d4022023-03-16 17:14:59 +0100558static unsigned mbedtls_aes_rk_offset(uint32_t *buf)
559{
560#if defined(MAY_NEED_TO_ALIGN)
561 int align_16_bytes = 0;
562
563#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
564 if (aes_padlock_ace == -1) {
565 aes_padlock_ace = mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE);
566 }
567 if (aes_padlock_ace) {
568 align_16_bytes = 1;
569 }
570#endif
571
Gilles Peskine6dec5412023-03-16 17:21:33 +0100572#if defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2
Gilles Peskineb71d4022023-03-16 17:14:59 +0100573 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
574 align_16_bytes = 1;
575 }
576#endif
577
578 if (align_16_bytes) {
579 /* These implementations needs 16-byte alignment
580 * for the round key array. */
581 unsigned delta = ((uintptr_t) buf & 0x0000000fU) / 4;
582 if (delta == 0) {
583 return 0;
584 } else {
585 return 4 - delta; // 16 bytes = 4 uint32_t
586 }
587 }
588#else /* MAY_NEED_TO_ALIGN */
589 (void) buf;
590#endif /* MAY_NEED_TO_ALIGN */
591
592 return 0;
593}
Dave Rodgman1d0033e2023-06-29 12:07:11 +0100594#endif /* defined(MAY_NEED_TO_ALIGN) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) || \
595 !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
Gilles Peskineb71d4022023-03-16 17:14:59 +0100596
Paul Bakker5121ce52009-01-03 21:22:43 +0000597/*
598 * AES key schedule (encryption)
599 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200600#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100601int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
602 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000603{
Paul Bakker23986e52011-04-24 08:57:21 +0000604 unsigned int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000605 uint32_t *RK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000606
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100607 AES_VALIDATE_RET(ctx != NULL);
608 AES_VALIDATE_RET(key != NULL);
Paul Bakker5121ce52009-01-03 21:22:43 +0000609
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100610 switch (keybits) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000611 case 128: ctx->nr = 10; break;
612 case 192: ctx->nr = 12; break;
613 case 256: ctx->nr = 14; break;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100614 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Paul Bakker5121ce52009-01-03 21:22:43 +0000615 }
616
Simon Butcher5201e412018-12-06 17:40:14 +0000617#if !defined(MBEDTLS_AES_ROM_TABLES)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100618 if (aes_init_done == 0) {
Simon Butcher5201e412018-12-06 17:40:14 +0000619 aes_gen_tables();
620 aes_init_done = 1;
Simon Butcher5201e412018-12-06 17:40:14 +0000621 }
622#endif
623
Gilles Peskineb71d4022023-03-16 17:14:59 +0100624 ctx->rk = RK = ctx->buf + mbedtls_aes_rk_offset(ctx->buf);
Paul Bakker5121ce52009-01-03 21:22:43 +0000625
Gilles Peskine5511a342023-03-10 22:29:32 +0100626#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100627 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
628 return mbedtls_aesni_setkey_enc((unsigned char *) ctx->rk, key, keybits);
629 }
Manuel Pégourié-Gonnard47a35362013-12-28 20:45:04 +0100630#endif
631
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100632 for (i = 0; i < (keybits >> 5); i++) {
633 RK[i] = MBEDTLS_GET_UINT32_LE(key, i << 2);
Paul Bakker5121ce52009-01-03 21:22:43 +0000634 }
635
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100636 switch (ctx->nr) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000637 case 10:
638
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100639 for (i = 0; i < 10; i++, RK += 4) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000640 RK[4] = RK[0] ^ RCON[i] ^
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100641 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[3])]) ^
642 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[3])] << 8) ^
643 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[3])] << 16) ^
644 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[3])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000645
646 RK[5] = RK[1] ^ RK[4];
647 RK[6] = RK[2] ^ RK[5];
648 RK[7] = RK[3] ^ RK[6];
649 }
650 break;
651
652 case 12:
653
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100654 for (i = 0; i < 8; i++, RK += 6) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000655 RK[6] = RK[0] ^ RCON[i] ^
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100656 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[5])]) ^
657 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[5])] << 8) ^
658 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[5])] << 16) ^
659 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[5])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000660
661 RK[7] = RK[1] ^ RK[6];
662 RK[8] = RK[2] ^ RK[7];
663 RK[9] = RK[3] ^ RK[8];
664 RK[10] = RK[4] ^ RK[9];
665 RK[11] = RK[5] ^ RK[10];
666 }
667 break;
668
669 case 14:
670
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100671 for (i = 0; i < 7; i++, RK += 8) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000672 RK[8] = RK[0] ^ RCON[i] ^
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100673 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[7])]) ^
674 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[7])] << 8) ^
675 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[7])] << 16) ^
676 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[7])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000677
678 RK[9] = RK[1] ^ RK[8];
679 RK[10] = RK[2] ^ RK[9];
680 RK[11] = RK[3] ^ RK[10];
681
682 RK[12] = RK[4] ^
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100683 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[11])]) ^
684 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[11])] << 8) ^
685 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[11])] << 16) ^
686 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[11])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000687
688 RK[13] = RK[5] ^ RK[12];
689 RK[14] = RK[6] ^ RK[13];
690 RK[15] = RK[7] ^ RK[14];
691 }
692 break;
Paul Bakker5121ce52009-01-03 21:22:43 +0000693 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000694
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100695 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000696}
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200697#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000698
699/*
700 * AES key schedule (decryption)
701 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200702#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100703int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
704 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000705{
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200706 int i, j, ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200707 mbedtls_aes_context cty;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000708 uint32_t *RK;
709 uint32_t *SK;
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200710
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100711 AES_VALIDATE_RET(ctx != NULL);
712 AES_VALIDATE_RET(key != NULL);
Simon Butcher5201e412018-12-06 17:40:14 +0000713
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100714 mbedtls_aes_init(&cty);
Paul Bakker5121ce52009-01-03 21:22:43 +0000715
Gilles Peskineb71d4022023-03-16 17:14:59 +0100716 ctx->rk = RK = ctx->buf + mbedtls_aes_rk_offset(ctx->buf);
Paul Bakker5121ce52009-01-03 21:22:43 +0000717
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200718 /* Also checks keybits */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100719 if ((ret = mbedtls_aes_setkey_enc(&cty, key, keybits)) != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200720 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100721 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000722
Manuel Pégourié-Gonnardafd5a082014-05-28 21:52:59 +0200723 ctx->nr = cty.nr;
724
Gilles Peskine5511a342023-03-10 22:29:32 +0100725#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100726 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
727 mbedtls_aesni_inverse_key((unsigned char *) ctx->rk,
728 (const unsigned char *) cty.rk, ctx->nr);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200729 goto exit;
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100730 }
731#endif
732
Paul Bakker5121ce52009-01-03 21:22:43 +0000733 SK = cty.rk + cty.nr * 4;
734
735 *RK++ = *SK++;
736 *RK++ = *SK++;
737 *RK++ = *SK++;
738 *RK++ = *SK++;
739
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100740 for (i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8) {
741 for (j = 0; j < 4; j++, SK++) {
742 *RK++ = AES_RT0(FSb[MBEDTLS_BYTE_0(*SK)]) ^
743 AES_RT1(FSb[MBEDTLS_BYTE_1(*SK)]) ^
744 AES_RT2(FSb[MBEDTLS_BYTE_2(*SK)]) ^
745 AES_RT3(FSb[MBEDTLS_BYTE_3(*SK)]);
Paul Bakker5121ce52009-01-03 21:22:43 +0000746 }
747 }
748
749 *RK++ = *SK++;
750 *RK++ = *SK++;
751 *RK++ = *SK++;
752 *RK++ = *SK++;
753
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200754exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100755 mbedtls_aes_free(&cty);
Paul Bakker2b222c82009-07-27 21:03:45 +0000756
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100757 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000758}
gabor-mezei-arm95db3012020-10-26 11:35:23 +0100759#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */
Jaeden Amero9366feb2018-05-29 18:55:17 +0100760
761#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100762static int mbedtls_aes_xts_decode_keys(const unsigned char *key,
763 unsigned int keybits,
764 const unsigned char **key1,
765 unsigned int *key1bits,
766 const unsigned char **key2,
767 unsigned int *key2bits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100768{
769 const unsigned int half_keybits = keybits / 2;
770 const unsigned int half_keybytes = half_keybits / 8;
771
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100772 switch (keybits) {
Jaeden Amero9366feb2018-05-29 18:55:17 +0100773 case 256: break;
774 case 512: break;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100775 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100776 }
777
778 *key1bits = half_keybits;
779 *key2bits = half_keybits;
780 *key1 = &key[0];
781 *key2 = &key[half_keybytes];
782
783 return 0;
784}
785
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100786int mbedtls_aes_xts_setkey_enc(mbedtls_aes_xts_context *ctx,
787 const unsigned char *key,
788 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100789{
Janos Follath24eed8d2019-11-22 13:21:35 +0000790 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100791 const unsigned char *key1, *key2;
792 unsigned int key1bits, key2bits;
793
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100794 AES_VALIDATE_RET(ctx != NULL);
795 AES_VALIDATE_RET(key != NULL);
Manuel Pégourié-Gonnard68e3dff2018-12-12 12:48:04 +0100796
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100797 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
798 &key2, &key2bits);
799 if (ret != 0) {
800 return ret;
801 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100802
803 /* Set the tweak key. Always set tweak key for the encryption mode. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100804 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
805 if (ret != 0) {
806 return ret;
807 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100808
809 /* Set crypt key for encryption. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100810 return mbedtls_aes_setkey_enc(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100811}
812
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100813int mbedtls_aes_xts_setkey_dec(mbedtls_aes_xts_context *ctx,
814 const unsigned char *key,
815 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100816{
Janos Follath24eed8d2019-11-22 13:21:35 +0000817 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100818 const unsigned char *key1, *key2;
819 unsigned int key1bits, key2bits;
820
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100821 AES_VALIDATE_RET(ctx != NULL);
822 AES_VALIDATE_RET(key != NULL);
Manuel Pégourié-Gonnard68e3dff2018-12-12 12:48:04 +0100823
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100824 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
825 &key2, &key2bits);
826 if (ret != 0) {
827 return ret;
828 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100829
830 /* Set the tweak key. Always set tweak key for encryption. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100831 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
832 if (ret != 0) {
833 return ret;
834 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100835
836 /* Set crypt key for decryption. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100837 return mbedtls_aes_setkey_dec(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100838}
839#endif /* MBEDTLS_CIPHER_MODE_XTS */
840
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100841#define AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Joe Subbiani6b897c92021-07-08 14:59:52 +0100842 do \
843 { \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100844 (X0) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y0)) ^ \
845 AES_FT1(MBEDTLS_BYTE_1(Y1)) ^ \
846 AES_FT2(MBEDTLS_BYTE_2(Y2)) ^ \
847 AES_FT3(MBEDTLS_BYTE_3(Y3)); \
Joe Subbiani6b897c92021-07-08 14:59:52 +0100848 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100849 (X1) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y1)) ^ \
850 AES_FT1(MBEDTLS_BYTE_1(Y2)) ^ \
851 AES_FT2(MBEDTLS_BYTE_2(Y3)) ^ \
852 AES_FT3(MBEDTLS_BYTE_3(Y0)); \
Joe Subbiani6b897c92021-07-08 14:59:52 +0100853 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100854 (X2) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y2)) ^ \
855 AES_FT1(MBEDTLS_BYTE_1(Y3)) ^ \
856 AES_FT2(MBEDTLS_BYTE_2(Y0)) ^ \
857 AES_FT3(MBEDTLS_BYTE_3(Y1)); \
Joe Subbiani6b897c92021-07-08 14:59:52 +0100858 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100859 (X3) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y3)) ^ \
860 AES_FT1(MBEDTLS_BYTE_1(Y0)) ^ \
861 AES_FT2(MBEDTLS_BYTE_2(Y1)) ^ \
862 AES_FT3(MBEDTLS_BYTE_3(Y2)); \
863 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000864
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100865#define AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100866 do \
867 { \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100868 (X0) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y0)) ^ \
869 AES_RT1(MBEDTLS_BYTE_1(Y3)) ^ \
870 AES_RT2(MBEDTLS_BYTE_2(Y2)) ^ \
871 AES_RT3(MBEDTLS_BYTE_3(Y1)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100872 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100873 (X1) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y1)) ^ \
874 AES_RT1(MBEDTLS_BYTE_1(Y0)) ^ \
875 AES_RT2(MBEDTLS_BYTE_2(Y3)) ^ \
876 AES_RT3(MBEDTLS_BYTE_3(Y2)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100877 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100878 (X2) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y2)) ^ \
879 AES_RT1(MBEDTLS_BYTE_1(Y1)) ^ \
880 AES_RT2(MBEDTLS_BYTE_2(Y0)) ^ \
881 AES_RT3(MBEDTLS_BYTE_3(Y3)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100882 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100883 (X3) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y3)) ^ \
884 AES_RT1(MBEDTLS_BYTE_1(Y2)) ^ \
885 AES_RT2(MBEDTLS_BYTE_2(Y1)) ^ \
886 AES_RT3(MBEDTLS_BYTE_3(Y0)); \
887 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000888
889/*
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200890 * AES-ECB block encryption
891 */
892#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100893int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx,
894 const unsigned char input[16],
895 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200896{
897 int i;
Gilles Peskine5197c662020-08-26 17:03:24 +0200898 uint32_t *RK = ctx->rk;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100899 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200900 uint32_t X[4];
901 uint32_t Y[4];
902 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200903
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100904 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
905 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
906 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
907 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200908
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100909 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
910 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]);
911 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 +0200912 }
913
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100914 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 +0200915
Gilles Peskine5197c662020-08-26 17:03:24 +0200916 t.X[0] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100917 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
918 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
919 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
920 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200921
Gilles Peskine5197c662020-08-26 17:03:24 +0200922 t.X[1] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100923 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
924 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
925 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
926 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200927
Gilles Peskine5197c662020-08-26 17:03:24 +0200928 t.X[2] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100929 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
930 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
931 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
932 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200933
Gilles Peskine5197c662020-08-26 17:03:24 +0200934 t.X[3] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100935 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
936 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
937 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
938 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200939
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100940 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
941 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
942 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
943 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +0000944
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100945 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500946
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100947 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200948}
949#endif /* !MBEDTLS_AES_ENCRYPT_ALT */
950
Gilles Peskine8db3efb2018-02-21 19:16:20 +0100951#if !defined(MBEDTLS_DEPRECATED_REMOVED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100952void mbedtls_aes_encrypt(mbedtls_aes_context *ctx,
953 const unsigned char input[16],
954 unsigned char output[16])
Hanno Beckerbedc2052017-06-26 12:46:56 +0100955{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100956 MBEDTLS_IGNORE_RETURN(mbedtls_internal_aes_encrypt(ctx, input, output));
Hanno Beckerbedc2052017-06-26 12:46:56 +0100957}
Gilles Peskine8db3efb2018-02-21 19:16:20 +0100958#endif /* !MBEDTLS_DEPRECATED_REMOVED */
Hanno Beckerbedc2052017-06-26 12:46:56 +0100959
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200960/*
961 * AES-ECB block decryption
962 */
963#if !defined(MBEDTLS_AES_DECRYPT_ALT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100964int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
965 const unsigned char input[16],
966 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200967{
968 int i;
Gilles Peskine5197c662020-08-26 17:03:24 +0200969 uint32_t *RK = ctx->rk;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100970 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200971 uint32_t X[4];
972 uint32_t Y[4];
973 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200974
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100975 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
976 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
977 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
978 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200979
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100980 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
981 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]);
982 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 +0200983 }
984
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100985 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 +0200986
Gilles Peskine5197c662020-08-26 17:03:24 +0200987 t.X[0] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100988 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
989 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
990 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
991 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200992
Gilles Peskine5197c662020-08-26 17:03:24 +0200993 t.X[1] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100994 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
995 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
996 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
997 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200998
Gilles Peskine5197c662020-08-26 17:03:24 +0200999 t.X[2] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001000 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
1001 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
1002 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
1003 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001004
Gilles Peskine5197c662020-08-26 17:03:24 +02001005 t.X[3] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001006 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
1007 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
1008 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
1009 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001010
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001011 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
1012 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
1013 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
1014 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +00001015
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001016 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -05001017
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001018 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001019}
1020#endif /* !MBEDTLS_AES_DECRYPT_ALT */
1021
Gilles Peskine8db3efb2018-02-21 19:16:20 +01001022#if !defined(MBEDTLS_DEPRECATED_REMOVED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001023void mbedtls_aes_decrypt(mbedtls_aes_context *ctx,
1024 const unsigned char input[16],
1025 unsigned char output[16])
Hanno Beckerbedc2052017-06-26 12:46:56 +01001026{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001027 MBEDTLS_IGNORE_RETURN(mbedtls_internal_aes_decrypt(ctx, input, output));
Hanno Beckerbedc2052017-06-26 12:46:56 +01001028}
Gilles Peskine8db3efb2018-02-21 19:16:20 +01001029#endif /* !MBEDTLS_DEPRECATED_REMOVED */
Hanno Beckerbedc2052017-06-26 12:46:56 +01001030
Gilles Peskineb71d4022023-03-16 17:14:59 +01001031#if defined(MAY_NEED_TO_ALIGN)
Gilles Peskine6978e732023-03-16 13:08:42 +01001032/* VIA Padlock and our intrinsics-based implementation of AESNI require
1033 * the round keys to be aligned on a 16-byte boundary. We take care of this
1034 * before creating them, but the AES context may have moved (this can happen
1035 * if the library is called from a language with managed memory), and in later
1036 * calls it might have a different alignment with respect to 16-byte memory.
1037 * So we may need to realign.
1038 * NOTE: In the LTS branch, the context contains a pointer to within itself,
1039 * so if it has been moved, things will probably go pear-shaped. We keep this
1040 * code for compatibility with the development branch, in case of future changes.
1041 */
1042static void aes_maybe_realign(mbedtls_aes_context *ctx)
1043{
Tom Cosgrove2c942a32023-03-19 14:04:04 +00001044 unsigned current_offset = (unsigned) (ctx->rk - ctx->buf);
Gilles Peskineb71d4022023-03-16 17:14:59 +01001045 unsigned new_offset = mbedtls_aes_rk_offset(ctx->buf);
1046 if (new_offset != current_offset) {
Gilles Peskine6978e732023-03-16 13:08:42 +01001047 memmove(ctx->buf + new_offset, // new address
1048 ctx->buf + current_offset, // current address
1049 (ctx->nr + 1) * 16); // number of round keys * bytes per rk
1050 ctx->rk = ctx->buf + new_offset;
1051 }
1052}
1053#endif
1054
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001055/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001056 * AES-ECB block encryption/decryption
1057 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001058int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
1059 int mode,
1060 const unsigned char input[16],
1061 unsigned char output[16])
Paul Bakker5121ce52009-01-03 21:22:43 +00001062{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001063 AES_VALIDATE_RET(ctx != NULL);
1064 AES_VALIDATE_RET(input != NULL);
1065 AES_VALIDATE_RET(output != NULL);
1066 AES_VALIDATE_RET(mode == MBEDTLS_AES_ENCRYPT ||
1067 mode == MBEDTLS_AES_DECRYPT);
Manuel Pégourié-Gonnard1aca2602018-12-12 12:56:55 +01001068
Gilles Peskineb71d4022023-03-16 17:14:59 +01001069#if defined(MAY_NEED_TO_ALIGN)
1070 aes_maybe_realign(ctx);
1071#endif
1072
Gilles Peskine5511a342023-03-10 22:29:32 +01001073#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001074 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1075 return mbedtls_aesni_crypt_ecb(ctx, mode, input, output);
1076 }
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +01001077#endif
1078
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001079#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001080 if (aes_padlock_ace) {
Gilles Peskine6978e732023-03-16 13:08:42 +01001081 return mbedtls_padlock_xcryptecb(ctx, mode, input, output);
Paul Bakker5121ce52009-01-03 21:22:43 +00001082 }
1083#endif
1084
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001085 if (mode == MBEDTLS_AES_ENCRYPT) {
1086 return mbedtls_internal_aes_encrypt(ctx, input, output);
1087 } else {
1088 return mbedtls_internal_aes_decrypt(ctx, input, output);
1089 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001090}
1091
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001092#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001093/*
1094 * AES-CBC buffer encryption/decryption
1095 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001096int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
1097 int mode,
1098 size_t length,
1099 unsigned char iv[16],
1100 const unsigned char *input,
1101 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001102{
1103 int i;
Gilles Peskine377a3102021-07-07 21:08:28 +02001104 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +00001105 unsigned char temp[16];
1106
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001107 AES_VALIDATE_RET(ctx != NULL);
1108 AES_VALIDATE_RET(mode == MBEDTLS_AES_ENCRYPT ||
1109 mode == MBEDTLS_AES_DECRYPT);
1110 AES_VALIDATE_RET(iv != NULL);
1111 AES_VALIDATE_RET(input != NULL);
1112 AES_VALIDATE_RET(output != NULL);
Manuel Pégourié-Gonnard3178d1a2018-12-12 13:05:00 +01001113
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001114 if (length % 16) {
1115 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
1116 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001117
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001118#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001119 if (aes_padlock_ace) {
1120 if (mbedtls_padlock_xcryptcbc(ctx, mode, length, iv, input, output) == 0) {
1121 return 0;
1122 }
Paul Bakker9af723c2014-05-01 13:03:14 +02001123
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001124 // If padlock data misaligned, we just fall back to
1125 // unaccelerated mode
1126 //
Paul Bakker5121ce52009-01-03 21:22:43 +00001127 }
1128#endif
1129
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001130 if (mode == MBEDTLS_AES_DECRYPT) {
1131 while (length > 0) {
1132 memcpy(temp, input, 16);
1133 ret = mbedtls_aes_crypt_ecb(ctx, mode, input, output);
1134 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +02001135 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001136 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001137
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001138 for (i = 0; i < 16; i++) {
1139 output[i] = (unsigned char) (output[i] ^ iv[i]);
1140 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001141
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001142 memcpy(iv, temp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001143
1144 input += 16;
1145 output += 16;
1146 length -= 16;
1147 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001148 } else {
1149 while (length > 0) {
1150 for (i = 0; i < 16; i++) {
1151 output[i] = (unsigned char) (input[i] ^ iv[i]);
1152 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001153
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001154 ret = mbedtls_aes_crypt_ecb(ctx, mode, output, output);
1155 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +02001156 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001157 }
1158 memcpy(iv, output, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001159
1160 input += 16;
1161 output += 16;
1162 length -= 16;
1163 }
1164 }
Gilles Peskine377a3102021-07-07 21:08:28 +02001165 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001166
Gilles Peskine377a3102021-07-07 21:08:28 +02001167exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001168 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001169}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001170#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001171
Aorimn5f778012016-06-09 23:22:58 +02001172#if defined(MBEDTLS_CIPHER_MODE_XTS)
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001173
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001174typedef unsigned char mbedtls_be128[16];
1175
1176/*
1177 * GF(2^128) multiplication function
1178 *
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001179 * This function multiplies a field element by x in the polynomial field
1180 * representation. It uses 64-bit word operations to gain speed but compensates
Shaun Case0e7791f2021-12-20 21:14:10 -08001181 * for machine endianness and hence works correctly on both big and little
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001182 * endian machines.
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001183 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001184static void mbedtls_gf128mul_x_ble(unsigned char r[16],
1185 const unsigned char x[16])
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001186{
1187 uint64_t a, b, ra, rb;
1188
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001189 a = MBEDTLS_GET_UINT64_LE(x, 0);
1190 b = MBEDTLS_GET_UINT64_LE(x, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001191
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001192 ra = (a << 1) ^ 0x0087 >> (8 - ((b >> 63) << 3));
1193 rb = (a >> 63) | (b << 1);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001194
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001195 MBEDTLS_PUT_UINT64_LE(ra, r, 0);
1196 MBEDTLS_PUT_UINT64_LE(rb, r, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001197}
1198
Aorimn5f778012016-06-09 23:22:58 +02001199/*
1200 * AES-XTS buffer encryption/decryption
1201 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001202int mbedtls_aes_crypt_xts(mbedtls_aes_xts_context *ctx,
1203 int mode,
1204 size_t length,
1205 const unsigned char data_unit[16],
1206 const unsigned char *input,
1207 unsigned char *output)
Aorimn5f778012016-06-09 23:22:58 +02001208{
Janos Follath24eed8d2019-11-22 13:21:35 +00001209 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amerod82cd862018-04-28 15:02:45 +01001210 size_t blocks = length / 16;
1211 size_t leftover = length % 16;
1212 unsigned char tweak[16];
1213 unsigned char prev_tweak[16];
1214 unsigned char tmp[16];
Aorimn5f778012016-06-09 23:22:58 +02001215
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001216 AES_VALIDATE_RET(ctx != NULL);
1217 AES_VALIDATE_RET(mode == MBEDTLS_AES_ENCRYPT ||
1218 mode == MBEDTLS_AES_DECRYPT);
1219 AES_VALIDATE_RET(data_unit != NULL);
1220 AES_VALIDATE_RET(input != NULL);
1221 AES_VALIDATE_RET(output != NULL);
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01001222
Jaeden Amero8381fcb2018-10-11 12:06:15 +01001223 /* Data units must be at least 16 bytes long. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001224 if (length < 16) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001225 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001226 }
Aorimn5f778012016-06-09 23:22:58 +02001227
Jaeden Ameroa74faba2018-10-11 12:07:43 +01001228 /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001229 if (length > (1 << 20) * 16) {
Jaeden Amero0a8b0202018-05-30 15:36:06 +01001230 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001231 }
Aorimn5f778012016-06-09 23:22:58 +02001232
Jaeden Amerod82cd862018-04-28 15:02:45 +01001233 /* Compute the tweak. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001234 ret = mbedtls_aes_crypt_ecb(&ctx->tweak, MBEDTLS_AES_ENCRYPT,
1235 data_unit, tweak);
1236 if (ret != 0) {
1237 return ret;
1238 }
Aorimn5f778012016-06-09 23:22:58 +02001239
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001240 while (blocks--) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001241 size_t i;
1242
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001243 if (leftover && (mode == MBEDTLS_AES_DECRYPT) && blocks == 0) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001244 /* We are on the last block in a decrypt operation that has
1245 * leftover bytes, so we need to use the next tweak for this block,
Tom Cosgrove49f99bc2022-12-04 16:44:21 +00001246 * and this tweak for the leftover bytes. Save the current tweak for
Jaeden Amerod82cd862018-04-28 15:02:45 +01001247 * the leftovers and then update the current tweak for use on this,
1248 * the last full block. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001249 memcpy(prev_tweak, tweak, sizeof(tweak));
1250 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001251 }
1252
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001253 for (i = 0; i < 16; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001254 tmp[i] = input[i] ^ tweak[i];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001255 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001256
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001257 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1258 if (ret != 0) {
1259 return ret;
1260 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001261
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001262 for (i = 0; i < 16; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001263 output[i] = tmp[i] ^ tweak[i];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001264 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001265
1266 /* Update the tweak for the next block. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001267 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001268
1269 output += 16;
1270 input += 16;
Aorimn5f778012016-06-09 23:22:58 +02001271 }
1272
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001273 if (leftover) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001274 /* If we are on the leftover bytes in a decrypt operation, we need to
1275 * use the previous tweak for these bytes (as saved in prev_tweak). */
1276 unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
Aorimn5f778012016-06-09 23:22:58 +02001277
Jaeden Amerod82cd862018-04-28 15:02:45 +01001278 /* We are now on the final part of the data unit, which doesn't divide
1279 * evenly by 16. It's time for ciphertext stealing. */
1280 size_t i;
1281 unsigned char *prev_output = output - 16;
Aorimn5f778012016-06-09 23:22:58 +02001282
Jaeden Amerod82cd862018-04-28 15:02:45 +01001283 /* Copy ciphertext bytes from the previous block to our output for each
Shaun Case0e7791f2021-12-20 21:14:10 -08001284 * byte of ciphertext we won't steal. At the same time, copy the
Jaeden Amerod82cd862018-04-28 15:02:45 +01001285 * remainder of the input for this final round (since the loop bounds
1286 * are the same). */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001287 for (i = 0; i < leftover; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001288 output[i] = prev_output[i];
1289 tmp[i] = input[i] ^ t[i];
Aorimn5f778012016-06-09 23:22:58 +02001290 }
Aorimn5f778012016-06-09 23:22:58 +02001291
Jaeden Amerod82cd862018-04-28 15:02:45 +01001292 /* Copy ciphertext bytes from the previous block for input in this
1293 * round. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001294 for (; i < 16; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001295 tmp[i] = prev_output[i] ^ t[i];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001296 }
Aorimn5f778012016-06-09 23:22:58 +02001297
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001298 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1299 if (ret != 0) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001300 return ret;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001301 }
Aorimn5f778012016-06-09 23:22:58 +02001302
Jaeden Amerod82cd862018-04-28 15:02:45 +01001303 /* Write the result back to the previous block, overriding the previous
1304 * output we copied. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001305 for (i = 0; i < 16; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001306 prev_output[i] = tmp[i] ^ t[i];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001307 }
Aorimn5f778012016-06-09 23:22:58 +02001308 }
1309
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001310 return 0;
Aorimn5f778012016-06-09 23:22:58 +02001311}
1312#endif /* MBEDTLS_CIPHER_MODE_XTS */
1313
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001314#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001315/*
1316 * AES-CFB128 buffer encryption/decryption
1317 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001318int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx,
1319 int mode,
1320 size_t length,
1321 size_t *iv_off,
1322 unsigned char iv[16],
1323 const unsigned char *input,
1324 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001325{
Paul Bakker27fdf462011-06-09 13:55:13 +00001326 int c;
Gilles Peskine377a3102021-07-07 21:08:28 +02001327 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001328 size_t n;
1329
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001330 AES_VALIDATE_RET(ctx != NULL);
1331 AES_VALIDATE_RET(mode == MBEDTLS_AES_ENCRYPT ||
1332 mode == MBEDTLS_AES_DECRYPT);
1333 AES_VALIDATE_RET(iv_off != NULL);
1334 AES_VALIDATE_RET(iv != NULL);
1335 AES_VALIDATE_RET(input != NULL);
1336 AES_VALIDATE_RET(output != NULL);
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001337
1338 n = *iv_off;
Paul Bakker5121ce52009-01-03 21:22:43 +00001339
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001340 if (n > 15) {
1341 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1342 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001343
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001344 if (mode == MBEDTLS_AES_DECRYPT) {
1345 while (length--) {
1346 if (n == 0) {
1347 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1348 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +02001349 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001350 }
Gilles Peskine377a3102021-07-07 21:08:28 +02001351 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001352
1353 c = *input++;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001354 *output++ = (unsigned char) (c ^ iv[n]);
Paul Bakker5121ce52009-01-03 21:22:43 +00001355 iv[n] = (unsigned char) c;
1356
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001357 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001358 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001359 } else {
1360 while (length--) {
1361 if (n == 0) {
1362 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1363 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +02001364 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001365 }
Gilles Peskine377a3102021-07-07 21:08:28 +02001366 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001367
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001368 iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++);
Paul Bakker5121ce52009-01-03 21:22:43 +00001369
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001370 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001371 }
1372 }
1373
1374 *iv_off = n;
Gilles Peskine377a3102021-07-07 21:08:28 +02001375 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001376
Gilles Peskine377a3102021-07-07 21:08:28 +02001377exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001378 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001379}
Paul Bakker556efba2014-01-24 15:38:12 +01001380
1381/*
1382 * AES-CFB8 buffer encryption/decryption
1383 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001384int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx,
1385 int mode,
1386 size_t length,
1387 unsigned char iv[16],
1388 const unsigned char *input,
1389 unsigned char *output)
Paul Bakker556efba2014-01-24 15:38:12 +01001390{
Gilles Peskine377a3102021-07-07 21:08:28 +02001391 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker556efba2014-01-24 15:38:12 +01001392 unsigned char c;
1393 unsigned char ov[17];
1394
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001395 AES_VALIDATE_RET(ctx != NULL);
1396 AES_VALIDATE_RET(mode == MBEDTLS_AES_ENCRYPT ||
1397 mode == MBEDTLS_AES_DECRYPT);
1398 AES_VALIDATE_RET(iv != NULL);
1399 AES_VALIDATE_RET(input != NULL);
1400 AES_VALIDATE_RET(output != NULL);
1401 while (length--) {
1402 memcpy(ov, iv, 16);
1403 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1404 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +02001405 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001406 }
Paul Bakker556efba2014-01-24 15:38:12 +01001407
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001408 if (mode == MBEDTLS_AES_DECRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001409 ov[16] = *input;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001410 }
Paul Bakker556efba2014-01-24 15:38:12 +01001411
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001412 c = *output++ = (unsigned char) (iv[0] ^ *input++);
Paul Bakker556efba2014-01-24 15:38:12 +01001413
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001414 if (mode == MBEDTLS_AES_ENCRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001415 ov[16] = c;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001416 }
Paul Bakker556efba2014-01-24 15:38:12 +01001417
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001418 memcpy(iv, ov + 1, 16);
Paul Bakker556efba2014-01-24 15:38:12 +01001419 }
Gilles Peskine377a3102021-07-07 21:08:28 +02001420 ret = 0;
Paul Bakker556efba2014-01-24 15:38:12 +01001421
Gilles Peskine377a3102021-07-07 21:08:28 +02001422exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001423 return ret;
Paul Bakker556efba2014-01-24 15:38:12 +01001424}
Simon Butcher76a5b222018-04-22 22:57:27 +01001425#endif /* MBEDTLS_CIPHER_MODE_CFB */
1426
1427#if defined(MBEDTLS_CIPHER_MODE_OFB)
1428/*
1429 * AES-OFB (Output Feedback Mode) buffer encryption/decryption
1430 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001431int mbedtls_aes_crypt_ofb(mbedtls_aes_context *ctx,
1432 size_t length,
1433 size_t *iv_off,
1434 unsigned char iv[16],
1435 const unsigned char *input,
1436 unsigned char *output)
Simon Butcher76a5b222018-04-22 22:57:27 +01001437{
Simon Butcherad4e4932018-04-29 00:43:47 +01001438 int ret = 0;
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001439 size_t n;
1440
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001441 AES_VALIDATE_RET(ctx != NULL);
1442 AES_VALIDATE_RET(iv_off != NULL);
1443 AES_VALIDATE_RET(iv != NULL);
1444 AES_VALIDATE_RET(input != NULL);
1445 AES_VALIDATE_RET(output != NULL);
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001446
1447 n = *iv_off;
Simon Butcher76a5b222018-04-22 22:57:27 +01001448
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001449 if (n > 15) {
1450 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1451 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001452
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001453 while (length--) {
1454 if (n == 0) {
1455 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1456 if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001457 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001458 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001459 }
Simon Butcher76a5b222018-04-22 22:57:27 +01001460 *output++ = *input++ ^ iv[n];
1461
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001462 n = (n + 1) & 0x0F;
Simon Butcher76a5b222018-04-22 22:57:27 +01001463 }
1464
1465 *iv_off = n;
1466
Simon Butcherad4e4932018-04-29 00:43:47 +01001467exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001468 return ret;
Simon Butcher76a5b222018-04-22 22:57:27 +01001469}
1470#endif /* MBEDTLS_CIPHER_MODE_OFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001471
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001472#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001473/*
1474 * AES-CTR buffer encryption/decryption
1475 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001476int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
1477 size_t length,
1478 size_t *nc_off,
1479 unsigned char nonce_counter[16],
1480 unsigned char stream_block[16],
1481 const unsigned char *input,
1482 unsigned char *output)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001483{
Paul Bakker369e14b2012-04-18 14:16:09 +00001484 int c, i;
Gilles Peskine377a3102021-07-07 21:08:28 +02001485 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001486 size_t n;
1487
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001488 AES_VALIDATE_RET(ctx != NULL);
1489 AES_VALIDATE_RET(nc_off != NULL);
1490 AES_VALIDATE_RET(nonce_counter != NULL);
1491 AES_VALIDATE_RET(stream_block != NULL);
1492 AES_VALIDATE_RET(input != NULL);
1493 AES_VALIDATE_RET(output != NULL);
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001494
1495 n = *nc_off;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001496
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001497 if (n > 0x0F) {
1498 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1499 }
Mohammad Azim Khan3f7f8172017-11-23 17:49:05 +00001500
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001501 while (length--) {
1502 if (n == 0) {
1503 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block);
1504 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +02001505 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001506 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001507
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001508 for (i = 16; i > 0; i--) {
1509 if (++nonce_counter[i - 1] != 0) {
Paul Bakker369e14b2012-04-18 14:16:09 +00001510 break;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001511 }
1512 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001513 }
1514 c = *input++;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001515 *output++ = (unsigned char) (c ^ stream_block[n]);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001516
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001517 n = (n + 1) & 0x0F;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001518 }
1519
1520 *nc_off = n;
Gilles Peskine377a3102021-07-07 21:08:28 +02001521 ret = 0;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001522
Gilles Peskine377a3102021-07-07 21:08:28 +02001523exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001524 return ret;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001525}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001526#endif /* MBEDTLS_CIPHER_MODE_CTR */
Manuel Pégourié-Gonnard1ec220b2014-03-10 11:20:17 +01001527
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001528#endif /* !MBEDTLS_AES_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001529
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001530#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001531/*
1532 * AES test vectors from:
1533 *
1534 * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
1535 */
1536static const unsigned char aes_test_ecb_dec[3][16] =
1537{
1538 { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
1539 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
1540 { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
1541 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
1542 { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
1543 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
1544};
1545
1546static const unsigned char aes_test_ecb_enc[3][16] =
1547{
1548 { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
1549 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
1550 { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
1551 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
1552 { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
1553 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
1554};
1555
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001556#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001557static const unsigned char aes_test_cbc_dec[3][16] =
1558{
1559 { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
1560 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
1561 { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
1562 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
1563 { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
1564 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
1565};
1566
1567static const unsigned char aes_test_cbc_enc[3][16] =
1568{
1569 { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
1570 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
1571 { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
1572 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
1573 { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
1574 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
1575};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001576#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001577
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001578#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001579/*
1580 * AES-CFB128 test vectors from:
1581 *
1582 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
1583 */
1584static const unsigned char aes_test_cfb128_key[3][32] =
1585{
1586 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1587 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
1588 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1589 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1590 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1591 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1592 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1593 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1594 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
1595};
1596
1597static const unsigned char aes_test_cfb128_iv[16] =
1598{
1599 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1600 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1601};
1602
1603static const unsigned char aes_test_cfb128_pt[64] =
1604{
1605 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1606 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1607 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1608 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1609 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1610 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1611 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1612 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1613};
1614
1615static const unsigned char aes_test_cfb128_ct[3][64] =
1616{
1617 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1618 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1619 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F,
1620 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B,
1621 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40,
1622 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF,
1623 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E,
1624 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 },
1625 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1626 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1627 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21,
1628 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A,
1629 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1,
1630 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9,
1631 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0,
1632 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF },
1633 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1634 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1635 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8,
1636 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B,
1637 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92,
1638 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9,
1639 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8,
1640 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 }
1641};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001642#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001643
Simon Butcherad4e4932018-04-29 00:43:47 +01001644#if defined(MBEDTLS_CIPHER_MODE_OFB)
1645/*
1646 * AES-OFB test vectors from:
1647 *
Simon Butcher5db13622018-06-04 22:11:25 +01001648 * https://csrc.nist.gov/publications/detail/sp/800-38a/final
Simon Butcherad4e4932018-04-29 00:43:47 +01001649 */
1650static const unsigned char aes_test_ofb_key[3][32] =
1651{
1652 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1653 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
1654 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1655 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1656 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1657 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1658 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1659 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1660 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
1661};
1662
1663static const unsigned char aes_test_ofb_iv[16] =
1664{
1665 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1666 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1667};
1668
1669static const unsigned char aes_test_ofb_pt[64] =
1670{
1671 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1672 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1673 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1674 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1675 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1676 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1677 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1678 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1679};
1680
1681static const unsigned char aes_test_ofb_ct[3][64] =
1682{
1683 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1684 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1685 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
1686 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
1687 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
1688 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
1689 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
1690 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e },
1691 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1692 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1693 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
1694 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
1695 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f,
1696 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
1697 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e,
1698 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a },
1699 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1700 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1701 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
1702 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
1703 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed,
1704 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
1705 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8,
1706 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 }
1707};
1708#endif /* MBEDTLS_CIPHER_MODE_OFB */
1709
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001710#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001711/*
1712 * AES-CTR test vectors from:
1713 *
1714 * http://www.faqs.org/rfcs/rfc3686.html
1715 */
1716
1717static const unsigned char aes_test_ctr_key[3][16] =
1718{
1719 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
1720 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
1721 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
1722 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
1723 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
1724 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
1725};
1726
1727static const unsigned char aes_test_ctr_nonce_counter[3][16] =
1728{
1729 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
1730 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
1731 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
1732 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
1733 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
1734 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
1735};
1736
1737static const unsigned char aes_test_ctr_pt[3][48] =
1738{
1739 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
1740 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
1741
1742 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1743 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1744 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1745 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
1746
1747 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1748 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1749 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1750 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
1751 0x20, 0x21, 0x22, 0x23 }
1752};
1753
1754static const unsigned char aes_test_ctr_ct[3][48] =
1755{
1756 { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79,
1757 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 },
1758 { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9,
1759 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88,
1760 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8,
1761 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 },
1762 { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
1763 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
1764 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
1765 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
1766 0x25, 0xB2, 0x07, 0x2F }
1767};
1768
1769static const int aes_test_ctr_len[3] =
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001770{ 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001771#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00001772
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001773#if defined(MBEDTLS_CIPHER_MODE_XTS)
1774/*
1775 * AES-XTS test vectors from:
1776 *
1777 * IEEE P1619/D16 Annex B
1778 * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf
1779 * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf)
1780 */
1781static const unsigned char aes_test_xts_key[][32] =
1782{
1783 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1784 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1785 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1786 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1787 { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1788 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1789 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1790 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1791 { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
1792 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
1793 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1794 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1795};
1796
1797static const unsigned char aes_test_xts_pt32[][32] =
1798{
1799 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1800 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1801 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1802 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1803 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1804 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1805 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1806 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1807 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1808 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1809 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1810 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1811};
1812
1813static const unsigned char aes_test_xts_ct32[][32] =
1814{
1815 { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec,
1816 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92,
1817 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85,
1818 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e },
1819 { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e,
1820 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b,
1821 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4,
1822 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 },
1823 { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a,
1824 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2,
1825 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53,
1826 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 },
1827};
1828
1829static const unsigned char aes_test_xts_data_unit[][16] =
1830{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001831 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1832 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1833 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1834 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1835 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1836 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001837};
1838
1839#endif /* MBEDTLS_CIPHER_MODE_XTS */
1840
Paul Bakker5121ce52009-01-03 21:22:43 +00001841/*
1842 * Checkup routine
1843 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001844int mbedtls_aes_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +00001845{
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001846 int ret = 0, i, j, u, mode;
1847 unsigned int keybits;
Paul Bakker5121ce52009-01-03 21:22:43 +00001848 unsigned char key[32];
1849 unsigned char buf[64];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001850 const unsigned char *aes_tests;
Andrzej Kurek8ffd8a62022-09-27 07:54:16 -04001851#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1852 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001853 unsigned char iv[16];
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03001854#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001855#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +02001856 unsigned char prv[16];
1857#endif
Simon Butcher2ff0e522018-06-14 09:57:07 +01001858#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1859 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker27fdf462011-06-09 13:55:13 +00001860 size_t offset;
Paul Bakkere91d01e2011-04-19 15:55:50 +00001861#endif
Simon Butcher66a89032018-06-15 18:20:29 +01001862#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS)
Paul Bakkere91d01e2011-04-19 15:55:50 +00001863 int len;
Simon Butcher66a89032018-06-15 18:20:29 +01001864#endif
1865#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001866 unsigned char nonce_counter[16];
1867 unsigned char stream_block[16];
1868#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001869 mbedtls_aes_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001870
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001871 memset(key, 0, 32);
1872 mbedtls_aes_init(&ctx);
Paul Bakker5121ce52009-01-03 21:22:43 +00001873
Gilles Peskine2c8ad942023-03-10 22:35:24 +01001874 if (verbose != 0) {
1875#if defined(MBEDTLS_AES_ALT)
1876 mbedtls_printf(" AES note: alternative implementation.\n");
1877#else /* MBEDTLS_AES_ALT */
1878#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
1879 if (mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE)) {
1880 mbedtls_printf(" AES note: using VIA Padlock.\n");
1881 } else
1882#endif
1883#if defined(MBEDTLS_AESNI_HAVE_CODE)
1884 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
Tom Cosgrove20458c02023-03-18 14:48:49 +00001885 mbedtls_printf(" AES note: using AESNI via ");
1886#if MBEDTLS_AESNI_HAVE_CODE == 1
1887 mbedtls_printf("assembly");
1888#elif MBEDTLS_AESNI_HAVE_CODE == 2
1889 mbedtls_printf("intrinsics");
1890#else
1891 mbedtls_printf("(unknown)");
1892#endif
1893 mbedtls_printf(".\n");
Gilles Peskine2c8ad942023-03-10 22:35:24 +01001894 } else
1895#endif
Gilles Peskine2c8ad942023-03-10 22:35:24 +01001896 mbedtls_printf(" AES note: built-in implementation.\n");
1897#endif /* MBEDTLS_AES_ALT */
1898 }
1899
Paul Bakker5121ce52009-01-03 21:22:43 +00001900 /*
1901 * ECB mode
1902 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001903 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +00001904 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001905 keybits = 128 + u * 64;
1906 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001907
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001908 if (verbose != 0) {
1909 mbedtls_printf(" AES-ECB-%3u (%s): ", keybits,
1910 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00001911 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001912
1913 memset(buf, 0, 16);
1914
1915 if (mode == MBEDTLS_AES_DECRYPT) {
1916 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1917 aes_tests = aes_test_ecb_dec[u];
1918 } else {
1919 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001920 aes_tests = aes_test_ecb_enc[u];
1921 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001922
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01001923 /*
1924 * AES-192 is an optional feature that may be unavailable when
1925 * there is an alternative underlying implementation i.e. when
1926 * MBEDTLS_AES_ALT is defined.
1927 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001928 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1929 mbedtls_printf("skipped\n");
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001930 continue;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001931 } else if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001932 goto exit;
1933 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001934
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001935 for (j = 0; j < 10000; j++) {
1936 ret = mbedtls_aes_crypt_ecb(&ctx, mode, buf, buf);
1937 if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001938 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001939 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001940 }
1941
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001942 if (memcmp(buf, aes_tests, 16) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001943 ret = 1;
1944 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001945 }
1946
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001947 if (verbose != 0) {
1948 mbedtls_printf("passed\n");
1949 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001950 }
1951
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001952 if (verbose != 0) {
1953 mbedtls_printf("\n");
1954 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001955
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001956#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001957 /*
1958 * CBC mode
1959 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001960 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +00001961 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001962 keybits = 128 + u * 64;
1963 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001964
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001965 if (verbose != 0) {
1966 mbedtls_printf(" AES-CBC-%3u (%s): ", keybits,
1967 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00001968 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001969
1970 memset(iv, 0, 16);
1971 memset(prv, 0, 16);
1972 memset(buf, 0, 16);
1973
1974 if (mode == MBEDTLS_AES_DECRYPT) {
1975 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1976 aes_tests = aes_test_cbc_dec[u];
1977 } else {
1978 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001979 aes_tests = aes_test_cbc_enc[u];
1980 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001981
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01001982 /*
1983 * AES-192 is an optional feature that may be unavailable when
1984 * there is an alternative underlying implementation i.e. when
1985 * MBEDTLS_AES_ALT is defined.
1986 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001987 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1988 mbedtls_printf("skipped\n");
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001989 continue;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001990 } else if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001991 goto exit;
1992 }
1993
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001994 for (j = 0; j < 10000; j++) {
1995 if (mode == MBEDTLS_AES_ENCRYPT) {
Paul Bakker5121ce52009-01-03 21:22:43 +00001996 unsigned char tmp[16];
1997
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001998 memcpy(tmp, prv, 16);
1999 memcpy(prv, buf, 16);
2000 memcpy(buf, tmp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00002001 }
2002
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002003 ret = mbedtls_aes_crypt_cbc(&ctx, mode, 16, iv, buf, buf);
2004 if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002005 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002006 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002007
2008 }
2009
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002010 if (memcmp(buf, aes_tests, 16) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002011 ret = 1;
2012 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00002013 }
2014
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002015 if (verbose != 0) {
2016 mbedtls_printf("passed\n");
2017 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002018 }
2019
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002020 if (verbose != 0) {
2021 mbedtls_printf("\n");
2022 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002023#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00002024
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002025#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00002026 /*
2027 * CFB128 mode
2028 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002029 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +00002030 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002031 keybits = 128 + u * 64;
2032 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00002033
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002034 if (verbose != 0) {
2035 mbedtls_printf(" AES-CFB128-%3u (%s): ", keybits,
2036 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2037 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002038
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002039 memcpy(iv, aes_test_cfb128_iv, 16);
2040 memcpy(key, aes_test_cfb128_key[u], keybits / 8);
Paul Bakker5121ce52009-01-03 21:22:43 +00002041
2042 offset = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002043 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01002044 /*
2045 * AES-192 is an optional feature that may be unavailable when
2046 * there is an alternative underlying implementation i.e. when
2047 * MBEDTLS_AES_ALT is defined.
2048 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002049 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2050 mbedtls_printf("skipped\n");
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002051 continue;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002052 } else if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002053 goto exit;
2054 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002055
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002056 if (mode == MBEDTLS_AES_DECRYPT) {
2057 memcpy(buf, aes_test_cfb128_ct[u], 64);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002058 aes_tests = aes_test_cfb128_pt;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002059 } else {
2060 memcpy(buf, aes_test_cfb128_pt, 64);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002061 aes_tests = aes_test_cfb128_ct[u];
2062 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002063
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002064 ret = mbedtls_aes_crypt_cfb128(&ctx, mode, 64, &offset, iv, buf, buf);
2065 if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002066 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002067 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002068
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002069 if (memcmp(buf, aes_tests, 64) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002070 ret = 1;
2071 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00002072 }
2073
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002074 if (verbose != 0) {
2075 mbedtls_printf("passed\n");
2076 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002077 }
2078
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002079 if (verbose != 0) {
2080 mbedtls_printf("\n");
2081 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002082#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002083
Simon Butcherad4e4932018-04-29 00:43:47 +01002084#if defined(MBEDTLS_CIPHER_MODE_OFB)
2085 /*
2086 * OFB mode
2087 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002088 for (i = 0; i < 6; i++) {
Simon Butcherad4e4932018-04-29 00:43:47 +01002089 u = i >> 1;
2090 keybits = 128 + u * 64;
2091 mode = i & 1;
2092
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002093 if (verbose != 0) {
2094 mbedtls_printf(" AES-OFB-%3u (%s): ", keybits,
2095 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2096 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002097
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002098 memcpy(iv, aes_test_ofb_iv, 16);
2099 memcpy(key, aes_test_ofb_key[u], keybits / 8);
Simon Butcherad4e4932018-04-29 00:43:47 +01002100
2101 offset = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002102 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Simon Butcherad4e4932018-04-29 00:43:47 +01002103 /*
2104 * AES-192 is an optional feature that may be unavailable when
2105 * there is an alternative underlying implementation i.e. when
2106 * MBEDTLS_AES_ALT is defined.
2107 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002108 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2109 mbedtls_printf("skipped\n");
Simon Butcherad4e4932018-04-29 00:43:47 +01002110 continue;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002111 } else if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01002112 goto exit;
2113 }
2114
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002115 if (mode == MBEDTLS_AES_DECRYPT) {
2116 memcpy(buf, aes_test_ofb_ct[u], 64);
Simon Butcherad4e4932018-04-29 00:43:47 +01002117 aes_tests = aes_test_ofb_pt;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002118 } else {
2119 memcpy(buf, aes_test_ofb_pt, 64);
Simon Butcherad4e4932018-04-29 00:43:47 +01002120 aes_tests = aes_test_ofb_ct[u];
2121 }
2122
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002123 ret = mbedtls_aes_crypt_ofb(&ctx, 64, &offset, iv, buf, buf);
2124 if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01002125 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002126 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002127
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002128 if (memcmp(buf, aes_tests, 64) != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01002129 ret = 1;
2130 goto exit;
2131 }
2132
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002133 if (verbose != 0) {
2134 mbedtls_printf("passed\n");
2135 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002136 }
2137
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002138 if (verbose != 0) {
2139 mbedtls_printf("\n");
2140 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002141#endif /* MBEDTLS_CIPHER_MODE_OFB */
2142
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002143#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002144 /*
2145 * CTR mode
2146 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002147 for (i = 0; i < 6; i++) {
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002148 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002149 mode = i & 1;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002150
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002151 if (verbose != 0) {
2152 mbedtls_printf(" AES-CTR-128 (%s): ",
2153 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2154 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002155
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002156 memcpy(nonce_counter, aes_test_ctr_nonce_counter[u], 16);
2157 memcpy(key, aes_test_ctr_key[u], 16);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002158
2159 offset = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002160 if ((ret = mbedtls_aes_setkey_enc(&ctx, key, 128)) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002161 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002162 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002163
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002164 len = aes_test_ctr_len[u];
2165
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002166 if (mode == MBEDTLS_AES_DECRYPT) {
2167 memcpy(buf, aes_test_ctr_ct[u], len);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002168 aes_tests = aes_test_ctr_pt[u];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002169 } else {
2170 memcpy(buf, aes_test_ctr_pt[u], len);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002171 aes_tests = aes_test_ctr_ct[u];
2172 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002173
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002174 ret = mbedtls_aes_crypt_ctr(&ctx, len, &offset, nonce_counter,
2175 stream_block, buf, buf);
2176 if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002177 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002178 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002179
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002180 if (memcmp(buf, aes_tests, len) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002181 ret = 1;
2182 goto exit;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002183 }
2184
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002185 if (verbose != 0) {
2186 mbedtls_printf("passed\n");
2187 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002188 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002189
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002190 if (verbose != 0) {
2191 mbedtls_printf("\n");
2192 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002193#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00002194
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002195#if defined(MBEDTLS_CIPHER_MODE_XTS)
2196 {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002197 static const int num_tests =
2198 sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key);
2199 mbedtls_aes_xts_context ctx_xts;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002200
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002201 /*
2202 * XTS mode
2203 */
2204 mbedtls_aes_xts_init(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002205
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002206 for (i = 0; i < num_tests << 1; i++) {
2207 const unsigned char *data_unit;
2208 u = i >> 1;
2209 mode = i & 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002210
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002211 if (verbose != 0) {
2212 mbedtls_printf(" AES-XTS-128 (%s): ",
2213 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2214 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002215
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002216 memset(key, 0, sizeof(key));
2217 memcpy(key, aes_test_xts_key[u], 32);
2218 data_unit = aes_test_xts_data_unit[u];
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002219
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002220 len = sizeof(*aes_test_xts_ct32);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002221
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002222 if (mode == MBEDTLS_AES_DECRYPT) {
2223 ret = mbedtls_aes_xts_setkey_dec(&ctx_xts, key, 256);
2224 if (ret != 0) {
2225 goto exit;
2226 }
2227 memcpy(buf, aes_test_xts_ct32[u], len);
2228 aes_tests = aes_test_xts_pt32[u];
2229 } else {
2230 ret = mbedtls_aes_xts_setkey_enc(&ctx_xts, key, 256);
2231 if (ret != 0) {
2232 goto exit;
2233 }
2234 memcpy(buf, aes_test_xts_pt32[u], len);
2235 aes_tests = aes_test_xts_ct32[u];
2236 }
2237
2238
2239 ret = mbedtls_aes_crypt_xts(&ctx_xts, mode, len, data_unit,
2240 buf, buf);
2241 if (ret != 0) {
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002242 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002243 }
2244
2245 if (memcmp(buf, aes_tests, len) != 0) {
2246 ret = 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002247 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002248 }
2249
2250 if (verbose != 0) {
2251 mbedtls_printf("passed\n");
2252 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002253 }
2254
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002255 if (verbose != 0) {
2256 mbedtls_printf("\n");
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002257 }
2258
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002259 mbedtls_aes_xts_free(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002260 }
2261#endif /* MBEDTLS_CIPHER_MODE_XTS */
2262
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002263 ret = 0;
2264
2265exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002266 if (ret != 0 && verbose != 0) {
2267 mbedtls_printf("failed\n");
2268 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002269
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002270 mbedtls_aes_free(&ctx);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002271
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002272 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002273}
2274
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002275#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002276
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002277#endif /* MBEDTLS_AES_C */