blob: cf63303df0de2bc7a03205955bf1f6659802c7f9 [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 Rodgman5c047d92023-06-27 19:20:27 +010061#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +000062static const unsigned char FSb[256] =
63{
64 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
65 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
66 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
67 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
68 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
69 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
70 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
71 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
72 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
73 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
74 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
75 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
76 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
77 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
78 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
79 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
80 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
81 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
82 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
83 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
84 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
85 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
86 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
87 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
88 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
89 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
90 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
91 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
92 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
93 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
94 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
95 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
96};
Dave Rodgman5c047d92023-06-27 19:20:27 +010097#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +000098
99/*
100 * Forward tables
101 */
102#define FT \
103\
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100104 V(A5, 63, 63, C6), V(84, 7C, 7C, F8), V(99, 77, 77, EE), V(8D, 7B, 7B, F6), \
105 V(0D, F2, F2, FF), V(BD, 6B, 6B, D6), V(B1, 6F, 6F, DE), V(54, C5, C5, 91), \
106 V(50, 30, 30, 60), V(03, 01, 01, 02), V(A9, 67, 67, CE), V(7D, 2B, 2B, 56), \
107 V(19, FE, FE, E7), V(62, D7, D7, B5), V(E6, AB, AB, 4D), V(9A, 76, 76, EC), \
108 V(45, CA, CA, 8F), V(9D, 82, 82, 1F), V(40, C9, C9, 89), V(87, 7D, 7D, FA), \
109 V(15, FA, FA, EF), V(EB, 59, 59, B2), V(C9, 47, 47, 8E), V(0B, F0, F0, FB), \
110 V(EC, AD, AD, 41), V(67, D4, D4, B3), V(FD, A2, A2, 5F), V(EA, AF, AF, 45), \
111 V(BF, 9C, 9C, 23), V(F7, A4, A4, 53), V(96, 72, 72, E4), V(5B, C0, C0, 9B), \
112 V(C2, B7, B7, 75), V(1C, FD, FD, E1), V(AE, 93, 93, 3D), V(6A, 26, 26, 4C), \
113 V(5A, 36, 36, 6C), V(41, 3F, 3F, 7E), V(02, F7, F7, F5), V(4F, CC, CC, 83), \
114 V(5C, 34, 34, 68), V(F4, A5, A5, 51), V(34, E5, E5, D1), V(08, F1, F1, F9), \
115 V(93, 71, 71, E2), V(73, D8, D8, AB), V(53, 31, 31, 62), V(3F, 15, 15, 2A), \
116 V(0C, 04, 04, 08), V(52, C7, C7, 95), V(65, 23, 23, 46), V(5E, C3, C3, 9D), \
117 V(28, 18, 18, 30), V(A1, 96, 96, 37), V(0F, 05, 05, 0A), V(B5, 9A, 9A, 2F), \
118 V(09, 07, 07, 0E), V(36, 12, 12, 24), V(9B, 80, 80, 1B), V(3D, E2, E2, DF), \
119 V(26, EB, EB, CD), V(69, 27, 27, 4E), V(CD, B2, B2, 7F), V(9F, 75, 75, EA), \
120 V(1B, 09, 09, 12), V(9E, 83, 83, 1D), V(74, 2C, 2C, 58), V(2E, 1A, 1A, 34), \
121 V(2D, 1B, 1B, 36), V(B2, 6E, 6E, DC), V(EE, 5A, 5A, B4), V(FB, A0, A0, 5B), \
122 V(F6, 52, 52, A4), V(4D, 3B, 3B, 76), V(61, D6, D6, B7), V(CE, B3, B3, 7D), \
123 V(7B, 29, 29, 52), V(3E, E3, E3, DD), V(71, 2F, 2F, 5E), V(97, 84, 84, 13), \
124 V(F5, 53, 53, A6), V(68, D1, D1, B9), V(00, 00, 00, 00), V(2C, ED, ED, C1), \
125 V(60, 20, 20, 40), V(1F, FC, FC, E3), V(C8, B1, B1, 79), V(ED, 5B, 5B, B6), \
126 V(BE, 6A, 6A, D4), V(46, CB, CB, 8D), V(D9, BE, BE, 67), V(4B, 39, 39, 72), \
127 V(DE, 4A, 4A, 94), V(D4, 4C, 4C, 98), V(E8, 58, 58, B0), V(4A, CF, CF, 85), \
128 V(6B, D0, D0, BB), V(2A, EF, EF, C5), V(E5, AA, AA, 4F), V(16, FB, FB, ED), \
129 V(C5, 43, 43, 86), V(D7, 4D, 4D, 9A), V(55, 33, 33, 66), V(94, 85, 85, 11), \
130 V(CF, 45, 45, 8A), V(10, F9, F9, E9), V(06, 02, 02, 04), V(81, 7F, 7F, FE), \
131 V(F0, 50, 50, A0), V(44, 3C, 3C, 78), V(BA, 9F, 9F, 25), V(E3, A8, A8, 4B), \
132 V(F3, 51, 51, A2), V(FE, A3, A3, 5D), V(C0, 40, 40, 80), V(8A, 8F, 8F, 05), \
133 V(AD, 92, 92, 3F), V(BC, 9D, 9D, 21), V(48, 38, 38, 70), V(04, F5, F5, F1), \
134 V(DF, BC, BC, 63), V(C1, B6, B6, 77), V(75, DA, DA, AF), V(63, 21, 21, 42), \
135 V(30, 10, 10, 20), V(1A, FF, FF, E5), V(0E, F3, F3, FD), V(6D, D2, D2, BF), \
136 V(4C, CD, CD, 81), V(14, 0C, 0C, 18), V(35, 13, 13, 26), V(2F, EC, EC, C3), \
137 V(E1, 5F, 5F, BE), V(A2, 97, 97, 35), V(CC, 44, 44, 88), V(39, 17, 17, 2E), \
138 V(57, C4, C4, 93), V(F2, A7, A7, 55), V(82, 7E, 7E, FC), V(47, 3D, 3D, 7A), \
139 V(AC, 64, 64, C8), V(E7, 5D, 5D, BA), V(2B, 19, 19, 32), V(95, 73, 73, E6), \
140 V(A0, 60, 60, C0), V(98, 81, 81, 19), V(D1, 4F, 4F, 9E), V(7F, DC, DC, A3), \
141 V(66, 22, 22, 44), V(7E, 2A, 2A, 54), V(AB, 90, 90, 3B), V(83, 88, 88, 0B), \
142 V(CA, 46, 46, 8C), V(29, EE, EE, C7), V(D3, B8, B8, 6B), V(3C, 14, 14, 28), \
143 V(79, DE, DE, A7), V(E2, 5E, 5E, BC), V(1D, 0B, 0B, 16), V(76, DB, DB, AD), \
144 V(3B, E0, E0, DB), V(56, 32, 32, 64), V(4E, 3A, 3A, 74), V(1E, 0A, 0A, 14), \
145 V(DB, 49, 49, 92), V(0A, 06, 06, 0C), V(6C, 24, 24, 48), V(E4, 5C, 5C, B8), \
146 V(5D, C2, C2, 9F), V(6E, D3, D3, BD), V(EF, AC, AC, 43), V(A6, 62, 62, C4), \
147 V(A8, 91, 91, 39), V(A4, 95, 95, 31), V(37, E4, E4, D3), V(8B, 79, 79, F2), \
148 V(32, E7, E7, D5), V(43, C8, C8, 8B), V(59, 37, 37, 6E), V(B7, 6D, 6D, DA), \
149 V(8C, 8D, 8D, 01), V(64, D5, D5, B1), V(D2, 4E, 4E, 9C), V(E0, A9, A9, 49), \
150 V(B4, 6C, 6C, D8), V(FA, 56, 56, AC), V(07, F4, F4, F3), V(25, EA, EA, CF), \
151 V(AF, 65, 65, CA), V(8E, 7A, 7A, F4), V(E9, AE, AE, 47), V(18, 08, 08, 10), \
152 V(D5, BA, BA, 6F), V(88, 78, 78, F0), V(6F, 25, 25, 4A), V(72, 2E, 2E, 5C), \
153 V(24, 1C, 1C, 38), V(F1, A6, A6, 57), V(C7, B4, B4, 73), V(51, C6, C6, 97), \
154 V(23, E8, E8, CB), V(7C, DD, DD, A1), V(9C, 74, 74, E8), V(21, 1F, 1F, 3E), \
155 V(DD, 4B, 4B, 96), V(DC, BD, BD, 61), V(86, 8B, 8B, 0D), V(85, 8A, 8A, 0F), \
156 V(90, 70, 70, E0), V(42, 3E, 3E, 7C), V(C4, B5, B5, 71), V(AA, 66, 66, CC), \
157 V(D8, 48, 48, 90), V(05, 03, 03, 06), V(01, F6, F6, F7), V(12, 0E, 0E, 1C), \
158 V(A3, 61, 61, C2), V(5F, 35, 35, 6A), V(F9, 57, 57, AE), V(D0, B9, B9, 69), \
159 V(91, 86, 86, 17), V(58, C1, C1, 99), V(27, 1D, 1D, 3A), V(B9, 9E, 9E, 27), \
160 V(38, E1, E1, D9), V(13, F8, F8, EB), V(B3, 98, 98, 2B), V(33, 11, 11, 22), \
161 V(BB, 69, 69, D2), V(70, D9, D9, A9), V(89, 8E, 8E, 07), V(A7, 94, 94, 33), \
162 V(B6, 9B, 9B, 2D), V(22, 1E, 1E, 3C), V(92, 87, 87, 15), V(20, E9, E9, C9), \
163 V(49, CE, CE, 87), V(FF, 55, 55, AA), V(78, 28, 28, 50), V(7A, DF, DF, A5), \
164 V(8F, 8C, 8C, 03), V(F8, A1, A1, 59), V(80, 89, 89, 09), V(17, 0D, 0D, 1A), \
165 V(DA, BF, BF, 65), V(31, E6, E6, D7), V(C6, 42, 42, 84), V(B8, 68, 68, D0), \
166 V(C3, 41, 41, 82), V(B0, 99, 99, 29), V(77, 2D, 2D, 5A), V(11, 0F, 0F, 1E), \
167 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 +0000168
Dave Rodgman5c047d92023-06-27 19:20:27 +0100169#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100170#define V(a, b, c, d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000171static const uint32_t FT0[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000172#undef V
173
Hanno Beckerad049a92017-06-19 16:31:54 +0100174#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200175
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100176#define V(a, b, c, d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000177static const uint32_t FT1[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000178#undef V
179
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100180#define V(a, b, c, d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000181static const uint32_t FT2[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000182#undef V
183
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100184#define V(a, b, c, d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000185static const uint32_t FT3[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000186#undef V
187
Dave Rodgman5c047d92023-06-27 19:20:27 +0100188#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) */
189
Hanno Becker177d3cf2017-06-07 15:52:48 +0100190#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200191
Paul Bakker5121ce52009-01-03 21:22:43 +0000192#undef FT
193
Dave Rodgman5c047d92023-06-27 19:20:27 +0100194#if !defined(MBEDTLS_AES_DECRYPT_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000195/*
196 * Reverse S-box
197 */
198static const unsigned char RSb[256] =
199{
200 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
201 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
202 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
203 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
204 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
205 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
206 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
207 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
208 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
209 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
210 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
211 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
212 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
213 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
214 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
215 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
216 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
217 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
218 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
219 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
220 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
221 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
222 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
223 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
224 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
225 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
226 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
227 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
228 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
229 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
230 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
231 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
232};
Dave Rodgmandbae1842023-06-27 18:27:31 +0100233#endif /* !(defined(MBEDTLS_AES_SETKEY_ENC_ALT) && defined(MBEDTLS_AES_DECRYPT_ALT)) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000234
235/*
236 * Reverse tables
237 */
238#define RT \
239\
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100240 V(50, A7, F4, 51), V(53, 65, 41, 7E), V(C3, A4, 17, 1A), V(96, 5E, 27, 3A), \
241 V(CB, 6B, AB, 3B), V(F1, 45, 9D, 1F), V(AB, 58, FA, AC), V(93, 03, E3, 4B), \
242 V(55, FA, 30, 20), V(F6, 6D, 76, AD), V(91, 76, CC, 88), V(25, 4C, 02, F5), \
243 V(FC, D7, E5, 4F), V(D7, CB, 2A, C5), V(80, 44, 35, 26), V(8F, A3, 62, B5), \
244 V(49, 5A, B1, DE), V(67, 1B, BA, 25), V(98, 0E, EA, 45), V(E1, C0, FE, 5D), \
245 V(02, 75, 2F, C3), V(12, F0, 4C, 81), V(A3, 97, 46, 8D), V(C6, F9, D3, 6B), \
246 V(E7, 5F, 8F, 03), V(95, 9C, 92, 15), V(EB, 7A, 6D, BF), V(DA, 59, 52, 95), \
247 V(2D, 83, BE, D4), V(D3, 21, 74, 58), V(29, 69, E0, 49), V(44, C8, C9, 8E), \
248 V(6A, 89, C2, 75), V(78, 79, 8E, F4), V(6B, 3E, 58, 99), V(DD, 71, B9, 27), \
249 V(B6, 4F, E1, BE), V(17, AD, 88, F0), V(66, AC, 20, C9), V(B4, 3A, CE, 7D), \
250 V(18, 4A, DF, 63), V(82, 31, 1A, E5), V(60, 33, 51, 97), V(45, 7F, 53, 62), \
251 V(E0, 77, 64, B1), V(84, AE, 6B, BB), V(1C, A0, 81, FE), V(94, 2B, 08, F9), \
252 V(58, 68, 48, 70), V(19, FD, 45, 8F), V(87, 6C, DE, 94), V(B7, F8, 7B, 52), \
253 V(23, D3, 73, AB), V(E2, 02, 4B, 72), V(57, 8F, 1F, E3), V(2A, AB, 55, 66), \
254 V(07, 28, EB, B2), V(03, C2, B5, 2F), V(9A, 7B, C5, 86), V(A5, 08, 37, D3), \
255 V(F2, 87, 28, 30), V(B2, A5, BF, 23), V(BA, 6A, 03, 02), V(5C, 82, 16, ED), \
256 V(2B, 1C, CF, 8A), V(92, B4, 79, A7), V(F0, F2, 07, F3), V(A1, E2, 69, 4E), \
257 V(CD, F4, DA, 65), V(D5, BE, 05, 06), V(1F, 62, 34, D1), V(8A, FE, A6, C4), \
258 V(9D, 53, 2E, 34), V(A0, 55, F3, A2), V(32, E1, 8A, 05), V(75, EB, F6, A4), \
259 V(39, EC, 83, 0B), V(AA, EF, 60, 40), V(06, 9F, 71, 5E), V(51, 10, 6E, BD), \
260 V(F9, 8A, 21, 3E), V(3D, 06, DD, 96), V(AE, 05, 3E, DD), V(46, BD, E6, 4D), \
261 V(B5, 8D, 54, 91), V(05, 5D, C4, 71), V(6F, D4, 06, 04), V(FF, 15, 50, 60), \
262 V(24, FB, 98, 19), V(97, E9, BD, D6), V(CC, 43, 40, 89), V(77, 9E, D9, 67), \
263 V(BD, 42, E8, B0), V(88, 8B, 89, 07), V(38, 5B, 19, E7), V(DB, EE, C8, 79), \
264 V(47, 0A, 7C, A1), V(E9, 0F, 42, 7C), V(C9, 1E, 84, F8), V(00, 00, 00, 00), \
265 V(83, 86, 80, 09), V(48, ED, 2B, 32), V(AC, 70, 11, 1E), V(4E, 72, 5A, 6C), \
266 V(FB, FF, 0E, FD), V(56, 38, 85, 0F), V(1E, D5, AE, 3D), V(27, 39, 2D, 36), \
267 V(64, D9, 0F, 0A), V(21, A6, 5C, 68), V(D1, 54, 5B, 9B), V(3A, 2E, 36, 24), \
268 V(B1, 67, 0A, 0C), V(0F, E7, 57, 93), V(D2, 96, EE, B4), V(9E, 91, 9B, 1B), \
269 V(4F, C5, C0, 80), V(A2, 20, DC, 61), V(69, 4B, 77, 5A), V(16, 1A, 12, 1C), \
270 V(0A, BA, 93, E2), V(E5, 2A, A0, C0), V(43, E0, 22, 3C), V(1D, 17, 1B, 12), \
271 V(0B, 0D, 09, 0E), V(AD, C7, 8B, F2), V(B9, A8, B6, 2D), V(C8, A9, 1E, 14), \
272 V(85, 19, F1, 57), V(4C, 07, 75, AF), V(BB, DD, 99, EE), V(FD, 60, 7F, A3), \
273 V(9F, 26, 01, F7), V(BC, F5, 72, 5C), V(C5, 3B, 66, 44), V(34, 7E, FB, 5B), \
274 V(76, 29, 43, 8B), V(DC, C6, 23, CB), V(68, FC, ED, B6), V(63, F1, E4, B8), \
275 V(CA, DC, 31, D7), V(10, 85, 63, 42), V(40, 22, 97, 13), V(20, 11, C6, 84), \
276 V(7D, 24, 4A, 85), V(F8, 3D, BB, D2), V(11, 32, F9, AE), V(6D, A1, 29, C7), \
277 V(4B, 2F, 9E, 1D), V(F3, 30, B2, DC), V(EC, 52, 86, 0D), V(D0, E3, C1, 77), \
278 V(6C, 16, B3, 2B), V(99, B9, 70, A9), V(FA, 48, 94, 11), V(22, 64, E9, 47), \
279 V(C4, 8C, FC, A8), V(1A, 3F, F0, A0), V(D8, 2C, 7D, 56), V(EF, 90, 33, 22), \
280 V(C7, 4E, 49, 87), V(C1, D1, 38, D9), V(FE, A2, CA, 8C), V(36, 0B, D4, 98), \
281 V(CF, 81, F5, A6), V(28, DE, 7A, A5), V(26, 8E, B7, DA), V(A4, BF, AD, 3F), \
282 V(E4, 9D, 3A, 2C), V(0D, 92, 78, 50), V(9B, CC, 5F, 6A), V(62, 46, 7E, 54), \
283 V(C2, 13, 8D, F6), V(E8, B8, D8, 90), V(5E, F7, 39, 2E), V(F5, AF, C3, 82), \
284 V(BE, 80, 5D, 9F), V(7C, 93, D0, 69), V(A9, 2D, D5, 6F), V(B3, 12, 25, CF), \
285 V(3B, 99, AC, C8), V(A7, 7D, 18, 10), V(6E, 63, 9C, E8), V(7B, BB, 3B, DB), \
286 V(09, 78, 26, CD), V(F4, 18, 59, 6E), V(01, B7, 9A, EC), V(A8, 9A, 4F, 83), \
287 V(65, 6E, 95, E6), V(7E, E6, FF, AA), V(08, CF, BC, 21), V(E6, E8, 15, EF), \
288 V(D9, 9B, E7, BA), V(CE, 36, 6F, 4A), V(D4, 09, 9F, EA), V(D6, 7C, B0, 29), \
289 V(AF, B2, A4, 31), V(31, 23, 3F, 2A), V(30, 94, A5, C6), V(C0, 66, A2, 35), \
290 V(37, BC, 4E, 74), V(A6, CA, 82, FC), V(B0, D0, 90, E0), V(15, D8, A7, 33), \
291 V(4A, 98, 04, F1), V(F7, DA, EC, 41), V(0E, 50, CD, 7F), V(2F, F6, 91, 17), \
292 V(8D, D6, 4D, 76), V(4D, B0, EF, 43), V(54, 4D, AA, CC), V(DF, 04, 96, E4), \
293 V(E3, B5, D1, 9E), V(1B, 88, 6A, 4C), V(B8, 1F, 2C, C1), V(7F, 51, 65, 46), \
294 V(04, EA, 5E, 9D), V(5D, 35, 8C, 01), V(73, 74, 87, FA), V(2E, 41, 0B, FB), \
295 V(5A, 1D, 67, B3), V(52, D2, DB, 92), V(33, 56, 10, E9), V(13, 47, D6, 6D), \
296 V(8C, 61, D7, 9A), V(7A, 0C, A1, 37), V(8E, 14, F8, 59), V(89, 3C, 13, EB), \
297 V(EE, 27, A9, CE), V(35, C9, 61, B7), V(ED, E5, 1C, E1), V(3C, B1, 47, 7A), \
298 V(59, DF, D2, 9C), V(3F, 73, F2, 55), V(79, CE, 14, 18), V(BF, 37, C7, 73), \
299 V(EA, CD, F7, 53), V(5B, AA, FD, 5F), V(14, 6F, 3D, DF), V(86, DB, 44, 78), \
300 V(81, F3, AF, CA), V(3E, C4, 68, B9), V(2C, 34, 24, 38), V(5F, 40, A3, C2), \
301 V(72, C3, 1D, 16), V(0C, 25, E2, BC), V(8B, 49, 3C, 28), V(41, 95, 0D, FF), \
302 V(71, 01, A8, 39), V(DE, B3, 0C, 08), V(9C, E4, B4, D8), V(90, C1, 56, 64), \
303 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 +0000304
Dave Rodgman5c047d92023-06-27 19:20:27 +0100305#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
306
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100307#define V(a, b, c, d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000308static const uint32_t RT0[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000309#undef V
310
Hanno Beckerad049a92017-06-19 16:31:54 +0100311#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200312
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100313#define V(a, b, c, d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000314static const uint32_t RT1[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000315#undef V
316
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100317#define V(a, b, c, d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000318static const uint32_t RT2[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000319#undef V
320
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100321#define V(a, b, c, d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000322static const uint32_t RT3[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000323#undef V
324
Dave Rodgman9d3b6332023-06-27 20:41:51 +0100325#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Dave Rodgman5c047d92023-06-27 19:20:27 +0100326
Hanno Becker177d3cf2017-06-07 15:52:48 +0100327#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200328
Paul Bakker5121ce52009-01-03 21:22:43 +0000329#undef RT
330
Dave Rodgman36c8e582023-06-27 18:31:24 +0100331#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000332/*
333 * Round constants
334 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000335static const uint32_t RCON[10] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000336{
337 0x00000001, 0x00000002, 0x00000004, 0x00000008,
338 0x00000010, 0x00000020, 0x00000040, 0x00000080,
339 0x0000001B, 0x00000036
340};
Dave Rodgman36c8e582023-06-27 18:31:24 +0100341#endif /* !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000342
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200343#else /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000344
345/*
346 * Forward S-box & tables
347 */
Dave Rodgman5c047d92023-06-27 19:20:27 +0100348#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000349static unsigned char FSb[256];
Dave Rodgman5c047d92023-06-27 19:20:27 +0100350#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
351#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker9af723c2014-05-01 13:03:14 +0200352static uint32_t FT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100353#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker9af723c2014-05-01 13:03:14 +0200354static uint32_t FT1[256];
355static uint32_t FT2[256];
356static uint32_t FT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100357#endif /* !MBEDTLS_AES_FEWER_TABLES */
Dave Rodgman5c047d92023-06-27 19:20:27 +0100358#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000359
360/*
361 * Reverse S-box & tables
362 */
Dave Rodgmandbae1842023-06-27 18:27:31 +0100363#if !(defined(MBEDTLS_AES_SETKEY_ENC_ALT) && defined(MBEDTLS_AES_DECRYPT_ALT))
Paul Bakker5121ce52009-01-03 21:22:43 +0000364static unsigned char RSb[256];
Dave Rodgmandbae1842023-06-27 18:27:31 +0100365#endif
Dave Rodgman5c047d92023-06-27 19:20:27 +0100366
367#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Paul Bakker5c2364c2012-10-01 14:41:15 +0000368static uint32_t RT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100369#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker5c2364c2012-10-01 14:41:15 +0000370static uint32_t RT1[256];
371static uint32_t RT2[256];
372static uint32_t RT3[256];
Dave Rodgman5c047d92023-06-27 19:20:27 +0100373#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Hanno Becker177d3cf2017-06-07 15:52:48 +0100374#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000375
Dave Rodgman1e6f7702023-06-27 18:16:13 +0100376#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000377/*
378 * Round constants
379 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000380static uint32_t RCON[10];
Paul Bakker5121ce52009-01-03 21:22:43 +0000381
382/*
383 * Tables generation code
384 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100385#define ROTL8(x) (((x) << 8) & 0xFFFFFFFF) | ((x) >> 24)
386#define XTIME(x) (((x) << 1) ^ (((x) & 0x80) ? 0x1B : 0x00))
387#define MUL(x, y) (((x) && (y)) ? pow[(log[(x)]+log[(y)]) % 255] : 0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000388
389static int aes_init_done = 0;
390
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100391static void aes_gen_tables(void)
Paul Bakker5121ce52009-01-03 21:22:43 +0000392{
393 int i, x, y, z;
394 int pow[256];
395 int log[256];
396
397 /*
398 * compute pow and log tables over GF(2^8)
399 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100400 for (i = 0, x = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000401 pow[i] = x;
402 log[x] = i;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100403 x = MBEDTLS_BYTE_0(x ^ XTIME(x));
Paul Bakker5121ce52009-01-03 21:22:43 +0000404 }
405
406 /*
407 * calculate the round constants
408 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100409 for (i = 0, x = 1; i < 10; i++) {
Paul Bakker5c2364c2012-10-01 14:41:15 +0000410 RCON[i] = (uint32_t) x;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100411 x = MBEDTLS_BYTE_0(XTIME(x));
Paul Bakker5121ce52009-01-03 21:22:43 +0000412 }
413
414 /*
415 * generate the forward and reverse S-boxes
416 */
417 FSb[0x00] = 0x63;
418 RSb[0x63] = 0x00;
419
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100420 for (i = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000421 x = pow[255 - log[i]];
422
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100423 y = x; y = MBEDTLS_BYTE_0((y << 1) | (y >> 7));
424 x ^= y; y = MBEDTLS_BYTE_0((y << 1) | (y >> 7));
425 x ^= y; y = MBEDTLS_BYTE_0((y << 1) | (y >> 7));
426 x ^= y; y = MBEDTLS_BYTE_0((y << 1) | (y >> 7));
Paul Bakker5121ce52009-01-03 21:22:43 +0000427 x ^= y ^ 0x63;
428
429 FSb[i] = (unsigned char) x;
430 RSb[x] = (unsigned char) i;
431 }
432
433 /*
434 * generate the forward and reverse tables
435 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100436 for (i = 0; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000437 x = FSb[i];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100438 y = MBEDTLS_BYTE_0(XTIME(x));
439 z = MBEDTLS_BYTE_0(y ^ x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000440
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100441 FT0[i] = ((uint32_t) y) ^
442 ((uint32_t) x << 8) ^
443 ((uint32_t) x << 16) ^
444 ((uint32_t) z << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000445
Hanno Beckerad049a92017-06-19 16:31:54 +0100446#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100447 FT1[i] = ROTL8(FT0[i]);
448 FT2[i] = ROTL8(FT1[i]);
449 FT3[i] = ROTL8(FT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100450#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000451
452 x = RSb[i];
453
Dave Rodgman5c047d92023-06-27 19:20:27 +0100454#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100455 RT0[i] = ((uint32_t) MUL(0x0E, x)) ^
456 ((uint32_t) MUL(0x09, x) << 8) ^
457 ((uint32_t) MUL(0x0D, x) << 16) ^
458 ((uint32_t) MUL(0x0B, x) << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000459
Hanno Beckerad049a92017-06-19 16:31:54 +0100460#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100461 RT1[i] = ROTL8(RT0[i]);
462 RT2[i] = ROTL8(RT1[i]);
463 RT3[i] = ROTL8(RT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100464#endif /* !MBEDTLS_AES_FEWER_TABLES */
Dave Rodgman5c047d92023-06-27 19:20:27 +0100465#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000466 }
467}
468
Dave Rodgman1e6f7702023-06-27 18:16:13 +0100469#endif /* !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
470
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200471#undef ROTL8
472
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200473#endif /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000474
Hanno Beckerad049a92017-06-19 16:31:54 +0100475#if defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200476
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100477#define ROTL8(x) ((uint32_t) ((x) << 8) + (uint32_t) ((x) >> 24))
478#define ROTL16(x) ((uint32_t) ((x) << 16) + (uint32_t) ((x) >> 16))
479#define ROTL24(x) ((uint32_t) ((x) << 24) + (uint32_t) ((x) >> 8))
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200480
481#define AES_RT0(idx) RT0[idx]
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100482#define AES_RT1(idx) ROTL8(RT0[idx])
483#define AES_RT2(idx) ROTL16(RT0[idx])
484#define AES_RT3(idx) ROTL24(RT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200485
486#define AES_FT0(idx) FT0[idx]
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100487#define AES_FT1(idx) ROTL8(FT0[idx])
488#define AES_FT2(idx) ROTL16(FT0[idx])
489#define AES_FT3(idx) ROTL24(FT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200490
Hanno Becker177d3cf2017-06-07 15:52:48 +0100491#else /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200492
493#define AES_RT0(idx) RT0[idx]
494#define AES_RT1(idx) RT1[idx]
495#define AES_RT2(idx) RT2[idx]
496#define AES_RT3(idx) RT3[idx]
497
498#define AES_FT0(idx) FT0[idx]
499#define AES_FT1(idx) FT1[idx]
500#define AES_FT2(idx) FT2[idx]
501#define AES_FT3(idx) FT3[idx]
502
Hanno Becker177d3cf2017-06-07 15:52:48 +0100503#endif /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200504
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100505void mbedtls_aes_init(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200506{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100507 AES_VALIDATE(ctx != NULL);
Simon Butcher5201e412018-12-06 17:40:14 +0000508
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100509 memset(ctx, 0, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200510}
511
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100512void mbedtls_aes_free(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200513{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100514 if (ctx == NULL) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200515 return;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100516 }
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200517
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100518 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200519}
520
Jaeden Amero9366feb2018-05-29 18:55:17 +0100521#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100522void mbedtls_aes_xts_init(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100523{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100524 AES_VALIDATE(ctx != NULL);
Simon Butcher5201e412018-12-06 17:40:14 +0000525
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100526 mbedtls_aes_init(&ctx->crypt);
527 mbedtls_aes_init(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100528}
529
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100530void mbedtls_aes_xts_free(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100531{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100532 if (ctx == NULL) {
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100533 return;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100534 }
Simon Butcher5201e412018-12-06 17:40:14 +0000535
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100536 mbedtls_aes_free(&ctx->crypt);
537 mbedtls_aes_free(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100538}
539#endif /* MBEDTLS_CIPHER_MODE_XTS */
540
Gilles Peskineb71d4022023-03-16 17:14:59 +0100541/* Some implementations need the round keys to be aligned.
542 * Return an offset to be added to buf, such that (buf + offset) is
543 * correctly aligned.
544 * Note that the offset is in units of elements of buf, i.e. 32-bit words,
545 * i.e. an offset of 1 means 4 bytes and so on.
546 */
547#if (defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)) || \
Gilles Peskine6dec5412023-03-16 17:21:33 +0100548 (defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2)
Gilles Peskineb71d4022023-03-16 17:14:59 +0100549#define MAY_NEED_TO_ALIGN
550#endif
Dave Rodgman9b20aea2023-06-27 18:22:34 +0100551
552#if defined(MAY_NEED_TO_ALIGN) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskineb71d4022023-03-16 17:14:59 +0100553static unsigned mbedtls_aes_rk_offset(uint32_t *buf)
554{
555#if defined(MAY_NEED_TO_ALIGN)
556 int align_16_bytes = 0;
557
558#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
559 if (aes_padlock_ace == -1) {
560 aes_padlock_ace = mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE);
561 }
562 if (aes_padlock_ace) {
563 align_16_bytes = 1;
564 }
565#endif
566
Gilles Peskine6dec5412023-03-16 17:21:33 +0100567#if defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2
Gilles Peskineb71d4022023-03-16 17:14:59 +0100568 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
569 align_16_bytes = 1;
570 }
571#endif
572
573 if (align_16_bytes) {
574 /* These implementations needs 16-byte alignment
575 * for the round key array. */
576 unsigned delta = ((uintptr_t) buf & 0x0000000fU) / 4;
577 if (delta == 0) {
578 return 0;
579 } else {
580 return 4 - delta; // 16 bytes = 4 uint32_t
581 }
582 }
583#else /* MAY_NEED_TO_ALIGN */
584 (void) buf;
585#endif /* MAY_NEED_TO_ALIGN */
586
587 return 0;
588}
Dave Rodgman9b20aea2023-06-27 18:22:34 +0100589#endif /* defined(MAY_NEED_TO_ALIGN) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
Gilles Peskineb71d4022023-03-16 17:14:59 +0100590
Paul Bakker5121ce52009-01-03 21:22:43 +0000591/*
592 * AES key schedule (encryption)
593 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200594#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100595int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
596 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000597{
Paul Bakker23986e52011-04-24 08:57:21 +0000598 unsigned int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000599 uint32_t *RK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000600
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100601 AES_VALIDATE_RET(ctx != NULL);
602 AES_VALIDATE_RET(key != NULL);
Paul Bakker5121ce52009-01-03 21:22:43 +0000603
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100604 switch (keybits) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000605 case 128: ctx->nr = 10; break;
606 case 192: ctx->nr = 12; break;
607 case 256: ctx->nr = 14; break;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100608 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Paul Bakker5121ce52009-01-03 21:22:43 +0000609 }
610
Simon Butcher5201e412018-12-06 17:40:14 +0000611#if !defined(MBEDTLS_AES_ROM_TABLES)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100612 if (aes_init_done == 0) {
Simon Butcher5201e412018-12-06 17:40:14 +0000613 aes_gen_tables();
614 aes_init_done = 1;
Simon Butcher5201e412018-12-06 17:40:14 +0000615 }
616#endif
617
Gilles Peskineb71d4022023-03-16 17:14:59 +0100618 ctx->rk = RK = ctx->buf + mbedtls_aes_rk_offset(ctx->buf);
Paul Bakker5121ce52009-01-03 21:22:43 +0000619
Gilles Peskine5511a342023-03-10 22:29:32 +0100620#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100621 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
622 return mbedtls_aesni_setkey_enc((unsigned char *) ctx->rk, key, keybits);
623 }
Manuel Pégourié-Gonnard47a35362013-12-28 20:45:04 +0100624#endif
625
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100626 for (i = 0; i < (keybits >> 5); i++) {
627 RK[i] = MBEDTLS_GET_UINT32_LE(key, i << 2);
Paul Bakker5121ce52009-01-03 21:22:43 +0000628 }
629
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100630 switch (ctx->nr) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000631 case 10:
632
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100633 for (i = 0; i < 10; i++, RK += 4) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000634 RK[4] = RK[0] ^ RCON[i] ^
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100635 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[3])]) ^
636 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[3])] << 8) ^
637 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[3])] << 16) ^
638 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[3])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000639
640 RK[5] = RK[1] ^ RK[4];
641 RK[6] = RK[2] ^ RK[5];
642 RK[7] = RK[3] ^ RK[6];
643 }
644 break;
645
646 case 12:
647
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100648 for (i = 0; i < 8; i++, RK += 6) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000649 RK[6] = RK[0] ^ RCON[i] ^
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100650 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[5])]) ^
651 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[5])] << 8) ^
652 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[5])] << 16) ^
653 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[5])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000654
655 RK[7] = RK[1] ^ RK[6];
656 RK[8] = RK[2] ^ RK[7];
657 RK[9] = RK[3] ^ RK[8];
658 RK[10] = RK[4] ^ RK[9];
659 RK[11] = RK[5] ^ RK[10];
660 }
661 break;
662
663 case 14:
664
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100665 for (i = 0; i < 7; i++, RK += 8) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000666 RK[8] = RK[0] ^ RCON[i] ^
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100667 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[7])]) ^
668 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[7])] << 8) ^
669 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[7])] << 16) ^
670 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[7])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000671
672 RK[9] = RK[1] ^ RK[8];
673 RK[10] = RK[2] ^ RK[9];
674 RK[11] = RK[3] ^ RK[10];
675
676 RK[12] = RK[4] ^
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100677 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[11])]) ^
678 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[11])] << 8) ^
679 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[11])] << 16) ^
680 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[11])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000681
682 RK[13] = RK[5] ^ RK[12];
683 RK[14] = RK[6] ^ RK[13];
684 RK[15] = RK[7] ^ RK[14];
685 }
686 break;
Paul Bakker5121ce52009-01-03 21:22:43 +0000687 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000688
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100689 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000690}
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200691#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000692
693/*
694 * AES key schedule (decryption)
695 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200696#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100697int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
698 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000699{
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200700 int i, j, ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200701 mbedtls_aes_context cty;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000702 uint32_t *RK;
703 uint32_t *SK;
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200704
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100705 AES_VALIDATE_RET(ctx != NULL);
706 AES_VALIDATE_RET(key != NULL);
Simon Butcher5201e412018-12-06 17:40:14 +0000707
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100708 mbedtls_aes_init(&cty);
Paul Bakker5121ce52009-01-03 21:22:43 +0000709
Gilles Peskineb71d4022023-03-16 17:14:59 +0100710 ctx->rk = RK = ctx->buf + mbedtls_aes_rk_offset(ctx->buf);
Paul Bakker5121ce52009-01-03 21:22:43 +0000711
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200712 /* Also checks keybits */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100713 if ((ret = mbedtls_aes_setkey_enc(&cty, key, keybits)) != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200714 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100715 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000716
Manuel Pégourié-Gonnardafd5a082014-05-28 21:52:59 +0200717 ctx->nr = cty.nr;
718
Gilles Peskine5511a342023-03-10 22:29:32 +0100719#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100720 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
721 mbedtls_aesni_inverse_key((unsigned char *) ctx->rk,
722 (const unsigned char *) cty.rk, ctx->nr);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200723 goto exit;
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100724 }
725#endif
726
Paul Bakker5121ce52009-01-03 21:22:43 +0000727 SK = cty.rk + cty.nr * 4;
728
729 *RK++ = *SK++;
730 *RK++ = *SK++;
731 *RK++ = *SK++;
732 *RK++ = *SK++;
733
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100734 for (i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8) {
735 for (j = 0; j < 4; j++, SK++) {
736 *RK++ = AES_RT0(FSb[MBEDTLS_BYTE_0(*SK)]) ^
737 AES_RT1(FSb[MBEDTLS_BYTE_1(*SK)]) ^
738 AES_RT2(FSb[MBEDTLS_BYTE_2(*SK)]) ^
739 AES_RT3(FSb[MBEDTLS_BYTE_3(*SK)]);
Paul Bakker5121ce52009-01-03 21:22:43 +0000740 }
741 }
742
743 *RK++ = *SK++;
744 *RK++ = *SK++;
745 *RK++ = *SK++;
746 *RK++ = *SK++;
747
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200748exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100749 mbedtls_aes_free(&cty);
Paul Bakker2b222c82009-07-27 21:03:45 +0000750
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100751 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000752}
gabor-mezei-arm95db3012020-10-26 11:35:23 +0100753#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */
Jaeden Amero9366feb2018-05-29 18:55:17 +0100754
755#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100756static int mbedtls_aes_xts_decode_keys(const unsigned char *key,
757 unsigned int keybits,
758 const unsigned char **key1,
759 unsigned int *key1bits,
760 const unsigned char **key2,
761 unsigned int *key2bits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100762{
763 const unsigned int half_keybits = keybits / 2;
764 const unsigned int half_keybytes = half_keybits / 8;
765
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100766 switch (keybits) {
Jaeden Amero9366feb2018-05-29 18:55:17 +0100767 case 256: break;
768 case 512: break;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100769 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100770 }
771
772 *key1bits = half_keybits;
773 *key2bits = half_keybits;
774 *key1 = &key[0];
775 *key2 = &key[half_keybytes];
776
777 return 0;
778}
779
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100780int mbedtls_aes_xts_setkey_enc(mbedtls_aes_xts_context *ctx,
781 const unsigned char *key,
782 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100783{
Janos Follath24eed8d2019-11-22 13:21:35 +0000784 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100785 const unsigned char *key1, *key2;
786 unsigned int key1bits, key2bits;
787
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100788 AES_VALIDATE_RET(ctx != NULL);
789 AES_VALIDATE_RET(key != NULL);
Manuel Pégourié-Gonnard68e3dff2018-12-12 12:48:04 +0100790
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100791 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
792 &key2, &key2bits);
793 if (ret != 0) {
794 return ret;
795 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100796
797 /* Set the tweak key. Always set tweak key for the encryption mode. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100798 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
799 if (ret != 0) {
800 return ret;
801 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100802
803 /* Set crypt key for encryption. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100804 return mbedtls_aes_setkey_enc(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100805}
806
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100807int mbedtls_aes_xts_setkey_dec(mbedtls_aes_xts_context *ctx,
808 const unsigned char *key,
809 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100810{
Janos Follath24eed8d2019-11-22 13:21:35 +0000811 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100812 const unsigned char *key1, *key2;
813 unsigned int key1bits, key2bits;
814
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100815 AES_VALIDATE_RET(ctx != NULL);
816 AES_VALIDATE_RET(key != NULL);
Manuel Pégourié-Gonnard68e3dff2018-12-12 12:48:04 +0100817
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100818 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
819 &key2, &key2bits);
820 if (ret != 0) {
821 return ret;
822 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100823
824 /* Set the tweak key. Always set tweak key for encryption. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100825 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
826 if (ret != 0) {
827 return ret;
828 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100829
830 /* Set crypt key for decryption. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100831 return mbedtls_aes_setkey_dec(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100832}
833#endif /* MBEDTLS_CIPHER_MODE_XTS */
834
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100835#define AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Joe Subbiani6b897c92021-07-08 14:59:52 +0100836 do \
837 { \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100838 (X0) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y0)) ^ \
839 AES_FT1(MBEDTLS_BYTE_1(Y1)) ^ \
840 AES_FT2(MBEDTLS_BYTE_2(Y2)) ^ \
841 AES_FT3(MBEDTLS_BYTE_3(Y3)); \
Joe Subbiani6b897c92021-07-08 14:59:52 +0100842 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100843 (X1) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y1)) ^ \
844 AES_FT1(MBEDTLS_BYTE_1(Y2)) ^ \
845 AES_FT2(MBEDTLS_BYTE_2(Y3)) ^ \
846 AES_FT3(MBEDTLS_BYTE_3(Y0)); \
Joe Subbiani6b897c92021-07-08 14:59:52 +0100847 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100848 (X2) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y2)) ^ \
849 AES_FT1(MBEDTLS_BYTE_1(Y3)) ^ \
850 AES_FT2(MBEDTLS_BYTE_2(Y0)) ^ \
851 AES_FT3(MBEDTLS_BYTE_3(Y1)); \
Joe Subbiani6b897c92021-07-08 14:59:52 +0100852 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100853 (X3) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y3)) ^ \
854 AES_FT1(MBEDTLS_BYTE_1(Y0)) ^ \
855 AES_FT2(MBEDTLS_BYTE_2(Y1)) ^ \
856 AES_FT3(MBEDTLS_BYTE_3(Y2)); \
857 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000858
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100859#define AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100860 do \
861 { \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100862 (X0) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y0)) ^ \
863 AES_RT1(MBEDTLS_BYTE_1(Y3)) ^ \
864 AES_RT2(MBEDTLS_BYTE_2(Y2)) ^ \
865 AES_RT3(MBEDTLS_BYTE_3(Y1)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100866 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100867 (X1) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y1)) ^ \
868 AES_RT1(MBEDTLS_BYTE_1(Y0)) ^ \
869 AES_RT2(MBEDTLS_BYTE_2(Y3)) ^ \
870 AES_RT3(MBEDTLS_BYTE_3(Y2)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100871 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100872 (X2) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y2)) ^ \
873 AES_RT1(MBEDTLS_BYTE_1(Y1)) ^ \
874 AES_RT2(MBEDTLS_BYTE_2(Y0)) ^ \
875 AES_RT3(MBEDTLS_BYTE_3(Y3)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100876 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100877 (X3) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y3)) ^ \
878 AES_RT1(MBEDTLS_BYTE_1(Y2)) ^ \
879 AES_RT2(MBEDTLS_BYTE_2(Y1)) ^ \
880 AES_RT3(MBEDTLS_BYTE_3(Y0)); \
881 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000882
883/*
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200884 * AES-ECB block encryption
885 */
886#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100887int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx,
888 const unsigned char input[16],
889 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200890{
891 int i;
Gilles Peskine5197c662020-08-26 17:03:24 +0200892 uint32_t *RK = ctx->rk;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100893 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200894 uint32_t X[4];
895 uint32_t Y[4];
896 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200897
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100898 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
899 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
900 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
901 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200902
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100903 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
904 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]);
905 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 +0200906 }
907
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100908 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 +0200909
Gilles Peskine5197c662020-08-26 17:03:24 +0200910 t.X[0] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100911 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
912 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
913 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
914 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200915
Gilles Peskine5197c662020-08-26 17:03:24 +0200916 t.X[1] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100917 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
918 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
919 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
920 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200921
Gilles Peskine5197c662020-08-26 17:03:24 +0200922 t.X[2] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100923 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
924 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
925 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
926 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200927
Gilles Peskine5197c662020-08-26 17:03:24 +0200928 t.X[3] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100929 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
930 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
931 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
932 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200933
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100934 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
935 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
936 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
937 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +0000938
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100939 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500940
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100941 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200942}
943#endif /* !MBEDTLS_AES_ENCRYPT_ALT */
944
Gilles Peskine8db3efb2018-02-21 19:16:20 +0100945#if !defined(MBEDTLS_DEPRECATED_REMOVED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100946void mbedtls_aes_encrypt(mbedtls_aes_context *ctx,
947 const unsigned char input[16],
948 unsigned char output[16])
Hanno Beckerbedc2052017-06-26 12:46:56 +0100949{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100950 MBEDTLS_IGNORE_RETURN(mbedtls_internal_aes_encrypt(ctx, input, output));
Hanno Beckerbedc2052017-06-26 12:46:56 +0100951}
Gilles Peskine8db3efb2018-02-21 19:16:20 +0100952#endif /* !MBEDTLS_DEPRECATED_REMOVED */
Hanno Beckerbedc2052017-06-26 12:46:56 +0100953
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200954/*
955 * AES-ECB block decryption
956 */
957#if !defined(MBEDTLS_AES_DECRYPT_ALT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100958int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
959 const unsigned char input[16],
960 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200961{
962 int i;
Gilles Peskine5197c662020-08-26 17:03:24 +0200963 uint32_t *RK = ctx->rk;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100964 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200965 uint32_t X[4];
966 uint32_t Y[4];
967 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200968
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100969 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
970 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
971 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
972 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200973
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100974 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
975 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]);
976 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 +0200977 }
978
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100979 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 +0200980
Gilles Peskine5197c662020-08-26 17:03:24 +0200981 t.X[0] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100982 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
983 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
984 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
985 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200986
Gilles Peskine5197c662020-08-26 17:03:24 +0200987 t.X[1] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100988 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
989 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
990 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
991 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200992
Gilles Peskine5197c662020-08-26 17:03:24 +0200993 t.X[2] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100994 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
995 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
996 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
997 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200998
Gilles Peskine5197c662020-08-26 17:03:24 +0200999 t.X[3] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001000 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
1001 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
1002 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
1003 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001004
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001005 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
1006 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
1007 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
1008 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +00001009
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001010 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -05001011
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001012 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001013}
1014#endif /* !MBEDTLS_AES_DECRYPT_ALT */
1015
Gilles Peskine8db3efb2018-02-21 19:16:20 +01001016#if !defined(MBEDTLS_DEPRECATED_REMOVED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001017void mbedtls_aes_decrypt(mbedtls_aes_context *ctx,
1018 const unsigned char input[16],
1019 unsigned char output[16])
Hanno Beckerbedc2052017-06-26 12:46:56 +01001020{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001021 MBEDTLS_IGNORE_RETURN(mbedtls_internal_aes_decrypt(ctx, input, output));
Hanno Beckerbedc2052017-06-26 12:46:56 +01001022}
Gilles Peskine8db3efb2018-02-21 19:16:20 +01001023#endif /* !MBEDTLS_DEPRECATED_REMOVED */
Hanno Beckerbedc2052017-06-26 12:46:56 +01001024
Gilles Peskineb71d4022023-03-16 17:14:59 +01001025#if defined(MAY_NEED_TO_ALIGN)
Gilles Peskine6978e732023-03-16 13:08:42 +01001026/* VIA Padlock and our intrinsics-based implementation of AESNI require
1027 * the round keys to be aligned on a 16-byte boundary. We take care of this
1028 * before creating them, but the AES context may have moved (this can happen
1029 * if the library is called from a language with managed memory), and in later
1030 * calls it might have a different alignment with respect to 16-byte memory.
1031 * So we may need to realign.
1032 * NOTE: In the LTS branch, the context contains a pointer to within itself,
1033 * so if it has been moved, things will probably go pear-shaped. We keep this
1034 * code for compatibility with the development branch, in case of future changes.
1035 */
1036static void aes_maybe_realign(mbedtls_aes_context *ctx)
1037{
Tom Cosgrove2c942a32023-03-19 14:04:04 +00001038 unsigned current_offset = (unsigned) (ctx->rk - ctx->buf);
Gilles Peskineb71d4022023-03-16 17:14:59 +01001039 unsigned new_offset = mbedtls_aes_rk_offset(ctx->buf);
1040 if (new_offset != current_offset) {
Gilles Peskine6978e732023-03-16 13:08:42 +01001041 memmove(ctx->buf + new_offset, // new address
1042 ctx->buf + current_offset, // current address
1043 (ctx->nr + 1) * 16); // number of round keys * bytes per rk
1044 ctx->rk = ctx->buf + new_offset;
1045 }
1046}
1047#endif
1048
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001049/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001050 * AES-ECB block encryption/decryption
1051 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001052int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
1053 int mode,
1054 const unsigned char input[16],
1055 unsigned char output[16])
Paul Bakker5121ce52009-01-03 21:22:43 +00001056{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001057 AES_VALIDATE_RET(ctx != NULL);
1058 AES_VALIDATE_RET(input != NULL);
1059 AES_VALIDATE_RET(output != NULL);
1060 AES_VALIDATE_RET(mode == MBEDTLS_AES_ENCRYPT ||
1061 mode == MBEDTLS_AES_DECRYPT);
Manuel Pégourié-Gonnard1aca2602018-12-12 12:56:55 +01001062
Gilles Peskineb71d4022023-03-16 17:14:59 +01001063#if defined(MAY_NEED_TO_ALIGN)
1064 aes_maybe_realign(ctx);
1065#endif
1066
Gilles Peskine5511a342023-03-10 22:29:32 +01001067#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001068 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1069 return mbedtls_aesni_crypt_ecb(ctx, mode, input, output);
1070 }
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +01001071#endif
1072
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001073#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001074 if (aes_padlock_ace) {
Gilles Peskine6978e732023-03-16 13:08:42 +01001075 return mbedtls_padlock_xcryptecb(ctx, mode, input, output);
Paul Bakker5121ce52009-01-03 21:22:43 +00001076 }
1077#endif
1078
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001079 if (mode == MBEDTLS_AES_ENCRYPT) {
1080 return mbedtls_internal_aes_encrypt(ctx, input, output);
1081 } else {
1082 return mbedtls_internal_aes_decrypt(ctx, input, output);
1083 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001084}
1085
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001086#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001087/*
1088 * AES-CBC buffer encryption/decryption
1089 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001090int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
1091 int mode,
1092 size_t length,
1093 unsigned char iv[16],
1094 const unsigned char *input,
1095 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001096{
1097 int i;
Gilles Peskine377a3102021-07-07 21:08:28 +02001098 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +00001099 unsigned char temp[16];
1100
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001101 AES_VALIDATE_RET(ctx != NULL);
1102 AES_VALIDATE_RET(mode == MBEDTLS_AES_ENCRYPT ||
1103 mode == MBEDTLS_AES_DECRYPT);
1104 AES_VALIDATE_RET(iv != NULL);
1105 AES_VALIDATE_RET(input != NULL);
1106 AES_VALIDATE_RET(output != NULL);
Manuel Pégourié-Gonnard3178d1a2018-12-12 13:05:00 +01001107
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001108 if (length % 16) {
1109 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
1110 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001111
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001112#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001113 if (aes_padlock_ace) {
1114 if (mbedtls_padlock_xcryptcbc(ctx, mode, length, iv, input, output) == 0) {
1115 return 0;
1116 }
Paul Bakker9af723c2014-05-01 13:03:14 +02001117
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001118 // If padlock data misaligned, we just fall back to
1119 // unaccelerated mode
1120 //
Paul Bakker5121ce52009-01-03 21:22:43 +00001121 }
1122#endif
1123
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001124 if (mode == MBEDTLS_AES_DECRYPT) {
1125 while (length > 0) {
1126 memcpy(temp, input, 16);
1127 ret = mbedtls_aes_crypt_ecb(ctx, mode, input, output);
1128 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +02001129 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001130 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001131
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001132 for (i = 0; i < 16; i++) {
1133 output[i] = (unsigned char) (output[i] ^ iv[i]);
1134 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001135
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001136 memcpy(iv, temp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001137
1138 input += 16;
1139 output += 16;
1140 length -= 16;
1141 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001142 } else {
1143 while (length > 0) {
1144 for (i = 0; i < 16; i++) {
1145 output[i] = (unsigned char) (input[i] ^ iv[i]);
1146 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001147
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001148 ret = mbedtls_aes_crypt_ecb(ctx, mode, output, output);
1149 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +02001150 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001151 }
1152 memcpy(iv, output, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001153
1154 input += 16;
1155 output += 16;
1156 length -= 16;
1157 }
1158 }
Gilles Peskine377a3102021-07-07 21:08:28 +02001159 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001160
Gilles Peskine377a3102021-07-07 21:08:28 +02001161exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001162 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001163}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001164#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001165
Aorimn5f778012016-06-09 23:22:58 +02001166#if defined(MBEDTLS_CIPHER_MODE_XTS)
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001167
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001168typedef unsigned char mbedtls_be128[16];
1169
1170/*
1171 * GF(2^128) multiplication function
1172 *
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001173 * This function multiplies a field element by x in the polynomial field
1174 * representation. It uses 64-bit word operations to gain speed but compensates
Shaun Case0e7791f2021-12-20 21:14:10 -08001175 * for machine endianness and hence works correctly on both big and little
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001176 * endian machines.
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001177 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001178static void mbedtls_gf128mul_x_ble(unsigned char r[16],
1179 const unsigned char x[16])
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001180{
1181 uint64_t a, b, ra, rb;
1182
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001183 a = MBEDTLS_GET_UINT64_LE(x, 0);
1184 b = MBEDTLS_GET_UINT64_LE(x, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001185
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001186 ra = (a << 1) ^ 0x0087 >> (8 - ((b >> 63) << 3));
1187 rb = (a >> 63) | (b << 1);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001188
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001189 MBEDTLS_PUT_UINT64_LE(ra, r, 0);
1190 MBEDTLS_PUT_UINT64_LE(rb, r, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001191}
1192
Aorimn5f778012016-06-09 23:22:58 +02001193/*
1194 * AES-XTS buffer encryption/decryption
1195 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001196int mbedtls_aes_crypt_xts(mbedtls_aes_xts_context *ctx,
1197 int mode,
1198 size_t length,
1199 const unsigned char data_unit[16],
1200 const unsigned char *input,
1201 unsigned char *output)
Aorimn5f778012016-06-09 23:22:58 +02001202{
Janos Follath24eed8d2019-11-22 13:21:35 +00001203 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amerod82cd862018-04-28 15:02:45 +01001204 size_t blocks = length / 16;
1205 size_t leftover = length % 16;
1206 unsigned char tweak[16];
1207 unsigned char prev_tweak[16];
1208 unsigned char tmp[16];
Aorimn5f778012016-06-09 23:22:58 +02001209
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001210 AES_VALIDATE_RET(ctx != NULL);
1211 AES_VALIDATE_RET(mode == MBEDTLS_AES_ENCRYPT ||
1212 mode == MBEDTLS_AES_DECRYPT);
1213 AES_VALIDATE_RET(data_unit != NULL);
1214 AES_VALIDATE_RET(input != NULL);
1215 AES_VALIDATE_RET(output != NULL);
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01001216
Jaeden Amero8381fcb2018-10-11 12:06:15 +01001217 /* Data units must be at least 16 bytes long. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001218 if (length < 16) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001219 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001220 }
Aorimn5f778012016-06-09 23:22:58 +02001221
Jaeden Ameroa74faba2018-10-11 12:07:43 +01001222 /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001223 if (length > (1 << 20) * 16) {
Jaeden Amero0a8b0202018-05-30 15:36:06 +01001224 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001225 }
Aorimn5f778012016-06-09 23:22:58 +02001226
Jaeden Amerod82cd862018-04-28 15:02:45 +01001227 /* Compute the tweak. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001228 ret = mbedtls_aes_crypt_ecb(&ctx->tweak, MBEDTLS_AES_ENCRYPT,
1229 data_unit, tweak);
1230 if (ret != 0) {
1231 return ret;
1232 }
Aorimn5f778012016-06-09 23:22:58 +02001233
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001234 while (blocks--) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001235 size_t i;
1236
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001237 if (leftover && (mode == MBEDTLS_AES_DECRYPT) && blocks == 0) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001238 /* We are on the last block in a decrypt operation that has
1239 * leftover bytes, so we need to use the next tweak for this block,
Tom Cosgrove49f99bc2022-12-04 16:44:21 +00001240 * and this tweak for the leftover bytes. Save the current tweak for
Jaeden Amerod82cd862018-04-28 15:02:45 +01001241 * the leftovers and then update the current tweak for use on this,
1242 * the last full block. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001243 memcpy(prev_tweak, tweak, sizeof(tweak));
1244 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001245 }
1246
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001247 for (i = 0; i < 16; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001248 tmp[i] = input[i] ^ tweak[i];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001249 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001250
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001251 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1252 if (ret != 0) {
1253 return ret;
1254 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001255
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001256 for (i = 0; i < 16; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001257 output[i] = tmp[i] ^ tweak[i];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001258 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001259
1260 /* Update the tweak for the next block. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001261 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001262
1263 output += 16;
1264 input += 16;
Aorimn5f778012016-06-09 23:22:58 +02001265 }
1266
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001267 if (leftover) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001268 /* If we are on the leftover bytes in a decrypt operation, we need to
1269 * use the previous tweak for these bytes (as saved in prev_tweak). */
1270 unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
Aorimn5f778012016-06-09 23:22:58 +02001271
Jaeden Amerod82cd862018-04-28 15:02:45 +01001272 /* We are now on the final part of the data unit, which doesn't divide
1273 * evenly by 16. It's time for ciphertext stealing. */
1274 size_t i;
1275 unsigned char *prev_output = output - 16;
Aorimn5f778012016-06-09 23:22:58 +02001276
Jaeden Amerod82cd862018-04-28 15:02:45 +01001277 /* Copy ciphertext bytes from the previous block to our output for each
Shaun Case0e7791f2021-12-20 21:14:10 -08001278 * byte of ciphertext we won't steal. At the same time, copy the
Jaeden Amerod82cd862018-04-28 15:02:45 +01001279 * remainder of the input for this final round (since the loop bounds
1280 * are the same). */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001281 for (i = 0; i < leftover; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001282 output[i] = prev_output[i];
1283 tmp[i] = input[i] ^ t[i];
Aorimn5f778012016-06-09 23:22:58 +02001284 }
Aorimn5f778012016-06-09 23:22:58 +02001285
Jaeden Amerod82cd862018-04-28 15:02:45 +01001286 /* Copy ciphertext bytes from the previous block for input in this
1287 * round. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001288 for (; i < 16; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001289 tmp[i] = prev_output[i] ^ t[i];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001290 }
Aorimn5f778012016-06-09 23:22:58 +02001291
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001292 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1293 if (ret != 0) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001294 return ret;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001295 }
Aorimn5f778012016-06-09 23:22:58 +02001296
Jaeden Amerod82cd862018-04-28 15:02:45 +01001297 /* Write the result back to the previous block, overriding the previous
1298 * output we copied. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001299 for (i = 0; i < 16; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001300 prev_output[i] = tmp[i] ^ t[i];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001301 }
Aorimn5f778012016-06-09 23:22:58 +02001302 }
1303
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001304 return 0;
Aorimn5f778012016-06-09 23:22:58 +02001305}
1306#endif /* MBEDTLS_CIPHER_MODE_XTS */
1307
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001308#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001309/*
1310 * AES-CFB128 buffer encryption/decryption
1311 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001312int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx,
1313 int mode,
1314 size_t length,
1315 size_t *iv_off,
1316 unsigned char iv[16],
1317 const unsigned char *input,
1318 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001319{
Paul Bakker27fdf462011-06-09 13:55:13 +00001320 int c;
Gilles Peskine377a3102021-07-07 21:08:28 +02001321 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001322 size_t n;
1323
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001324 AES_VALIDATE_RET(ctx != NULL);
1325 AES_VALIDATE_RET(mode == MBEDTLS_AES_ENCRYPT ||
1326 mode == MBEDTLS_AES_DECRYPT);
1327 AES_VALIDATE_RET(iv_off != NULL);
1328 AES_VALIDATE_RET(iv != NULL);
1329 AES_VALIDATE_RET(input != NULL);
1330 AES_VALIDATE_RET(output != NULL);
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001331
1332 n = *iv_off;
Paul Bakker5121ce52009-01-03 21:22:43 +00001333
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001334 if (n > 15) {
1335 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1336 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001337
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001338 if (mode == MBEDTLS_AES_DECRYPT) {
1339 while (length--) {
1340 if (n == 0) {
1341 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1342 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +02001343 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001344 }
Gilles Peskine377a3102021-07-07 21:08:28 +02001345 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001346
1347 c = *input++;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001348 *output++ = (unsigned char) (c ^ iv[n]);
Paul Bakker5121ce52009-01-03 21:22:43 +00001349 iv[n] = (unsigned char) c;
1350
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001351 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001352 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001353 } else {
1354 while (length--) {
1355 if (n == 0) {
1356 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1357 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +02001358 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001359 }
Gilles Peskine377a3102021-07-07 21:08:28 +02001360 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001361
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001362 iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++);
Paul Bakker5121ce52009-01-03 21:22:43 +00001363
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001364 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001365 }
1366 }
1367
1368 *iv_off = n;
Gilles Peskine377a3102021-07-07 21:08:28 +02001369 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001370
Gilles Peskine377a3102021-07-07 21:08:28 +02001371exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001372 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001373}
Paul Bakker556efba2014-01-24 15:38:12 +01001374
1375/*
1376 * AES-CFB8 buffer encryption/decryption
1377 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001378int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx,
1379 int mode,
1380 size_t length,
1381 unsigned char iv[16],
1382 const unsigned char *input,
1383 unsigned char *output)
Paul Bakker556efba2014-01-24 15:38:12 +01001384{
Gilles Peskine377a3102021-07-07 21:08:28 +02001385 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker556efba2014-01-24 15:38:12 +01001386 unsigned char c;
1387 unsigned char ov[17];
1388
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001389 AES_VALIDATE_RET(ctx != NULL);
1390 AES_VALIDATE_RET(mode == MBEDTLS_AES_ENCRYPT ||
1391 mode == MBEDTLS_AES_DECRYPT);
1392 AES_VALIDATE_RET(iv != NULL);
1393 AES_VALIDATE_RET(input != NULL);
1394 AES_VALIDATE_RET(output != NULL);
1395 while (length--) {
1396 memcpy(ov, iv, 16);
1397 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1398 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +02001399 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001400 }
Paul Bakker556efba2014-01-24 15:38:12 +01001401
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001402 if (mode == MBEDTLS_AES_DECRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001403 ov[16] = *input;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001404 }
Paul Bakker556efba2014-01-24 15:38:12 +01001405
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001406 c = *output++ = (unsigned char) (iv[0] ^ *input++);
Paul Bakker556efba2014-01-24 15:38:12 +01001407
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001408 if (mode == MBEDTLS_AES_ENCRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001409 ov[16] = c;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001410 }
Paul Bakker556efba2014-01-24 15:38:12 +01001411
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001412 memcpy(iv, ov + 1, 16);
Paul Bakker556efba2014-01-24 15:38:12 +01001413 }
Gilles Peskine377a3102021-07-07 21:08:28 +02001414 ret = 0;
Paul Bakker556efba2014-01-24 15:38:12 +01001415
Gilles Peskine377a3102021-07-07 21:08:28 +02001416exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001417 return ret;
Paul Bakker556efba2014-01-24 15:38:12 +01001418}
Simon Butcher76a5b222018-04-22 22:57:27 +01001419#endif /* MBEDTLS_CIPHER_MODE_CFB */
1420
1421#if defined(MBEDTLS_CIPHER_MODE_OFB)
1422/*
1423 * AES-OFB (Output Feedback Mode) buffer encryption/decryption
1424 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001425int mbedtls_aes_crypt_ofb(mbedtls_aes_context *ctx,
1426 size_t length,
1427 size_t *iv_off,
1428 unsigned char iv[16],
1429 const unsigned char *input,
1430 unsigned char *output)
Simon Butcher76a5b222018-04-22 22:57:27 +01001431{
Simon Butcherad4e4932018-04-29 00:43:47 +01001432 int ret = 0;
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001433 size_t n;
1434
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001435 AES_VALIDATE_RET(ctx != NULL);
1436 AES_VALIDATE_RET(iv_off != NULL);
1437 AES_VALIDATE_RET(iv != NULL);
1438 AES_VALIDATE_RET(input != NULL);
1439 AES_VALIDATE_RET(output != NULL);
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001440
1441 n = *iv_off;
Simon Butcher76a5b222018-04-22 22:57:27 +01001442
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001443 if (n > 15) {
1444 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1445 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001446
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001447 while (length--) {
1448 if (n == 0) {
1449 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1450 if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001451 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001452 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001453 }
Simon Butcher76a5b222018-04-22 22:57:27 +01001454 *output++ = *input++ ^ iv[n];
1455
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001456 n = (n + 1) & 0x0F;
Simon Butcher76a5b222018-04-22 22:57:27 +01001457 }
1458
1459 *iv_off = n;
1460
Simon Butcherad4e4932018-04-29 00:43:47 +01001461exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001462 return ret;
Simon Butcher76a5b222018-04-22 22:57:27 +01001463}
1464#endif /* MBEDTLS_CIPHER_MODE_OFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001465
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001466#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001467/*
1468 * AES-CTR buffer encryption/decryption
1469 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001470int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
1471 size_t length,
1472 size_t *nc_off,
1473 unsigned char nonce_counter[16],
1474 unsigned char stream_block[16],
1475 const unsigned char *input,
1476 unsigned char *output)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001477{
Paul Bakker369e14b2012-04-18 14:16:09 +00001478 int c, i;
Gilles Peskine377a3102021-07-07 21:08:28 +02001479 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001480 size_t n;
1481
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001482 AES_VALIDATE_RET(ctx != NULL);
1483 AES_VALIDATE_RET(nc_off != NULL);
1484 AES_VALIDATE_RET(nonce_counter != NULL);
1485 AES_VALIDATE_RET(stream_block != NULL);
1486 AES_VALIDATE_RET(input != NULL);
1487 AES_VALIDATE_RET(output != NULL);
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001488
1489 n = *nc_off;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001490
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001491 if (n > 0x0F) {
1492 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1493 }
Mohammad Azim Khan3f7f8172017-11-23 17:49:05 +00001494
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001495 while (length--) {
1496 if (n == 0) {
1497 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block);
1498 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +02001499 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001500 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001501
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001502 for (i = 16; i > 0; i--) {
1503 if (++nonce_counter[i - 1] != 0) {
Paul Bakker369e14b2012-04-18 14:16:09 +00001504 break;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001505 }
1506 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001507 }
1508 c = *input++;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001509 *output++ = (unsigned char) (c ^ stream_block[n]);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001510
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001511 n = (n + 1) & 0x0F;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001512 }
1513
1514 *nc_off = n;
Gilles Peskine377a3102021-07-07 21:08:28 +02001515 ret = 0;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001516
Gilles Peskine377a3102021-07-07 21:08:28 +02001517exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001518 return ret;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001519}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001520#endif /* MBEDTLS_CIPHER_MODE_CTR */
Manuel Pégourié-Gonnard1ec220b2014-03-10 11:20:17 +01001521
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001522#endif /* !MBEDTLS_AES_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001523
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001524#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001525/*
1526 * AES test vectors from:
1527 *
1528 * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
1529 */
1530static const unsigned char aes_test_ecb_dec[3][16] =
1531{
1532 { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
1533 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
1534 { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
1535 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
1536 { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
1537 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
1538};
1539
1540static const unsigned char aes_test_ecb_enc[3][16] =
1541{
1542 { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
1543 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
1544 { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
1545 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
1546 { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
1547 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
1548};
1549
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001550#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001551static const unsigned char aes_test_cbc_dec[3][16] =
1552{
1553 { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
1554 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
1555 { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
1556 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
1557 { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
1558 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
1559};
1560
1561static const unsigned char aes_test_cbc_enc[3][16] =
1562{
1563 { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
1564 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
1565 { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
1566 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
1567 { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
1568 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
1569};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001570#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001571
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001572#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001573/*
1574 * AES-CFB128 test vectors from:
1575 *
1576 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
1577 */
1578static const unsigned char aes_test_cfb128_key[3][32] =
1579{
1580 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1581 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
1582 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1583 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1584 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1585 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1586 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1587 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1588 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
1589};
1590
1591static const unsigned char aes_test_cfb128_iv[16] =
1592{
1593 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1594 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1595};
1596
1597static const unsigned char aes_test_cfb128_pt[64] =
1598{
1599 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1600 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1601 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1602 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1603 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1604 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1605 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1606 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1607};
1608
1609static const unsigned char aes_test_cfb128_ct[3][64] =
1610{
1611 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1612 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1613 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F,
1614 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B,
1615 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40,
1616 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF,
1617 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E,
1618 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 },
1619 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1620 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1621 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21,
1622 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A,
1623 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1,
1624 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9,
1625 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0,
1626 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF },
1627 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1628 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1629 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8,
1630 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B,
1631 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92,
1632 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9,
1633 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8,
1634 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 }
1635};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001636#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001637
Simon Butcherad4e4932018-04-29 00:43:47 +01001638#if defined(MBEDTLS_CIPHER_MODE_OFB)
1639/*
1640 * AES-OFB test vectors from:
1641 *
Simon Butcher5db13622018-06-04 22:11:25 +01001642 * https://csrc.nist.gov/publications/detail/sp/800-38a/final
Simon Butcherad4e4932018-04-29 00:43:47 +01001643 */
1644static const unsigned char aes_test_ofb_key[3][32] =
1645{
1646 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1647 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
1648 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1649 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1650 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1651 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1652 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1653 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1654 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
1655};
1656
1657static const unsigned char aes_test_ofb_iv[16] =
1658{
1659 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1660 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1661};
1662
1663static const unsigned char aes_test_ofb_pt[64] =
1664{
1665 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1666 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1667 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1668 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1669 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1670 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1671 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1672 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1673};
1674
1675static const unsigned char aes_test_ofb_ct[3][64] =
1676{
1677 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1678 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1679 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
1680 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
1681 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
1682 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
1683 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
1684 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e },
1685 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1686 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1687 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
1688 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
1689 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f,
1690 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
1691 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e,
1692 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a },
1693 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1694 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1695 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
1696 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
1697 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed,
1698 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
1699 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8,
1700 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 }
1701};
1702#endif /* MBEDTLS_CIPHER_MODE_OFB */
1703
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001704#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001705/*
1706 * AES-CTR test vectors from:
1707 *
1708 * http://www.faqs.org/rfcs/rfc3686.html
1709 */
1710
1711static const unsigned char aes_test_ctr_key[3][16] =
1712{
1713 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
1714 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
1715 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
1716 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
1717 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
1718 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
1719};
1720
1721static const unsigned char aes_test_ctr_nonce_counter[3][16] =
1722{
1723 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
1724 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
1725 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
1726 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
1727 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
1728 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
1729};
1730
1731static const unsigned char aes_test_ctr_pt[3][48] =
1732{
1733 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
1734 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
1735
1736 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1737 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1738 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1739 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
1740
1741 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1742 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1743 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1744 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
1745 0x20, 0x21, 0x22, 0x23 }
1746};
1747
1748static const unsigned char aes_test_ctr_ct[3][48] =
1749{
1750 { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79,
1751 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 },
1752 { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9,
1753 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88,
1754 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8,
1755 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 },
1756 { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
1757 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
1758 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
1759 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
1760 0x25, 0xB2, 0x07, 0x2F }
1761};
1762
1763static const int aes_test_ctr_len[3] =
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001764{ 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001765#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00001766
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001767#if defined(MBEDTLS_CIPHER_MODE_XTS)
1768/*
1769 * AES-XTS test vectors from:
1770 *
1771 * IEEE P1619/D16 Annex B
1772 * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf
1773 * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf)
1774 */
1775static const unsigned char aes_test_xts_key[][32] =
1776{
1777 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1778 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1779 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1780 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1781 { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1782 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1783 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1784 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1785 { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
1786 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
1787 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1788 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1789};
1790
1791static const unsigned char aes_test_xts_pt32[][32] =
1792{
1793 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1794 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1795 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1796 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1797 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1798 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1799 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1800 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1801 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1802 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1803 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1804 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1805};
1806
1807static const unsigned char aes_test_xts_ct32[][32] =
1808{
1809 { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec,
1810 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92,
1811 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85,
1812 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e },
1813 { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e,
1814 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b,
1815 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4,
1816 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 },
1817 { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a,
1818 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2,
1819 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53,
1820 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 },
1821};
1822
1823static const unsigned char aes_test_xts_data_unit[][16] =
1824{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001825 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1826 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1827 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1828 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1829 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1830 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001831};
1832
1833#endif /* MBEDTLS_CIPHER_MODE_XTS */
1834
Paul Bakker5121ce52009-01-03 21:22:43 +00001835/*
1836 * Checkup routine
1837 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001838int mbedtls_aes_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +00001839{
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001840 int ret = 0, i, j, u, mode;
1841 unsigned int keybits;
Paul Bakker5121ce52009-01-03 21:22:43 +00001842 unsigned char key[32];
1843 unsigned char buf[64];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001844 const unsigned char *aes_tests;
Andrzej Kurek8ffd8a62022-09-27 07:54:16 -04001845#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1846 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001847 unsigned char iv[16];
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03001848#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001849#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +02001850 unsigned char prv[16];
1851#endif
Simon Butcher2ff0e522018-06-14 09:57:07 +01001852#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1853 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker27fdf462011-06-09 13:55:13 +00001854 size_t offset;
Paul Bakkere91d01e2011-04-19 15:55:50 +00001855#endif
Simon Butcher66a89032018-06-15 18:20:29 +01001856#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS)
Paul Bakkere91d01e2011-04-19 15:55:50 +00001857 int len;
Simon Butcher66a89032018-06-15 18:20:29 +01001858#endif
1859#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001860 unsigned char nonce_counter[16];
1861 unsigned char stream_block[16];
1862#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001863 mbedtls_aes_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001864
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001865 memset(key, 0, 32);
1866 mbedtls_aes_init(&ctx);
Paul Bakker5121ce52009-01-03 21:22:43 +00001867
Gilles Peskine2c8ad942023-03-10 22:35:24 +01001868 if (verbose != 0) {
1869#if defined(MBEDTLS_AES_ALT)
1870 mbedtls_printf(" AES note: alternative implementation.\n");
1871#else /* MBEDTLS_AES_ALT */
1872#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
1873 if (mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE)) {
1874 mbedtls_printf(" AES note: using VIA Padlock.\n");
1875 } else
1876#endif
1877#if defined(MBEDTLS_AESNI_HAVE_CODE)
1878 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
Tom Cosgrove20458c02023-03-18 14:48:49 +00001879 mbedtls_printf(" AES note: using AESNI via ");
1880#if MBEDTLS_AESNI_HAVE_CODE == 1
1881 mbedtls_printf("assembly");
1882#elif MBEDTLS_AESNI_HAVE_CODE == 2
1883 mbedtls_printf("intrinsics");
1884#else
1885 mbedtls_printf("(unknown)");
1886#endif
1887 mbedtls_printf(".\n");
Gilles Peskine2c8ad942023-03-10 22:35:24 +01001888 } else
1889#endif
Gilles Peskine2c8ad942023-03-10 22:35:24 +01001890 mbedtls_printf(" AES note: built-in implementation.\n");
1891#endif /* MBEDTLS_AES_ALT */
1892 }
1893
Paul Bakker5121ce52009-01-03 21:22:43 +00001894 /*
1895 * ECB mode
1896 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001897 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +00001898 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001899 keybits = 128 + u * 64;
1900 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001901
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001902 if (verbose != 0) {
1903 mbedtls_printf(" AES-ECB-%3u (%s): ", keybits,
1904 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00001905 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001906
1907 memset(buf, 0, 16);
1908
1909 if (mode == MBEDTLS_AES_DECRYPT) {
1910 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1911 aes_tests = aes_test_ecb_dec[u];
1912 } else {
1913 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001914 aes_tests = aes_test_ecb_enc[u];
1915 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001916
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01001917 /*
1918 * AES-192 is an optional feature that may be unavailable when
1919 * there is an alternative underlying implementation i.e. when
1920 * MBEDTLS_AES_ALT is defined.
1921 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001922 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1923 mbedtls_printf("skipped\n");
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001924 continue;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001925 } else if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001926 goto exit;
1927 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001928
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001929 for (j = 0; j < 10000; j++) {
1930 ret = mbedtls_aes_crypt_ecb(&ctx, mode, buf, buf);
1931 if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001932 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001933 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001934 }
1935
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001936 if (memcmp(buf, aes_tests, 16) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001937 ret = 1;
1938 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001939 }
1940
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001941 if (verbose != 0) {
1942 mbedtls_printf("passed\n");
1943 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001944 }
1945
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001946 if (verbose != 0) {
1947 mbedtls_printf("\n");
1948 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001949
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001950#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001951 /*
1952 * CBC mode
1953 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001954 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +00001955 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001956 keybits = 128 + u * 64;
1957 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001958
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001959 if (verbose != 0) {
1960 mbedtls_printf(" AES-CBC-%3u (%s): ", keybits,
1961 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00001962 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001963
1964 memset(iv, 0, 16);
1965 memset(prv, 0, 16);
1966 memset(buf, 0, 16);
1967
1968 if (mode == MBEDTLS_AES_DECRYPT) {
1969 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1970 aes_tests = aes_test_cbc_dec[u];
1971 } else {
1972 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001973 aes_tests = aes_test_cbc_enc[u];
1974 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001975
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01001976 /*
1977 * AES-192 is an optional feature that may be unavailable when
1978 * there is an alternative underlying implementation i.e. when
1979 * MBEDTLS_AES_ALT is defined.
1980 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001981 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1982 mbedtls_printf("skipped\n");
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001983 continue;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001984 } else if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001985 goto exit;
1986 }
1987
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001988 for (j = 0; j < 10000; j++) {
1989 if (mode == MBEDTLS_AES_ENCRYPT) {
Paul Bakker5121ce52009-01-03 21:22:43 +00001990 unsigned char tmp[16];
1991
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001992 memcpy(tmp, prv, 16);
1993 memcpy(prv, buf, 16);
1994 memcpy(buf, tmp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001995 }
1996
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001997 ret = mbedtls_aes_crypt_cbc(&ctx, mode, 16, iv, buf, buf);
1998 if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001999 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002000 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002001
2002 }
2003
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002004 if (memcmp(buf, aes_tests, 16) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002005 ret = 1;
2006 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00002007 }
2008
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002009 if (verbose != 0) {
2010 mbedtls_printf("passed\n");
2011 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002012 }
2013
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002014 if (verbose != 0) {
2015 mbedtls_printf("\n");
2016 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002017#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00002018
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002019#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00002020 /*
2021 * CFB128 mode
2022 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002023 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +00002024 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002025 keybits = 128 + u * 64;
2026 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00002027
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002028 if (verbose != 0) {
2029 mbedtls_printf(" AES-CFB128-%3u (%s): ", keybits,
2030 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2031 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002032
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002033 memcpy(iv, aes_test_cfb128_iv, 16);
2034 memcpy(key, aes_test_cfb128_key[u], keybits / 8);
Paul Bakker5121ce52009-01-03 21:22:43 +00002035
2036 offset = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002037 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01002038 /*
2039 * AES-192 is an optional feature that may be unavailable when
2040 * there is an alternative underlying implementation i.e. when
2041 * MBEDTLS_AES_ALT is defined.
2042 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002043 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2044 mbedtls_printf("skipped\n");
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002045 continue;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002046 } else if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002047 goto exit;
2048 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002049
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002050 if (mode == MBEDTLS_AES_DECRYPT) {
2051 memcpy(buf, aes_test_cfb128_ct[u], 64);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002052 aes_tests = aes_test_cfb128_pt;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002053 } else {
2054 memcpy(buf, aes_test_cfb128_pt, 64);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002055 aes_tests = aes_test_cfb128_ct[u];
2056 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002057
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002058 ret = mbedtls_aes_crypt_cfb128(&ctx, mode, 64, &offset, iv, buf, buf);
2059 if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002060 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002061 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002062
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002063 if (memcmp(buf, aes_tests, 64) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002064 ret = 1;
2065 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00002066 }
2067
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002068 if (verbose != 0) {
2069 mbedtls_printf("passed\n");
2070 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002071 }
2072
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002073 if (verbose != 0) {
2074 mbedtls_printf("\n");
2075 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002076#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002077
Simon Butcherad4e4932018-04-29 00:43:47 +01002078#if defined(MBEDTLS_CIPHER_MODE_OFB)
2079 /*
2080 * OFB mode
2081 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002082 for (i = 0; i < 6; i++) {
Simon Butcherad4e4932018-04-29 00:43:47 +01002083 u = i >> 1;
2084 keybits = 128 + u * 64;
2085 mode = i & 1;
2086
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002087 if (verbose != 0) {
2088 mbedtls_printf(" AES-OFB-%3u (%s): ", keybits,
2089 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2090 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002091
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002092 memcpy(iv, aes_test_ofb_iv, 16);
2093 memcpy(key, aes_test_ofb_key[u], keybits / 8);
Simon Butcherad4e4932018-04-29 00:43:47 +01002094
2095 offset = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002096 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Simon Butcherad4e4932018-04-29 00:43:47 +01002097 /*
2098 * AES-192 is an optional feature that may be unavailable when
2099 * there is an alternative underlying implementation i.e. when
2100 * MBEDTLS_AES_ALT is defined.
2101 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002102 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2103 mbedtls_printf("skipped\n");
Simon Butcherad4e4932018-04-29 00:43:47 +01002104 continue;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002105 } else if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01002106 goto exit;
2107 }
2108
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002109 if (mode == MBEDTLS_AES_DECRYPT) {
2110 memcpy(buf, aes_test_ofb_ct[u], 64);
Simon Butcherad4e4932018-04-29 00:43:47 +01002111 aes_tests = aes_test_ofb_pt;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002112 } else {
2113 memcpy(buf, aes_test_ofb_pt, 64);
Simon Butcherad4e4932018-04-29 00:43:47 +01002114 aes_tests = aes_test_ofb_ct[u];
2115 }
2116
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002117 ret = mbedtls_aes_crypt_ofb(&ctx, 64, &offset, iv, buf, buf);
2118 if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01002119 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002120 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002121
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002122 if (memcmp(buf, aes_tests, 64) != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01002123 ret = 1;
2124 goto exit;
2125 }
2126
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002127 if (verbose != 0) {
2128 mbedtls_printf("passed\n");
2129 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002130 }
2131
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002132 if (verbose != 0) {
2133 mbedtls_printf("\n");
2134 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002135#endif /* MBEDTLS_CIPHER_MODE_OFB */
2136
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002137#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002138 /*
2139 * CTR mode
2140 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002141 for (i = 0; i < 6; i++) {
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002142 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002143 mode = i & 1;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002144
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002145 if (verbose != 0) {
2146 mbedtls_printf(" AES-CTR-128 (%s): ",
2147 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2148 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002149
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002150 memcpy(nonce_counter, aes_test_ctr_nonce_counter[u], 16);
2151 memcpy(key, aes_test_ctr_key[u], 16);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002152
2153 offset = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002154 if ((ret = mbedtls_aes_setkey_enc(&ctx, key, 128)) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002155 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002156 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002157
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002158 len = aes_test_ctr_len[u];
2159
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002160 if (mode == MBEDTLS_AES_DECRYPT) {
2161 memcpy(buf, aes_test_ctr_ct[u], len);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002162 aes_tests = aes_test_ctr_pt[u];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002163 } else {
2164 memcpy(buf, aes_test_ctr_pt[u], len);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002165 aes_tests = aes_test_ctr_ct[u];
2166 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002167
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002168 ret = mbedtls_aes_crypt_ctr(&ctx, len, &offset, nonce_counter,
2169 stream_block, buf, buf);
2170 if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002171 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002172 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002173
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002174 if (memcmp(buf, aes_tests, len) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002175 ret = 1;
2176 goto exit;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002177 }
2178
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002179 if (verbose != 0) {
2180 mbedtls_printf("passed\n");
2181 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002182 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002183
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002184 if (verbose != 0) {
2185 mbedtls_printf("\n");
2186 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002187#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00002188
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002189#if defined(MBEDTLS_CIPHER_MODE_XTS)
2190 {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002191 static const int num_tests =
2192 sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key);
2193 mbedtls_aes_xts_context ctx_xts;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002194
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002195 /*
2196 * XTS mode
2197 */
2198 mbedtls_aes_xts_init(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002199
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002200 for (i = 0; i < num_tests << 1; i++) {
2201 const unsigned char *data_unit;
2202 u = i >> 1;
2203 mode = i & 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002204
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002205 if (verbose != 0) {
2206 mbedtls_printf(" AES-XTS-128 (%s): ",
2207 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2208 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002209
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002210 memset(key, 0, sizeof(key));
2211 memcpy(key, aes_test_xts_key[u], 32);
2212 data_unit = aes_test_xts_data_unit[u];
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002213
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002214 len = sizeof(*aes_test_xts_ct32);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002215
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002216 if (mode == MBEDTLS_AES_DECRYPT) {
2217 ret = mbedtls_aes_xts_setkey_dec(&ctx_xts, key, 256);
2218 if (ret != 0) {
2219 goto exit;
2220 }
2221 memcpy(buf, aes_test_xts_ct32[u], len);
2222 aes_tests = aes_test_xts_pt32[u];
2223 } else {
2224 ret = mbedtls_aes_xts_setkey_enc(&ctx_xts, key, 256);
2225 if (ret != 0) {
2226 goto exit;
2227 }
2228 memcpy(buf, aes_test_xts_pt32[u], len);
2229 aes_tests = aes_test_xts_ct32[u];
2230 }
2231
2232
2233 ret = mbedtls_aes_crypt_xts(&ctx_xts, mode, len, data_unit,
2234 buf, buf);
2235 if (ret != 0) {
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002236 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002237 }
2238
2239 if (memcmp(buf, aes_tests, len) != 0) {
2240 ret = 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002241 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002242 }
2243
2244 if (verbose != 0) {
2245 mbedtls_printf("passed\n");
2246 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002247 }
2248
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002249 if (verbose != 0) {
2250 mbedtls_printf("\n");
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002251 }
2252
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002253 mbedtls_aes_xts_free(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002254 }
2255#endif /* MBEDTLS_CIPHER_MODE_XTS */
2256
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002257 ret = 0;
2258
2259exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002260 if (ret != 0 && verbose != 0) {
2261 mbedtls_printf("failed\n");
2262 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002263
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002264 mbedtls_aes_free(&ctx);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002265
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002266 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002267}
2268
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002269#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002270
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002271#endif /* MBEDTLS_AES_C */