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