blob: 836367cea74992cac1df75154d42ec384b2a98dd [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
Dave Rodgman7ff79652023-11-03 12:04:52 +00005 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
Paul Bakker5121ce52009-01-03 21:22:43 +00006 */
7/*
8 * The AES block cipher was designed by Vincent Rijmen and Joan Daemen.
9 *
Tom Cosgroveaaec1372023-08-04 13:53:36 +010010 * https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/aes-development/rijndael-ammended.pdf
Paul Bakker5121ce52009-01-03 21:22:43 +000011 * http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
12 */
13
Gilles Peskinedb09ef62020-06-03 01:43:33 +020014#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000015
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020016#if defined(MBEDTLS_AES_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000017
Rich Evans00ab4702015-02-06 13:43:58 +000018#include <string.h>
19
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000020#include "mbedtls/aes.h"
Ron Eldor9924bdc2018-10-04 10:59:13 +030021#include "mbedtls/platform.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050022#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000023#include "mbedtls/error.h"
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020024#if defined(MBEDTLS_PADLOCK_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000025#include "mbedtls/padlock.h"
Paul Bakker67820bd2012-06-04 12:47:23 +000026#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020027#if defined(MBEDTLS_AESNI_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000028#include "mbedtls/aesni.h"
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +010029#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000030
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000031#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010032
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020033#if !defined(MBEDTLS_AES_ALT)
Paul Bakker90995b52013-06-24 19:20:35 +020034
Manuel Pégourié-Gonnard0e9cddb2018-12-10 16:37:51 +010035/* Parameter validation macros based on platform_util.h */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010036#define AES_VALIDATE_RET(cond) \
37 MBEDTLS_INTERNAL_VALIDATE_RET(cond, MBEDTLS_ERR_AES_BAD_INPUT_DATA)
38#define AES_VALIDATE(cond) \
39 MBEDTLS_INTERNAL_VALIDATE(cond)
Manuel Pégourié-Gonnard0e9cddb2018-12-10 16:37:51 +010040
Pengyu Lv7fb6fc62023-09-14 14:02:02 +080041#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Paul Bakker048d04e2012-02-12 17:31:04 +000042static int aes_padlock_ace = -1;
43#endif
44
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020045#if defined(MBEDTLS_AES_ROM_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +000046/*
47 * Forward S-box
48 */
Dave Rodgman584b62f2023-06-27 21:03:31 +010049#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
50 !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +000051static const unsigned char FSb[256] =
52{
53 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
54 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
55 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
56 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
57 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
58 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
59 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
60 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
61 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
62 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
63 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
64 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
65 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
66 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
67 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
68 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
69 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
70 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
71 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
72 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
73 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
74 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
75 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
76 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
77 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
78 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
79 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
80 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
81 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
82 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
83 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
84 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
85};
Dave Rodgman1d0033e2023-06-29 12:07:11 +010086#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
87 !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +000088
89/*
90 * Forward tables
91 */
92#define FT \
93\
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010094 V(A5, 63, 63, C6), V(84, 7C, 7C, F8), V(99, 77, 77, EE), V(8D, 7B, 7B, F6), \
95 V(0D, F2, F2, FF), V(BD, 6B, 6B, D6), V(B1, 6F, 6F, DE), V(54, C5, C5, 91), \
96 V(50, 30, 30, 60), V(03, 01, 01, 02), V(A9, 67, 67, CE), V(7D, 2B, 2B, 56), \
97 V(19, FE, FE, E7), V(62, D7, D7, B5), V(E6, AB, AB, 4D), V(9A, 76, 76, EC), \
98 V(45, CA, CA, 8F), V(9D, 82, 82, 1F), V(40, C9, C9, 89), V(87, 7D, 7D, FA), \
99 V(15, FA, FA, EF), V(EB, 59, 59, B2), V(C9, 47, 47, 8E), V(0B, F0, F0, FB), \
100 V(EC, AD, AD, 41), V(67, D4, D4, B3), V(FD, A2, A2, 5F), V(EA, AF, AF, 45), \
101 V(BF, 9C, 9C, 23), V(F7, A4, A4, 53), V(96, 72, 72, E4), V(5B, C0, C0, 9B), \
102 V(C2, B7, B7, 75), V(1C, FD, FD, E1), V(AE, 93, 93, 3D), V(6A, 26, 26, 4C), \
103 V(5A, 36, 36, 6C), V(41, 3F, 3F, 7E), V(02, F7, F7, F5), V(4F, CC, CC, 83), \
104 V(5C, 34, 34, 68), V(F4, A5, A5, 51), V(34, E5, E5, D1), V(08, F1, F1, F9), \
105 V(93, 71, 71, E2), V(73, D8, D8, AB), V(53, 31, 31, 62), V(3F, 15, 15, 2A), \
106 V(0C, 04, 04, 08), V(52, C7, C7, 95), V(65, 23, 23, 46), V(5E, C3, C3, 9D), \
107 V(28, 18, 18, 30), V(A1, 96, 96, 37), V(0F, 05, 05, 0A), V(B5, 9A, 9A, 2F), \
108 V(09, 07, 07, 0E), V(36, 12, 12, 24), V(9B, 80, 80, 1B), V(3D, E2, E2, DF), \
109 V(26, EB, EB, CD), V(69, 27, 27, 4E), V(CD, B2, B2, 7F), V(9F, 75, 75, EA), \
110 V(1B, 09, 09, 12), V(9E, 83, 83, 1D), V(74, 2C, 2C, 58), V(2E, 1A, 1A, 34), \
111 V(2D, 1B, 1B, 36), V(B2, 6E, 6E, DC), V(EE, 5A, 5A, B4), V(FB, A0, A0, 5B), \
112 V(F6, 52, 52, A4), V(4D, 3B, 3B, 76), V(61, D6, D6, B7), V(CE, B3, B3, 7D), \
113 V(7B, 29, 29, 52), V(3E, E3, E3, DD), V(71, 2F, 2F, 5E), V(97, 84, 84, 13), \
114 V(F5, 53, 53, A6), V(68, D1, D1, B9), V(00, 00, 00, 00), V(2C, ED, ED, C1), \
115 V(60, 20, 20, 40), V(1F, FC, FC, E3), V(C8, B1, B1, 79), V(ED, 5B, 5B, B6), \
116 V(BE, 6A, 6A, D4), V(46, CB, CB, 8D), V(D9, BE, BE, 67), V(4B, 39, 39, 72), \
117 V(DE, 4A, 4A, 94), V(D4, 4C, 4C, 98), V(E8, 58, 58, B0), V(4A, CF, CF, 85), \
118 V(6B, D0, D0, BB), V(2A, EF, EF, C5), V(E5, AA, AA, 4F), V(16, FB, FB, ED), \
119 V(C5, 43, 43, 86), V(D7, 4D, 4D, 9A), V(55, 33, 33, 66), V(94, 85, 85, 11), \
120 V(CF, 45, 45, 8A), V(10, F9, F9, E9), V(06, 02, 02, 04), V(81, 7F, 7F, FE), \
121 V(F0, 50, 50, A0), V(44, 3C, 3C, 78), V(BA, 9F, 9F, 25), V(E3, A8, A8, 4B), \
122 V(F3, 51, 51, A2), V(FE, A3, A3, 5D), V(C0, 40, 40, 80), V(8A, 8F, 8F, 05), \
123 V(AD, 92, 92, 3F), V(BC, 9D, 9D, 21), V(48, 38, 38, 70), V(04, F5, F5, F1), \
124 V(DF, BC, BC, 63), V(C1, B6, B6, 77), V(75, DA, DA, AF), V(63, 21, 21, 42), \
125 V(30, 10, 10, 20), V(1A, FF, FF, E5), V(0E, F3, F3, FD), V(6D, D2, D2, BF), \
126 V(4C, CD, CD, 81), V(14, 0C, 0C, 18), V(35, 13, 13, 26), V(2F, EC, EC, C3), \
127 V(E1, 5F, 5F, BE), V(A2, 97, 97, 35), V(CC, 44, 44, 88), V(39, 17, 17, 2E), \
128 V(57, C4, C4, 93), V(F2, A7, A7, 55), V(82, 7E, 7E, FC), V(47, 3D, 3D, 7A), \
129 V(AC, 64, 64, C8), V(E7, 5D, 5D, BA), V(2B, 19, 19, 32), V(95, 73, 73, E6), \
130 V(A0, 60, 60, C0), V(98, 81, 81, 19), V(D1, 4F, 4F, 9E), V(7F, DC, DC, A3), \
131 V(66, 22, 22, 44), V(7E, 2A, 2A, 54), V(AB, 90, 90, 3B), V(83, 88, 88, 0B), \
132 V(CA, 46, 46, 8C), V(29, EE, EE, C7), V(D3, B8, B8, 6B), V(3C, 14, 14, 28), \
133 V(79, DE, DE, A7), V(E2, 5E, 5E, BC), V(1D, 0B, 0B, 16), V(76, DB, DB, AD), \
134 V(3B, E0, E0, DB), V(56, 32, 32, 64), V(4E, 3A, 3A, 74), V(1E, 0A, 0A, 14), \
135 V(DB, 49, 49, 92), V(0A, 06, 06, 0C), V(6C, 24, 24, 48), V(E4, 5C, 5C, B8), \
136 V(5D, C2, C2, 9F), V(6E, D3, D3, BD), V(EF, AC, AC, 43), V(A6, 62, 62, C4), \
137 V(A8, 91, 91, 39), V(A4, 95, 95, 31), V(37, E4, E4, D3), V(8B, 79, 79, F2), \
138 V(32, E7, E7, D5), V(43, C8, C8, 8B), V(59, 37, 37, 6E), V(B7, 6D, 6D, DA), \
139 V(8C, 8D, 8D, 01), V(64, D5, D5, B1), V(D2, 4E, 4E, 9C), V(E0, A9, A9, 49), \
140 V(B4, 6C, 6C, D8), V(FA, 56, 56, AC), V(07, F4, F4, F3), V(25, EA, EA, CF), \
141 V(AF, 65, 65, CA), V(8E, 7A, 7A, F4), V(E9, AE, AE, 47), V(18, 08, 08, 10), \
142 V(D5, BA, BA, 6F), V(88, 78, 78, F0), V(6F, 25, 25, 4A), V(72, 2E, 2E, 5C), \
143 V(24, 1C, 1C, 38), V(F1, A6, A6, 57), V(C7, B4, B4, 73), V(51, C6, C6, 97), \
144 V(23, E8, E8, CB), V(7C, DD, DD, A1), V(9C, 74, 74, E8), V(21, 1F, 1F, 3E), \
145 V(DD, 4B, 4B, 96), V(DC, BD, BD, 61), V(86, 8B, 8B, 0D), V(85, 8A, 8A, 0F), \
146 V(90, 70, 70, E0), V(42, 3E, 3E, 7C), V(C4, B5, B5, 71), V(AA, 66, 66, CC), \
147 V(D8, 48, 48, 90), V(05, 03, 03, 06), V(01, F6, F6, F7), V(12, 0E, 0E, 1C), \
148 V(A3, 61, 61, C2), V(5F, 35, 35, 6A), V(F9, 57, 57, AE), V(D0, B9, B9, 69), \
149 V(91, 86, 86, 17), V(58, C1, C1, 99), V(27, 1D, 1D, 3A), V(B9, 9E, 9E, 27), \
150 V(38, E1, E1, D9), V(13, F8, F8, EB), V(B3, 98, 98, 2B), V(33, 11, 11, 22), \
151 V(BB, 69, 69, D2), V(70, D9, D9, A9), V(89, 8E, 8E, 07), V(A7, 94, 94, 33), \
152 V(B6, 9B, 9B, 2D), V(22, 1E, 1E, 3C), V(92, 87, 87, 15), V(20, E9, E9, C9), \
153 V(49, CE, CE, 87), V(FF, 55, 55, AA), V(78, 28, 28, 50), V(7A, DF, DF, A5), \
154 V(8F, 8C, 8C, 03), V(F8, A1, A1, 59), V(80, 89, 89, 09), V(17, 0D, 0D, 1A), \
155 V(DA, BF, BF, 65), V(31, E6, E6, D7), V(C6, 42, 42, 84), V(B8, 68, 68, D0), \
156 V(C3, 41, 41, 82), V(B0, 99, 99, 29), V(77, 2D, 2D, 5A), V(11, 0F, 0F, 1E), \
157 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 +0000158
Dave Rodgman5c047d92023-06-27 19:20:27 +0100159#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100160#define V(a, b, c, d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000161static const uint32_t FT0[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000162#undef V
163
Hanno Beckerad049a92017-06-19 16:31:54 +0100164#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200165
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100166#define V(a, b, c, d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000167static const uint32_t FT1[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000168#undef V
169
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100170#define V(a, b, c, d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000171static const uint32_t FT2[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000172#undef V
173
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100174#define V(a, b, c, d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000175static const uint32_t FT3[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000176#undef V
177
Hanno Becker177d3cf2017-06-07 15:52:48 +0100178#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200179
Dave Rodgman1ce92e42023-06-29 12:01:24 +0100180#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) */
181
Paul Bakker5121ce52009-01-03 21:22:43 +0000182#undef FT
183
Dave Rodgman5c047d92023-06-27 19:20:27 +0100184#if !defined(MBEDTLS_AES_DECRYPT_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000185/*
186 * Reverse S-box
187 */
188static const unsigned char RSb[256] =
189{
190 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
191 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
192 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
193 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
194 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
195 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
196 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
197 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
198 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
199 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
200 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
201 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
202 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
203 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
204 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
205 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
206 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
207 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
208 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
209 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
210 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
211 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
212 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
213 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
214 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
215 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
216 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
217 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
218 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
219 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
220 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
221 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
222};
Dave Rodgmana4a33732023-06-29 11:58:04 +0100223#endif /* defined(MBEDTLS_AES_DECRYPT_ALT)) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000224
225/*
226 * Reverse tables
227 */
228#define RT \
229\
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100230 V(50, A7, F4, 51), V(53, 65, 41, 7E), V(C3, A4, 17, 1A), V(96, 5E, 27, 3A), \
231 V(CB, 6B, AB, 3B), V(F1, 45, 9D, 1F), V(AB, 58, FA, AC), V(93, 03, E3, 4B), \
232 V(55, FA, 30, 20), V(F6, 6D, 76, AD), V(91, 76, CC, 88), V(25, 4C, 02, F5), \
233 V(FC, D7, E5, 4F), V(D7, CB, 2A, C5), V(80, 44, 35, 26), V(8F, A3, 62, B5), \
234 V(49, 5A, B1, DE), V(67, 1B, BA, 25), V(98, 0E, EA, 45), V(E1, C0, FE, 5D), \
235 V(02, 75, 2F, C3), V(12, F0, 4C, 81), V(A3, 97, 46, 8D), V(C6, F9, D3, 6B), \
236 V(E7, 5F, 8F, 03), V(95, 9C, 92, 15), V(EB, 7A, 6D, BF), V(DA, 59, 52, 95), \
237 V(2D, 83, BE, D4), V(D3, 21, 74, 58), V(29, 69, E0, 49), V(44, C8, C9, 8E), \
238 V(6A, 89, C2, 75), V(78, 79, 8E, F4), V(6B, 3E, 58, 99), V(DD, 71, B9, 27), \
239 V(B6, 4F, E1, BE), V(17, AD, 88, F0), V(66, AC, 20, C9), V(B4, 3A, CE, 7D), \
240 V(18, 4A, DF, 63), V(82, 31, 1A, E5), V(60, 33, 51, 97), V(45, 7F, 53, 62), \
241 V(E0, 77, 64, B1), V(84, AE, 6B, BB), V(1C, A0, 81, FE), V(94, 2B, 08, F9), \
242 V(58, 68, 48, 70), V(19, FD, 45, 8F), V(87, 6C, DE, 94), V(B7, F8, 7B, 52), \
243 V(23, D3, 73, AB), V(E2, 02, 4B, 72), V(57, 8F, 1F, E3), V(2A, AB, 55, 66), \
244 V(07, 28, EB, B2), V(03, C2, B5, 2F), V(9A, 7B, C5, 86), V(A5, 08, 37, D3), \
245 V(F2, 87, 28, 30), V(B2, A5, BF, 23), V(BA, 6A, 03, 02), V(5C, 82, 16, ED), \
246 V(2B, 1C, CF, 8A), V(92, B4, 79, A7), V(F0, F2, 07, F3), V(A1, E2, 69, 4E), \
247 V(CD, F4, DA, 65), V(D5, BE, 05, 06), V(1F, 62, 34, D1), V(8A, FE, A6, C4), \
248 V(9D, 53, 2E, 34), V(A0, 55, F3, A2), V(32, E1, 8A, 05), V(75, EB, F6, A4), \
249 V(39, EC, 83, 0B), V(AA, EF, 60, 40), V(06, 9F, 71, 5E), V(51, 10, 6E, BD), \
250 V(F9, 8A, 21, 3E), V(3D, 06, DD, 96), V(AE, 05, 3E, DD), V(46, BD, E6, 4D), \
251 V(B5, 8D, 54, 91), V(05, 5D, C4, 71), V(6F, D4, 06, 04), V(FF, 15, 50, 60), \
252 V(24, FB, 98, 19), V(97, E9, BD, D6), V(CC, 43, 40, 89), V(77, 9E, D9, 67), \
253 V(BD, 42, E8, B0), V(88, 8B, 89, 07), V(38, 5B, 19, E7), V(DB, EE, C8, 79), \
254 V(47, 0A, 7C, A1), V(E9, 0F, 42, 7C), V(C9, 1E, 84, F8), V(00, 00, 00, 00), \
255 V(83, 86, 80, 09), V(48, ED, 2B, 32), V(AC, 70, 11, 1E), V(4E, 72, 5A, 6C), \
256 V(FB, FF, 0E, FD), V(56, 38, 85, 0F), V(1E, D5, AE, 3D), V(27, 39, 2D, 36), \
257 V(64, D9, 0F, 0A), V(21, A6, 5C, 68), V(D1, 54, 5B, 9B), V(3A, 2E, 36, 24), \
258 V(B1, 67, 0A, 0C), V(0F, E7, 57, 93), V(D2, 96, EE, B4), V(9E, 91, 9B, 1B), \
259 V(4F, C5, C0, 80), V(A2, 20, DC, 61), V(69, 4B, 77, 5A), V(16, 1A, 12, 1C), \
260 V(0A, BA, 93, E2), V(E5, 2A, A0, C0), V(43, E0, 22, 3C), V(1D, 17, 1B, 12), \
261 V(0B, 0D, 09, 0E), V(AD, C7, 8B, F2), V(B9, A8, B6, 2D), V(C8, A9, 1E, 14), \
262 V(85, 19, F1, 57), V(4C, 07, 75, AF), V(BB, DD, 99, EE), V(FD, 60, 7F, A3), \
263 V(9F, 26, 01, F7), V(BC, F5, 72, 5C), V(C5, 3B, 66, 44), V(34, 7E, FB, 5B), \
264 V(76, 29, 43, 8B), V(DC, C6, 23, CB), V(68, FC, ED, B6), V(63, F1, E4, B8), \
265 V(CA, DC, 31, D7), V(10, 85, 63, 42), V(40, 22, 97, 13), V(20, 11, C6, 84), \
266 V(7D, 24, 4A, 85), V(F8, 3D, BB, D2), V(11, 32, F9, AE), V(6D, A1, 29, C7), \
267 V(4B, 2F, 9E, 1D), V(F3, 30, B2, DC), V(EC, 52, 86, 0D), V(D0, E3, C1, 77), \
268 V(6C, 16, B3, 2B), V(99, B9, 70, A9), V(FA, 48, 94, 11), V(22, 64, E9, 47), \
269 V(C4, 8C, FC, A8), V(1A, 3F, F0, A0), V(D8, 2C, 7D, 56), V(EF, 90, 33, 22), \
270 V(C7, 4E, 49, 87), V(C1, D1, 38, D9), V(FE, A2, CA, 8C), V(36, 0B, D4, 98), \
271 V(CF, 81, F5, A6), V(28, DE, 7A, A5), V(26, 8E, B7, DA), V(A4, BF, AD, 3F), \
272 V(E4, 9D, 3A, 2C), V(0D, 92, 78, 50), V(9B, CC, 5F, 6A), V(62, 46, 7E, 54), \
273 V(C2, 13, 8D, F6), V(E8, B8, D8, 90), V(5E, F7, 39, 2E), V(F5, AF, C3, 82), \
274 V(BE, 80, 5D, 9F), V(7C, 93, D0, 69), V(A9, 2D, D5, 6F), V(B3, 12, 25, CF), \
275 V(3B, 99, AC, C8), V(A7, 7D, 18, 10), V(6E, 63, 9C, E8), V(7B, BB, 3B, DB), \
276 V(09, 78, 26, CD), V(F4, 18, 59, 6E), V(01, B7, 9A, EC), V(A8, 9A, 4F, 83), \
277 V(65, 6E, 95, E6), V(7E, E6, FF, AA), V(08, CF, BC, 21), V(E6, E8, 15, EF), \
278 V(D9, 9B, E7, BA), V(CE, 36, 6F, 4A), V(D4, 09, 9F, EA), V(D6, 7C, B0, 29), \
279 V(AF, B2, A4, 31), V(31, 23, 3F, 2A), V(30, 94, A5, C6), V(C0, 66, A2, 35), \
280 V(37, BC, 4E, 74), V(A6, CA, 82, FC), V(B0, D0, 90, E0), V(15, D8, A7, 33), \
281 V(4A, 98, 04, F1), V(F7, DA, EC, 41), V(0E, 50, CD, 7F), V(2F, F6, 91, 17), \
282 V(8D, D6, 4D, 76), V(4D, B0, EF, 43), V(54, 4D, AA, CC), V(DF, 04, 96, E4), \
283 V(E3, B5, D1, 9E), V(1B, 88, 6A, 4C), V(B8, 1F, 2C, C1), V(7F, 51, 65, 46), \
284 V(04, EA, 5E, 9D), V(5D, 35, 8C, 01), V(73, 74, 87, FA), V(2E, 41, 0B, FB), \
285 V(5A, 1D, 67, B3), V(52, D2, DB, 92), V(33, 56, 10, E9), V(13, 47, D6, 6D), \
286 V(8C, 61, D7, 9A), V(7A, 0C, A1, 37), V(8E, 14, F8, 59), V(89, 3C, 13, EB), \
287 V(EE, 27, A9, CE), V(35, C9, 61, B7), V(ED, E5, 1C, E1), V(3C, B1, 47, 7A), \
288 V(59, DF, D2, 9C), V(3F, 73, F2, 55), V(79, CE, 14, 18), V(BF, 37, C7, 73), \
289 V(EA, CD, F7, 53), V(5B, AA, FD, 5F), V(14, 6F, 3D, DF), V(86, DB, 44, 78), \
290 V(81, F3, AF, CA), V(3E, C4, 68, B9), V(2C, 34, 24, 38), V(5F, 40, A3, C2), \
291 V(72, C3, 1D, 16), V(0C, 25, E2, BC), V(8B, 49, 3C, 28), V(41, 95, 0D, FF), \
292 V(71, 01, A8, 39), V(DE, B3, 0C, 08), V(9C, E4, B4, D8), V(90, C1, 56, 64), \
293 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 +0000294
Dave Rodgman5c047d92023-06-27 19:20:27 +0100295#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
296
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100297#define V(a, b, c, d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000298static const uint32_t RT0[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000299#undef V
300
Hanno Beckerad049a92017-06-19 16:31:54 +0100301#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200302
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100303#define V(a, b, c, d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000304static const uint32_t RT1[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000305#undef V
306
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100307#define V(a, b, c, d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000308static const uint32_t RT2[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000309#undef V
310
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100311#define V(a, b, c, d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000312static const uint32_t RT3[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000313#undef V
314
Hanno Becker177d3cf2017-06-07 15:52:48 +0100315#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200316
Dave Rodgmanf72b8372023-06-29 16:33:03 +0100317#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
318
Paul Bakker5121ce52009-01-03 21:22:43 +0000319#undef RT
320
Dave Rodgman36c8e582023-06-27 18:31:24 +0100321#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000322/*
323 * Round constants
324 */
Jerzy Kasenberg1222ae62023-10-12 09:16:34 +0200325static const uint32_t round_constants[10] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000326{
327 0x00000001, 0x00000002, 0x00000004, 0x00000008,
328 0x00000010, 0x00000020, 0x00000040, 0x00000080,
329 0x0000001B, 0x00000036
330};
Dave Rodgman36c8e582023-06-27 18:31:24 +0100331#endif /* !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000332
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200333#else /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000334
335/*
336 * Forward S-box & tables
337 */
Dave Rodgman584b62f2023-06-27 21:03:31 +0100338#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
339 !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000340static unsigned char FSb[256];
Dave Rodgman1d0033e2023-06-29 12:07:11 +0100341#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
342 !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Dave Rodgman5c047d92023-06-27 19:20:27 +0100343#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker9af723c2014-05-01 13:03:14 +0200344static uint32_t FT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100345#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker9af723c2014-05-01 13:03:14 +0200346static uint32_t FT1[256];
347static uint32_t FT2[256];
348static uint32_t FT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100349#endif /* !MBEDTLS_AES_FEWER_TABLES */
Dave Rodgman5c047d92023-06-27 19:20:27 +0100350#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000351
352/*
353 * Reverse S-box & tables
354 */
Dave Rodgmandbae1842023-06-27 18:27:31 +0100355#if !(defined(MBEDTLS_AES_SETKEY_ENC_ALT) && defined(MBEDTLS_AES_DECRYPT_ALT))
Paul Bakker5121ce52009-01-03 21:22:43 +0000356static unsigned char RSb[256];
Dave Rodgman1d0033e2023-06-29 12:07:11 +0100357#endif /* !(defined(MBEDTLS_AES_SETKEY_ENC_ALT) && defined(MBEDTLS_AES_DECRYPT_ALT)) */
Dave Rodgman5c047d92023-06-27 19:20:27 +0100358
359#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Paul Bakker5c2364c2012-10-01 14:41:15 +0000360static uint32_t RT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100361#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker5c2364c2012-10-01 14:41:15 +0000362static uint32_t RT1[256];
363static uint32_t RT2[256];
364static uint32_t RT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100365#endif /* !MBEDTLS_AES_FEWER_TABLES */
Dave Rodgmana4a33732023-06-29 11:58:04 +0100366#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000367
Dave Rodgman1e6f7702023-06-27 18:16:13 +0100368#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000369/*
370 * Round constants
371 */
Jerzy Kasenberg1222ae62023-10-12 09:16:34 +0200372static uint32_t round_constants[10];
Paul Bakker5121ce52009-01-03 21:22:43 +0000373
374/*
375 * Tables generation code
376 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100377#define ROTL8(x) (((x) << 8) & 0xFFFFFFFF) | ((x) >> 24)
378#define XTIME(x) (((x) << 1) ^ (((x) & 0x80) ? 0x1B : 0x00))
379#define MUL(x, y) (((x) && (y)) ? pow[(log[(x)]+log[(y)]) % 255] : 0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000380
381static int aes_init_done = 0;
382
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100383static void aes_gen_tables(void)
Paul Bakker5121ce52009-01-03 21:22:43 +0000384{
385 int i, x, y, z;
386 int pow[256];
387 int log[256];
388
389 /*
390 * compute pow and log tables over GF(2^8)
391 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100392 for (i = 0, x = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000393 pow[i] = x;
394 log[x] = i;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100395 x = MBEDTLS_BYTE_0(x ^ XTIME(x));
Paul Bakker5121ce52009-01-03 21:22:43 +0000396 }
397
398 /*
399 * calculate the round constants
400 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100401 for (i = 0, x = 1; i < 10; i++) {
Jerzy Kasenberg1222ae62023-10-12 09:16:34 +0200402 round_constants[i] = (uint32_t) x;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100403 x = MBEDTLS_BYTE_0(XTIME(x));
Paul Bakker5121ce52009-01-03 21:22:43 +0000404 }
405
406 /*
407 * generate the forward and reverse S-boxes
408 */
409 FSb[0x00] = 0x63;
410 RSb[0x63] = 0x00;
411
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100412 for (i = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000413 x = pow[255 - log[i]];
414
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100415 y = x; y = MBEDTLS_BYTE_0((y << 1) | (y >> 7));
416 x ^= y; y = MBEDTLS_BYTE_0((y << 1) | (y >> 7));
417 x ^= y; y = MBEDTLS_BYTE_0((y << 1) | (y >> 7));
418 x ^= y; y = MBEDTLS_BYTE_0((y << 1) | (y >> 7));
Paul Bakker5121ce52009-01-03 21:22:43 +0000419 x ^= y ^ 0x63;
420
421 FSb[i] = (unsigned char) x;
422 RSb[x] = (unsigned char) i;
423 }
424
425 /*
426 * generate the forward and reverse tables
427 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100428 for (i = 0; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000429 x = FSb[i];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100430 y = MBEDTLS_BYTE_0(XTIME(x));
431 z = MBEDTLS_BYTE_0(y ^ x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000432
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100433 FT0[i] = ((uint32_t) y) ^
434 ((uint32_t) x << 8) ^
435 ((uint32_t) x << 16) ^
436 ((uint32_t) z << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000437
Hanno Beckerad049a92017-06-19 16:31:54 +0100438#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100439 FT1[i] = ROTL8(FT0[i]);
440 FT2[i] = ROTL8(FT1[i]);
441 FT3[i] = ROTL8(FT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100442#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000443
444 x = RSb[i];
445
Dave Rodgman5c047d92023-06-27 19:20:27 +0100446#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100447 RT0[i] = ((uint32_t) MUL(0x0E, x)) ^
448 ((uint32_t) MUL(0x09, x) << 8) ^
449 ((uint32_t) MUL(0x0D, x) << 16) ^
450 ((uint32_t) MUL(0x0B, x) << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000451
Hanno Beckerad049a92017-06-19 16:31:54 +0100452#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100453 RT1[i] = ROTL8(RT0[i]);
454 RT2[i] = ROTL8(RT1[i]);
455 RT3[i] = ROTL8(RT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100456#endif /* !MBEDTLS_AES_FEWER_TABLES */
Dave Rodgman5c047d92023-06-27 19:20:27 +0100457#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000458 }
459}
460
Dave Rodgman1e6f7702023-06-27 18:16:13 +0100461#endif /* !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
462
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200463#undef ROTL8
464
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200465#endif /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000466
Hanno Beckerad049a92017-06-19 16:31:54 +0100467#if defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200468
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100469#define ROTL8(x) ((uint32_t) ((x) << 8) + (uint32_t) ((x) >> 24))
470#define ROTL16(x) ((uint32_t) ((x) << 16) + (uint32_t) ((x) >> 16))
471#define ROTL24(x) ((uint32_t) ((x) << 24) + (uint32_t) ((x) >> 8))
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200472
473#define AES_RT0(idx) RT0[idx]
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100474#define AES_RT1(idx) ROTL8(RT0[idx])
475#define AES_RT2(idx) ROTL16(RT0[idx])
476#define AES_RT3(idx) ROTL24(RT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200477
478#define AES_FT0(idx) FT0[idx]
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100479#define AES_FT1(idx) ROTL8(FT0[idx])
480#define AES_FT2(idx) ROTL16(FT0[idx])
481#define AES_FT3(idx) ROTL24(FT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200482
Hanno Becker177d3cf2017-06-07 15:52:48 +0100483#else /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200484
485#define AES_RT0(idx) RT0[idx]
486#define AES_RT1(idx) RT1[idx]
487#define AES_RT2(idx) RT2[idx]
488#define AES_RT3(idx) RT3[idx]
489
490#define AES_FT0(idx) FT0[idx]
491#define AES_FT1(idx) FT1[idx]
492#define AES_FT2(idx) FT2[idx]
493#define AES_FT3(idx) FT3[idx]
494
Hanno Becker177d3cf2017-06-07 15:52:48 +0100495#endif /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200496
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100497void mbedtls_aes_init(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200498{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100499 AES_VALIDATE(ctx != NULL);
Simon Butcher5201e412018-12-06 17:40:14 +0000500
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100501 memset(ctx, 0, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200502}
503
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100504void mbedtls_aes_free(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200505{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100506 if (ctx == NULL) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200507 return;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100508 }
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200509
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100510 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200511}
512
Jaeden Amero9366feb2018-05-29 18:55:17 +0100513#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100514void mbedtls_aes_xts_init(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100515{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100516 AES_VALIDATE(ctx != NULL);
Simon Butcher5201e412018-12-06 17:40:14 +0000517
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100518 mbedtls_aes_init(&ctx->crypt);
519 mbedtls_aes_init(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100520}
521
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100522void mbedtls_aes_xts_free(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100523{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100524 if (ctx == NULL) {
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100525 return;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100526 }
Simon Butcher5201e412018-12-06 17:40:14 +0000527
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100528 mbedtls_aes_free(&ctx->crypt);
529 mbedtls_aes_free(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100530}
531#endif /* MBEDTLS_CIPHER_MODE_XTS */
532
Gilles Peskineb71d4022023-03-16 17:14:59 +0100533/* Some implementations need the round keys to be aligned.
534 * Return an offset to be added to buf, such that (buf + offset) is
535 * correctly aligned.
536 * Note that the offset is in units of elements of buf, i.e. 32-bit words,
537 * i.e. an offset of 1 means 4 bytes and so on.
538 */
Pengyu Lv7fb6fc62023-09-14 14:02:02 +0800539#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE) || \
Gilles Peskine6dec5412023-03-16 17:21:33 +0100540 (defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2)
Gilles Peskineb71d4022023-03-16 17:14:59 +0100541#define MAY_NEED_TO_ALIGN
542#endif
Dave Rodgman9b20aea2023-06-27 18:22:34 +0100543
Dave Rodgman584b62f2023-06-27 21:03:31 +0100544#if defined(MAY_NEED_TO_ALIGN) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) || \
545 !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskineb71d4022023-03-16 17:14:59 +0100546static unsigned mbedtls_aes_rk_offset(uint32_t *buf)
547{
548#if defined(MAY_NEED_TO_ALIGN)
549 int align_16_bytes = 0;
550
Pengyu Lv7fb6fc62023-09-14 14:02:02 +0800551#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Gilles Peskineb71d4022023-03-16 17:14:59 +0100552 if (aes_padlock_ace == -1) {
553 aes_padlock_ace = mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE);
554 }
555 if (aes_padlock_ace) {
556 align_16_bytes = 1;
557 }
558#endif
559
Gilles Peskine6dec5412023-03-16 17:21:33 +0100560#if defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2
Gilles Peskineb71d4022023-03-16 17:14:59 +0100561 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
562 align_16_bytes = 1;
563 }
564#endif
565
566 if (align_16_bytes) {
567 /* These implementations needs 16-byte alignment
568 * for the round key array. */
569 unsigned delta = ((uintptr_t) buf & 0x0000000fU) / 4;
570 if (delta == 0) {
571 return 0;
572 } else {
573 return 4 - delta; // 16 bytes = 4 uint32_t
574 }
575 }
576#else /* MAY_NEED_TO_ALIGN */
577 (void) buf;
578#endif /* MAY_NEED_TO_ALIGN */
579
580 return 0;
581}
Dave Rodgman1d0033e2023-06-29 12:07:11 +0100582#endif /* defined(MAY_NEED_TO_ALIGN) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) || \
583 !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
Gilles Peskineb71d4022023-03-16 17:14:59 +0100584
Paul Bakker5121ce52009-01-03 21:22:43 +0000585/*
586 * AES key schedule (encryption)
587 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200588#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100589int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
590 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000591{
Paul Bakker23986e52011-04-24 08:57:21 +0000592 unsigned int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000593 uint32_t *RK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000594
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100595 AES_VALIDATE_RET(ctx != NULL);
596 AES_VALIDATE_RET(key != NULL);
Paul Bakker5121ce52009-01-03 21:22:43 +0000597
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100598 switch (keybits) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000599 case 128: ctx->nr = 10; break;
600 case 192: ctx->nr = 12; break;
601 case 256: ctx->nr = 14; break;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100602 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Paul Bakker5121ce52009-01-03 21:22:43 +0000603 }
604
Simon Butcher5201e412018-12-06 17:40:14 +0000605#if !defined(MBEDTLS_AES_ROM_TABLES)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100606 if (aes_init_done == 0) {
Simon Butcher5201e412018-12-06 17:40:14 +0000607 aes_gen_tables();
608 aes_init_done = 1;
Simon Butcher5201e412018-12-06 17:40:14 +0000609 }
610#endif
611
Gilles Peskineb71d4022023-03-16 17:14:59 +0100612 ctx->rk = RK = ctx->buf + mbedtls_aes_rk_offset(ctx->buf);
Paul Bakker5121ce52009-01-03 21:22:43 +0000613
Gilles Peskine5511a342023-03-10 22:29:32 +0100614#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100615 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
616 return mbedtls_aesni_setkey_enc((unsigned char *) ctx->rk, key, keybits);
617 }
Manuel Pégourié-Gonnard47a35362013-12-28 20:45:04 +0100618#endif
619
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100620 for (i = 0; i < (keybits >> 5); i++) {
621 RK[i] = MBEDTLS_GET_UINT32_LE(key, i << 2);
Paul Bakker5121ce52009-01-03 21:22:43 +0000622 }
623
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100624 switch (ctx->nr) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000625 case 10:
626
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100627 for (i = 0; i < 10; i++, RK += 4) {
Jerzy Kasenberg1222ae62023-10-12 09:16:34 +0200628 RK[4] = RK[0] ^ round_constants[i] ^
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100629 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[3])]) ^
630 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[3])] << 8) ^
631 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[3])] << 16) ^
632 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[3])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000633
634 RK[5] = RK[1] ^ RK[4];
635 RK[6] = RK[2] ^ RK[5];
636 RK[7] = RK[3] ^ RK[6];
637 }
638 break;
639
640 case 12:
641
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100642 for (i = 0; i < 8; i++, RK += 6) {
Jerzy Kasenberg1222ae62023-10-12 09:16:34 +0200643 RK[6] = RK[0] ^ round_constants[i] ^
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100644 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[5])]) ^
645 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[5])] << 8) ^
646 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[5])] << 16) ^
647 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[5])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000648
649 RK[7] = RK[1] ^ RK[6];
650 RK[8] = RK[2] ^ RK[7];
651 RK[9] = RK[3] ^ RK[8];
652 RK[10] = RK[4] ^ RK[9];
653 RK[11] = RK[5] ^ RK[10];
654 }
655 break;
656
657 case 14:
658
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100659 for (i = 0; i < 7; i++, RK += 8) {
Jerzy Kasenberg1222ae62023-10-12 09:16:34 +0200660 RK[8] = RK[0] ^ round_constants[i] ^
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100661 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[7])]) ^
662 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[7])] << 8) ^
663 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[7])] << 16) ^
664 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[7])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000665
666 RK[9] = RK[1] ^ RK[8];
667 RK[10] = RK[2] ^ RK[9];
668 RK[11] = RK[3] ^ RK[10];
669
670 RK[12] = RK[4] ^
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100671 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[11])]) ^
672 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[11])] << 8) ^
673 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[11])] << 16) ^
674 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[11])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000675
676 RK[13] = RK[5] ^ RK[12];
677 RK[14] = RK[6] ^ RK[13];
678 RK[15] = RK[7] ^ RK[14];
679 }
680 break;
Paul Bakker5121ce52009-01-03 21:22:43 +0000681 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000682
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100683 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000684}
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200685#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000686
687/*
688 * AES key schedule (decryption)
689 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200690#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100691int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
692 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000693{
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200694 int i, j, ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200695 mbedtls_aes_context cty;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000696 uint32_t *RK;
697 uint32_t *SK;
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200698
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100699 AES_VALIDATE_RET(ctx != NULL);
700 AES_VALIDATE_RET(key != NULL);
Simon Butcher5201e412018-12-06 17:40:14 +0000701
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100702 mbedtls_aes_init(&cty);
Paul Bakker5121ce52009-01-03 21:22:43 +0000703
Gilles Peskineb71d4022023-03-16 17:14:59 +0100704 ctx->rk = RK = ctx->buf + mbedtls_aes_rk_offset(ctx->buf);
Paul Bakker5121ce52009-01-03 21:22:43 +0000705
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200706 /* Also checks keybits */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100707 if ((ret = mbedtls_aes_setkey_enc(&cty, key, keybits)) != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200708 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100709 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000710
Manuel Pégourié-Gonnardafd5a082014-05-28 21:52:59 +0200711 ctx->nr = cty.nr;
712
Gilles Peskine5511a342023-03-10 22:29:32 +0100713#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100714 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
715 mbedtls_aesni_inverse_key((unsigned char *) ctx->rk,
716 (const unsigned char *) cty.rk, ctx->nr);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200717 goto exit;
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100718 }
719#endif
720
Paul Bakker5121ce52009-01-03 21:22:43 +0000721 SK = cty.rk + cty.nr * 4;
722
723 *RK++ = *SK++;
724 *RK++ = *SK++;
725 *RK++ = *SK++;
726 *RK++ = *SK++;
727
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100728 for (i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8) {
729 for (j = 0; j < 4; j++, SK++) {
730 *RK++ = AES_RT0(FSb[MBEDTLS_BYTE_0(*SK)]) ^
731 AES_RT1(FSb[MBEDTLS_BYTE_1(*SK)]) ^
732 AES_RT2(FSb[MBEDTLS_BYTE_2(*SK)]) ^
733 AES_RT3(FSb[MBEDTLS_BYTE_3(*SK)]);
Paul Bakker5121ce52009-01-03 21:22:43 +0000734 }
735 }
736
737 *RK++ = *SK++;
738 *RK++ = *SK++;
739 *RK++ = *SK++;
740 *RK++ = *SK++;
741
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200742exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100743 mbedtls_aes_free(&cty);
Paul Bakker2b222c82009-07-27 21:03:45 +0000744
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100745 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000746}
gabor-mezei-arm95db3012020-10-26 11:35:23 +0100747#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */
Jaeden Amero9366feb2018-05-29 18:55:17 +0100748
749#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100750static int mbedtls_aes_xts_decode_keys(const unsigned char *key,
751 unsigned int keybits,
752 const unsigned char **key1,
753 unsigned int *key1bits,
754 const unsigned char **key2,
755 unsigned int *key2bits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100756{
757 const unsigned int half_keybits = keybits / 2;
758 const unsigned int half_keybytes = half_keybits / 8;
759
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100760 switch (keybits) {
Jaeden Amero9366feb2018-05-29 18:55:17 +0100761 case 256: break;
762 case 512: break;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100763 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100764 }
765
766 *key1bits = half_keybits;
767 *key2bits = half_keybits;
768 *key1 = &key[0];
769 *key2 = &key[half_keybytes];
770
771 return 0;
772}
773
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100774int mbedtls_aes_xts_setkey_enc(mbedtls_aes_xts_context *ctx,
775 const unsigned char *key,
776 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100777{
Janos Follath24eed8d2019-11-22 13:21:35 +0000778 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100779 const unsigned char *key1, *key2;
780 unsigned int key1bits, key2bits;
781
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100782 AES_VALIDATE_RET(ctx != NULL);
783 AES_VALIDATE_RET(key != NULL);
Manuel Pégourié-Gonnard68e3dff2018-12-12 12:48:04 +0100784
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100785 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
786 &key2, &key2bits);
787 if (ret != 0) {
788 return ret;
789 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100790
791 /* Set the tweak key. Always set tweak key for the encryption mode. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100792 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
793 if (ret != 0) {
794 return ret;
795 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100796
797 /* Set crypt key for encryption. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100798 return mbedtls_aes_setkey_enc(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100799}
800
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100801int mbedtls_aes_xts_setkey_dec(mbedtls_aes_xts_context *ctx,
802 const unsigned char *key,
803 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100804{
Janos Follath24eed8d2019-11-22 13:21:35 +0000805 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100806 const unsigned char *key1, *key2;
807 unsigned int key1bits, key2bits;
808
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100809 AES_VALIDATE_RET(ctx != NULL);
810 AES_VALIDATE_RET(key != NULL);
Manuel Pégourié-Gonnard68e3dff2018-12-12 12:48:04 +0100811
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100812 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
813 &key2, &key2bits);
814 if (ret != 0) {
815 return ret;
816 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100817
818 /* Set the tweak key. Always set tweak key for encryption. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100819 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
820 if (ret != 0) {
821 return ret;
822 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100823
824 /* Set crypt key for decryption. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100825 return mbedtls_aes_setkey_dec(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100826}
827#endif /* MBEDTLS_CIPHER_MODE_XTS */
828
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100829#define AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Joe Subbiani6b897c92021-07-08 14:59:52 +0100830 do \
831 { \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100832 (X0) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y0)) ^ \
833 AES_FT1(MBEDTLS_BYTE_1(Y1)) ^ \
834 AES_FT2(MBEDTLS_BYTE_2(Y2)) ^ \
835 AES_FT3(MBEDTLS_BYTE_3(Y3)); \
Joe Subbiani6b897c92021-07-08 14:59:52 +0100836 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100837 (X1) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y1)) ^ \
838 AES_FT1(MBEDTLS_BYTE_1(Y2)) ^ \
839 AES_FT2(MBEDTLS_BYTE_2(Y3)) ^ \
840 AES_FT3(MBEDTLS_BYTE_3(Y0)); \
Joe Subbiani6b897c92021-07-08 14:59:52 +0100841 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100842 (X2) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y2)) ^ \
843 AES_FT1(MBEDTLS_BYTE_1(Y3)) ^ \
844 AES_FT2(MBEDTLS_BYTE_2(Y0)) ^ \
845 AES_FT3(MBEDTLS_BYTE_3(Y1)); \
Joe Subbiani6b897c92021-07-08 14:59:52 +0100846 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100847 (X3) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y3)) ^ \
848 AES_FT1(MBEDTLS_BYTE_1(Y0)) ^ \
849 AES_FT2(MBEDTLS_BYTE_2(Y1)) ^ \
850 AES_FT3(MBEDTLS_BYTE_3(Y2)); \
851 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000852
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100853#define AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100854 do \
855 { \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100856 (X0) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y0)) ^ \
857 AES_RT1(MBEDTLS_BYTE_1(Y3)) ^ \
858 AES_RT2(MBEDTLS_BYTE_2(Y2)) ^ \
859 AES_RT3(MBEDTLS_BYTE_3(Y1)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100860 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100861 (X1) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y1)) ^ \
862 AES_RT1(MBEDTLS_BYTE_1(Y0)) ^ \
863 AES_RT2(MBEDTLS_BYTE_2(Y3)) ^ \
864 AES_RT3(MBEDTLS_BYTE_3(Y2)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100865 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100866 (X2) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y2)) ^ \
867 AES_RT1(MBEDTLS_BYTE_1(Y1)) ^ \
868 AES_RT2(MBEDTLS_BYTE_2(Y0)) ^ \
869 AES_RT3(MBEDTLS_BYTE_3(Y3)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100870 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100871 (X3) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y3)) ^ \
872 AES_RT1(MBEDTLS_BYTE_1(Y2)) ^ \
873 AES_RT2(MBEDTLS_BYTE_2(Y1)) ^ \
874 AES_RT3(MBEDTLS_BYTE_3(Y0)); \
875 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000876
877/*
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200878 * AES-ECB block encryption
879 */
880#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100881int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx,
882 const unsigned char input[16],
883 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200884{
885 int i;
Gilles Peskine5197c662020-08-26 17:03:24 +0200886 uint32_t *RK = ctx->rk;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100887 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200888 uint32_t X[4];
889 uint32_t Y[4];
890 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200891
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100892 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
893 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
894 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
895 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200896
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100897 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
898 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]);
899 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 +0200900 }
901
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100902 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 +0200903
Gilles Peskine5197c662020-08-26 17:03:24 +0200904 t.X[0] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100905 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
906 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
907 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
908 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200909
Gilles Peskine5197c662020-08-26 17:03:24 +0200910 t.X[1] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100911 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
912 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
913 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
914 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200915
Gilles Peskine5197c662020-08-26 17:03:24 +0200916 t.X[2] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100917 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
918 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
919 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
920 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200921
Gilles Peskine5197c662020-08-26 17:03:24 +0200922 t.X[3] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100923 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
924 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
925 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
926 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200927
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100928 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
929 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
930 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
931 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +0000932
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100933 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500934
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100935 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200936}
937#endif /* !MBEDTLS_AES_ENCRYPT_ALT */
938
Gilles Peskine8db3efb2018-02-21 19:16:20 +0100939#if !defined(MBEDTLS_DEPRECATED_REMOVED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100940void mbedtls_aes_encrypt(mbedtls_aes_context *ctx,
941 const unsigned char input[16],
942 unsigned char output[16])
Hanno Beckerbedc2052017-06-26 12:46:56 +0100943{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100944 MBEDTLS_IGNORE_RETURN(mbedtls_internal_aes_encrypt(ctx, input, output));
Hanno Beckerbedc2052017-06-26 12:46:56 +0100945}
Gilles Peskine8db3efb2018-02-21 19:16:20 +0100946#endif /* !MBEDTLS_DEPRECATED_REMOVED */
Hanno Beckerbedc2052017-06-26 12:46:56 +0100947
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200948/*
949 * AES-ECB block decryption
950 */
951#if !defined(MBEDTLS_AES_DECRYPT_ALT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100952int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
953 const unsigned char input[16],
954 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200955{
956 int i;
Gilles Peskine5197c662020-08-26 17:03:24 +0200957 uint32_t *RK = ctx->rk;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100958 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200959 uint32_t X[4];
960 uint32_t Y[4];
961 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200962
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100963 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
964 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
965 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
966 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200967
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100968 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
969 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]);
970 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 +0200971 }
972
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100973 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 +0200974
Gilles Peskine5197c662020-08-26 17:03:24 +0200975 t.X[0] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100976 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
977 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
978 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
979 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200980
Gilles Peskine5197c662020-08-26 17:03:24 +0200981 t.X[1] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100982 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
983 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
984 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
985 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200986
Gilles Peskine5197c662020-08-26 17:03:24 +0200987 t.X[2] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100988 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
989 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
990 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
991 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200992
Gilles Peskine5197c662020-08-26 17:03:24 +0200993 t.X[3] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100994 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
995 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
996 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
997 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200998
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100999 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
1000 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
1001 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
1002 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +00001003
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001004 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -05001005
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001006 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001007}
1008#endif /* !MBEDTLS_AES_DECRYPT_ALT */
1009
Gilles Peskine8db3efb2018-02-21 19:16:20 +01001010#if !defined(MBEDTLS_DEPRECATED_REMOVED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001011void mbedtls_aes_decrypt(mbedtls_aes_context *ctx,
1012 const unsigned char input[16],
1013 unsigned char output[16])
Hanno Beckerbedc2052017-06-26 12:46:56 +01001014{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001015 MBEDTLS_IGNORE_RETURN(mbedtls_internal_aes_decrypt(ctx, input, output));
Hanno Beckerbedc2052017-06-26 12:46:56 +01001016}
Gilles Peskine8db3efb2018-02-21 19:16:20 +01001017#endif /* !MBEDTLS_DEPRECATED_REMOVED */
Hanno Beckerbedc2052017-06-26 12:46:56 +01001018
Gilles Peskineb71d4022023-03-16 17:14:59 +01001019#if defined(MAY_NEED_TO_ALIGN)
Gilles Peskine6978e732023-03-16 13:08:42 +01001020/* VIA Padlock and our intrinsics-based implementation of AESNI require
1021 * the round keys to be aligned on a 16-byte boundary. We take care of this
1022 * before creating them, but the AES context may have moved (this can happen
1023 * if the library is called from a language with managed memory), and in later
1024 * calls it might have a different alignment with respect to 16-byte memory.
1025 * So we may need to realign.
1026 * NOTE: In the LTS branch, the context contains a pointer to within itself,
1027 * so if it has been moved, things will probably go pear-shaped. We keep this
1028 * code for compatibility with the development branch, in case of future changes.
1029 */
1030static void aes_maybe_realign(mbedtls_aes_context *ctx)
1031{
Tom Cosgrove2c942a32023-03-19 14:04:04 +00001032 unsigned current_offset = (unsigned) (ctx->rk - ctx->buf);
Gilles Peskineb71d4022023-03-16 17:14:59 +01001033 unsigned new_offset = mbedtls_aes_rk_offset(ctx->buf);
1034 if (new_offset != current_offset) {
Gilles Peskine6978e732023-03-16 13:08:42 +01001035 memmove(ctx->buf + new_offset, // new address
1036 ctx->buf + current_offset, // current address
1037 (ctx->nr + 1) * 16); // number of round keys * bytes per rk
1038 ctx->rk = ctx->buf + new_offset;
1039 }
1040}
1041#endif
1042
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001043/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001044 * AES-ECB block encryption/decryption
1045 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001046int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
1047 int mode,
1048 const unsigned char input[16],
1049 unsigned char output[16])
Paul Bakker5121ce52009-01-03 21:22:43 +00001050{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001051 AES_VALIDATE_RET(ctx != NULL);
1052 AES_VALIDATE_RET(input != NULL);
1053 AES_VALIDATE_RET(output != NULL);
1054 AES_VALIDATE_RET(mode == MBEDTLS_AES_ENCRYPT ||
1055 mode == MBEDTLS_AES_DECRYPT);
Manuel Pégourié-Gonnard1aca2602018-12-12 12:56:55 +01001056
Gilles Peskineb71d4022023-03-16 17:14:59 +01001057#if defined(MAY_NEED_TO_ALIGN)
1058 aes_maybe_realign(ctx);
1059#endif
1060
Gilles Peskine5511a342023-03-10 22:29:32 +01001061#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001062 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1063 return mbedtls_aesni_crypt_ecb(ctx, mode, input, output);
1064 }
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +01001065#endif
1066
Pengyu Lv7fb6fc62023-09-14 14:02:02 +08001067#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001068 if (aes_padlock_ace) {
Gilles Peskine6978e732023-03-16 13:08:42 +01001069 return mbedtls_padlock_xcryptecb(ctx, mode, input, output);
Paul Bakker5121ce52009-01-03 21:22:43 +00001070 }
1071#endif
1072
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001073 if (mode == MBEDTLS_AES_ENCRYPT) {
1074 return mbedtls_internal_aes_encrypt(ctx, input, output);
1075 } else {
1076 return mbedtls_internal_aes_decrypt(ctx, input, output);
1077 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001078}
1079
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001080#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001081/*
1082 * AES-CBC buffer encryption/decryption
1083 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001084int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
1085 int mode,
1086 size_t length,
1087 unsigned char iv[16],
1088 const unsigned char *input,
1089 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001090{
1091 int i;
Gilles Peskine377a3102021-07-07 21:08:28 +02001092 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +00001093 unsigned char temp[16];
1094
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001095 AES_VALIDATE_RET(ctx != NULL);
1096 AES_VALIDATE_RET(mode == MBEDTLS_AES_ENCRYPT ||
1097 mode == MBEDTLS_AES_DECRYPT);
1098 AES_VALIDATE_RET(iv != NULL);
1099 AES_VALIDATE_RET(input != NULL);
1100 AES_VALIDATE_RET(output != NULL);
Manuel Pégourié-Gonnard3178d1a2018-12-12 13:05:00 +01001101
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001102 if (length % 16) {
1103 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
1104 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001105
Pengyu Lv7fb6fc62023-09-14 14:02:02 +08001106#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001107 if (aes_padlock_ace) {
1108 if (mbedtls_padlock_xcryptcbc(ctx, mode, length, iv, input, output) == 0) {
1109 return 0;
1110 }
Paul Bakker9af723c2014-05-01 13:03:14 +02001111
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001112 // If padlock data misaligned, we just fall back to
1113 // unaccelerated mode
1114 //
Paul Bakker5121ce52009-01-03 21:22:43 +00001115 }
1116#endif
1117
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001118 if (mode == MBEDTLS_AES_DECRYPT) {
1119 while (length > 0) {
1120 memcpy(temp, input, 16);
1121 ret = mbedtls_aes_crypt_ecb(ctx, mode, input, output);
1122 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +02001123 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001124 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001125
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001126 for (i = 0; i < 16; i++) {
1127 output[i] = (unsigned char) (output[i] ^ iv[i]);
1128 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001129
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001130 memcpy(iv, temp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001131
1132 input += 16;
1133 output += 16;
1134 length -= 16;
1135 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001136 } else {
1137 while (length > 0) {
1138 for (i = 0; i < 16; i++) {
1139 output[i] = (unsigned char) (input[i] ^ iv[i]);
1140 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001141
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001142 ret = mbedtls_aes_crypt_ecb(ctx, mode, output, output);
1143 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +02001144 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001145 }
1146 memcpy(iv, output, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001147
1148 input += 16;
1149 output += 16;
1150 length -= 16;
1151 }
1152 }
Gilles Peskine377a3102021-07-07 21:08:28 +02001153 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001154
Gilles Peskine377a3102021-07-07 21:08:28 +02001155exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001156 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001157}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001158#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001159
Aorimn5f778012016-06-09 23:22:58 +02001160#if defined(MBEDTLS_CIPHER_MODE_XTS)
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001161
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001162typedef unsigned char mbedtls_be128[16];
1163
1164/*
1165 * GF(2^128) multiplication function
1166 *
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001167 * This function multiplies a field element by x in the polynomial field
1168 * representation. It uses 64-bit word operations to gain speed but compensates
Shaun Case0e7791f2021-12-20 21:14:10 -08001169 * for machine endianness and hence works correctly on both big and little
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001170 * endian machines.
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001171 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001172static void mbedtls_gf128mul_x_ble(unsigned char r[16],
1173 const unsigned char x[16])
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001174{
1175 uint64_t a, b, ra, rb;
1176
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001177 a = MBEDTLS_GET_UINT64_LE(x, 0);
1178 b = MBEDTLS_GET_UINT64_LE(x, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001179
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001180 ra = (a << 1) ^ 0x0087 >> (8 - ((b >> 63) << 3));
1181 rb = (a >> 63) | (b << 1);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001182
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001183 MBEDTLS_PUT_UINT64_LE(ra, r, 0);
1184 MBEDTLS_PUT_UINT64_LE(rb, r, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001185}
1186
Aorimn5f778012016-06-09 23:22:58 +02001187/*
1188 * AES-XTS buffer encryption/decryption
1189 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001190int mbedtls_aes_crypt_xts(mbedtls_aes_xts_context *ctx,
1191 int mode,
1192 size_t length,
1193 const unsigned char data_unit[16],
1194 const unsigned char *input,
1195 unsigned char *output)
Aorimn5f778012016-06-09 23:22:58 +02001196{
Janos Follath24eed8d2019-11-22 13:21:35 +00001197 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amerod82cd862018-04-28 15:02:45 +01001198 size_t blocks = length / 16;
1199 size_t leftover = length % 16;
1200 unsigned char tweak[16];
1201 unsigned char prev_tweak[16];
1202 unsigned char tmp[16];
Aorimn5f778012016-06-09 23:22:58 +02001203
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001204 AES_VALIDATE_RET(ctx != NULL);
1205 AES_VALIDATE_RET(mode == MBEDTLS_AES_ENCRYPT ||
1206 mode == MBEDTLS_AES_DECRYPT);
1207 AES_VALIDATE_RET(data_unit != NULL);
1208 AES_VALIDATE_RET(input != NULL);
1209 AES_VALIDATE_RET(output != NULL);
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01001210
Jaeden Amero8381fcb2018-10-11 12:06:15 +01001211 /* Data units must be at least 16 bytes long. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001212 if (length < 16) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001213 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001214 }
Aorimn5f778012016-06-09 23:22:58 +02001215
Jaeden Ameroa74faba2018-10-11 12:07:43 +01001216 /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001217 if (length > (1 << 20) * 16) {
Jaeden Amero0a8b0202018-05-30 15:36:06 +01001218 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001219 }
Aorimn5f778012016-06-09 23:22:58 +02001220
Jaeden Amerod82cd862018-04-28 15:02:45 +01001221 /* Compute the tweak. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001222 ret = mbedtls_aes_crypt_ecb(&ctx->tweak, MBEDTLS_AES_ENCRYPT,
1223 data_unit, tweak);
1224 if (ret != 0) {
1225 return ret;
1226 }
Aorimn5f778012016-06-09 23:22:58 +02001227
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001228 while (blocks--) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001229 size_t i;
1230
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001231 if (leftover && (mode == MBEDTLS_AES_DECRYPT) && blocks == 0) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001232 /* We are on the last block in a decrypt operation that has
1233 * leftover bytes, so we need to use the next tweak for this block,
Tom Cosgrove49f99bc2022-12-04 16:44:21 +00001234 * and this tweak for the leftover bytes. Save the current tweak for
Jaeden Amerod82cd862018-04-28 15:02:45 +01001235 * the leftovers and then update the current tweak for use on this,
1236 * the last full block. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001237 memcpy(prev_tweak, tweak, sizeof(tweak));
1238 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001239 }
1240
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001241 for (i = 0; i < 16; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001242 tmp[i] = input[i] ^ tweak[i];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001243 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001244
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001245 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1246 if (ret != 0) {
1247 return ret;
1248 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001249
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001250 for (i = 0; i < 16; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001251 output[i] = tmp[i] ^ tweak[i];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001252 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001253
1254 /* Update the tweak for the next block. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001255 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001256
1257 output += 16;
1258 input += 16;
Aorimn5f778012016-06-09 23:22:58 +02001259 }
1260
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001261 if (leftover) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001262 /* If we are on the leftover bytes in a decrypt operation, we need to
1263 * use the previous tweak for these bytes (as saved in prev_tweak). */
1264 unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
Aorimn5f778012016-06-09 23:22:58 +02001265
Jaeden Amerod82cd862018-04-28 15:02:45 +01001266 /* We are now on the final part of the data unit, which doesn't divide
1267 * evenly by 16. It's time for ciphertext stealing. */
1268 size_t i;
1269 unsigned char *prev_output = output - 16;
Aorimn5f778012016-06-09 23:22:58 +02001270
Jaeden Amerod82cd862018-04-28 15:02:45 +01001271 /* Copy ciphertext bytes from the previous block to our output for each
Shaun Case0e7791f2021-12-20 21:14:10 -08001272 * byte of ciphertext we won't steal. At the same time, copy the
Jaeden Amerod82cd862018-04-28 15:02:45 +01001273 * remainder of the input for this final round (since the loop bounds
1274 * are the same). */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001275 for (i = 0; i < leftover; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001276 output[i] = prev_output[i];
1277 tmp[i] = input[i] ^ t[i];
Aorimn5f778012016-06-09 23:22:58 +02001278 }
Aorimn5f778012016-06-09 23:22:58 +02001279
Jaeden Amerod82cd862018-04-28 15:02:45 +01001280 /* Copy ciphertext bytes from the previous block for input in this
1281 * round. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001282 for (; i < 16; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001283 tmp[i] = prev_output[i] ^ t[i];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001284 }
Aorimn5f778012016-06-09 23:22:58 +02001285
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001286 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1287 if (ret != 0) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001288 return ret;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001289 }
Aorimn5f778012016-06-09 23:22:58 +02001290
Jaeden Amerod82cd862018-04-28 15:02:45 +01001291 /* Write the result back to the previous block, overriding the previous
1292 * output we copied. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001293 for (i = 0; i < 16; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001294 prev_output[i] = tmp[i] ^ t[i];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001295 }
Aorimn5f778012016-06-09 23:22:58 +02001296 }
1297
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001298 return 0;
Aorimn5f778012016-06-09 23:22:58 +02001299}
1300#endif /* MBEDTLS_CIPHER_MODE_XTS */
1301
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001302#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001303/*
1304 * AES-CFB128 buffer encryption/decryption
1305 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001306int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx,
1307 int mode,
1308 size_t length,
1309 size_t *iv_off,
1310 unsigned char iv[16],
1311 const unsigned char *input,
1312 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001313{
Paul Bakker27fdf462011-06-09 13:55:13 +00001314 int c;
Gilles Peskine377a3102021-07-07 21:08:28 +02001315 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001316 size_t n;
1317
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001318 AES_VALIDATE_RET(ctx != NULL);
1319 AES_VALIDATE_RET(mode == MBEDTLS_AES_ENCRYPT ||
1320 mode == MBEDTLS_AES_DECRYPT);
1321 AES_VALIDATE_RET(iv_off != NULL);
1322 AES_VALIDATE_RET(iv != NULL);
1323 AES_VALIDATE_RET(input != NULL);
1324 AES_VALIDATE_RET(output != NULL);
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001325
1326 n = *iv_off;
Paul Bakker5121ce52009-01-03 21:22:43 +00001327
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001328 if (n > 15) {
1329 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1330 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001331
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001332 if (mode == MBEDTLS_AES_DECRYPT) {
1333 while (length--) {
1334 if (n == 0) {
1335 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1336 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +02001337 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001338 }
Gilles Peskine377a3102021-07-07 21:08:28 +02001339 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001340
1341 c = *input++;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001342 *output++ = (unsigned char) (c ^ iv[n]);
Paul Bakker5121ce52009-01-03 21:22:43 +00001343 iv[n] = (unsigned char) c;
1344
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001345 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001346 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001347 } else {
1348 while (length--) {
1349 if (n == 0) {
1350 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1351 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +02001352 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001353 }
Gilles Peskine377a3102021-07-07 21:08:28 +02001354 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001355
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001356 iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++);
Paul Bakker5121ce52009-01-03 21:22:43 +00001357
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001358 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001359 }
1360 }
1361
1362 *iv_off = n;
Gilles Peskine377a3102021-07-07 21:08:28 +02001363 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001364
Gilles Peskine377a3102021-07-07 21:08:28 +02001365exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001366 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001367}
Paul Bakker556efba2014-01-24 15:38:12 +01001368
1369/*
1370 * AES-CFB8 buffer encryption/decryption
1371 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001372int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx,
1373 int mode,
1374 size_t length,
1375 unsigned char iv[16],
1376 const unsigned char *input,
1377 unsigned char *output)
Paul Bakker556efba2014-01-24 15:38:12 +01001378{
Gilles Peskine377a3102021-07-07 21:08:28 +02001379 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker556efba2014-01-24 15:38:12 +01001380 unsigned char c;
1381 unsigned char ov[17];
1382
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001383 AES_VALIDATE_RET(ctx != NULL);
1384 AES_VALIDATE_RET(mode == MBEDTLS_AES_ENCRYPT ||
1385 mode == MBEDTLS_AES_DECRYPT);
1386 AES_VALIDATE_RET(iv != NULL);
1387 AES_VALIDATE_RET(input != NULL);
1388 AES_VALIDATE_RET(output != NULL);
1389 while (length--) {
1390 memcpy(ov, iv, 16);
1391 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1392 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +02001393 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001394 }
Paul Bakker556efba2014-01-24 15:38:12 +01001395
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001396 if (mode == MBEDTLS_AES_DECRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001397 ov[16] = *input;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001398 }
Paul Bakker556efba2014-01-24 15:38:12 +01001399
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001400 c = *output++ = (unsigned char) (iv[0] ^ *input++);
Paul Bakker556efba2014-01-24 15:38:12 +01001401
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001402 if (mode == MBEDTLS_AES_ENCRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001403 ov[16] = c;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001404 }
Paul Bakker556efba2014-01-24 15:38:12 +01001405
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001406 memcpy(iv, ov + 1, 16);
Paul Bakker556efba2014-01-24 15:38:12 +01001407 }
Gilles Peskine377a3102021-07-07 21:08:28 +02001408 ret = 0;
Paul Bakker556efba2014-01-24 15:38:12 +01001409
Gilles Peskine377a3102021-07-07 21:08:28 +02001410exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001411 return ret;
Paul Bakker556efba2014-01-24 15:38:12 +01001412}
Simon Butcher76a5b222018-04-22 22:57:27 +01001413#endif /* MBEDTLS_CIPHER_MODE_CFB */
1414
1415#if defined(MBEDTLS_CIPHER_MODE_OFB)
1416/*
1417 * AES-OFB (Output Feedback Mode) buffer encryption/decryption
1418 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001419int mbedtls_aes_crypt_ofb(mbedtls_aes_context *ctx,
1420 size_t length,
1421 size_t *iv_off,
1422 unsigned char iv[16],
1423 const unsigned char *input,
1424 unsigned char *output)
Simon Butcher76a5b222018-04-22 22:57:27 +01001425{
Simon Butcherad4e4932018-04-29 00:43:47 +01001426 int ret = 0;
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001427 size_t n;
1428
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001429 AES_VALIDATE_RET(ctx != NULL);
1430 AES_VALIDATE_RET(iv_off != NULL);
1431 AES_VALIDATE_RET(iv != NULL);
1432 AES_VALIDATE_RET(input != NULL);
1433 AES_VALIDATE_RET(output != NULL);
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001434
1435 n = *iv_off;
Simon Butcher76a5b222018-04-22 22:57:27 +01001436
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001437 if (n > 15) {
1438 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1439 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001440
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001441 while (length--) {
1442 if (n == 0) {
1443 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1444 if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001445 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001446 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001447 }
Simon Butcher76a5b222018-04-22 22:57:27 +01001448 *output++ = *input++ ^ iv[n];
1449
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001450 n = (n + 1) & 0x0F;
Simon Butcher76a5b222018-04-22 22:57:27 +01001451 }
1452
1453 *iv_off = n;
1454
Simon Butcherad4e4932018-04-29 00:43:47 +01001455exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001456 return ret;
Simon Butcher76a5b222018-04-22 22:57:27 +01001457}
1458#endif /* MBEDTLS_CIPHER_MODE_OFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001459
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001460#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001461/*
1462 * AES-CTR buffer encryption/decryption
1463 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001464int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
1465 size_t length,
1466 size_t *nc_off,
1467 unsigned char nonce_counter[16],
1468 unsigned char stream_block[16],
1469 const unsigned char *input,
1470 unsigned char *output)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001471{
Paul Bakker369e14b2012-04-18 14:16:09 +00001472 int c, i;
Gilles Peskine377a3102021-07-07 21:08:28 +02001473 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001474 size_t n;
1475
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001476 AES_VALIDATE_RET(ctx != NULL);
1477 AES_VALIDATE_RET(nc_off != NULL);
1478 AES_VALIDATE_RET(nonce_counter != NULL);
1479 AES_VALIDATE_RET(stream_block != NULL);
1480 AES_VALIDATE_RET(input != NULL);
1481 AES_VALIDATE_RET(output != NULL);
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001482
1483 n = *nc_off;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001484
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001485 if (n > 0x0F) {
1486 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1487 }
Mohammad Azim Khan3f7f8172017-11-23 17:49:05 +00001488
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001489 while (length--) {
1490 if (n == 0) {
1491 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block);
1492 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +02001493 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001494 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001495
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001496 for (i = 16; i > 0; i--) {
1497 if (++nonce_counter[i - 1] != 0) {
Paul Bakker369e14b2012-04-18 14:16:09 +00001498 break;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001499 }
1500 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001501 }
1502 c = *input++;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001503 *output++ = (unsigned char) (c ^ stream_block[n]);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001504
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001505 n = (n + 1) & 0x0F;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001506 }
1507
1508 *nc_off = n;
Gilles Peskine377a3102021-07-07 21:08:28 +02001509 ret = 0;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001510
Gilles Peskine377a3102021-07-07 21:08:28 +02001511exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001512 return ret;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001513}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001514#endif /* MBEDTLS_CIPHER_MODE_CTR */
Manuel Pégourié-Gonnard1ec220b2014-03-10 11:20:17 +01001515
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001516#endif /* !MBEDTLS_AES_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001517
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001518#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001519/*
1520 * AES test vectors from:
1521 *
1522 * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
1523 */
1524static const unsigned char aes_test_ecb_dec[3][16] =
1525{
1526 { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
1527 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
1528 { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
1529 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
1530 { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
1531 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
1532};
1533
1534static const unsigned char aes_test_ecb_enc[3][16] =
1535{
1536 { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
1537 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
1538 { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
1539 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
1540 { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
1541 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
1542};
1543
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001544#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001545static const unsigned char aes_test_cbc_dec[3][16] =
1546{
1547 { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
1548 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
1549 { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
1550 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
1551 { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
1552 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
1553};
1554
1555static const unsigned char aes_test_cbc_enc[3][16] =
1556{
1557 { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
1558 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
1559 { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
1560 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
1561 { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
1562 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
1563};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001564#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001565
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001566#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001567/*
1568 * AES-CFB128 test vectors from:
1569 *
1570 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
1571 */
1572static const unsigned char aes_test_cfb128_key[3][32] =
1573{
1574 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1575 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
1576 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1577 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1578 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1579 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1580 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1581 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1582 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
1583};
1584
1585static const unsigned char aes_test_cfb128_iv[16] =
1586{
1587 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1588 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1589};
1590
1591static const unsigned char aes_test_cfb128_pt[64] =
1592{
1593 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1594 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1595 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1596 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1597 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1598 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1599 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1600 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1601};
1602
1603static const unsigned char aes_test_cfb128_ct[3][64] =
1604{
1605 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1606 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1607 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F,
1608 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B,
1609 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40,
1610 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF,
1611 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E,
1612 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 },
1613 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1614 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1615 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21,
1616 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A,
1617 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1,
1618 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9,
1619 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0,
1620 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF },
1621 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1622 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1623 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8,
1624 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B,
1625 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92,
1626 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9,
1627 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8,
1628 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 }
1629};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001630#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001631
Simon Butcherad4e4932018-04-29 00:43:47 +01001632#if defined(MBEDTLS_CIPHER_MODE_OFB)
1633/*
1634 * AES-OFB test vectors from:
1635 *
Simon Butcher5db13622018-06-04 22:11:25 +01001636 * https://csrc.nist.gov/publications/detail/sp/800-38a/final
Simon Butcherad4e4932018-04-29 00:43:47 +01001637 */
1638static const unsigned char aes_test_ofb_key[3][32] =
1639{
1640 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1641 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
1642 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1643 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1644 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1645 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1646 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1647 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1648 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
1649};
1650
1651static const unsigned char aes_test_ofb_iv[16] =
1652{
1653 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1654 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1655};
1656
1657static const unsigned char aes_test_ofb_pt[64] =
1658{
1659 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1660 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1661 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1662 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1663 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1664 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1665 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1666 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1667};
1668
1669static const unsigned char aes_test_ofb_ct[3][64] =
1670{
1671 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1672 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1673 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
1674 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
1675 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
1676 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
1677 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
1678 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e },
1679 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1680 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1681 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
1682 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
1683 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f,
1684 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
1685 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e,
1686 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a },
1687 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1688 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1689 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
1690 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
1691 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed,
1692 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
1693 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8,
1694 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 }
1695};
1696#endif /* MBEDTLS_CIPHER_MODE_OFB */
1697
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001698#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001699/*
1700 * AES-CTR test vectors from:
1701 *
1702 * http://www.faqs.org/rfcs/rfc3686.html
1703 */
1704
1705static const unsigned char aes_test_ctr_key[3][16] =
1706{
1707 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
1708 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
1709 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
1710 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
1711 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
1712 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
1713};
1714
1715static const unsigned char aes_test_ctr_nonce_counter[3][16] =
1716{
1717 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
1718 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
1719 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
1720 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
1721 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
1722 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
1723};
1724
1725static const unsigned char aes_test_ctr_pt[3][48] =
1726{
1727 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
1728 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
1729
1730 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1731 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1732 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1733 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
1734
1735 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1736 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1737 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1738 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
1739 0x20, 0x21, 0x22, 0x23 }
1740};
1741
1742static const unsigned char aes_test_ctr_ct[3][48] =
1743{
1744 { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79,
1745 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 },
1746 { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9,
1747 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88,
1748 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8,
1749 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 },
1750 { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
1751 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
1752 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
1753 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
1754 0x25, 0xB2, 0x07, 0x2F }
1755};
1756
1757static const int aes_test_ctr_len[3] =
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001758{ 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001759#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00001760
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001761#if defined(MBEDTLS_CIPHER_MODE_XTS)
1762/*
1763 * AES-XTS test vectors from:
1764 *
1765 * IEEE P1619/D16 Annex B
1766 * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf
1767 * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf)
1768 */
1769static const unsigned char aes_test_xts_key[][32] =
1770{
1771 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1772 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1773 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1774 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1775 { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1776 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1777 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1778 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1779 { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
1780 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
1781 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1782 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1783};
1784
1785static const unsigned char aes_test_xts_pt32[][32] =
1786{
1787 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1788 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1789 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1790 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1791 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1792 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1793 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1794 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1795 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1796 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1797 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1798 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1799};
1800
1801static const unsigned char aes_test_xts_ct32[][32] =
1802{
1803 { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec,
1804 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92,
1805 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85,
1806 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e },
1807 { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e,
1808 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b,
1809 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4,
1810 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 },
1811 { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a,
1812 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2,
1813 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53,
1814 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 },
1815};
1816
1817static const unsigned char aes_test_xts_data_unit[][16] =
1818{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001819 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1820 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1821 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1822 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1823 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1824 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001825};
1826
1827#endif /* MBEDTLS_CIPHER_MODE_XTS */
1828
Paul Bakker5121ce52009-01-03 21:22:43 +00001829/*
1830 * Checkup routine
1831 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001832int mbedtls_aes_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +00001833{
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001834 int ret = 0, i, j, u, mode;
1835 unsigned int keybits;
Paul Bakker5121ce52009-01-03 21:22:43 +00001836 unsigned char key[32];
1837 unsigned char buf[64];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001838 const unsigned char *aes_tests;
Andrzej Kurek8ffd8a62022-09-27 07:54:16 -04001839#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1840 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001841 unsigned char iv[16];
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03001842#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001843#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +02001844 unsigned char prv[16];
1845#endif
Simon Butcher2ff0e522018-06-14 09:57:07 +01001846#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1847 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker27fdf462011-06-09 13:55:13 +00001848 size_t offset;
Paul Bakkere91d01e2011-04-19 15:55:50 +00001849#endif
Simon Butcher66a89032018-06-15 18:20:29 +01001850#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS)
Paul Bakkere91d01e2011-04-19 15:55:50 +00001851 int len;
Simon Butcher66a89032018-06-15 18:20:29 +01001852#endif
1853#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001854 unsigned char nonce_counter[16];
1855 unsigned char stream_block[16];
1856#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001857 mbedtls_aes_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001858
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001859 memset(key, 0, 32);
1860 mbedtls_aes_init(&ctx);
Paul Bakker5121ce52009-01-03 21:22:43 +00001861
Gilles Peskine2c8ad942023-03-10 22:35:24 +01001862 if (verbose != 0) {
1863#if defined(MBEDTLS_AES_ALT)
1864 mbedtls_printf(" AES note: alternative implementation.\n");
1865#else /* MBEDTLS_AES_ALT */
Pengyu Lv7fb6fc62023-09-14 14:02:02 +08001866#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Gilles Peskine2c8ad942023-03-10 22:35:24 +01001867 if (mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE)) {
1868 mbedtls_printf(" AES note: using VIA Padlock.\n");
1869 } else
1870#endif
1871#if defined(MBEDTLS_AESNI_HAVE_CODE)
1872 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
Tom Cosgrove20458c02023-03-18 14:48:49 +00001873 mbedtls_printf(" AES note: using AESNI via ");
1874#if MBEDTLS_AESNI_HAVE_CODE == 1
1875 mbedtls_printf("assembly");
1876#elif MBEDTLS_AESNI_HAVE_CODE == 2
1877 mbedtls_printf("intrinsics");
1878#else
1879 mbedtls_printf("(unknown)");
1880#endif
1881 mbedtls_printf(".\n");
Gilles Peskine2c8ad942023-03-10 22:35:24 +01001882 } else
1883#endif
Gilles Peskine2c8ad942023-03-10 22:35:24 +01001884 mbedtls_printf(" AES note: built-in implementation.\n");
1885#endif /* MBEDTLS_AES_ALT */
1886 }
1887
Paul Bakker5121ce52009-01-03 21:22:43 +00001888 /*
1889 * ECB mode
1890 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001891 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +00001892 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001893 keybits = 128 + u * 64;
1894 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001895
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001896 if (verbose != 0) {
1897 mbedtls_printf(" AES-ECB-%3u (%s): ", keybits,
1898 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00001899 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001900
1901 memset(buf, 0, 16);
1902
1903 if (mode == MBEDTLS_AES_DECRYPT) {
1904 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1905 aes_tests = aes_test_ecb_dec[u];
1906 } else {
1907 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001908 aes_tests = aes_test_ecb_enc[u];
1909 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001910
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01001911 /*
1912 * AES-192 is an optional feature that may be unavailable when
1913 * there is an alternative underlying implementation i.e. when
1914 * MBEDTLS_AES_ALT is defined.
1915 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001916 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1917 mbedtls_printf("skipped\n");
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001918 continue;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001919 } else if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001920 goto exit;
1921 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001922
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001923 for (j = 0; j < 10000; j++) {
1924 ret = mbedtls_aes_crypt_ecb(&ctx, mode, buf, buf);
1925 if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001926 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001927 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001928 }
1929
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001930 if (memcmp(buf, aes_tests, 16) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001931 ret = 1;
1932 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001933 }
1934
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001935 if (verbose != 0) {
1936 mbedtls_printf("passed\n");
1937 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001938 }
1939
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001940 if (verbose != 0) {
1941 mbedtls_printf("\n");
1942 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001943
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001944#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001945 /*
1946 * CBC mode
1947 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001948 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +00001949 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001950 keybits = 128 + u * 64;
1951 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001952
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001953 if (verbose != 0) {
1954 mbedtls_printf(" AES-CBC-%3u (%s): ", keybits,
1955 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00001956 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001957
1958 memset(iv, 0, 16);
1959 memset(prv, 0, 16);
1960 memset(buf, 0, 16);
1961
1962 if (mode == MBEDTLS_AES_DECRYPT) {
1963 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1964 aes_tests = aes_test_cbc_dec[u];
1965 } else {
1966 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001967 aes_tests = aes_test_cbc_enc[u];
1968 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001969
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01001970 /*
1971 * AES-192 is an optional feature that may be unavailable when
1972 * there is an alternative underlying implementation i.e. when
1973 * MBEDTLS_AES_ALT is defined.
1974 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001975 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1976 mbedtls_printf("skipped\n");
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001977 continue;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001978 } else if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001979 goto exit;
1980 }
1981
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001982 for (j = 0; j < 10000; j++) {
1983 if (mode == MBEDTLS_AES_ENCRYPT) {
Paul Bakker5121ce52009-01-03 21:22:43 +00001984 unsigned char tmp[16];
1985
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001986 memcpy(tmp, prv, 16);
1987 memcpy(prv, buf, 16);
1988 memcpy(buf, tmp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001989 }
1990
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001991 ret = mbedtls_aes_crypt_cbc(&ctx, mode, 16, iv, buf, buf);
1992 if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001993 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001994 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001995
1996 }
1997
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001998 if (memcmp(buf, aes_tests, 16) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001999 ret = 1;
2000 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00002001 }
2002
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002003 if (verbose != 0) {
2004 mbedtls_printf("passed\n");
2005 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002006 }
2007
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002008 if (verbose != 0) {
2009 mbedtls_printf("\n");
2010 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002011#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00002012
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002013#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00002014 /*
2015 * CFB128 mode
2016 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002017 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +00002018 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002019 keybits = 128 + u * 64;
2020 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00002021
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002022 if (verbose != 0) {
2023 mbedtls_printf(" AES-CFB128-%3u (%s): ", keybits,
2024 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2025 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002026
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002027 memcpy(iv, aes_test_cfb128_iv, 16);
2028 memcpy(key, aes_test_cfb128_key[u], keybits / 8);
Paul Bakker5121ce52009-01-03 21:22:43 +00002029
2030 offset = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002031 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01002032 /*
2033 * AES-192 is an optional feature that may be unavailable when
2034 * there is an alternative underlying implementation i.e. when
2035 * MBEDTLS_AES_ALT is defined.
2036 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002037 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2038 mbedtls_printf("skipped\n");
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002039 continue;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002040 } else if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002041 goto exit;
2042 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002043
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002044 if (mode == MBEDTLS_AES_DECRYPT) {
2045 memcpy(buf, aes_test_cfb128_ct[u], 64);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002046 aes_tests = aes_test_cfb128_pt;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002047 } else {
2048 memcpy(buf, aes_test_cfb128_pt, 64);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002049 aes_tests = aes_test_cfb128_ct[u];
2050 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002051
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002052 ret = mbedtls_aes_crypt_cfb128(&ctx, mode, 64, &offset, iv, buf, buf);
2053 if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002054 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002055 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002056
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002057 if (memcmp(buf, aes_tests, 64) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002058 ret = 1;
2059 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00002060 }
2061
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002062 if (verbose != 0) {
2063 mbedtls_printf("passed\n");
2064 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002065 }
2066
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002067 if (verbose != 0) {
2068 mbedtls_printf("\n");
2069 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002070#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002071
Simon Butcherad4e4932018-04-29 00:43:47 +01002072#if defined(MBEDTLS_CIPHER_MODE_OFB)
2073 /*
2074 * OFB mode
2075 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002076 for (i = 0; i < 6; i++) {
Simon Butcherad4e4932018-04-29 00:43:47 +01002077 u = i >> 1;
2078 keybits = 128 + u * 64;
2079 mode = i & 1;
2080
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002081 if (verbose != 0) {
2082 mbedtls_printf(" AES-OFB-%3u (%s): ", keybits,
2083 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2084 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002085
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002086 memcpy(iv, aes_test_ofb_iv, 16);
2087 memcpy(key, aes_test_ofb_key[u], keybits / 8);
Simon Butcherad4e4932018-04-29 00:43:47 +01002088
2089 offset = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002090 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Simon Butcherad4e4932018-04-29 00:43:47 +01002091 /*
2092 * AES-192 is an optional feature that may be unavailable when
2093 * there is an alternative underlying implementation i.e. when
2094 * MBEDTLS_AES_ALT is defined.
2095 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002096 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2097 mbedtls_printf("skipped\n");
Simon Butcherad4e4932018-04-29 00:43:47 +01002098 continue;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002099 } else if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01002100 goto exit;
2101 }
2102
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002103 if (mode == MBEDTLS_AES_DECRYPT) {
2104 memcpy(buf, aes_test_ofb_ct[u], 64);
Simon Butcherad4e4932018-04-29 00:43:47 +01002105 aes_tests = aes_test_ofb_pt;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002106 } else {
2107 memcpy(buf, aes_test_ofb_pt, 64);
Simon Butcherad4e4932018-04-29 00:43:47 +01002108 aes_tests = aes_test_ofb_ct[u];
2109 }
2110
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002111 ret = mbedtls_aes_crypt_ofb(&ctx, 64, &offset, iv, buf, buf);
2112 if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01002113 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002114 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002115
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002116 if (memcmp(buf, aes_tests, 64) != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01002117 ret = 1;
2118 goto exit;
2119 }
2120
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002121 if (verbose != 0) {
2122 mbedtls_printf("passed\n");
2123 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002124 }
2125
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002126 if (verbose != 0) {
2127 mbedtls_printf("\n");
2128 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002129#endif /* MBEDTLS_CIPHER_MODE_OFB */
2130
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002131#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002132 /*
2133 * CTR mode
2134 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002135 for (i = 0; i < 6; i++) {
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002136 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002137 mode = i & 1;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002138
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002139 if (verbose != 0) {
2140 mbedtls_printf(" AES-CTR-128 (%s): ",
2141 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2142 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002143
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002144 memcpy(nonce_counter, aes_test_ctr_nonce_counter[u], 16);
2145 memcpy(key, aes_test_ctr_key[u], 16);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002146
2147 offset = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002148 if ((ret = mbedtls_aes_setkey_enc(&ctx, key, 128)) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002149 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002150 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002151
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002152 len = aes_test_ctr_len[u];
2153
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002154 if (mode == MBEDTLS_AES_DECRYPT) {
2155 memcpy(buf, aes_test_ctr_ct[u], len);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002156 aes_tests = aes_test_ctr_pt[u];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002157 } else {
2158 memcpy(buf, aes_test_ctr_pt[u], len);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002159 aes_tests = aes_test_ctr_ct[u];
2160 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002161
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002162 ret = mbedtls_aes_crypt_ctr(&ctx, len, &offset, nonce_counter,
2163 stream_block, buf, buf);
2164 if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002165 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002166 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002167
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002168 if (memcmp(buf, aes_tests, len) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002169 ret = 1;
2170 goto exit;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002171 }
2172
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002173 if (verbose != 0) {
2174 mbedtls_printf("passed\n");
2175 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002176 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002177
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002178 if (verbose != 0) {
2179 mbedtls_printf("\n");
2180 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002181#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00002182
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002183#if defined(MBEDTLS_CIPHER_MODE_XTS)
2184 {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002185 static const int num_tests =
2186 sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key);
2187 mbedtls_aes_xts_context ctx_xts;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002188
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002189 /*
2190 * XTS mode
2191 */
2192 mbedtls_aes_xts_init(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002193
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002194 for (i = 0; i < num_tests << 1; i++) {
2195 const unsigned char *data_unit;
2196 u = i >> 1;
2197 mode = i & 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002198
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002199 if (verbose != 0) {
2200 mbedtls_printf(" AES-XTS-128 (%s): ",
2201 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2202 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002203
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002204 memset(key, 0, sizeof(key));
2205 memcpy(key, aes_test_xts_key[u], 32);
2206 data_unit = aes_test_xts_data_unit[u];
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002207
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002208 len = sizeof(*aes_test_xts_ct32);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002209
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002210 if (mode == MBEDTLS_AES_DECRYPT) {
2211 ret = mbedtls_aes_xts_setkey_dec(&ctx_xts, key, 256);
2212 if (ret != 0) {
2213 goto exit;
2214 }
2215 memcpy(buf, aes_test_xts_ct32[u], len);
2216 aes_tests = aes_test_xts_pt32[u];
2217 } else {
2218 ret = mbedtls_aes_xts_setkey_enc(&ctx_xts, key, 256);
2219 if (ret != 0) {
2220 goto exit;
2221 }
2222 memcpy(buf, aes_test_xts_pt32[u], len);
2223 aes_tests = aes_test_xts_ct32[u];
2224 }
2225
2226
2227 ret = mbedtls_aes_crypt_xts(&ctx_xts, mode, len, data_unit,
2228 buf, buf);
2229 if (ret != 0) {
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002230 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002231 }
2232
2233 if (memcmp(buf, aes_tests, len) != 0) {
2234 ret = 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002235 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002236 }
2237
2238 if (verbose != 0) {
2239 mbedtls_printf("passed\n");
2240 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002241 }
2242
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002243 if (verbose != 0) {
2244 mbedtls_printf("\n");
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002245 }
2246
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002247 mbedtls_aes_xts_free(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002248 }
2249#endif /* MBEDTLS_CIPHER_MODE_XTS */
2250
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002251 ret = 0;
2252
2253exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002254 if (ret != 0 && verbose != 0) {
2255 mbedtls_printf("failed\n");
2256 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002257
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002258 mbedtls_aes_free(&ctx);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002259
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002260 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002261}
2262
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002263#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002264
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002265#endif /* MBEDTLS_AES_C */