blob: 4afc3c48ae208f860cee6fc60c8bd4ea506b5b25 [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é-Gonnard2cf5a7c2015-04-08 12:49:31 +020043#if defined(MBEDTLS_SELF_TEST)
44#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000045#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010046#else
Rich Evans00ab4702015-02-06 13:43:58 +000047#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020048#define mbedtls_printf printf
49#endif /* MBEDTLS_PLATFORM_C */
50#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010051
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020052#if !defined(MBEDTLS_AES_ALT)
Paul Bakker90995b52013-06-24 19:20:35 +020053
Manuel Pégourié-Gonnard0e9cddb2018-12-10 16:37:51 +010054/* Parameter validation macros based on platform_util.h */
55#define AES_VALIDATE_RET( cond ) \
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +010056 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_AES_BAD_INPUT_DATA )
Manuel Pégourié-Gonnard0e9cddb2018-12-10 16:37:51 +010057#define AES_VALIDATE( cond ) \
58 MBEDTLS_INTERNAL_VALIDATE( cond )
59
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020060#if defined(MBEDTLS_PADLOCK_C) && \
61 ( defined(MBEDTLS_HAVE_X86) || defined(MBEDTLS_PADLOCK_ALIGN16) )
Paul Bakker048d04e2012-02-12 17:31:04 +000062static int aes_padlock_ace = -1;
63#endif
64
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020065#if defined(MBEDTLS_AES_ROM_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +000066/*
67 * Forward S-box
68 */
69static const unsigned char FSb[256] =
70{
71 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
72 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
73 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
74 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
75 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
76 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
77 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
78 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
79 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
80 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
81 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
82 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
83 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
84 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
85 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
86 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
87 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
88 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
89 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
90 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
91 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
92 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
93 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
94 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
95 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
96 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
97 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
98 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
99 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
100 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
101 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
102 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
103};
104
105/*
106 * Forward tables
107 */
108#define FT \
109\
110 V(A5,63,63,C6), V(84,7C,7C,F8), V(99,77,77,EE), V(8D,7B,7B,F6), \
111 V(0D,F2,F2,FF), V(BD,6B,6B,D6), V(B1,6F,6F,DE), V(54,C5,C5,91), \
112 V(50,30,30,60), V(03,01,01,02), V(A9,67,67,CE), V(7D,2B,2B,56), \
113 V(19,FE,FE,E7), V(62,D7,D7,B5), V(E6,AB,AB,4D), V(9A,76,76,EC), \
114 V(45,CA,CA,8F), V(9D,82,82,1F), V(40,C9,C9,89), V(87,7D,7D,FA), \
115 V(15,FA,FA,EF), V(EB,59,59,B2), V(C9,47,47,8E), V(0B,F0,F0,FB), \
116 V(EC,AD,AD,41), V(67,D4,D4,B3), V(FD,A2,A2,5F), V(EA,AF,AF,45), \
117 V(BF,9C,9C,23), V(F7,A4,A4,53), V(96,72,72,E4), V(5B,C0,C0,9B), \
118 V(C2,B7,B7,75), V(1C,FD,FD,E1), V(AE,93,93,3D), V(6A,26,26,4C), \
119 V(5A,36,36,6C), V(41,3F,3F,7E), V(02,F7,F7,F5), V(4F,CC,CC,83), \
120 V(5C,34,34,68), V(F4,A5,A5,51), V(34,E5,E5,D1), V(08,F1,F1,F9), \
121 V(93,71,71,E2), V(73,D8,D8,AB), V(53,31,31,62), V(3F,15,15,2A), \
122 V(0C,04,04,08), V(52,C7,C7,95), V(65,23,23,46), V(5E,C3,C3,9D), \
123 V(28,18,18,30), V(A1,96,96,37), V(0F,05,05,0A), V(B5,9A,9A,2F), \
124 V(09,07,07,0E), V(36,12,12,24), V(9B,80,80,1B), V(3D,E2,E2,DF), \
125 V(26,EB,EB,CD), V(69,27,27,4E), V(CD,B2,B2,7F), V(9F,75,75,EA), \
126 V(1B,09,09,12), V(9E,83,83,1D), V(74,2C,2C,58), V(2E,1A,1A,34), \
127 V(2D,1B,1B,36), V(B2,6E,6E,DC), V(EE,5A,5A,B4), V(FB,A0,A0,5B), \
128 V(F6,52,52,A4), V(4D,3B,3B,76), V(61,D6,D6,B7), V(CE,B3,B3,7D), \
129 V(7B,29,29,52), V(3E,E3,E3,DD), V(71,2F,2F,5E), V(97,84,84,13), \
130 V(F5,53,53,A6), V(68,D1,D1,B9), V(00,00,00,00), V(2C,ED,ED,C1), \
131 V(60,20,20,40), V(1F,FC,FC,E3), V(C8,B1,B1,79), V(ED,5B,5B,B6), \
132 V(BE,6A,6A,D4), V(46,CB,CB,8D), V(D9,BE,BE,67), V(4B,39,39,72), \
133 V(DE,4A,4A,94), V(D4,4C,4C,98), V(E8,58,58,B0), V(4A,CF,CF,85), \
134 V(6B,D0,D0,BB), V(2A,EF,EF,C5), V(E5,AA,AA,4F), V(16,FB,FB,ED), \
135 V(C5,43,43,86), V(D7,4D,4D,9A), V(55,33,33,66), V(94,85,85,11), \
136 V(CF,45,45,8A), V(10,F9,F9,E9), V(06,02,02,04), V(81,7F,7F,FE), \
137 V(F0,50,50,A0), V(44,3C,3C,78), V(BA,9F,9F,25), V(E3,A8,A8,4B), \
138 V(F3,51,51,A2), V(FE,A3,A3,5D), V(C0,40,40,80), V(8A,8F,8F,05), \
139 V(AD,92,92,3F), V(BC,9D,9D,21), V(48,38,38,70), V(04,F5,F5,F1), \
140 V(DF,BC,BC,63), V(C1,B6,B6,77), V(75,DA,DA,AF), V(63,21,21,42), \
141 V(30,10,10,20), V(1A,FF,FF,E5), V(0E,F3,F3,FD), V(6D,D2,D2,BF), \
142 V(4C,CD,CD,81), V(14,0C,0C,18), V(35,13,13,26), V(2F,EC,EC,C3), \
143 V(E1,5F,5F,BE), V(A2,97,97,35), V(CC,44,44,88), V(39,17,17,2E), \
144 V(57,C4,C4,93), V(F2,A7,A7,55), V(82,7E,7E,FC), V(47,3D,3D,7A), \
145 V(AC,64,64,C8), V(E7,5D,5D,BA), V(2B,19,19,32), V(95,73,73,E6), \
146 V(A0,60,60,C0), V(98,81,81,19), V(D1,4F,4F,9E), V(7F,DC,DC,A3), \
147 V(66,22,22,44), V(7E,2A,2A,54), V(AB,90,90,3B), V(83,88,88,0B), \
148 V(CA,46,46,8C), V(29,EE,EE,C7), V(D3,B8,B8,6B), V(3C,14,14,28), \
149 V(79,DE,DE,A7), V(E2,5E,5E,BC), V(1D,0B,0B,16), V(76,DB,DB,AD), \
150 V(3B,E0,E0,DB), V(56,32,32,64), V(4E,3A,3A,74), V(1E,0A,0A,14), \
151 V(DB,49,49,92), V(0A,06,06,0C), V(6C,24,24,48), V(E4,5C,5C,B8), \
152 V(5D,C2,C2,9F), V(6E,D3,D3,BD), V(EF,AC,AC,43), V(A6,62,62,C4), \
153 V(A8,91,91,39), V(A4,95,95,31), V(37,E4,E4,D3), V(8B,79,79,F2), \
154 V(32,E7,E7,D5), V(43,C8,C8,8B), V(59,37,37,6E), V(B7,6D,6D,DA), \
155 V(8C,8D,8D,01), V(64,D5,D5,B1), V(D2,4E,4E,9C), V(E0,A9,A9,49), \
156 V(B4,6C,6C,D8), V(FA,56,56,AC), V(07,F4,F4,F3), V(25,EA,EA,CF), \
157 V(AF,65,65,CA), V(8E,7A,7A,F4), V(E9,AE,AE,47), V(18,08,08,10), \
158 V(D5,BA,BA,6F), V(88,78,78,F0), V(6F,25,25,4A), V(72,2E,2E,5C), \
159 V(24,1C,1C,38), V(F1,A6,A6,57), V(C7,B4,B4,73), V(51,C6,C6,97), \
160 V(23,E8,E8,CB), V(7C,DD,DD,A1), V(9C,74,74,E8), V(21,1F,1F,3E), \
161 V(DD,4B,4B,96), V(DC,BD,BD,61), V(86,8B,8B,0D), V(85,8A,8A,0F), \
162 V(90,70,70,E0), V(42,3E,3E,7C), V(C4,B5,B5,71), V(AA,66,66,CC), \
163 V(D8,48,48,90), V(05,03,03,06), V(01,F6,F6,F7), V(12,0E,0E,1C), \
164 V(A3,61,61,C2), V(5F,35,35,6A), V(F9,57,57,AE), V(D0,B9,B9,69), \
165 V(91,86,86,17), V(58,C1,C1,99), V(27,1D,1D,3A), V(B9,9E,9E,27), \
166 V(38,E1,E1,D9), V(13,F8,F8,EB), V(B3,98,98,2B), V(33,11,11,22), \
167 V(BB,69,69,D2), V(70,D9,D9,A9), V(89,8E,8E,07), V(A7,94,94,33), \
168 V(B6,9B,9B,2D), V(22,1E,1E,3C), V(92,87,87,15), V(20,E9,E9,C9), \
169 V(49,CE,CE,87), V(FF,55,55,AA), V(78,28,28,50), V(7A,DF,DF,A5), \
170 V(8F,8C,8C,03), V(F8,A1,A1,59), V(80,89,89,09), V(17,0D,0D,1A), \
171 V(DA,BF,BF,65), V(31,E6,E6,D7), V(C6,42,42,84), V(B8,68,68,D0), \
172 V(C3,41,41,82), V(B0,99,99,29), V(77,2D,2D,5A), V(11,0F,0F,1E), \
173 V(CB,B0,B0,7B), V(FC,54,54,A8), V(D6,BB,BB,6D), V(3A,16,16,2C)
174
175#define V(a,b,c,d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000176static const uint32_t FT0[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000177#undef V
178
Hanno Beckerad049a92017-06-19 16:31:54 +0100179#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200180
Paul Bakker5121ce52009-01-03 21:22:43 +0000181#define V(a,b,c,d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000182static const uint32_t FT1[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000183#undef V
184
185#define V(a,b,c,d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000186static const uint32_t FT2[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000187#undef V
188
189#define V(a,b,c,d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000190static const uint32_t FT3[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000191#undef V
192
Hanno Becker177d3cf2017-06-07 15:52:48 +0100193#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200194
Paul Bakker5121ce52009-01-03 21:22:43 +0000195#undef FT
196
197/*
198 * Reverse S-box
199 */
200static const unsigned char RSb[256] =
201{
202 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
203 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
204 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
205 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
206 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
207 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
208 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
209 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
210 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
211 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
212 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
213 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
214 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
215 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
216 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
217 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
218 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
219 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
220 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
221 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
222 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
223 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
224 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
225 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
226 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
227 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
228 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
229 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
230 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
231 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
232 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
233 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
234};
235
236/*
237 * Reverse tables
238 */
239#define RT \
240\
241 V(50,A7,F4,51), V(53,65,41,7E), V(C3,A4,17,1A), V(96,5E,27,3A), \
242 V(CB,6B,AB,3B), V(F1,45,9D,1F), V(AB,58,FA,AC), V(93,03,E3,4B), \
243 V(55,FA,30,20), V(F6,6D,76,AD), V(91,76,CC,88), V(25,4C,02,F5), \
244 V(FC,D7,E5,4F), V(D7,CB,2A,C5), V(80,44,35,26), V(8F,A3,62,B5), \
245 V(49,5A,B1,DE), V(67,1B,BA,25), V(98,0E,EA,45), V(E1,C0,FE,5D), \
246 V(02,75,2F,C3), V(12,F0,4C,81), V(A3,97,46,8D), V(C6,F9,D3,6B), \
247 V(E7,5F,8F,03), V(95,9C,92,15), V(EB,7A,6D,BF), V(DA,59,52,95), \
248 V(2D,83,BE,D4), V(D3,21,74,58), V(29,69,E0,49), V(44,C8,C9,8E), \
249 V(6A,89,C2,75), V(78,79,8E,F4), V(6B,3E,58,99), V(DD,71,B9,27), \
250 V(B6,4F,E1,BE), V(17,AD,88,F0), V(66,AC,20,C9), V(B4,3A,CE,7D), \
251 V(18,4A,DF,63), V(82,31,1A,E5), V(60,33,51,97), V(45,7F,53,62), \
252 V(E0,77,64,B1), V(84,AE,6B,BB), V(1C,A0,81,FE), V(94,2B,08,F9), \
253 V(58,68,48,70), V(19,FD,45,8F), V(87,6C,DE,94), V(B7,F8,7B,52), \
254 V(23,D3,73,AB), V(E2,02,4B,72), V(57,8F,1F,E3), V(2A,AB,55,66), \
255 V(07,28,EB,B2), V(03,C2,B5,2F), V(9A,7B,C5,86), V(A5,08,37,D3), \
256 V(F2,87,28,30), V(B2,A5,BF,23), V(BA,6A,03,02), V(5C,82,16,ED), \
257 V(2B,1C,CF,8A), V(92,B4,79,A7), V(F0,F2,07,F3), V(A1,E2,69,4E), \
258 V(CD,F4,DA,65), V(D5,BE,05,06), V(1F,62,34,D1), V(8A,FE,A6,C4), \
259 V(9D,53,2E,34), V(A0,55,F3,A2), V(32,E1,8A,05), V(75,EB,F6,A4), \
260 V(39,EC,83,0B), V(AA,EF,60,40), V(06,9F,71,5E), V(51,10,6E,BD), \
261 V(F9,8A,21,3E), V(3D,06,DD,96), V(AE,05,3E,DD), V(46,BD,E6,4D), \
262 V(B5,8D,54,91), V(05,5D,C4,71), V(6F,D4,06,04), V(FF,15,50,60), \
263 V(24,FB,98,19), V(97,E9,BD,D6), V(CC,43,40,89), V(77,9E,D9,67), \
264 V(BD,42,E8,B0), V(88,8B,89,07), V(38,5B,19,E7), V(DB,EE,C8,79), \
265 V(47,0A,7C,A1), V(E9,0F,42,7C), V(C9,1E,84,F8), V(00,00,00,00), \
266 V(83,86,80,09), V(48,ED,2B,32), V(AC,70,11,1E), V(4E,72,5A,6C), \
267 V(FB,FF,0E,FD), V(56,38,85,0F), V(1E,D5,AE,3D), V(27,39,2D,36), \
268 V(64,D9,0F,0A), V(21,A6,5C,68), V(D1,54,5B,9B), V(3A,2E,36,24), \
269 V(B1,67,0A,0C), V(0F,E7,57,93), V(D2,96,EE,B4), V(9E,91,9B,1B), \
270 V(4F,C5,C0,80), V(A2,20,DC,61), V(69,4B,77,5A), V(16,1A,12,1C), \
271 V(0A,BA,93,E2), V(E5,2A,A0,C0), V(43,E0,22,3C), V(1D,17,1B,12), \
272 V(0B,0D,09,0E), V(AD,C7,8B,F2), V(B9,A8,B6,2D), V(C8,A9,1E,14), \
273 V(85,19,F1,57), V(4C,07,75,AF), V(BB,DD,99,EE), V(FD,60,7F,A3), \
274 V(9F,26,01,F7), V(BC,F5,72,5C), V(C5,3B,66,44), V(34,7E,FB,5B), \
275 V(76,29,43,8B), V(DC,C6,23,CB), V(68,FC,ED,B6), V(63,F1,E4,B8), \
276 V(CA,DC,31,D7), V(10,85,63,42), V(40,22,97,13), V(20,11,C6,84), \
277 V(7D,24,4A,85), V(F8,3D,BB,D2), V(11,32,F9,AE), V(6D,A1,29,C7), \
278 V(4B,2F,9E,1D), V(F3,30,B2,DC), V(EC,52,86,0D), V(D0,E3,C1,77), \
279 V(6C,16,B3,2B), V(99,B9,70,A9), V(FA,48,94,11), V(22,64,E9,47), \
280 V(C4,8C,FC,A8), V(1A,3F,F0,A0), V(D8,2C,7D,56), V(EF,90,33,22), \
281 V(C7,4E,49,87), V(C1,D1,38,D9), V(FE,A2,CA,8C), V(36,0B,D4,98), \
282 V(CF,81,F5,A6), V(28,DE,7A,A5), V(26,8E,B7,DA), V(A4,BF,AD,3F), \
283 V(E4,9D,3A,2C), V(0D,92,78,50), V(9B,CC,5F,6A), V(62,46,7E,54), \
284 V(C2,13,8D,F6), V(E8,B8,D8,90), V(5E,F7,39,2E), V(F5,AF,C3,82), \
285 V(BE,80,5D,9F), V(7C,93,D0,69), V(A9,2D,D5,6F), V(B3,12,25,CF), \
286 V(3B,99,AC,C8), V(A7,7D,18,10), V(6E,63,9C,E8), V(7B,BB,3B,DB), \
287 V(09,78,26,CD), V(F4,18,59,6E), V(01,B7,9A,EC), V(A8,9A,4F,83), \
288 V(65,6E,95,E6), V(7E,E6,FF,AA), V(08,CF,BC,21), V(E6,E8,15,EF), \
289 V(D9,9B,E7,BA), V(CE,36,6F,4A), V(D4,09,9F,EA), V(D6,7C,B0,29), \
290 V(AF,B2,A4,31), V(31,23,3F,2A), V(30,94,A5,C6), V(C0,66,A2,35), \
291 V(37,BC,4E,74), V(A6,CA,82,FC), V(B0,D0,90,E0), V(15,D8,A7,33), \
292 V(4A,98,04,F1), V(F7,DA,EC,41), V(0E,50,CD,7F), V(2F,F6,91,17), \
293 V(8D,D6,4D,76), V(4D,B0,EF,43), V(54,4D,AA,CC), V(DF,04,96,E4), \
294 V(E3,B5,D1,9E), V(1B,88,6A,4C), V(B8,1F,2C,C1), V(7F,51,65,46), \
295 V(04,EA,5E,9D), V(5D,35,8C,01), V(73,74,87,FA), V(2E,41,0B,FB), \
296 V(5A,1D,67,B3), V(52,D2,DB,92), V(33,56,10,E9), V(13,47,D6,6D), \
297 V(8C,61,D7,9A), V(7A,0C,A1,37), V(8E,14,F8,59), V(89,3C,13,EB), \
298 V(EE,27,A9,CE), V(35,C9,61,B7), V(ED,E5,1C,E1), V(3C,B1,47,7A), \
299 V(59,DF,D2,9C), V(3F,73,F2,55), V(79,CE,14,18), V(BF,37,C7,73), \
300 V(EA,CD,F7,53), V(5B,AA,FD,5F), V(14,6F,3D,DF), V(86,DB,44,78), \
301 V(81,F3,AF,CA), V(3E,C4,68,B9), V(2C,34,24,38), V(5F,40,A3,C2), \
302 V(72,C3,1D,16), V(0C,25,E2,BC), V(8B,49,3C,28), V(41,95,0D,FF), \
303 V(71,01,A8,39), V(DE,B3,0C,08), V(9C,E4,B4,D8), V(90,C1,56,64), \
304 V(61,84,CB,7B), V(70,B6,32,D5), V(74,5C,6C,48), V(42,57,B8,D0)
305
306#define V(a,b,c,d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000307static const uint32_t RT0[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000308#undef V
309
Hanno Beckerad049a92017-06-19 16:31:54 +0100310#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200311
Paul Bakker5121ce52009-01-03 21:22:43 +0000312#define V(a,b,c,d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000313static const uint32_t RT1[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000314#undef V
315
316#define V(a,b,c,d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000317static const uint32_t RT2[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000318#undef V
319
320#define V(a,b,c,d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000321static const uint32_t RT3[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000322#undef V
323
Hanno Becker177d3cf2017-06-07 15:52:48 +0100324#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200325
Paul Bakker5121ce52009-01-03 21:22:43 +0000326#undef RT
327
328/*
329 * Round constants
330 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000331static const uint32_t RCON[10] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000332{
333 0x00000001, 0x00000002, 0x00000004, 0x00000008,
334 0x00000010, 0x00000020, 0x00000040, 0x00000080,
335 0x0000001B, 0x00000036
336};
337
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200338#else /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000339
340/*
341 * Forward S-box & tables
342 */
343static unsigned char FSb[256];
Paul Bakker9af723c2014-05-01 13:03:14 +0200344static uint32_t FT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100345#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker9af723c2014-05-01 13:03:14 +0200346static uint32_t FT1[256];
347static uint32_t FT2[256];
348static uint32_t FT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100349#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000350
351/*
352 * Reverse S-box & tables
353 */
354static unsigned char RSb[256];
Paul Bakker5c2364c2012-10-01 14:41:15 +0000355static uint32_t RT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100356#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker5c2364c2012-10-01 14:41:15 +0000357static uint32_t RT1[256];
358static uint32_t RT2[256];
359static uint32_t RT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100360#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000361
362/*
363 * Round constants
364 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000365static uint32_t RCON[10];
Paul Bakker5121ce52009-01-03 21:22:43 +0000366
367/*
368 * Tables generation code
369 */
Hanno Becker1eeca412018-10-15 12:01:35 +0100370#define ROTL8(x) ( ( (x) << 8 ) & 0xFFFFFFFF ) | ( (x) >> 24 )
371#define XTIME(x) ( ( (x) << 1 ) ^ ( ( (x) & 0x80 ) ? 0x1B : 0x00 ) )
Hanno Becker818bac52018-10-26 09:13:26 +0100372#define MUL(x,y) ( ( (x) && (y) ) ? pow[(log[(x)]+log[(y)]) % 255] : 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000373
374static int aes_init_done = 0;
375
376static void aes_gen_tables( void )
377{
378 int i, x, y, z;
379 int pow[256];
380 int log[256];
381
382 /*
383 * compute pow and log tables over GF(2^8)
384 */
385 for( i = 0, x = 1; i < 256; i++ )
386 {
387 pow[i] = x;
388 log[x] = i;
Joe Subbianicd84d762021-07-08 14:59:52 +0100389 x = MBEDTLS_BYTE_0( x ^ XTIME( x ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000390 }
391
392 /*
393 * calculate the round constants
394 */
395 for( i = 0, x = 1; i < 10; i++ )
396 {
Paul Bakker5c2364c2012-10-01 14:41:15 +0000397 RCON[i] = (uint32_t) x;
Joe Subbianicd84d762021-07-08 14:59:52 +0100398 x = MBEDTLS_BYTE_0( XTIME( x ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000399 }
400
401 /*
402 * generate the forward and reverse S-boxes
403 */
404 FSb[0x00] = 0x63;
405 RSb[0x63] = 0x00;
406
407 for( i = 1; i < 256; i++ )
408 {
409 x = pow[255 - log[i]];
410
Joe Subbianicd84d762021-07-08 14:59:52 +0100411 y = x; y = MBEDTLS_BYTE_0( ( y << 1 ) | ( y >> 7 ) );
412 x ^= y; y = MBEDTLS_BYTE_0( ( y << 1 ) | ( y >> 7 ) );
413 x ^= y; y = MBEDTLS_BYTE_0( ( y << 1 ) | ( y >> 7 ) );
414 x ^= y; y = MBEDTLS_BYTE_0( ( y << 1 ) | ( y >> 7 ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000415 x ^= y ^ 0x63;
416
417 FSb[i] = (unsigned char) x;
418 RSb[x] = (unsigned char) i;
419 }
420
421 /*
422 * generate the forward and reverse tables
423 */
424 for( i = 0; i < 256; i++ )
425 {
426 x = FSb[i];
Joe Subbianicd84d762021-07-08 14:59:52 +0100427 y = MBEDTLS_BYTE_0( XTIME( x ) );
428 z = MBEDTLS_BYTE_0( y ^ x );
Paul Bakker5121ce52009-01-03 21:22:43 +0000429
Paul Bakker5c2364c2012-10-01 14:41:15 +0000430 FT0[i] = ( (uint32_t) y ) ^
431 ( (uint32_t) x << 8 ) ^
432 ( (uint32_t) x << 16 ) ^
433 ( (uint32_t) z << 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000434
Hanno Beckerad049a92017-06-19 16:31:54 +0100435#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +0000436 FT1[i] = ROTL8( FT0[i] );
437 FT2[i] = ROTL8( FT1[i] );
438 FT3[i] = ROTL8( FT2[i] );
Hanno Becker177d3cf2017-06-07 15:52:48 +0100439#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000440
441 x = RSb[i];
442
Paul Bakker5c2364c2012-10-01 14:41:15 +0000443 RT0[i] = ( (uint32_t) MUL( 0x0E, x ) ) ^
444 ( (uint32_t) MUL( 0x09, x ) << 8 ) ^
445 ( (uint32_t) MUL( 0x0D, x ) << 16 ) ^
446 ( (uint32_t) MUL( 0x0B, x ) << 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000447
Hanno Beckerad049a92017-06-19 16:31:54 +0100448#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +0000449 RT1[i] = ROTL8( RT0[i] );
450 RT2[i] = ROTL8( RT1[i] );
451 RT3[i] = ROTL8( RT2[i] );
Hanno Becker177d3cf2017-06-07 15:52:48 +0100452#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000453 }
454}
455
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200456#undef ROTL8
457
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200458#endif /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000459
Hanno Beckerad049a92017-06-19 16:31:54 +0100460#if defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200461
462#define ROTL8(x) ( (uint32_t)( ( x ) << 8 ) + (uint32_t)( ( x ) >> 24 ) )
463#define ROTL16(x) ( (uint32_t)( ( x ) << 16 ) + (uint32_t)( ( x ) >> 16 ) )
464#define ROTL24(x) ( (uint32_t)( ( x ) << 24 ) + (uint32_t)( ( x ) >> 8 ) )
465
466#define AES_RT0(idx) RT0[idx]
467#define AES_RT1(idx) ROTL8( RT0[idx] )
468#define AES_RT2(idx) ROTL16( RT0[idx] )
469#define AES_RT3(idx) ROTL24( RT0[idx] )
470
471#define AES_FT0(idx) FT0[idx]
472#define AES_FT1(idx) ROTL8( FT0[idx] )
473#define AES_FT2(idx) ROTL16( FT0[idx] )
474#define AES_FT3(idx) ROTL24( FT0[idx] )
475
Hanno Becker177d3cf2017-06-07 15:52:48 +0100476#else /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200477
478#define AES_RT0(idx) RT0[idx]
479#define AES_RT1(idx) RT1[idx]
480#define AES_RT2(idx) RT2[idx]
481#define AES_RT3(idx) RT3[idx]
482
483#define AES_FT0(idx) FT0[idx]
484#define AES_FT1(idx) FT1[idx]
485#define AES_FT2(idx) FT2[idx]
486#define AES_FT3(idx) FT3[idx]
487
Hanno Becker177d3cf2017-06-07 15:52:48 +0100488#endif /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200489
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200490void mbedtls_aes_init( mbedtls_aes_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200491{
Manuel Pégourié-Gonnard0e9cddb2018-12-10 16:37:51 +0100492 AES_VALIDATE( ctx != NULL );
Simon Butcher5201e412018-12-06 17:40:14 +0000493
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200494 memset( ctx, 0, sizeof( mbedtls_aes_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200495}
496
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200497void mbedtls_aes_free( mbedtls_aes_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200498{
499 if( ctx == NULL )
500 return;
501
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500502 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_aes_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200503}
504
Jaeden Amero9366feb2018-05-29 18:55:17 +0100505#if defined(MBEDTLS_CIPHER_MODE_XTS)
506void mbedtls_aes_xts_init( mbedtls_aes_xts_context *ctx )
507{
Manuel Pégourié-Gonnard0e9cddb2018-12-10 16:37:51 +0100508 AES_VALIDATE( ctx != NULL );
Simon Butcher5201e412018-12-06 17:40:14 +0000509
Jaeden Amero9366feb2018-05-29 18:55:17 +0100510 mbedtls_aes_init( &ctx->crypt );
511 mbedtls_aes_init( &ctx->tweak );
512}
513
514void mbedtls_aes_xts_free( mbedtls_aes_xts_context *ctx )
515{
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100516 if( ctx == NULL )
517 return;
Simon Butcher5201e412018-12-06 17:40:14 +0000518
Jaeden Amero9366feb2018-05-29 18:55:17 +0100519 mbedtls_aes_free( &ctx->crypt );
520 mbedtls_aes_free( &ctx->tweak );
521}
522#endif /* MBEDTLS_CIPHER_MODE_XTS */
523
Paul Bakker5121ce52009-01-03 21:22:43 +0000524/*
525 * AES key schedule (encryption)
526 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200527#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200528int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key,
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200529 unsigned int keybits )
Paul Bakker5121ce52009-01-03 21:22:43 +0000530{
Paul Bakker23986e52011-04-24 08:57:21 +0000531 unsigned int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000532 uint32_t *RK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000533
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100534 AES_VALIDATE_RET( ctx != NULL );
535 AES_VALIDATE_RET( key != NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000536
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200537 switch( keybits )
Paul Bakker5121ce52009-01-03 21:22:43 +0000538 {
539 case 128: ctx->nr = 10; break;
540 case 192: ctx->nr = 12; break;
541 case 256: ctx->nr = 14; break;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200542 default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000543 }
544
Simon Butcher5201e412018-12-06 17:40:14 +0000545#if !defined(MBEDTLS_AES_ROM_TABLES)
546 if( aes_init_done == 0 )
547 {
548 aes_gen_tables();
549 aes_init_done = 1;
Simon Butcher5201e412018-12-06 17:40:14 +0000550 }
551#endif
552
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200553#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_PADLOCK_ALIGN16)
Paul Bakker048d04e2012-02-12 17:31:04 +0000554 if( aes_padlock_ace == -1 )
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100555 aes_padlock_ace = mbedtls_padlock_has_support( MBEDTLS_PADLOCK_ACE );
Paul Bakker048d04e2012-02-12 17:31:04 +0000556
557 if( aes_padlock_ace )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200558 ctx->rk = RK = MBEDTLS_PADLOCK_ALIGN16( ctx->buf );
Paul Bakker048d04e2012-02-12 17:31:04 +0000559 else
Paul Bakker5121ce52009-01-03 21:22:43 +0000560#endif
Paul Bakker048d04e2012-02-12 17:31:04 +0000561 ctx->rk = RK = ctx->buf;
Paul Bakker5121ce52009-01-03 21:22:43 +0000562
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200563#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100564 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) )
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200565 return( mbedtls_aesni_setkey_enc( (unsigned char *) ctx->rk, key, keybits ) );
Manuel Pégourié-Gonnard47a35362013-12-28 20:45:04 +0100566#endif
567
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200568 for( i = 0; i < ( keybits >> 5 ); i++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000569 {
Joe Subbiani6a506312021-07-07 16:56:29 +0100570 RK[i] = MBEDTLS_GET_UINT32_LE( key, i << 2 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000571 }
572
573 switch( ctx->nr )
574 {
575 case 10:
576
577 for( i = 0; i < 10; i++, RK += 4 )
578 {
579 RK[4] = RK[0] ^ RCON[i] ^
Joe Subbianicd84d762021-07-08 14:59:52 +0100580 ( (uint32_t) FSb[ MBEDTLS_BYTE_1( RK[3] ) ] ) ^
581 ( (uint32_t) FSb[ MBEDTLS_BYTE_2( RK[3] ) ] << 8 ) ^
582 ( (uint32_t) FSb[ MBEDTLS_BYTE_3( RK[3] ) ] << 16 ) ^
583 ( (uint32_t) FSb[ MBEDTLS_BYTE_0( RK[3] ) ] << 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000584
585 RK[5] = RK[1] ^ RK[4];
586 RK[6] = RK[2] ^ RK[5];
587 RK[7] = RK[3] ^ RK[6];
588 }
589 break;
590
591 case 12:
592
593 for( i = 0; i < 8; i++, RK += 6 )
594 {
595 RK[6] = RK[0] ^ RCON[i] ^
Joe Subbianicd84d762021-07-08 14:59:52 +0100596 ( (uint32_t) FSb[ MBEDTLS_BYTE_1( RK[5] ) ] ) ^
597 ( (uint32_t) FSb[ MBEDTLS_BYTE_2( RK[5] ) ] << 8 ) ^
598 ( (uint32_t) FSb[ MBEDTLS_BYTE_3( RK[5] ) ] << 16 ) ^
599 ( (uint32_t) FSb[ MBEDTLS_BYTE_0( RK[5] ) ] << 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000600
601 RK[7] = RK[1] ^ RK[6];
602 RK[8] = RK[2] ^ RK[7];
603 RK[9] = RK[3] ^ RK[8];
604 RK[10] = RK[4] ^ RK[9];
605 RK[11] = RK[5] ^ RK[10];
606 }
607 break;
608
609 case 14:
610
611 for( i = 0; i < 7; i++, RK += 8 )
612 {
613 RK[8] = RK[0] ^ RCON[i] ^
Joe Subbianicd84d762021-07-08 14:59:52 +0100614 ( (uint32_t) FSb[ MBEDTLS_BYTE_1( RK[7] ) ] ) ^
615 ( (uint32_t) FSb[ MBEDTLS_BYTE_2( RK[7] ) ] << 8 ) ^
616 ( (uint32_t) FSb[ MBEDTLS_BYTE_3( RK[7] ) ] << 16 ) ^
617 ( (uint32_t) FSb[ MBEDTLS_BYTE_0( RK[7] ) ] << 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000618
619 RK[9] = RK[1] ^ RK[8];
620 RK[10] = RK[2] ^ RK[9];
621 RK[11] = RK[3] ^ RK[10];
622
623 RK[12] = RK[4] ^
Joe Subbianicd84d762021-07-08 14:59:52 +0100624 ( (uint32_t) FSb[ MBEDTLS_BYTE_0( RK[11] ) ] ) ^
625 ( (uint32_t) FSb[ MBEDTLS_BYTE_1( RK[11] ) ] << 8 ) ^
626 ( (uint32_t) FSb[ MBEDTLS_BYTE_2( RK[11] ) ] << 16 ) ^
627 ( (uint32_t) FSb[ MBEDTLS_BYTE_3( RK[11] ) ] << 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000628
629 RK[13] = RK[5] ^ RK[12];
630 RK[14] = RK[6] ^ RK[13];
631 RK[15] = RK[7] ^ RK[14];
632 }
633 break;
Paul Bakker5121ce52009-01-03 21:22:43 +0000634 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000635
636 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000637}
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200638#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000639
640/*
641 * AES key schedule (decryption)
642 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200643#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200644int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key,
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200645 unsigned int keybits )
Paul Bakker5121ce52009-01-03 21:22:43 +0000646{
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200647 int i, j, ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200648 mbedtls_aes_context cty;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000649 uint32_t *RK;
650 uint32_t *SK;
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200651
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100652 AES_VALIDATE_RET( ctx != NULL );
653 AES_VALIDATE_RET( key != NULL );
Simon Butcher5201e412018-12-06 17:40:14 +0000654
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200655 mbedtls_aes_init( &cty );
Paul Bakker5121ce52009-01-03 21:22:43 +0000656
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200657#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_PADLOCK_ALIGN16)
Paul Bakker048d04e2012-02-12 17:31:04 +0000658 if( aes_padlock_ace == -1 )
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100659 aes_padlock_ace = mbedtls_padlock_has_support( MBEDTLS_PADLOCK_ACE );
Paul Bakker048d04e2012-02-12 17:31:04 +0000660
661 if( aes_padlock_ace )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200662 ctx->rk = RK = MBEDTLS_PADLOCK_ALIGN16( ctx->buf );
Paul Bakker048d04e2012-02-12 17:31:04 +0000663 else
Paul Bakker5121ce52009-01-03 21:22:43 +0000664#endif
Paul Bakker048d04e2012-02-12 17:31:04 +0000665 ctx->rk = RK = ctx->buf;
Paul Bakker5121ce52009-01-03 21:22:43 +0000666
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200667 /* Also checks keybits */
668 if( ( ret = mbedtls_aes_setkey_enc( &cty, key, keybits ) ) != 0 )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200669 goto exit;
Paul Bakker2b222c82009-07-27 21:03:45 +0000670
Manuel Pégourié-Gonnardafd5a082014-05-28 21:52:59 +0200671 ctx->nr = cty.nr;
672
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200673#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100674 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) )
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100675 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200676 mbedtls_aesni_inverse_key( (unsigned char *) ctx->rk,
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100677 (const unsigned char *) cty.rk, ctx->nr );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200678 goto exit;
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100679 }
680#endif
681
Paul Bakker5121ce52009-01-03 21:22:43 +0000682 SK = cty.rk + cty.nr * 4;
683
684 *RK++ = *SK++;
685 *RK++ = *SK++;
686 *RK++ = *SK++;
687 *RK++ = *SK++;
688
689 for( i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8 )
690 {
691 for( j = 0; j < 4; j++, SK++ )
692 {
Joe Subbianicd84d762021-07-08 14:59:52 +0100693 *RK++ = AES_RT0( FSb[ MBEDTLS_BYTE_0( *SK ) ] ) ^
694 AES_RT1( FSb[ MBEDTLS_BYTE_1( *SK ) ] ) ^
695 AES_RT2( FSb[ MBEDTLS_BYTE_2( *SK ) ] ) ^
696 AES_RT3( FSb[ MBEDTLS_BYTE_3( *SK ) ] );
Paul Bakker5121ce52009-01-03 21:22:43 +0000697 }
698 }
699
700 *RK++ = *SK++;
701 *RK++ = *SK++;
702 *RK++ = *SK++;
703 *RK++ = *SK++;
704
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200705exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200706 mbedtls_aes_free( &cty );
Paul Bakker2b222c82009-07-27 21:03:45 +0000707
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200708 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000709}
gabor-mezei-arm95db3012020-10-26 11:35:23 +0100710#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */
Jaeden Amero9366feb2018-05-29 18:55:17 +0100711
712#if defined(MBEDTLS_CIPHER_MODE_XTS)
713static int mbedtls_aes_xts_decode_keys( const unsigned char *key,
714 unsigned int keybits,
715 const unsigned char **key1,
716 unsigned int *key1bits,
717 const unsigned char **key2,
718 unsigned int *key2bits )
719{
720 const unsigned int half_keybits = keybits / 2;
721 const unsigned int half_keybytes = half_keybits / 8;
722
723 switch( keybits )
724 {
725 case 256: break;
726 case 512: break;
727 default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH );
728 }
729
730 *key1bits = half_keybits;
731 *key2bits = half_keybits;
732 *key1 = &key[0];
733 *key2 = &key[half_keybytes];
734
735 return 0;
736}
737
738int mbedtls_aes_xts_setkey_enc( mbedtls_aes_xts_context *ctx,
739 const unsigned char *key,
740 unsigned int keybits)
741{
Janos Follath24eed8d2019-11-22 13:21:35 +0000742 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100743 const unsigned char *key1, *key2;
744 unsigned int key1bits, key2bits;
745
Manuel Pégourié-Gonnard68e3dff2018-12-12 12:48:04 +0100746 AES_VALIDATE_RET( ctx != NULL );
747 AES_VALIDATE_RET( key != NULL );
748
Jaeden Amero9366feb2018-05-29 18:55:17 +0100749 ret = mbedtls_aes_xts_decode_keys( key, keybits, &key1, &key1bits,
750 &key2, &key2bits );
751 if( ret != 0 )
752 return( ret );
753
754 /* Set the tweak key. Always set tweak key for the encryption mode. */
755 ret = mbedtls_aes_setkey_enc( &ctx->tweak, key2, key2bits );
756 if( ret != 0 )
757 return( ret );
758
759 /* Set crypt key for encryption. */
760 return mbedtls_aes_setkey_enc( &ctx->crypt, key1, key1bits );
761}
762
763int mbedtls_aes_xts_setkey_dec( mbedtls_aes_xts_context *ctx,
764 const unsigned char *key,
765 unsigned int keybits)
766{
Janos Follath24eed8d2019-11-22 13:21:35 +0000767 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100768 const unsigned char *key1, *key2;
769 unsigned int key1bits, key2bits;
770
Manuel Pégourié-Gonnard68e3dff2018-12-12 12:48:04 +0100771 AES_VALIDATE_RET( ctx != NULL );
772 AES_VALIDATE_RET( key != NULL );
773
Jaeden Amero9366feb2018-05-29 18:55:17 +0100774 ret = mbedtls_aes_xts_decode_keys( key, keybits, &key1, &key1bits,
775 &key2, &key2bits );
776 if( ret != 0 )
777 return( ret );
778
779 /* Set the tweak key. Always set tweak key for encryption. */
780 ret = mbedtls_aes_setkey_enc( &ctx->tweak, key2, key2bits );
781 if( ret != 0 )
782 return( ret );
783
784 /* Set crypt key for decryption. */
785 return mbedtls_aes_setkey_dec( &ctx->crypt, key1, key1bits );
786}
787#endif /* MBEDTLS_CIPHER_MODE_XTS */
788
Joe Subbianicd84d762021-07-08 14:59:52 +0100789#define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \
790 do \
791 { \
792 (X0) = *RK++ ^ AES_FT0( MBEDTLS_BYTE_0( Y0 ) ) ^ \
793 AES_FT1( MBEDTLS_BYTE_1( Y1 ) ) ^ \
794 AES_FT2( MBEDTLS_BYTE_2( Y2 ) ) ^ \
795 AES_FT3( MBEDTLS_BYTE_3( Y3 ) ); \
796 \
797 (X1) = *RK++ ^ AES_FT0( MBEDTLS_BYTE_0( Y1 ) ) ^ \
798 AES_FT1( MBEDTLS_BYTE_1( Y2 ) ) ^ \
799 AES_FT2( MBEDTLS_BYTE_2( Y3 ) ) ^ \
800 AES_FT3( MBEDTLS_BYTE_3( Y0 ) ); \
801 \
802 (X2) = *RK++ ^ AES_FT0( MBEDTLS_BYTE_0( Y2 ) ) ^ \
803 AES_FT1( MBEDTLS_BYTE_1( Y3 ) ) ^ \
804 AES_FT2( MBEDTLS_BYTE_2( Y0 ) ) ^ \
805 AES_FT3( MBEDTLS_BYTE_3( Y1 ) ); \
806 \
807 (X3) = *RK++ ^ AES_FT0( MBEDTLS_BYTE_0( Y3 ) ) ^ \
808 AES_FT1( MBEDTLS_BYTE_1( Y0 ) ) ^ \
809 AES_FT2( MBEDTLS_BYTE_2( Y1 ) ) ^ \
810 AES_FT3( MBEDTLS_BYTE_3( Y2 ) ); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100811 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000812
Hanno Becker1eeca412018-10-15 12:01:35 +0100813#define AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \
814 do \
815 { \
Joe Subbianicd84d762021-07-08 14:59:52 +0100816 (X0) = *RK++ ^ AES_RT0( MBEDTLS_BYTE_0( Y0 ) ) ^ \
817 AES_RT1( MBEDTLS_BYTE_1( Y3 ) ) ^ \
818 AES_RT2( MBEDTLS_BYTE_2( Y2 ) ) ^ \
819 AES_RT3( MBEDTLS_BYTE_3( Y1 ) ); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100820 \
Joe Subbianicd84d762021-07-08 14:59:52 +0100821 (X1) = *RK++ ^ AES_RT0( MBEDTLS_BYTE_0( Y1 ) ) ^ \
822 AES_RT1( MBEDTLS_BYTE_1( Y0 ) ) ^ \
823 AES_RT2( MBEDTLS_BYTE_2( Y3 ) ) ^ \
824 AES_RT3( MBEDTLS_BYTE_3( Y2 ) ); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100825 \
Joe Subbianicd84d762021-07-08 14:59:52 +0100826 (X2) = *RK++ ^ AES_RT0( MBEDTLS_BYTE_0( Y2 ) ) ^ \
827 AES_RT1( MBEDTLS_BYTE_1( Y1 ) ) ^ \
828 AES_RT2( MBEDTLS_BYTE_2( Y0 ) ) ^ \
829 AES_RT3( MBEDTLS_BYTE_3( Y3 ) ); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100830 \
Joe Subbianicd84d762021-07-08 14:59:52 +0100831 (X3) = *RK++ ^ AES_RT0( MBEDTLS_BYTE_0( Y3 ) ) ^ \
832 AES_RT1( MBEDTLS_BYTE_1( Y2 ) ) ^ \
833 AES_RT2( MBEDTLS_BYTE_2( Y1 ) ) ^ \
834 AES_RT3( MBEDTLS_BYTE_3( Y0 ) ); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100835 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000836
837/*
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200838 * AES-ECB block encryption
839 */
840#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Andres AGf5bf7182017-03-03 14:09:56 +0000841int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx,
842 const unsigned char input[16],
843 unsigned char output[16] )
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200844{
845 int i;
Gilles Peskine5197c662020-08-26 17:03:24 +0200846 uint32_t *RK = ctx->rk;
847 struct
848 {
849 uint32_t X[4];
850 uint32_t Y[4];
851 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200852
Joe Subbiani6a506312021-07-07 16:56:29 +0100853 t.X[0] = MBEDTLS_GET_UINT32_LE( input, 0 ); t.X[0] ^= *RK++;
854 t.X[1] = MBEDTLS_GET_UINT32_LE( input, 4 ); t.X[1] ^= *RK++;
855 t.X[2] = MBEDTLS_GET_UINT32_LE( input, 8 ); t.X[2] ^= *RK++;
856 t.X[3] = MBEDTLS_GET_UINT32_LE( input, 12 ); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200857
858 for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- )
859 {
Gilles Peskine5197c662020-08-26 17:03:24 +0200860 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] );
861 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 +0200862 }
863
Gilles Peskine5197c662020-08-26 17:03:24 +0200864 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 +0200865
Gilles Peskine5197c662020-08-26 17:03:24 +0200866 t.X[0] = *RK++ ^ \
Joe Subbianicd84d762021-07-08 14:59:52 +0100867 ( (uint32_t) FSb[ MBEDTLS_BYTE_0( t.Y[0] ) ] ) ^
868 ( (uint32_t) FSb[ MBEDTLS_BYTE_1( t.Y[1] ) ] << 8 ) ^
869 ( (uint32_t) FSb[ MBEDTLS_BYTE_2( t.Y[2] ) ] << 16 ) ^
870 ( (uint32_t) FSb[ MBEDTLS_BYTE_3( t.Y[3] ) ] << 24 );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200871
Gilles Peskine5197c662020-08-26 17:03:24 +0200872 t.X[1] = *RK++ ^ \
Joe Subbianicd84d762021-07-08 14:59:52 +0100873 ( (uint32_t) FSb[ MBEDTLS_BYTE_0( t.Y[1] ) ] ) ^
874 ( (uint32_t) FSb[ MBEDTLS_BYTE_1( t.Y[2] ) ] << 8 ) ^
875 ( (uint32_t) FSb[ MBEDTLS_BYTE_2( t.Y[3] ) ] << 16 ) ^
876 ( (uint32_t) FSb[ MBEDTLS_BYTE_3( t.Y[0] ) ] << 24 );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200877
Gilles Peskine5197c662020-08-26 17:03:24 +0200878 t.X[2] = *RK++ ^ \
Joe Subbianicd84d762021-07-08 14:59:52 +0100879 ( (uint32_t) FSb[ MBEDTLS_BYTE_0( t.Y[2] ) ] ) ^
880 ( (uint32_t) FSb[ MBEDTLS_BYTE_1( t.Y[3] ) ] << 8 ) ^
881 ( (uint32_t) FSb[ MBEDTLS_BYTE_2( t.Y[0] ) ] << 16 ) ^
882 ( (uint32_t) FSb[ MBEDTLS_BYTE_3( t.Y[1] ) ] << 24 );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200883
Gilles Peskine5197c662020-08-26 17:03:24 +0200884 t.X[3] = *RK++ ^ \
Joe Subbianicd84d762021-07-08 14:59:52 +0100885 ( (uint32_t) FSb[ MBEDTLS_BYTE_0( t.Y[3] ) ] ) ^
886 ( (uint32_t) FSb[ MBEDTLS_BYTE_1( t.Y[0] ) ] << 8 ) ^
887 ( (uint32_t) FSb[ MBEDTLS_BYTE_2( t.Y[1] ) ] << 16 ) ^
888 ( (uint32_t) FSb[ MBEDTLS_BYTE_3( t.Y[2] ) ] << 24 );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200889
Joe Subbiani5ecac212021-06-24 13:00:03 +0100890 MBEDTLS_PUT_UINT32_LE( t.X[0], output, 0 );
891 MBEDTLS_PUT_UINT32_LE( t.X[1], output, 4 );
892 MBEDTLS_PUT_UINT32_LE( t.X[2], output, 8 );
893 MBEDTLS_PUT_UINT32_LE( t.X[3], output, 12 );
Andres AGf5bf7182017-03-03 14:09:56 +0000894
Gilles Peskine5197c662020-08-26 17:03:24 +0200895 mbedtls_platform_zeroize( &t, sizeof( t ) );
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500896
Andres AGf5bf7182017-03-03 14:09:56 +0000897 return( 0 );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200898}
899#endif /* !MBEDTLS_AES_ENCRYPT_ALT */
900
901/*
902 * AES-ECB block decryption
903 */
904#if !defined(MBEDTLS_AES_DECRYPT_ALT)
Andres AGf5bf7182017-03-03 14:09:56 +0000905int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx,
906 const unsigned char input[16],
907 unsigned char output[16] )
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200908{
909 int i;
Gilles Peskine5197c662020-08-26 17:03:24 +0200910 uint32_t *RK = ctx->rk;
911 struct
912 {
913 uint32_t X[4];
914 uint32_t Y[4];
915 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200916
Joe Subbiani6a506312021-07-07 16:56:29 +0100917 t.X[0] = MBEDTLS_GET_UINT32_LE( input, 0 ); t.X[0] ^= *RK++;
918 t.X[1] = MBEDTLS_GET_UINT32_LE( input, 4 ); t.X[1] ^= *RK++;
919 t.X[2] = MBEDTLS_GET_UINT32_LE( input, 8 ); t.X[2] ^= *RK++;
920 t.X[3] = MBEDTLS_GET_UINT32_LE( input, 12 ); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200921
922 for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- )
923 {
Gilles Peskine5197c662020-08-26 17:03:24 +0200924 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] );
925 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 +0200926 }
927
Gilles Peskine5197c662020-08-26 17:03:24 +0200928 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 +0200929
Gilles Peskine5197c662020-08-26 17:03:24 +0200930 t.X[0] = *RK++ ^ \
Joe Subbianicd84d762021-07-08 14:59:52 +0100931 ( (uint32_t) RSb[ MBEDTLS_BYTE_0( t.Y[0] ) ] ) ^
932 ( (uint32_t) RSb[ MBEDTLS_BYTE_1( t.Y[3] ) ] << 8 ) ^
933 ( (uint32_t) RSb[ MBEDTLS_BYTE_2( t.Y[2] ) ] << 16 ) ^
934 ( (uint32_t) RSb[ MBEDTLS_BYTE_3( t.Y[1] ) ] << 24 );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200935
Gilles Peskine5197c662020-08-26 17:03:24 +0200936 t.X[1] = *RK++ ^ \
Joe Subbianicd84d762021-07-08 14:59:52 +0100937 ( (uint32_t) RSb[ MBEDTLS_BYTE_0( t.Y[1] ) ] ) ^
938 ( (uint32_t) RSb[ MBEDTLS_BYTE_1( t.Y[0] ) ] << 8 ) ^
939 ( (uint32_t) RSb[ MBEDTLS_BYTE_2( t.Y[3] ) ] << 16 ) ^
940 ( (uint32_t) RSb[ MBEDTLS_BYTE_3( t.Y[2] ) ] << 24 );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200941
Gilles Peskine5197c662020-08-26 17:03:24 +0200942 t.X[2] = *RK++ ^ \
Joe Subbianicd84d762021-07-08 14:59:52 +0100943 ( (uint32_t) RSb[ MBEDTLS_BYTE_0( t.Y[2] ) ] ) ^
944 ( (uint32_t) RSb[ MBEDTLS_BYTE_1( t.Y[1] ) ] << 8 ) ^
945 ( (uint32_t) RSb[ MBEDTLS_BYTE_2( t.Y[0] ) ] << 16 ) ^
946 ( (uint32_t) RSb[ MBEDTLS_BYTE_3( t.Y[3] ) ] << 24 );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200947
Gilles Peskine5197c662020-08-26 17:03:24 +0200948 t.X[3] = *RK++ ^ \
Joe Subbianicd84d762021-07-08 14:59:52 +0100949 ( (uint32_t) RSb[ MBEDTLS_BYTE_0( t.Y[3] ) ] ) ^
950 ( (uint32_t) RSb[ MBEDTLS_BYTE_1( t.Y[2] ) ] << 8 ) ^
951 ( (uint32_t) RSb[ MBEDTLS_BYTE_2( t.Y[1] ) ] << 16 ) ^
952 ( (uint32_t) RSb[ MBEDTLS_BYTE_3( t.Y[0] ) ] << 24 );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200953
Joe Subbiani5ecac212021-06-24 13:00:03 +0100954 MBEDTLS_PUT_UINT32_LE( t.X[0], output, 0 );
955 MBEDTLS_PUT_UINT32_LE( t.X[1], output, 4 );
956 MBEDTLS_PUT_UINT32_LE( t.X[2], output, 8 );
957 MBEDTLS_PUT_UINT32_LE( t.X[3], output, 12 );
Andres AGf5bf7182017-03-03 14:09:56 +0000958
Gilles Peskine5197c662020-08-26 17:03:24 +0200959 mbedtls_platform_zeroize( &t, sizeof( t ) );
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500960
Andres AGf5bf7182017-03-03 14:09:56 +0000961 return( 0 );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200962}
963#endif /* !MBEDTLS_AES_DECRYPT_ALT */
964
965/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000966 * AES-ECB block encryption/decryption
967 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200968int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx,
Manuel Pégourié-Gonnardeb6d3962018-12-18 09:59:35 +0100969 int mode,
970 const unsigned char input[16],
971 unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000972{
Manuel Pégourié-Gonnard1aca2602018-12-12 12:56:55 +0100973 AES_VALIDATE_RET( ctx != NULL );
974 AES_VALIDATE_RET( input != NULL );
975 AES_VALIDATE_RET( output != NULL );
976 AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
977 mode == MBEDTLS_AES_DECRYPT );
978
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200979#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100980 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200981 return( mbedtls_aesni_crypt_ecb( ctx, mode, input, output ) );
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +0100982#endif
983
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200984#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Xiang Xiao12e18362021-05-07 00:55:52 -0700985 if( aes_padlock_ace > 0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000986 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200987 if( mbedtls_padlock_xcryptecb( ctx, mode, input, output ) == 0 )
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000988 return( 0 );
989
990 // If padlock data misaligned, we just fall back to
991 // unaccelerated mode
992 //
Paul Bakker5121ce52009-01-03 21:22:43 +0000993 }
994#endif
995
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200996 if( mode == MBEDTLS_AES_ENCRYPT )
Andres AGf5bf7182017-03-03 14:09:56 +0000997 return( mbedtls_internal_aes_encrypt( ctx, input, output ) );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200998 else
Andres AGf5bf7182017-03-03 14:09:56 +0000999 return( mbedtls_internal_aes_decrypt( ctx, input, output ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001000}
1001
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001002#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001003/*
1004 * AES-CBC buffer encryption/decryption
1005 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001006int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx,
Paul Bakker5121ce52009-01-03 21:22:43 +00001007 int mode,
Paul Bakker23986e52011-04-24 08:57:21 +00001008 size_t length,
Paul Bakker5121ce52009-01-03 21:22:43 +00001009 unsigned char iv[16],
Paul Bakkerff60ee62010-03-16 21:09:09 +00001010 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +00001011 unsigned char *output )
1012{
1013 int i;
Gilles Peskine7820a572021-07-07 21:08:28 +02001014 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +00001015 unsigned char temp[16];
1016
Manuel Pégourié-Gonnard3178d1a2018-12-12 13:05:00 +01001017 AES_VALIDATE_RET( ctx != NULL );
1018 AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
1019 mode == MBEDTLS_AES_DECRYPT );
1020 AES_VALIDATE_RET( iv != NULL );
1021 AES_VALIDATE_RET( input != NULL );
1022 AES_VALIDATE_RET( output != NULL );
1023
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001024 if( length % 16 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001025 return( MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH );
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001026
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001027#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Xiang Xiao12e18362021-05-07 00:55:52 -07001028 if( aes_padlock_ace > 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001029 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001030 if( mbedtls_padlock_xcryptcbc( ctx, mode, length, iv, input, output ) == 0 )
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001031 return( 0 );
Paul Bakker9af723c2014-05-01 13:03:14 +02001032
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001033 // If padlock data misaligned, we just fall back to
1034 // unaccelerated mode
1035 //
Paul Bakker5121ce52009-01-03 21:22:43 +00001036 }
1037#endif
1038
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001039 if( mode == MBEDTLS_AES_DECRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +00001040 {
1041 while( length > 0 )
1042 {
1043 memcpy( temp, input, 16 );
Gilles Peskine7820a572021-07-07 21:08:28 +02001044 ret = mbedtls_aes_crypt_ecb( ctx, mode, input, output );
1045 if( ret != 0 )
1046 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001047
1048 for( i = 0; i < 16; i++ )
1049 output[i] = (unsigned char)( output[i] ^ iv[i] );
1050
1051 memcpy( iv, temp, 16 );
1052
1053 input += 16;
1054 output += 16;
1055 length -= 16;
1056 }
1057 }
1058 else
1059 {
1060 while( length > 0 )
1061 {
1062 for( i = 0; i < 16; i++ )
1063 output[i] = (unsigned char)( input[i] ^ iv[i] );
1064
Gilles Peskine7820a572021-07-07 21:08:28 +02001065 ret = mbedtls_aes_crypt_ecb( ctx, mode, output, output );
1066 if( ret != 0 )
1067 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001068 memcpy( iv, output, 16 );
1069
1070 input += 16;
1071 output += 16;
1072 length -= 16;
1073 }
1074 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001075 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001076
Gilles Peskine7820a572021-07-07 21:08:28 +02001077exit:
1078 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001079}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001080#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001081
Aorimn5f778012016-06-09 23:22:58 +02001082#if defined(MBEDTLS_CIPHER_MODE_XTS)
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001083
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001084typedef unsigned char mbedtls_be128[16];
1085
1086/*
1087 * GF(2^128) multiplication function
1088 *
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001089 * This function multiplies a field element by x in the polynomial field
1090 * representation. It uses 64-bit word operations to gain speed but compensates
1091 * for machine endianess and hence works correctly on both big and little
1092 * endian machines.
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001093 */
1094static void mbedtls_gf128mul_x_ble( unsigned char r[16],
Jaeden Amero8cfc75f2018-05-31 16:53:08 +01001095 const unsigned char x[16] )
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001096{
1097 uint64_t a, b, ra, rb;
1098
Joe Subbiani99edd6c2021-07-16 12:29:49 +01001099 a = MBEDTLS_GET_UINT64_LE( x, 0 );
1100 b = MBEDTLS_GET_UINT64_LE( x, 8 );
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001101
Jaeden Amero8cfc75f2018-05-31 16:53:08 +01001102 ra = ( a << 1 ) ^ 0x0087 >> ( 8 - ( ( b >> 63 ) << 3 ) );
1103 rb = ( a >> 63 ) | ( b << 1 );
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001104
Joe Subbiani99edd6c2021-07-16 12:29:49 +01001105 MBEDTLS_PUT_UINT64_LE( ra, r, 0 );
1106 MBEDTLS_PUT_UINT64_LE( rb, r, 8 );
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001107}
1108
Aorimn5f778012016-06-09 23:22:58 +02001109/*
1110 * AES-XTS buffer encryption/decryption
1111 */
Jaeden Amero9366feb2018-05-29 18:55:17 +01001112int mbedtls_aes_crypt_xts( mbedtls_aes_xts_context *ctx,
1113 int mode,
Jaeden Amero5162b932018-05-29 12:55:24 +01001114 size_t length,
Jaeden Amerocd9fc5e2018-05-30 15:23:24 +01001115 const unsigned char data_unit[16],
Jaeden Amero9366feb2018-05-29 18:55:17 +01001116 const unsigned char *input,
1117 unsigned char *output )
Aorimn5f778012016-06-09 23:22:58 +02001118{
Janos Follath24eed8d2019-11-22 13:21:35 +00001119 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amerod82cd862018-04-28 15:02:45 +01001120 size_t blocks = length / 16;
1121 size_t leftover = length % 16;
1122 unsigned char tweak[16];
1123 unsigned char prev_tweak[16];
1124 unsigned char tmp[16];
Aorimn5f778012016-06-09 23:22:58 +02001125
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01001126 AES_VALIDATE_RET( ctx != NULL );
1127 AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
1128 mode == MBEDTLS_AES_DECRYPT );
Manuel Pégourié-Gonnard998a3582018-12-18 10:03:13 +01001129 AES_VALIDATE_RET( data_unit != NULL );
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01001130 AES_VALIDATE_RET( input != NULL );
1131 AES_VALIDATE_RET( output != NULL );
1132
Jaeden Amero8381fcb2018-10-11 12:06:15 +01001133 /* Data units must be at least 16 bytes long. */
Aorimn5f778012016-06-09 23:22:58 +02001134 if( length < 16 )
Jaeden Amerod82cd862018-04-28 15:02:45 +01001135 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Aorimn5f778012016-06-09 23:22:58 +02001136
Jaeden Ameroa74faba2018-10-11 12:07:43 +01001137 /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */
Jaeden Amero0a8b0202018-05-30 15:36:06 +01001138 if( length > ( 1 << 20 ) * 16 )
1139 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Aorimn5f778012016-06-09 23:22:58 +02001140
Jaeden Amerod82cd862018-04-28 15:02:45 +01001141 /* Compute the tweak. */
Jaeden Amerocd9fc5e2018-05-30 15:23:24 +01001142 ret = mbedtls_aes_crypt_ecb( &ctx->tweak, MBEDTLS_AES_ENCRYPT,
1143 data_unit, tweak );
Jaeden Amerod82cd862018-04-28 15:02:45 +01001144 if( ret != 0 )
1145 return( ret );
Aorimn5f778012016-06-09 23:22:58 +02001146
Jaeden Amerod82cd862018-04-28 15:02:45 +01001147 while( blocks-- )
Aorimn5f778012016-06-09 23:22:58 +02001148 {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001149 size_t i;
1150
1151 if( leftover && ( mode == MBEDTLS_AES_DECRYPT ) && blocks == 0 )
1152 {
1153 /* We are on the last block in a decrypt operation that has
1154 * leftover bytes, so we need to use the next tweak for this block,
1155 * and this tweak for the lefover bytes. Save the current tweak for
1156 * the leftovers and then update the current tweak for use on this,
1157 * the last full block. */
1158 memcpy( prev_tweak, tweak, sizeof( tweak ) );
1159 mbedtls_gf128mul_x_ble( tweak, tweak );
1160 }
1161
1162 for( i = 0; i < 16; i++ )
1163 tmp[i] = input[i] ^ tweak[i];
1164
1165 ret = mbedtls_aes_crypt_ecb( &ctx->crypt, mode, tmp, tmp );
1166 if( ret != 0 )
1167 return( ret );
1168
1169 for( i = 0; i < 16; i++ )
1170 output[i] = tmp[i] ^ tweak[i];
1171
1172 /* Update the tweak for the next block. */
1173 mbedtls_gf128mul_x_ble( tweak, tweak );
1174
1175 output += 16;
1176 input += 16;
Aorimn5f778012016-06-09 23:22:58 +02001177 }
1178
Jaeden Amerod82cd862018-04-28 15:02:45 +01001179 if( leftover )
Aorimn5f778012016-06-09 23:22:58 +02001180 {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001181 /* If we are on the leftover bytes in a decrypt operation, we need to
1182 * use the previous tweak for these bytes (as saved in prev_tweak). */
1183 unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
Aorimn5f778012016-06-09 23:22:58 +02001184
Jaeden Amerod82cd862018-04-28 15:02:45 +01001185 /* We are now on the final part of the data unit, which doesn't divide
1186 * evenly by 16. It's time for ciphertext stealing. */
1187 size_t i;
1188 unsigned char *prev_output = output - 16;
Aorimn5f778012016-06-09 23:22:58 +02001189
Jaeden Amerod82cd862018-04-28 15:02:45 +01001190 /* Copy ciphertext bytes from the previous block to our output for each
1191 * byte of cyphertext we won't steal. At the same time, copy the
1192 * remainder of the input for this final round (since the loop bounds
1193 * are the same). */
1194 for( i = 0; i < leftover; i++ )
Aorimn5f778012016-06-09 23:22:58 +02001195 {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001196 output[i] = prev_output[i];
1197 tmp[i] = input[i] ^ t[i];
Aorimn5f778012016-06-09 23:22:58 +02001198 }
Aorimn5f778012016-06-09 23:22:58 +02001199
Jaeden Amerod82cd862018-04-28 15:02:45 +01001200 /* Copy ciphertext bytes from the previous block for input in this
1201 * round. */
1202 for( ; i < 16; i++ )
1203 tmp[i] = prev_output[i] ^ t[i];
Aorimn5f778012016-06-09 23:22:58 +02001204
Jaeden Amerod82cd862018-04-28 15:02:45 +01001205 ret = mbedtls_aes_crypt_ecb( &ctx->crypt, mode, tmp, tmp );
1206 if( ret != 0 )
1207 return ret;
Aorimn5f778012016-06-09 23:22:58 +02001208
Jaeden Amerod82cd862018-04-28 15:02:45 +01001209 /* Write the result back to the previous block, overriding the previous
1210 * output we copied. */
1211 for( i = 0; i < 16; i++ )
1212 prev_output[i] = tmp[i] ^ t[i];
Aorimn5f778012016-06-09 23:22:58 +02001213 }
1214
1215 return( 0 );
1216}
1217#endif /* MBEDTLS_CIPHER_MODE_XTS */
1218
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001219#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001220/*
1221 * AES-CFB128 buffer encryption/decryption
1222 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001223int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx,
Paul Bakker5121ce52009-01-03 21:22:43 +00001224 int mode,
Paul Bakker23986e52011-04-24 08:57:21 +00001225 size_t length,
Paul Bakker27fdf462011-06-09 13:55:13 +00001226 size_t *iv_off,
Paul Bakker5121ce52009-01-03 21:22:43 +00001227 unsigned char iv[16],
Paul Bakkerff60ee62010-03-16 21:09:09 +00001228 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +00001229 unsigned char *output )
1230{
Paul Bakker27fdf462011-06-09 13:55:13 +00001231 int c;
Gilles Peskine7820a572021-07-07 21:08:28 +02001232 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001233 size_t n;
1234
1235 AES_VALIDATE_RET( ctx != NULL );
1236 AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
1237 mode == MBEDTLS_AES_DECRYPT );
1238 AES_VALIDATE_RET( iv_off != NULL );
1239 AES_VALIDATE_RET( iv != NULL );
1240 AES_VALIDATE_RET( input != NULL );
1241 AES_VALIDATE_RET( output != NULL );
1242
1243 n = *iv_off;
Paul Bakker5121ce52009-01-03 21:22:43 +00001244
Manuel Pégourié-Gonnarde55e1032018-12-18 12:09:02 +01001245 if( n > 15 )
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001246 return( MBEDTLS_ERR_AES_BAD_INPUT_DATA );
1247
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001248 if( mode == MBEDTLS_AES_DECRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +00001249 {
1250 while( length-- )
1251 {
1252 if( n == 0 )
Gilles Peskine7820a572021-07-07 21:08:28 +02001253 {
1254 ret = mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
1255 if( ret != 0 )
1256 goto exit;
1257 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001258
1259 c = *input++;
1260 *output++ = (unsigned char)( c ^ iv[n] );
1261 iv[n] = (unsigned char) c;
1262
Paul Bakker66d5d072014-06-17 16:39:18 +02001263 n = ( n + 1 ) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001264 }
1265 }
1266 else
1267 {
1268 while( length-- )
1269 {
1270 if( n == 0 )
Gilles Peskine7820a572021-07-07 21:08:28 +02001271 {
1272 ret = mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
1273 if( ret != 0 )
1274 goto exit;
1275 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001276
1277 iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ );
1278
Paul Bakker66d5d072014-06-17 16:39:18 +02001279 n = ( n + 1 ) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001280 }
1281 }
1282
1283 *iv_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001284 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001285
Gilles Peskine7820a572021-07-07 21:08:28 +02001286exit:
1287 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001288}
Paul Bakker556efba2014-01-24 15:38:12 +01001289
1290/*
1291 * AES-CFB8 buffer encryption/decryption
1292 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001293int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx,
Manuel Pégourié-Gonnardeb6d3962018-12-18 09:59:35 +01001294 int mode,
1295 size_t length,
1296 unsigned char iv[16],
1297 const unsigned char *input,
1298 unsigned char *output )
Paul Bakker556efba2014-01-24 15:38:12 +01001299{
Gilles Peskine7820a572021-07-07 21:08:28 +02001300 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker556efba2014-01-24 15:38:12 +01001301 unsigned char c;
1302 unsigned char ov[17];
1303
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001304 AES_VALIDATE_RET( ctx != NULL );
1305 AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
1306 mode == MBEDTLS_AES_DECRYPT );
1307 AES_VALIDATE_RET( iv != NULL );
1308 AES_VALIDATE_RET( input != NULL );
1309 AES_VALIDATE_RET( output != NULL );
Paul Bakker556efba2014-01-24 15:38:12 +01001310 while( length-- )
1311 {
Paul Bakker66d5d072014-06-17 16:39:18 +02001312 memcpy( ov, iv, 16 );
Gilles Peskine7820a572021-07-07 21:08:28 +02001313 ret = mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
1314 if( ret != 0 )
1315 goto exit;
Paul Bakker556efba2014-01-24 15:38:12 +01001316
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001317 if( mode == MBEDTLS_AES_DECRYPT )
Paul Bakker556efba2014-01-24 15:38:12 +01001318 ov[16] = *input;
1319
1320 c = *output++ = (unsigned char)( iv[0] ^ *input++ );
1321
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001322 if( mode == MBEDTLS_AES_ENCRYPT )
Paul Bakker556efba2014-01-24 15:38:12 +01001323 ov[16] = c;
1324
Paul Bakker66d5d072014-06-17 16:39:18 +02001325 memcpy( iv, ov + 1, 16 );
Paul Bakker556efba2014-01-24 15:38:12 +01001326 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001327 ret = 0;
Paul Bakker556efba2014-01-24 15:38:12 +01001328
Gilles Peskine7820a572021-07-07 21:08:28 +02001329exit:
1330 return( ret );
Paul Bakker556efba2014-01-24 15:38:12 +01001331}
Simon Butcher76a5b222018-04-22 22:57:27 +01001332#endif /* MBEDTLS_CIPHER_MODE_CFB */
1333
1334#if defined(MBEDTLS_CIPHER_MODE_OFB)
1335/*
1336 * AES-OFB (Output Feedback Mode) buffer encryption/decryption
1337 */
1338int mbedtls_aes_crypt_ofb( mbedtls_aes_context *ctx,
Simon Butcher00131442018-05-22 22:40:36 +01001339 size_t length,
1340 size_t *iv_off,
1341 unsigned char iv[16],
1342 const unsigned char *input,
1343 unsigned char *output )
Simon Butcher76a5b222018-04-22 22:57:27 +01001344{
Simon Butcherad4e4932018-04-29 00:43:47 +01001345 int ret = 0;
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001346 size_t n;
1347
1348 AES_VALIDATE_RET( ctx != NULL );
1349 AES_VALIDATE_RET( iv_off != NULL );
1350 AES_VALIDATE_RET( iv != NULL );
1351 AES_VALIDATE_RET( input != NULL );
1352 AES_VALIDATE_RET( output != NULL );
1353
1354 n = *iv_off;
Simon Butcher76a5b222018-04-22 22:57:27 +01001355
Manuel Pégourié-Gonnarde55e1032018-12-18 12:09:02 +01001356 if( n > 15 )
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001357 return( MBEDTLS_ERR_AES_BAD_INPUT_DATA );
1358
Simon Butcher76a5b222018-04-22 22:57:27 +01001359 while( length-- )
1360 {
1361 if( n == 0 )
Simon Butcherad4e4932018-04-29 00:43:47 +01001362 {
1363 ret = mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
1364 if( ret != 0 )
1365 goto exit;
1366 }
Simon Butcher76a5b222018-04-22 22:57:27 +01001367 *output++ = *input++ ^ iv[n];
1368
1369 n = ( n + 1 ) & 0x0F;
1370 }
1371
1372 *iv_off = n;
1373
Simon Butcherad4e4932018-04-29 00:43:47 +01001374exit:
1375 return( ret );
Simon Butcher76a5b222018-04-22 22:57:27 +01001376}
1377#endif /* MBEDTLS_CIPHER_MODE_OFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001378
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001379#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001380/*
1381 * AES-CTR buffer encryption/decryption
1382 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001383int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx,
Paul Bakker27fdf462011-06-09 13:55:13 +00001384 size_t length,
1385 size_t *nc_off,
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001386 unsigned char nonce_counter[16],
1387 unsigned char stream_block[16],
1388 const unsigned char *input,
1389 unsigned char *output )
1390{
Paul Bakker369e14b2012-04-18 14:16:09 +00001391 int c, i;
Gilles Peskine7820a572021-07-07 21:08:28 +02001392 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001393 size_t n;
1394
1395 AES_VALIDATE_RET( ctx != NULL );
1396 AES_VALIDATE_RET( nc_off != NULL );
1397 AES_VALIDATE_RET( nonce_counter != NULL );
1398 AES_VALIDATE_RET( stream_block != NULL );
1399 AES_VALIDATE_RET( input != NULL );
1400 AES_VALIDATE_RET( output != NULL );
1401
1402 n = *nc_off;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001403
Mohammad Azim Khan3f7f8172017-11-23 17:49:05 +00001404 if ( n > 0x0F )
1405 return( MBEDTLS_ERR_AES_BAD_INPUT_DATA );
1406
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001407 while( length-- )
1408 {
1409 if( n == 0 ) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001410 ret = mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block );
1411 if( ret != 0 )
1412 goto exit;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001413
Paul Bakker369e14b2012-04-18 14:16:09 +00001414 for( i = 16; i > 0; i-- )
1415 if( ++nonce_counter[i - 1] != 0 )
1416 break;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001417 }
1418 c = *input++;
1419 *output++ = (unsigned char)( c ^ stream_block[n] );
1420
Paul Bakker66d5d072014-06-17 16:39:18 +02001421 n = ( n + 1 ) & 0x0F;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001422 }
1423
1424 *nc_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001425 ret = 0;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001426
Gilles Peskine7820a572021-07-07 21:08:28 +02001427exit:
1428 return( ret );
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001429}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001430#endif /* MBEDTLS_CIPHER_MODE_CTR */
Manuel Pégourié-Gonnard1ec220b2014-03-10 11:20:17 +01001431
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001432#endif /* !MBEDTLS_AES_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001433
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001434#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001435/*
1436 * AES test vectors from:
1437 *
1438 * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
1439 */
1440static const unsigned char aes_test_ecb_dec[3][16] =
1441{
1442 { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
1443 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
1444 { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
1445 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
1446 { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
1447 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
1448};
1449
1450static const unsigned char aes_test_ecb_enc[3][16] =
1451{
1452 { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
1453 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
1454 { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
1455 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
1456 { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
1457 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
1458};
1459
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001460#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001461static const unsigned char aes_test_cbc_dec[3][16] =
1462{
1463 { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
1464 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
1465 { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
1466 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
1467 { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
1468 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
1469};
1470
1471static const unsigned char aes_test_cbc_enc[3][16] =
1472{
1473 { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
1474 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
1475 { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
1476 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
1477 { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
1478 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
1479};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001480#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001481
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001482#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001483/*
1484 * AES-CFB128 test vectors from:
1485 *
1486 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
1487 */
1488static const unsigned char aes_test_cfb128_key[3][32] =
1489{
1490 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1491 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
1492 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1493 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1494 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1495 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1496 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1497 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1498 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
1499};
1500
1501static const unsigned char aes_test_cfb128_iv[16] =
1502{
1503 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1504 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1505};
1506
1507static const unsigned char aes_test_cfb128_pt[64] =
1508{
1509 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1510 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1511 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1512 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1513 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1514 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1515 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1516 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1517};
1518
1519static const unsigned char aes_test_cfb128_ct[3][64] =
1520{
1521 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1522 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1523 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F,
1524 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B,
1525 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40,
1526 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF,
1527 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E,
1528 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 },
1529 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1530 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1531 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21,
1532 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A,
1533 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1,
1534 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9,
1535 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0,
1536 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF },
1537 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1538 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1539 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8,
1540 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B,
1541 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92,
1542 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9,
1543 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8,
1544 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 }
1545};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001546#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001547
Simon Butcherad4e4932018-04-29 00:43:47 +01001548#if defined(MBEDTLS_CIPHER_MODE_OFB)
1549/*
1550 * AES-OFB test vectors from:
1551 *
Simon Butcher5db13622018-06-04 22:11:25 +01001552 * https://csrc.nist.gov/publications/detail/sp/800-38a/final
Simon Butcherad4e4932018-04-29 00:43:47 +01001553 */
1554static const unsigned char aes_test_ofb_key[3][32] =
1555{
1556 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1557 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
1558 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1559 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1560 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1561 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1562 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1563 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1564 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
1565};
1566
1567static const unsigned char aes_test_ofb_iv[16] =
1568{
1569 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1570 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1571};
1572
1573static const unsigned char aes_test_ofb_pt[64] =
1574{
1575 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1576 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1577 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1578 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1579 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1580 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1581 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1582 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1583};
1584
1585static const unsigned char aes_test_ofb_ct[3][64] =
1586{
1587 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1588 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1589 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
1590 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
1591 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
1592 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
1593 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
1594 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e },
1595 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1596 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1597 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
1598 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
1599 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f,
1600 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
1601 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e,
1602 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a },
1603 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1604 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1605 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
1606 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
1607 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed,
1608 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
1609 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8,
1610 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 }
1611};
1612#endif /* MBEDTLS_CIPHER_MODE_OFB */
1613
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001614#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001615/*
1616 * AES-CTR test vectors from:
1617 *
1618 * http://www.faqs.org/rfcs/rfc3686.html
1619 */
1620
1621static const unsigned char aes_test_ctr_key[3][16] =
1622{
1623 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
1624 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
1625 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
1626 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
1627 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
1628 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
1629};
1630
1631static const unsigned char aes_test_ctr_nonce_counter[3][16] =
1632{
1633 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
1634 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
1635 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
1636 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
1637 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
1638 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
1639};
1640
1641static const unsigned char aes_test_ctr_pt[3][48] =
1642{
1643 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
1644 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
1645
1646 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1647 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1648 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1649 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
1650
1651 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1652 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1653 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1654 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
1655 0x20, 0x21, 0x22, 0x23 }
1656};
1657
1658static const unsigned char aes_test_ctr_ct[3][48] =
1659{
1660 { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79,
1661 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 },
1662 { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9,
1663 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88,
1664 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8,
1665 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 },
1666 { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
1667 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
1668 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
1669 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
1670 0x25, 0xB2, 0x07, 0x2F }
1671};
1672
1673static const int aes_test_ctr_len[3] =
1674 { 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001675#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00001676
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001677#if defined(MBEDTLS_CIPHER_MODE_XTS)
1678/*
1679 * AES-XTS test vectors from:
1680 *
1681 * IEEE P1619/D16 Annex B
1682 * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf
1683 * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf)
1684 */
1685static const unsigned char aes_test_xts_key[][32] =
1686{
1687 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1688 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1689 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1690 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1691 { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1692 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1693 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1694 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1695 { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
1696 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
1697 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1698 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1699};
1700
1701static const unsigned char aes_test_xts_pt32[][32] =
1702{
1703 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1704 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1705 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1706 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1707 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1708 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1709 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1710 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1711 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1712 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1713 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1714 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1715};
1716
1717static const unsigned char aes_test_xts_ct32[][32] =
1718{
1719 { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec,
1720 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92,
1721 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85,
1722 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e },
1723 { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e,
1724 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b,
1725 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4,
1726 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 },
1727 { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a,
1728 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2,
1729 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53,
1730 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 },
1731};
1732
1733static const unsigned char aes_test_xts_data_unit[][16] =
1734{
1735 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1736 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1737 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1738 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1739 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1740 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1741};
1742
1743#endif /* MBEDTLS_CIPHER_MODE_XTS */
1744
Paul Bakker5121ce52009-01-03 21:22:43 +00001745/*
1746 * Checkup routine
1747 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001748int mbedtls_aes_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +00001749{
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001750 int ret = 0, i, j, u, mode;
1751 unsigned int keybits;
Paul Bakker5121ce52009-01-03 21:22:43 +00001752 unsigned char key[32];
1753 unsigned char buf[64];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001754 const unsigned char *aes_tests;
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03001755#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001756 unsigned char iv[16];
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03001757#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001758#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +02001759 unsigned char prv[16];
1760#endif
Simon Butcher2ff0e522018-06-14 09:57:07 +01001761#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1762 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker27fdf462011-06-09 13:55:13 +00001763 size_t offset;
Paul Bakkere91d01e2011-04-19 15:55:50 +00001764#endif
Simon Butcher66a89032018-06-15 18:20:29 +01001765#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS)
Paul Bakkere91d01e2011-04-19 15:55:50 +00001766 int len;
Simon Butcher66a89032018-06-15 18:20:29 +01001767#endif
1768#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001769 unsigned char nonce_counter[16];
1770 unsigned char stream_block[16];
1771#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001772 mbedtls_aes_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001773
1774 memset( key, 0, 32 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001775 mbedtls_aes_init( &ctx );
Paul Bakker5121ce52009-01-03 21:22:43 +00001776
1777 /*
1778 * ECB mode
1779 */
1780 for( i = 0; i < 6; i++ )
1781 {
1782 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001783 keybits = 128 + u * 64;
1784 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001785
1786 if( verbose != 0 )
Kenneth Soerensen518d4352020-04-01 17:22:45 +02001787 mbedtls_printf( " AES-ECB-%3u (%s): ", keybits,
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001788 ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001789
1790 memset( buf, 0, 16 );
1791
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001792 if( mode == MBEDTLS_AES_DECRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +00001793 {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001794 ret = mbedtls_aes_setkey_dec( &ctx, key, keybits );
1795 aes_tests = aes_test_ecb_dec[u];
Paul Bakker5121ce52009-01-03 21:22:43 +00001796 }
1797 else
1798 {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001799 ret = mbedtls_aes_setkey_enc( &ctx, key, keybits );
1800 aes_tests = aes_test_ecb_enc[u];
1801 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001802
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01001803 /*
1804 * AES-192 is an optional feature that may be unavailable when
1805 * there is an alternative underlying implementation i.e. when
1806 * MBEDTLS_AES_ALT is defined.
1807 */
Ron Eldor9924bdc2018-10-04 10:59:13 +03001808 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 )
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001809 {
1810 mbedtls_printf( "skipped\n" );
1811 continue;
1812 }
1813 else if( ret != 0 )
1814 {
1815 goto exit;
1816 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001817
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001818 for( j = 0; j < 10000; j++ )
1819 {
1820 ret = mbedtls_aes_crypt_ecb( &ctx, mode, buf, buf );
1821 if( ret != 0 )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001822 goto exit;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001823 }
1824
1825 if( memcmp( buf, aes_tests, 16 ) != 0 )
1826 {
1827 ret = 1;
1828 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001829 }
1830
1831 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001832 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001833 }
1834
1835 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001836 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001837
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001838#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001839 /*
1840 * CBC mode
1841 */
1842 for( i = 0; i < 6; i++ )
1843 {
1844 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001845 keybits = 128 + u * 64;
1846 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001847
1848 if( verbose != 0 )
Kenneth Soerensen518d4352020-04-01 17:22:45 +02001849 mbedtls_printf( " AES-CBC-%3u (%s): ", keybits,
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001850 ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001851
1852 memset( iv , 0, 16 );
1853 memset( prv, 0, 16 );
1854 memset( buf, 0, 16 );
1855
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001856 if( mode == MBEDTLS_AES_DECRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +00001857 {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001858 ret = mbedtls_aes_setkey_dec( &ctx, key, keybits );
1859 aes_tests = aes_test_cbc_dec[u];
Paul Bakker5121ce52009-01-03 21:22:43 +00001860 }
1861 else
1862 {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001863 ret = mbedtls_aes_setkey_enc( &ctx, key, keybits );
1864 aes_tests = aes_test_cbc_enc[u];
1865 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001866
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01001867 /*
1868 * AES-192 is an optional feature that may be unavailable when
1869 * there is an alternative underlying implementation i.e. when
1870 * MBEDTLS_AES_ALT is defined.
1871 */
Ron Eldor9924bdc2018-10-04 10:59:13 +03001872 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 )
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001873 {
1874 mbedtls_printf( "skipped\n" );
1875 continue;
1876 }
1877 else if( ret != 0 )
1878 {
1879 goto exit;
1880 }
1881
1882 for( j = 0; j < 10000; j++ )
1883 {
1884 if( mode == MBEDTLS_AES_ENCRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +00001885 {
1886 unsigned char tmp[16];
1887
Paul Bakker5121ce52009-01-03 21:22:43 +00001888 memcpy( tmp, prv, 16 );
1889 memcpy( prv, buf, 16 );
1890 memcpy( buf, tmp, 16 );
1891 }
1892
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001893 ret = mbedtls_aes_crypt_cbc( &ctx, mode, 16, iv, buf, buf );
1894 if( ret != 0 )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001895 goto exit;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001896
1897 }
1898
1899 if( memcmp( buf, aes_tests, 16 ) != 0 )
1900 {
1901 ret = 1;
1902 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001903 }
1904
1905 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001906 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001907 }
1908
1909 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001910 mbedtls_printf( "\n" );
1911#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001912
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001913#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001914 /*
1915 * CFB128 mode
1916 */
1917 for( i = 0; i < 6; i++ )
1918 {
1919 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001920 keybits = 128 + u * 64;
1921 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001922
1923 if( verbose != 0 )
Kenneth Soerensen518d4352020-04-01 17:22:45 +02001924 mbedtls_printf( " AES-CFB128-%3u (%s): ", keybits,
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001925 ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001926
1927 memcpy( iv, aes_test_cfb128_iv, 16 );
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001928 memcpy( key, aes_test_cfb128_key[u], keybits / 8 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001929
1930 offset = 0;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001931 ret = mbedtls_aes_setkey_enc( &ctx, key, keybits );
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01001932 /*
1933 * AES-192 is an optional feature that may be unavailable when
1934 * there is an alternative underlying implementation i.e. when
1935 * MBEDTLS_AES_ALT is defined.
1936 */
Ron Eldor9924bdc2018-10-04 10:59:13 +03001937 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 )
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001938 {
1939 mbedtls_printf( "skipped\n" );
1940 continue;
1941 }
1942 else if( ret != 0 )
1943 {
1944 goto exit;
1945 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001946
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001947 if( mode == MBEDTLS_AES_DECRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +00001948 {
1949 memcpy( buf, aes_test_cfb128_ct[u], 64 );
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001950 aes_tests = aes_test_cfb128_pt;
Paul Bakker5121ce52009-01-03 21:22:43 +00001951 }
1952 else
1953 {
1954 memcpy( buf, aes_test_cfb128_pt, 64 );
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001955 aes_tests = aes_test_cfb128_ct[u];
1956 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001957
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001958 ret = mbedtls_aes_crypt_cfb128( &ctx, mode, 64, &offset, iv, buf, buf );
1959 if( ret != 0 )
1960 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001961
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001962 if( memcmp( buf, aes_tests, 64 ) != 0 )
1963 {
1964 ret = 1;
1965 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001966 }
1967
1968 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001969 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001970 }
1971
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001972 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001973 mbedtls_printf( "\n" );
1974#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001975
Simon Butcherad4e4932018-04-29 00:43:47 +01001976#if defined(MBEDTLS_CIPHER_MODE_OFB)
1977 /*
1978 * OFB mode
1979 */
1980 for( i = 0; i < 6; i++ )
1981 {
1982 u = i >> 1;
1983 keybits = 128 + u * 64;
1984 mode = i & 1;
1985
1986 if( verbose != 0 )
Kenneth Soerensen518d4352020-04-01 17:22:45 +02001987 mbedtls_printf( " AES-OFB-%3u (%s): ", keybits,
Simon Butcherad4e4932018-04-29 00:43:47 +01001988 ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
1989
1990 memcpy( iv, aes_test_ofb_iv, 16 );
1991 memcpy( key, aes_test_ofb_key[u], keybits / 8 );
1992
1993 offset = 0;
1994 ret = mbedtls_aes_setkey_enc( &ctx, key, keybits );
1995 /*
1996 * AES-192 is an optional feature that may be unavailable when
1997 * there is an alternative underlying implementation i.e. when
1998 * MBEDTLS_AES_ALT is defined.
1999 */
Ron Eldor9924bdc2018-10-04 10:59:13 +03002000 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 )
Simon Butcherad4e4932018-04-29 00:43:47 +01002001 {
2002 mbedtls_printf( "skipped\n" );
2003 continue;
2004 }
2005 else if( ret != 0 )
2006 {
2007 goto exit;
2008 }
2009
2010 if( mode == MBEDTLS_AES_DECRYPT )
2011 {
2012 memcpy( buf, aes_test_ofb_ct[u], 64 );
2013 aes_tests = aes_test_ofb_pt;
2014 }
2015 else
2016 {
2017 memcpy( buf, aes_test_ofb_pt, 64 );
2018 aes_tests = aes_test_ofb_ct[u];
2019 }
2020
2021 ret = mbedtls_aes_crypt_ofb( &ctx, 64, &offset, iv, buf, buf );
2022 if( ret != 0 )
2023 goto exit;
2024
2025 if( memcmp( buf, aes_tests, 64 ) != 0 )
2026 {
2027 ret = 1;
2028 goto exit;
2029 }
2030
2031 if( verbose != 0 )
2032 mbedtls_printf( "passed\n" );
2033 }
2034
2035 if( verbose != 0 )
2036 mbedtls_printf( "\n" );
2037#endif /* MBEDTLS_CIPHER_MODE_OFB */
2038
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002039#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002040 /*
2041 * CTR mode
2042 */
2043 for( i = 0; i < 6; i++ )
2044 {
2045 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002046 mode = i & 1;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002047
2048 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002049 mbedtls_printf( " AES-CTR-128 (%s): ",
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002050 ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002051
2052 memcpy( nonce_counter, aes_test_ctr_nonce_counter[u], 16 );
2053 memcpy( key, aes_test_ctr_key[u], 16 );
2054
2055 offset = 0;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002056 if( ( ret = mbedtls_aes_setkey_enc( &ctx, key, 128 ) ) != 0 )
2057 goto exit;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002058
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002059 len = aes_test_ctr_len[u];
2060
2061 if( mode == MBEDTLS_AES_DECRYPT )
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002062 {
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002063 memcpy( buf, aes_test_ctr_ct[u], len );
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002064 aes_tests = aes_test_ctr_pt[u];
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002065 }
2066 else
2067 {
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002068 memcpy( buf, aes_test_ctr_pt[u], len );
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002069 aes_tests = aes_test_ctr_ct[u];
2070 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002071
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002072 ret = mbedtls_aes_crypt_ctr( &ctx, len, &offset, nonce_counter,
2073 stream_block, buf, buf );
2074 if( ret != 0 )
2075 goto exit;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002076
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002077 if( memcmp( buf, aes_tests, len ) != 0 )
2078 {
2079 ret = 1;
2080 goto exit;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002081 }
2082
2083 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002084 mbedtls_printf( "passed\n" );
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002085 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002086
2087 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002088 mbedtls_printf( "\n" );
2089#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00002090
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002091#if defined(MBEDTLS_CIPHER_MODE_XTS)
2092 {
2093 static const int num_tests =
2094 sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key);
2095 mbedtls_aes_xts_context ctx_xts;
2096
2097 /*
2098 * XTS mode
2099 */
2100 mbedtls_aes_xts_init( &ctx_xts );
2101
2102 for( i = 0; i < num_tests << 1; i++ )
2103 {
2104 const unsigned char *data_unit;
2105 u = i >> 1;
2106 mode = i & 1;
2107
2108 if( verbose != 0 )
2109 mbedtls_printf( " AES-XTS-128 (%s): ",
2110 ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
2111
2112 memset( key, 0, sizeof( key ) );
2113 memcpy( key, aes_test_xts_key[u], 32 );
2114 data_unit = aes_test_xts_data_unit[u];
2115
2116 len = sizeof( *aes_test_xts_ct32 );
2117
2118 if( mode == MBEDTLS_AES_DECRYPT )
2119 {
2120 ret = mbedtls_aes_xts_setkey_dec( &ctx_xts, key, 256 );
2121 if( ret != 0)
2122 goto exit;
2123 memcpy( buf, aes_test_xts_ct32[u], len );
2124 aes_tests = aes_test_xts_pt32[u];
2125 }
2126 else
2127 {
2128 ret = mbedtls_aes_xts_setkey_enc( &ctx_xts, key, 256 );
2129 if( ret != 0)
2130 goto exit;
2131 memcpy( buf, aes_test_xts_pt32[u], len );
2132 aes_tests = aes_test_xts_ct32[u];
2133 }
2134
2135
2136 ret = mbedtls_aes_crypt_xts( &ctx_xts, mode, len, data_unit,
2137 buf, buf );
2138 if( ret != 0 )
2139 goto exit;
2140
2141 if( memcmp( buf, aes_tests, len ) != 0 )
2142 {
2143 ret = 1;
2144 goto exit;
2145 }
2146
2147 if( verbose != 0 )
2148 mbedtls_printf( "passed\n" );
2149 }
2150
2151 if( verbose != 0 )
2152 mbedtls_printf( "\n" );
2153
2154 mbedtls_aes_xts_free( &ctx_xts );
2155 }
2156#endif /* MBEDTLS_CIPHER_MODE_XTS */
2157
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002158 ret = 0;
2159
2160exit:
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002161 if( ret != 0 && verbose != 0 )
2162 mbedtls_printf( "failed\n" );
2163
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002164 mbedtls_aes_free( &ctx );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002165
2166 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002167}
2168
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002169#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002170
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002171#endif /* MBEDTLS_AES_C */