blob: a48658fc787d58b0e1d5dabe8db8c8360fb30b7f [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * FIPS-197 compliant AES implementation
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Paul Bakker5121ce52009-01-03 21:22:43 +000018 */
19/*
20 * The AES block cipher was designed by Vincent Rijmen and Joan Daemen.
21 *
22 * http://csrc.nist.gov/encryption/aes/rijndael/Rijndael.pdf
23 * http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
24 */
25
Gilles Peskinedb09ef62020-06-03 01:43:33 +020026#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000027
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020028#if defined(MBEDTLS_AES_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000029
Rich Evans00ab4702015-02-06 13:43:58 +000030#include <string.h>
31
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000032#include "mbedtls/aes.h"
Ron Eldor9924bdc2018-10-04 10:59:13 +030033#include "mbedtls/platform.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050034#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000035#include "mbedtls/error.h"
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020036#if defined(MBEDTLS_PADLOCK_C)
Chris Jones16dbaeb2021-03-09 17:47:55 +000037#include "padlock.h"
Paul Bakker67820bd2012-06-04 12:47:23 +000038#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020039#if defined(MBEDTLS_AESNI_C)
Chris Jones187782f2021-03-09 17:28:35 +000040#include "aesni.h"
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +010041#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000042
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000043#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010044
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020045#if !defined(MBEDTLS_AES_ALT)
Paul Bakker90995b52013-06-24 19:20:35 +020046
Manuel Pégourié-Gonnard0e9cddb2018-12-10 16:37:51 +010047/* Parameter validation macros based on platform_util.h */
48#define AES_VALIDATE_RET( cond ) \
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +010049 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_AES_BAD_INPUT_DATA )
Manuel Pégourié-Gonnard0e9cddb2018-12-10 16:37:51 +010050#define AES_VALIDATE( cond ) \
51 MBEDTLS_INTERNAL_VALIDATE( cond )
52
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020053#if defined(MBEDTLS_PADLOCK_C) && \
54 ( defined(MBEDTLS_HAVE_X86) || defined(MBEDTLS_PADLOCK_ALIGN16) )
Paul Bakker048d04e2012-02-12 17:31:04 +000055static int aes_padlock_ace = -1;
56#endif
57
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020058#if defined(MBEDTLS_AES_ROM_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +000059/*
60 * Forward S-box
61 */
62static const unsigned char FSb[256] =
63{
64 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
65 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
66 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
67 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
68 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
69 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
70 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
71 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
72 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
73 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
74 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
75 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
76 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
77 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
78 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
79 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
80 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
81 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
82 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
83 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
84 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
85 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
86 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
87 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
88 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
89 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
90 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
91 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
92 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
93 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
94 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
95 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
96};
97
98/*
99 * Forward tables
100 */
101#define FT \
102\
103 V(A5,63,63,C6), V(84,7C,7C,F8), V(99,77,77,EE), V(8D,7B,7B,F6), \
104 V(0D,F2,F2,FF), V(BD,6B,6B,D6), V(B1,6F,6F,DE), V(54,C5,C5,91), \
105 V(50,30,30,60), V(03,01,01,02), V(A9,67,67,CE), V(7D,2B,2B,56), \
106 V(19,FE,FE,E7), V(62,D7,D7,B5), V(E6,AB,AB,4D), V(9A,76,76,EC), \
107 V(45,CA,CA,8F), V(9D,82,82,1F), V(40,C9,C9,89), V(87,7D,7D,FA), \
108 V(15,FA,FA,EF), V(EB,59,59,B2), V(C9,47,47,8E), V(0B,F0,F0,FB), \
109 V(EC,AD,AD,41), V(67,D4,D4,B3), V(FD,A2,A2,5F), V(EA,AF,AF,45), \
110 V(BF,9C,9C,23), V(F7,A4,A4,53), V(96,72,72,E4), V(5B,C0,C0,9B), \
111 V(C2,B7,B7,75), V(1C,FD,FD,E1), V(AE,93,93,3D), V(6A,26,26,4C), \
112 V(5A,36,36,6C), V(41,3F,3F,7E), V(02,F7,F7,F5), V(4F,CC,CC,83), \
113 V(5C,34,34,68), V(F4,A5,A5,51), V(34,E5,E5,D1), V(08,F1,F1,F9), \
114 V(93,71,71,E2), V(73,D8,D8,AB), V(53,31,31,62), V(3F,15,15,2A), \
115 V(0C,04,04,08), V(52,C7,C7,95), V(65,23,23,46), V(5E,C3,C3,9D), \
116 V(28,18,18,30), V(A1,96,96,37), V(0F,05,05,0A), V(B5,9A,9A,2F), \
117 V(09,07,07,0E), V(36,12,12,24), V(9B,80,80,1B), V(3D,E2,E2,DF), \
118 V(26,EB,EB,CD), V(69,27,27,4E), V(CD,B2,B2,7F), V(9F,75,75,EA), \
119 V(1B,09,09,12), V(9E,83,83,1D), V(74,2C,2C,58), V(2E,1A,1A,34), \
120 V(2D,1B,1B,36), V(B2,6E,6E,DC), V(EE,5A,5A,B4), V(FB,A0,A0,5B), \
121 V(F6,52,52,A4), V(4D,3B,3B,76), V(61,D6,D6,B7), V(CE,B3,B3,7D), \
122 V(7B,29,29,52), V(3E,E3,E3,DD), V(71,2F,2F,5E), V(97,84,84,13), \
123 V(F5,53,53,A6), V(68,D1,D1,B9), V(00,00,00,00), V(2C,ED,ED,C1), \
124 V(60,20,20,40), V(1F,FC,FC,E3), V(C8,B1,B1,79), V(ED,5B,5B,B6), \
125 V(BE,6A,6A,D4), V(46,CB,CB,8D), V(D9,BE,BE,67), V(4B,39,39,72), \
126 V(DE,4A,4A,94), V(D4,4C,4C,98), V(E8,58,58,B0), V(4A,CF,CF,85), \
127 V(6B,D0,D0,BB), V(2A,EF,EF,C5), V(E5,AA,AA,4F), V(16,FB,FB,ED), \
128 V(C5,43,43,86), V(D7,4D,4D,9A), V(55,33,33,66), V(94,85,85,11), \
129 V(CF,45,45,8A), V(10,F9,F9,E9), V(06,02,02,04), V(81,7F,7F,FE), \
130 V(F0,50,50,A0), V(44,3C,3C,78), V(BA,9F,9F,25), V(E3,A8,A8,4B), \
131 V(F3,51,51,A2), V(FE,A3,A3,5D), V(C0,40,40,80), V(8A,8F,8F,05), \
132 V(AD,92,92,3F), V(BC,9D,9D,21), V(48,38,38,70), V(04,F5,F5,F1), \
133 V(DF,BC,BC,63), V(C1,B6,B6,77), V(75,DA,DA,AF), V(63,21,21,42), \
134 V(30,10,10,20), V(1A,FF,FF,E5), V(0E,F3,F3,FD), V(6D,D2,D2,BF), \
135 V(4C,CD,CD,81), V(14,0C,0C,18), V(35,13,13,26), V(2F,EC,EC,C3), \
136 V(E1,5F,5F,BE), V(A2,97,97,35), V(CC,44,44,88), V(39,17,17,2E), \
137 V(57,C4,C4,93), V(F2,A7,A7,55), V(82,7E,7E,FC), V(47,3D,3D,7A), \
138 V(AC,64,64,C8), V(E7,5D,5D,BA), V(2B,19,19,32), V(95,73,73,E6), \
139 V(A0,60,60,C0), V(98,81,81,19), V(D1,4F,4F,9E), V(7F,DC,DC,A3), \
140 V(66,22,22,44), V(7E,2A,2A,54), V(AB,90,90,3B), V(83,88,88,0B), \
141 V(CA,46,46,8C), V(29,EE,EE,C7), V(D3,B8,B8,6B), V(3C,14,14,28), \
142 V(79,DE,DE,A7), V(E2,5E,5E,BC), V(1D,0B,0B,16), V(76,DB,DB,AD), \
143 V(3B,E0,E0,DB), V(56,32,32,64), V(4E,3A,3A,74), V(1E,0A,0A,14), \
144 V(DB,49,49,92), V(0A,06,06,0C), V(6C,24,24,48), V(E4,5C,5C,B8), \
145 V(5D,C2,C2,9F), V(6E,D3,D3,BD), V(EF,AC,AC,43), V(A6,62,62,C4), \
146 V(A8,91,91,39), V(A4,95,95,31), V(37,E4,E4,D3), V(8B,79,79,F2), \
147 V(32,E7,E7,D5), V(43,C8,C8,8B), V(59,37,37,6E), V(B7,6D,6D,DA), \
148 V(8C,8D,8D,01), V(64,D5,D5,B1), V(D2,4E,4E,9C), V(E0,A9,A9,49), \
149 V(B4,6C,6C,D8), V(FA,56,56,AC), V(07,F4,F4,F3), V(25,EA,EA,CF), \
150 V(AF,65,65,CA), V(8E,7A,7A,F4), V(E9,AE,AE,47), V(18,08,08,10), \
151 V(D5,BA,BA,6F), V(88,78,78,F0), V(6F,25,25,4A), V(72,2E,2E,5C), \
152 V(24,1C,1C,38), V(F1,A6,A6,57), V(C7,B4,B4,73), V(51,C6,C6,97), \
153 V(23,E8,E8,CB), V(7C,DD,DD,A1), V(9C,74,74,E8), V(21,1F,1F,3E), \
154 V(DD,4B,4B,96), V(DC,BD,BD,61), V(86,8B,8B,0D), V(85,8A,8A,0F), \
155 V(90,70,70,E0), V(42,3E,3E,7C), V(C4,B5,B5,71), V(AA,66,66,CC), \
156 V(D8,48,48,90), V(05,03,03,06), V(01,F6,F6,F7), V(12,0E,0E,1C), \
157 V(A3,61,61,C2), V(5F,35,35,6A), V(F9,57,57,AE), V(D0,B9,B9,69), \
158 V(91,86,86,17), V(58,C1,C1,99), V(27,1D,1D,3A), V(B9,9E,9E,27), \
159 V(38,E1,E1,D9), V(13,F8,F8,EB), V(B3,98,98,2B), V(33,11,11,22), \
160 V(BB,69,69,D2), V(70,D9,D9,A9), V(89,8E,8E,07), V(A7,94,94,33), \
161 V(B6,9B,9B,2D), V(22,1E,1E,3C), V(92,87,87,15), V(20,E9,E9,C9), \
162 V(49,CE,CE,87), V(FF,55,55,AA), V(78,28,28,50), V(7A,DF,DF,A5), \
163 V(8F,8C,8C,03), V(F8,A1,A1,59), V(80,89,89,09), V(17,0D,0D,1A), \
164 V(DA,BF,BF,65), V(31,E6,E6,D7), V(C6,42,42,84), V(B8,68,68,D0), \
165 V(C3,41,41,82), V(B0,99,99,29), V(77,2D,2D,5A), V(11,0F,0F,1E), \
166 V(CB,B0,B0,7B), V(FC,54,54,A8), V(D6,BB,BB,6D), V(3A,16,16,2C)
167
168#define V(a,b,c,d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000169static const uint32_t FT0[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000170#undef V
171
Hanno Beckerad049a92017-06-19 16:31:54 +0100172#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200173
Paul Bakker5121ce52009-01-03 21:22:43 +0000174#define V(a,b,c,d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000175static const uint32_t FT1[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000176#undef V
177
178#define V(a,b,c,d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000179static const uint32_t FT2[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000180#undef V
181
182#define V(a,b,c,d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000183static const uint32_t FT3[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000184#undef V
185
Hanno Becker177d3cf2017-06-07 15:52:48 +0100186#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200187
Paul Bakker5121ce52009-01-03 21:22:43 +0000188#undef FT
189
190/*
191 * Reverse S-box
192 */
193static const unsigned char RSb[256] =
194{
195 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
196 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
197 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
198 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
199 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
200 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
201 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
202 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
203 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
204 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
205 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
206 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
207 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
208 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
209 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
210 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
211 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
212 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
213 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
214 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
215 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
216 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
217 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
218 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
219 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
220 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
221 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
222 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
223 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
224 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
225 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
226 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
227};
228
229/*
230 * Reverse tables
231 */
232#define RT \
233\
234 V(50,A7,F4,51), V(53,65,41,7E), V(C3,A4,17,1A), V(96,5E,27,3A), \
235 V(CB,6B,AB,3B), V(F1,45,9D,1F), V(AB,58,FA,AC), V(93,03,E3,4B), \
236 V(55,FA,30,20), V(F6,6D,76,AD), V(91,76,CC,88), V(25,4C,02,F5), \
237 V(FC,D7,E5,4F), V(D7,CB,2A,C5), V(80,44,35,26), V(8F,A3,62,B5), \
238 V(49,5A,B1,DE), V(67,1B,BA,25), V(98,0E,EA,45), V(E1,C0,FE,5D), \
239 V(02,75,2F,C3), V(12,F0,4C,81), V(A3,97,46,8D), V(C6,F9,D3,6B), \
240 V(E7,5F,8F,03), V(95,9C,92,15), V(EB,7A,6D,BF), V(DA,59,52,95), \
241 V(2D,83,BE,D4), V(D3,21,74,58), V(29,69,E0,49), V(44,C8,C9,8E), \
242 V(6A,89,C2,75), V(78,79,8E,F4), V(6B,3E,58,99), V(DD,71,B9,27), \
243 V(B6,4F,E1,BE), V(17,AD,88,F0), V(66,AC,20,C9), V(B4,3A,CE,7D), \
244 V(18,4A,DF,63), V(82,31,1A,E5), V(60,33,51,97), V(45,7F,53,62), \
245 V(E0,77,64,B1), V(84,AE,6B,BB), V(1C,A0,81,FE), V(94,2B,08,F9), \
246 V(58,68,48,70), V(19,FD,45,8F), V(87,6C,DE,94), V(B7,F8,7B,52), \
247 V(23,D3,73,AB), V(E2,02,4B,72), V(57,8F,1F,E3), V(2A,AB,55,66), \
248 V(07,28,EB,B2), V(03,C2,B5,2F), V(9A,7B,C5,86), V(A5,08,37,D3), \
249 V(F2,87,28,30), V(B2,A5,BF,23), V(BA,6A,03,02), V(5C,82,16,ED), \
250 V(2B,1C,CF,8A), V(92,B4,79,A7), V(F0,F2,07,F3), V(A1,E2,69,4E), \
251 V(CD,F4,DA,65), V(D5,BE,05,06), V(1F,62,34,D1), V(8A,FE,A6,C4), \
252 V(9D,53,2E,34), V(A0,55,F3,A2), V(32,E1,8A,05), V(75,EB,F6,A4), \
253 V(39,EC,83,0B), V(AA,EF,60,40), V(06,9F,71,5E), V(51,10,6E,BD), \
254 V(F9,8A,21,3E), V(3D,06,DD,96), V(AE,05,3E,DD), V(46,BD,E6,4D), \
255 V(B5,8D,54,91), V(05,5D,C4,71), V(6F,D4,06,04), V(FF,15,50,60), \
256 V(24,FB,98,19), V(97,E9,BD,D6), V(CC,43,40,89), V(77,9E,D9,67), \
257 V(BD,42,E8,B0), V(88,8B,89,07), V(38,5B,19,E7), V(DB,EE,C8,79), \
258 V(47,0A,7C,A1), V(E9,0F,42,7C), V(C9,1E,84,F8), V(00,00,00,00), \
259 V(83,86,80,09), V(48,ED,2B,32), V(AC,70,11,1E), V(4E,72,5A,6C), \
260 V(FB,FF,0E,FD), V(56,38,85,0F), V(1E,D5,AE,3D), V(27,39,2D,36), \
261 V(64,D9,0F,0A), V(21,A6,5C,68), V(D1,54,5B,9B), V(3A,2E,36,24), \
262 V(B1,67,0A,0C), V(0F,E7,57,93), V(D2,96,EE,B4), V(9E,91,9B,1B), \
263 V(4F,C5,C0,80), V(A2,20,DC,61), V(69,4B,77,5A), V(16,1A,12,1C), \
264 V(0A,BA,93,E2), V(E5,2A,A0,C0), V(43,E0,22,3C), V(1D,17,1B,12), \
265 V(0B,0D,09,0E), V(AD,C7,8B,F2), V(B9,A8,B6,2D), V(C8,A9,1E,14), \
266 V(85,19,F1,57), V(4C,07,75,AF), V(BB,DD,99,EE), V(FD,60,7F,A3), \
267 V(9F,26,01,F7), V(BC,F5,72,5C), V(C5,3B,66,44), V(34,7E,FB,5B), \
268 V(76,29,43,8B), V(DC,C6,23,CB), V(68,FC,ED,B6), V(63,F1,E4,B8), \
269 V(CA,DC,31,D7), V(10,85,63,42), V(40,22,97,13), V(20,11,C6,84), \
270 V(7D,24,4A,85), V(F8,3D,BB,D2), V(11,32,F9,AE), V(6D,A1,29,C7), \
271 V(4B,2F,9E,1D), V(F3,30,B2,DC), V(EC,52,86,0D), V(D0,E3,C1,77), \
272 V(6C,16,B3,2B), V(99,B9,70,A9), V(FA,48,94,11), V(22,64,E9,47), \
273 V(C4,8C,FC,A8), V(1A,3F,F0,A0), V(D8,2C,7D,56), V(EF,90,33,22), \
274 V(C7,4E,49,87), V(C1,D1,38,D9), V(FE,A2,CA,8C), V(36,0B,D4,98), \
275 V(CF,81,F5,A6), V(28,DE,7A,A5), V(26,8E,B7,DA), V(A4,BF,AD,3F), \
276 V(E4,9D,3A,2C), V(0D,92,78,50), V(9B,CC,5F,6A), V(62,46,7E,54), \
277 V(C2,13,8D,F6), V(E8,B8,D8,90), V(5E,F7,39,2E), V(F5,AF,C3,82), \
278 V(BE,80,5D,9F), V(7C,93,D0,69), V(A9,2D,D5,6F), V(B3,12,25,CF), \
279 V(3B,99,AC,C8), V(A7,7D,18,10), V(6E,63,9C,E8), V(7B,BB,3B,DB), \
280 V(09,78,26,CD), V(F4,18,59,6E), V(01,B7,9A,EC), V(A8,9A,4F,83), \
281 V(65,6E,95,E6), V(7E,E6,FF,AA), V(08,CF,BC,21), V(E6,E8,15,EF), \
282 V(D9,9B,E7,BA), V(CE,36,6F,4A), V(D4,09,9F,EA), V(D6,7C,B0,29), \
283 V(AF,B2,A4,31), V(31,23,3F,2A), V(30,94,A5,C6), V(C0,66,A2,35), \
284 V(37,BC,4E,74), V(A6,CA,82,FC), V(B0,D0,90,E0), V(15,D8,A7,33), \
285 V(4A,98,04,F1), V(F7,DA,EC,41), V(0E,50,CD,7F), V(2F,F6,91,17), \
286 V(8D,D6,4D,76), V(4D,B0,EF,43), V(54,4D,AA,CC), V(DF,04,96,E4), \
287 V(E3,B5,D1,9E), V(1B,88,6A,4C), V(B8,1F,2C,C1), V(7F,51,65,46), \
288 V(04,EA,5E,9D), V(5D,35,8C,01), V(73,74,87,FA), V(2E,41,0B,FB), \
289 V(5A,1D,67,B3), V(52,D2,DB,92), V(33,56,10,E9), V(13,47,D6,6D), \
290 V(8C,61,D7,9A), V(7A,0C,A1,37), V(8E,14,F8,59), V(89,3C,13,EB), \
291 V(EE,27,A9,CE), V(35,C9,61,B7), V(ED,E5,1C,E1), V(3C,B1,47,7A), \
292 V(59,DF,D2,9C), V(3F,73,F2,55), V(79,CE,14,18), V(BF,37,C7,73), \
293 V(EA,CD,F7,53), V(5B,AA,FD,5F), V(14,6F,3D,DF), V(86,DB,44,78), \
294 V(81,F3,AF,CA), V(3E,C4,68,B9), V(2C,34,24,38), V(5F,40,A3,C2), \
295 V(72,C3,1D,16), V(0C,25,E2,BC), V(8B,49,3C,28), V(41,95,0D,FF), \
296 V(71,01,A8,39), V(DE,B3,0C,08), V(9C,E4,B4,D8), V(90,C1,56,64), \
297 V(61,84,CB,7B), V(70,B6,32,D5), V(74,5C,6C,48), V(42,57,B8,D0)
298
299#define V(a,b,c,d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000300static const uint32_t RT0[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000301#undef V
302
Hanno Beckerad049a92017-06-19 16:31:54 +0100303#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200304
Paul Bakker5121ce52009-01-03 21:22:43 +0000305#define V(a,b,c,d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000306static const uint32_t RT1[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000307#undef V
308
309#define V(a,b,c,d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000310static const uint32_t RT2[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000311#undef V
312
313#define V(a,b,c,d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000314static const uint32_t RT3[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000315#undef V
316
Hanno Becker177d3cf2017-06-07 15:52:48 +0100317#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200318
Paul Bakker5121ce52009-01-03 21:22:43 +0000319#undef RT
320
321/*
322 * Round constants
323 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000324static const uint32_t RCON[10] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000325{
326 0x00000001, 0x00000002, 0x00000004, 0x00000008,
327 0x00000010, 0x00000020, 0x00000040, 0x00000080,
328 0x0000001B, 0x00000036
329};
330
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200331#else /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000332
333/*
334 * Forward S-box & tables
335 */
336static unsigned char FSb[256];
Paul Bakker9af723c2014-05-01 13:03:14 +0200337static uint32_t FT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100338#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker9af723c2014-05-01 13:03:14 +0200339static uint32_t FT1[256];
340static uint32_t FT2[256];
341static uint32_t FT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100342#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000343
344/*
345 * Reverse S-box & tables
346 */
347static unsigned char RSb[256];
Paul Bakker5c2364c2012-10-01 14:41:15 +0000348static uint32_t RT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100349#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker5c2364c2012-10-01 14:41:15 +0000350static uint32_t RT1[256];
351static uint32_t RT2[256];
352static uint32_t RT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100353#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000354
355/*
356 * Round constants
357 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000358static uint32_t RCON[10];
Paul Bakker5121ce52009-01-03 21:22:43 +0000359
360/*
361 * Tables generation code
362 */
Hanno Becker1eeca412018-10-15 12:01:35 +0100363#define ROTL8(x) ( ( (x) << 8 ) & 0xFFFFFFFF ) | ( (x) >> 24 )
364#define XTIME(x) ( ( (x) << 1 ) ^ ( ( (x) & 0x80 ) ? 0x1B : 0x00 ) )
Hanno Becker818bac52018-10-26 09:13:26 +0100365#define MUL(x,y) ( ( (x) && (y) ) ? pow[(log[(x)]+log[(y)]) % 255] : 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000366
367static int aes_init_done = 0;
368
369static void aes_gen_tables( void )
370{
371 int i, x, y, z;
372 int pow[256];
373 int log[256];
374
375 /*
376 * compute pow and log tables over GF(2^8)
377 */
378 for( i = 0, x = 1; i < 256; i++ )
379 {
380 pow[i] = x;
381 log[x] = i;
Joe Subbianicd84d762021-07-08 14:59:52 +0100382 x = MBEDTLS_BYTE_0( x ^ XTIME( x ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000383 }
384
385 /*
386 * calculate the round constants
387 */
388 for( i = 0, x = 1; i < 10; i++ )
389 {
Paul Bakker5c2364c2012-10-01 14:41:15 +0000390 RCON[i] = (uint32_t) x;
Joe Subbianicd84d762021-07-08 14:59:52 +0100391 x = MBEDTLS_BYTE_0( XTIME( x ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000392 }
393
394 /*
395 * generate the forward and reverse S-boxes
396 */
397 FSb[0x00] = 0x63;
398 RSb[0x63] = 0x00;
399
400 for( i = 1; i < 256; i++ )
401 {
402 x = pow[255 - log[i]];
403
Joe Subbianicd84d762021-07-08 14:59:52 +0100404 y = x; y = MBEDTLS_BYTE_0( ( y << 1 ) | ( y >> 7 ) );
405 x ^= y; y = MBEDTLS_BYTE_0( ( y << 1 ) | ( y >> 7 ) );
406 x ^= y; y = MBEDTLS_BYTE_0( ( y << 1 ) | ( y >> 7 ) );
407 x ^= y; y = MBEDTLS_BYTE_0( ( y << 1 ) | ( y >> 7 ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000408 x ^= y ^ 0x63;
409
410 FSb[i] = (unsigned char) x;
411 RSb[x] = (unsigned char) i;
412 }
413
414 /*
415 * generate the forward and reverse tables
416 */
417 for( i = 0; i < 256; i++ )
418 {
419 x = FSb[i];
Joe Subbianicd84d762021-07-08 14:59:52 +0100420 y = MBEDTLS_BYTE_0( XTIME( x ) );
421 z = MBEDTLS_BYTE_0( y ^ x );
Paul Bakker5121ce52009-01-03 21:22:43 +0000422
Paul Bakker5c2364c2012-10-01 14:41:15 +0000423 FT0[i] = ( (uint32_t) y ) ^
424 ( (uint32_t) x << 8 ) ^
425 ( (uint32_t) x << 16 ) ^
426 ( (uint32_t) z << 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000427
Hanno Beckerad049a92017-06-19 16:31:54 +0100428#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +0000429 FT1[i] = ROTL8( FT0[i] );
430 FT2[i] = ROTL8( FT1[i] );
431 FT3[i] = ROTL8( FT2[i] );
Hanno Becker177d3cf2017-06-07 15:52:48 +0100432#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000433
434 x = RSb[i];
435
Paul Bakker5c2364c2012-10-01 14:41:15 +0000436 RT0[i] = ( (uint32_t) MUL( 0x0E, x ) ) ^
437 ( (uint32_t) MUL( 0x09, x ) << 8 ) ^
438 ( (uint32_t) MUL( 0x0D, x ) << 16 ) ^
439 ( (uint32_t) MUL( 0x0B, x ) << 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000440
Hanno Beckerad049a92017-06-19 16:31:54 +0100441#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +0000442 RT1[i] = ROTL8( RT0[i] );
443 RT2[i] = ROTL8( RT1[i] );
444 RT3[i] = ROTL8( RT2[i] );
Hanno Becker177d3cf2017-06-07 15:52:48 +0100445#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000446 }
447}
448
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200449#undef ROTL8
450
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200451#endif /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000452
Hanno Beckerad049a92017-06-19 16:31:54 +0100453#if defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200454
455#define ROTL8(x) ( (uint32_t)( ( x ) << 8 ) + (uint32_t)( ( x ) >> 24 ) )
456#define ROTL16(x) ( (uint32_t)( ( x ) << 16 ) + (uint32_t)( ( x ) >> 16 ) )
457#define ROTL24(x) ( (uint32_t)( ( x ) << 24 ) + (uint32_t)( ( x ) >> 8 ) )
458
459#define AES_RT0(idx) RT0[idx]
460#define AES_RT1(idx) ROTL8( RT0[idx] )
461#define AES_RT2(idx) ROTL16( RT0[idx] )
462#define AES_RT3(idx) ROTL24( RT0[idx] )
463
464#define AES_FT0(idx) FT0[idx]
465#define AES_FT1(idx) ROTL8( FT0[idx] )
466#define AES_FT2(idx) ROTL16( FT0[idx] )
467#define AES_FT3(idx) ROTL24( FT0[idx] )
468
Hanno Becker177d3cf2017-06-07 15:52:48 +0100469#else /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200470
471#define AES_RT0(idx) RT0[idx]
472#define AES_RT1(idx) RT1[idx]
473#define AES_RT2(idx) RT2[idx]
474#define AES_RT3(idx) RT3[idx]
475
476#define AES_FT0(idx) FT0[idx]
477#define AES_FT1(idx) FT1[idx]
478#define AES_FT2(idx) FT2[idx]
479#define AES_FT3(idx) FT3[idx]
480
Hanno Becker177d3cf2017-06-07 15:52:48 +0100481#endif /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200482
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200483void mbedtls_aes_init( mbedtls_aes_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200484{
Manuel Pégourié-Gonnard0e9cddb2018-12-10 16:37:51 +0100485 AES_VALIDATE( ctx != NULL );
Simon Butcher5201e412018-12-06 17:40:14 +0000486
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200487 memset( ctx, 0, sizeof( mbedtls_aes_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200488}
489
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200490void mbedtls_aes_free( mbedtls_aes_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200491{
492 if( ctx == NULL )
493 return;
494
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500495 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_aes_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200496}
497
Jaeden Amero9366feb2018-05-29 18:55:17 +0100498#if defined(MBEDTLS_CIPHER_MODE_XTS)
499void mbedtls_aes_xts_init( mbedtls_aes_xts_context *ctx )
500{
Manuel Pégourié-Gonnard0e9cddb2018-12-10 16:37:51 +0100501 AES_VALIDATE( ctx != NULL );
Simon Butcher5201e412018-12-06 17:40:14 +0000502
Jaeden Amero9366feb2018-05-29 18:55:17 +0100503 mbedtls_aes_init( &ctx->crypt );
504 mbedtls_aes_init( &ctx->tweak );
505}
506
507void mbedtls_aes_xts_free( mbedtls_aes_xts_context *ctx )
508{
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100509 if( ctx == NULL )
510 return;
Simon Butcher5201e412018-12-06 17:40:14 +0000511
Jaeden Amero9366feb2018-05-29 18:55:17 +0100512 mbedtls_aes_free( &ctx->crypt );
513 mbedtls_aes_free( &ctx->tweak );
514}
515#endif /* MBEDTLS_CIPHER_MODE_XTS */
516
Paul Bakker5121ce52009-01-03 21:22:43 +0000517/*
518 * AES key schedule (encryption)
519 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200520#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200521int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key,
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200522 unsigned int keybits )
Paul Bakker5121ce52009-01-03 21:22:43 +0000523{
Paul Bakker23986e52011-04-24 08:57:21 +0000524 unsigned int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000525 uint32_t *RK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000526
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100527 AES_VALIDATE_RET( ctx != NULL );
528 AES_VALIDATE_RET( key != NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000529
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200530 switch( keybits )
Paul Bakker5121ce52009-01-03 21:22:43 +0000531 {
532 case 128: ctx->nr = 10; break;
533 case 192: ctx->nr = 12; break;
534 case 256: ctx->nr = 14; break;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200535 default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000536 }
537
Simon Butcher5201e412018-12-06 17:40:14 +0000538#if !defined(MBEDTLS_AES_ROM_TABLES)
539 if( aes_init_done == 0 )
540 {
541 aes_gen_tables();
542 aes_init_done = 1;
Simon Butcher5201e412018-12-06 17:40:14 +0000543 }
544#endif
545
Werner Lewis7656a372022-06-13 12:28:20 +0100546 ctx->rk_offset = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200547#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_PADLOCK_ALIGN16)
Paul Bakker048d04e2012-02-12 17:31:04 +0000548 if( aes_padlock_ace == -1 )
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100549 aes_padlock_ace = mbedtls_padlock_has_support( MBEDTLS_PADLOCK_ACE );
Paul Bakker048d04e2012-02-12 17:31:04 +0000550
551 if( aes_padlock_ace )
Werner Lewisdd76ef32022-05-30 12:00:21 +0100552 ctx->rk_offset = MBEDTLS_PADLOCK_ALIGN16( ctx->buf ) - ctx->buf;
Paul Bakker5121ce52009-01-03 21:22:43 +0000553#endif
Werner Lewisdd76ef32022-05-30 12:00:21 +0100554 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000555
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200556#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100557 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) )
Werner Lewisdd76ef32022-05-30 12:00:21 +0100558 return( mbedtls_aesni_setkey_enc( (unsigned char *) RK, key, keybits ) );
Manuel Pégourié-Gonnard47a35362013-12-28 20:45:04 +0100559#endif
560
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200561 for( i = 0; i < ( keybits >> 5 ); i++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000562 {
Joe Subbiani6a506312021-07-07 16:56:29 +0100563 RK[i] = MBEDTLS_GET_UINT32_LE( key, i << 2 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000564 }
565
566 switch( ctx->nr )
567 {
568 case 10:
569
570 for( i = 0; i < 10; i++, RK += 4 )
571 {
572 RK[4] = RK[0] ^ RCON[i] ^
Joe Subbianicd84d762021-07-08 14:59:52 +0100573 ( (uint32_t) FSb[ MBEDTLS_BYTE_1( RK[3] ) ] ) ^
574 ( (uint32_t) FSb[ MBEDTLS_BYTE_2( RK[3] ) ] << 8 ) ^
575 ( (uint32_t) FSb[ MBEDTLS_BYTE_3( RK[3] ) ] << 16 ) ^
576 ( (uint32_t) FSb[ MBEDTLS_BYTE_0( RK[3] ) ] << 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000577
578 RK[5] = RK[1] ^ RK[4];
579 RK[6] = RK[2] ^ RK[5];
580 RK[7] = RK[3] ^ RK[6];
581 }
582 break;
583
584 case 12:
585
586 for( i = 0; i < 8; i++, RK += 6 )
587 {
588 RK[6] = RK[0] ^ RCON[i] ^
Joe Subbianicd84d762021-07-08 14:59:52 +0100589 ( (uint32_t) FSb[ MBEDTLS_BYTE_1( RK[5] ) ] ) ^
590 ( (uint32_t) FSb[ MBEDTLS_BYTE_2( RK[5] ) ] << 8 ) ^
591 ( (uint32_t) FSb[ MBEDTLS_BYTE_3( RK[5] ) ] << 16 ) ^
592 ( (uint32_t) FSb[ MBEDTLS_BYTE_0( RK[5] ) ] << 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000593
594 RK[7] = RK[1] ^ RK[6];
595 RK[8] = RK[2] ^ RK[7];
596 RK[9] = RK[3] ^ RK[8];
597 RK[10] = RK[4] ^ RK[9];
598 RK[11] = RK[5] ^ RK[10];
599 }
600 break;
601
602 case 14:
603
604 for( i = 0; i < 7; i++, RK += 8 )
605 {
606 RK[8] = RK[0] ^ RCON[i] ^
Joe Subbianicd84d762021-07-08 14:59:52 +0100607 ( (uint32_t) FSb[ MBEDTLS_BYTE_1( RK[7] ) ] ) ^
608 ( (uint32_t) FSb[ MBEDTLS_BYTE_2( RK[7] ) ] << 8 ) ^
609 ( (uint32_t) FSb[ MBEDTLS_BYTE_3( RK[7] ) ] << 16 ) ^
610 ( (uint32_t) FSb[ MBEDTLS_BYTE_0( RK[7] ) ] << 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000611
612 RK[9] = RK[1] ^ RK[8];
613 RK[10] = RK[2] ^ RK[9];
614 RK[11] = RK[3] ^ RK[10];
615
616 RK[12] = RK[4] ^
Joe Subbianicd84d762021-07-08 14:59:52 +0100617 ( (uint32_t) FSb[ MBEDTLS_BYTE_0( RK[11] ) ] ) ^
618 ( (uint32_t) FSb[ MBEDTLS_BYTE_1( RK[11] ) ] << 8 ) ^
619 ( (uint32_t) FSb[ MBEDTLS_BYTE_2( RK[11] ) ] << 16 ) ^
620 ( (uint32_t) FSb[ MBEDTLS_BYTE_3( RK[11] ) ] << 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000621
622 RK[13] = RK[5] ^ RK[12];
623 RK[14] = RK[6] ^ RK[13];
624 RK[15] = RK[7] ^ RK[14];
625 }
626 break;
Paul Bakker5121ce52009-01-03 21:22:43 +0000627 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000628
629 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000630}
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200631#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000632
633/*
634 * AES key schedule (decryption)
635 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200636#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200637int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key,
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200638 unsigned int keybits )
Paul Bakker5121ce52009-01-03 21:22:43 +0000639{
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200640 int i, j, ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200641 mbedtls_aes_context cty;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000642 uint32_t *RK;
643 uint32_t *SK;
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200644
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100645 AES_VALIDATE_RET( ctx != NULL );
646 AES_VALIDATE_RET( key != NULL );
Simon Butcher5201e412018-12-06 17:40:14 +0000647
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200648 mbedtls_aes_init( &cty );
Paul Bakker5121ce52009-01-03 21:22:43 +0000649
Werner Lewis7656a372022-06-13 12:28:20 +0100650 ctx->rk_offset = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200651#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_PADLOCK_ALIGN16)
Paul Bakker048d04e2012-02-12 17:31:04 +0000652 if( aes_padlock_ace == -1 )
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100653 aes_padlock_ace = mbedtls_padlock_has_support( MBEDTLS_PADLOCK_ACE );
Paul Bakker048d04e2012-02-12 17:31:04 +0000654
655 if( aes_padlock_ace )
Werner Lewisdd76ef32022-05-30 12:00:21 +0100656 ctx->rk_offset = MBEDTLS_PADLOCK_ALIGN16( ctx->buf ) - ctx->buf;
Paul Bakker5121ce52009-01-03 21:22:43 +0000657#endif
Werner Lewisdd76ef32022-05-30 12:00:21 +0100658 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000659
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200660 /* Also checks keybits */
661 if( ( ret = mbedtls_aes_setkey_enc( &cty, key, keybits ) ) != 0 )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200662 goto exit;
Paul Bakker2b222c82009-07-27 21:03:45 +0000663
Manuel Pégourié-Gonnardafd5a082014-05-28 21:52:59 +0200664 ctx->nr = cty.nr;
665
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200666#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100667 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) )
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100668 {
Werner Lewisdd76ef32022-05-30 12:00:21 +0100669 mbedtls_aesni_inverse_key( (unsigned char *) RK,
670 (const unsigned char *) ( cty.buf + cty.rk_offset ), ctx->nr );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200671 goto exit;
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100672 }
673#endif
674
Werner Lewisdd76ef32022-05-30 12:00:21 +0100675 SK = cty.buf + cty.rk_offset + cty.nr * 4;
Paul Bakker5121ce52009-01-03 21:22:43 +0000676
677 *RK++ = *SK++;
678 *RK++ = *SK++;
679 *RK++ = *SK++;
680 *RK++ = *SK++;
681
682 for( i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8 )
683 {
684 for( j = 0; j < 4; j++, SK++ )
685 {
Joe Subbianicd84d762021-07-08 14:59:52 +0100686 *RK++ = AES_RT0( FSb[ MBEDTLS_BYTE_0( *SK ) ] ) ^
687 AES_RT1( FSb[ MBEDTLS_BYTE_1( *SK ) ] ) ^
688 AES_RT2( FSb[ MBEDTLS_BYTE_2( *SK ) ] ) ^
689 AES_RT3( FSb[ MBEDTLS_BYTE_3( *SK ) ] );
Paul Bakker5121ce52009-01-03 21:22:43 +0000690 }
691 }
692
693 *RK++ = *SK++;
694 *RK++ = *SK++;
695 *RK++ = *SK++;
696 *RK++ = *SK++;
697
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200698exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200699 mbedtls_aes_free( &cty );
Paul Bakker2b222c82009-07-27 21:03:45 +0000700
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200701 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000702}
gabor-mezei-arm95db3012020-10-26 11:35:23 +0100703#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */
Jaeden Amero9366feb2018-05-29 18:55:17 +0100704
705#if defined(MBEDTLS_CIPHER_MODE_XTS)
706static int mbedtls_aes_xts_decode_keys( const unsigned char *key,
707 unsigned int keybits,
708 const unsigned char **key1,
709 unsigned int *key1bits,
710 const unsigned char **key2,
711 unsigned int *key2bits )
712{
713 const unsigned int half_keybits = keybits / 2;
714 const unsigned int half_keybytes = half_keybits / 8;
715
716 switch( keybits )
717 {
718 case 256: break;
719 case 512: break;
720 default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH );
721 }
722
723 *key1bits = half_keybits;
724 *key2bits = half_keybits;
725 *key1 = &key[0];
726 *key2 = &key[half_keybytes];
727
728 return 0;
729}
730
731int mbedtls_aes_xts_setkey_enc( mbedtls_aes_xts_context *ctx,
732 const unsigned char *key,
733 unsigned int keybits)
734{
Janos Follath24eed8d2019-11-22 13:21:35 +0000735 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100736 const unsigned char *key1, *key2;
737 unsigned int key1bits, key2bits;
738
Manuel Pégourié-Gonnard68e3dff2018-12-12 12:48:04 +0100739 AES_VALIDATE_RET( ctx != NULL );
740 AES_VALIDATE_RET( key != NULL );
741
Jaeden Amero9366feb2018-05-29 18:55:17 +0100742 ret = mbedtls_aes_xts_decode_keys( key, keybits, &key1, &key1bits,
743 &key2, &key2bits );
744 if( ret != 0 )
745 return( ret );
746
747 /* Set the tweak key. Always set tweak key for the encryption mode. */
748 ret = mbedtls_aes_setkey_enc( &ctx->tweak, key2, key2bits );
749 if( ret != 0 )
750 return( ret );
751
752 /* Set crypt key for encryption. */
753 return mbedtls_aes_setkey_enc( &ctx->crypt, key1, key1bits );
754}
755
756int mbedtls_aes_xts_setkey_dec( mbedtls_aes_xts_context *ctx,
757 const unsigned char *key,
758 unsigned int keybits)
759{
Janos Follath24eed8d2019-11-22 13:21:35 +0000760 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100761 const unsigned char *key1, *key2;
762 unsigned int key1bits, key2bits;
763
Manuel Pégourié-Gonnard68e3dff2018-12-12 12:48:04 +0100764 AES_VALIDATE_RET( ctx != NULL );
765 AES_VALIDATE_RET( key != NULL );
766
Jaeden Amero9366feb2018-05-29 18:55:17 +0100767 ret = mbedtls_aes_xts_decode_keys( key, keybits, &key1, &key1bits,
768 &key2, &key2bits );
769 if( ret != 0 )
770 return( ret );
771
772 /* Set the tweak key. Always set tweak key for encryption. */
773 ret = mbedtls_aes_setkey_enc( &ctx->tweak, key2, key2bits );
774 if( ret != 0 )
775 return( ret );
776
777 /* Set crypt key for decryption. */
778 return mbedtls_aes_setkey_dec( &ctx->crypt, key1, key1bits );
779}
780#endif /* MBEDTLS_CIPHER_MODE_XTS */
781
Joe Subbianicd84d762021-07-08 14:59:52 +0100782#define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \
783 do \
784 { \
785 (X0) = *RK++ ^ AES_FT0( MBEDTLS_BYTE_0( Y0 ) ) ^ \
786 AES_FT1( MBEDTLS_BYTE_1( Y1 ) ) ^ \
787 AES_FT2( MBEDTLS_BYTE_2( Y2 ) ) ^ \
788 AES_FT3( MBEDTLS_BYTE_3( Y3 ) ); \
789 \
790 (X1) = *RK++ ^ AES_FT0( MBEDTLS_BYTE_0( Y1 ) ) ^ \
791 AES_FT1( MBEDTLS_BYTE_1( Y2 ) ) ^ \
792 AES_FT2( MBEDTLS_BYTE_2( Y3 ) ) ^ \
793 AES_FT3( MBEDTLS_BYTE_3( Y0 ) ); \
794 \
795 (X2) = *RK++ ^ AES_FT0( MBEDTLS_BYTE_0( Y2 ) ) ^ \
796 AES_FT1( MBEDTLS_BYTE_1( Y3 ) ) ^ \
797 AES_FT2( MBEDTLS_BYTE_2( Y0 ) ) ^ \
798 AES_FT3( MBEDTLS_BYTE_3( Y1 ) ); \
799 \
800 (X3) = *RK++ ^ AES_FT0( MBEDTLS_BYTE_0( Y3 ) ) ^ \
801 AES_FT1( MBEDTLS_BYTE_1( Y0 ) ) ^ \
802 AES_FT2( MBEDTLS_BYTE_2( Y1 ) ) ^ \
803 AES_FT3( MBEDTLS_BYTE_3( Y2 ) ); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100804 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000805
Hanno Becker1eeca412018-10-15 12:01:35 +0100806#define AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \
807 do \
808 { \
Joe Subbianicd84d762021-07-08 14:59:52 +0100809 (X0) = *RK++ ^ AES_RT0( MBEDTLS_BYTE_0( Y0 ) ) ^ \
810 AES_RT1( MBEDTLS_BYTE_1( Y3 ) ) ^ \
811 AES_RT2( MBEDTLS_BYTE_2( Y2 ) ) ^ \
812 AES_RT3( MBEDTLS_BYTE_3( Y1 ) ); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100813 \
Joe Subbianicd84d762021-07-08 14:59:52 +0100814 (X1) = *RK++ ^ AES_RT0( MBEDTLS_BYTE_0( Y1 ) ) ^ \
815 AES_RT1( MBEDTLS_BYTE_1( Y0 ) ) ^ \
816 AES_RT2( MBEDTLS_BYTE_2( Y3 ) ) ^ \
817 AES_RT3( MBEDTLS_BYTE_3( Y2 ) ); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100818 \
Joe Subbianicd84d762021-07-08 14:59:52 +0100819 (X2) = *RK++ ^ AES_RT0( MBEDTLS_BYTE_0( Y2 ) ) ^ \
820 AES_RT1( MBEDTLS_BYTE_1( Y1 ) ) ^ \
821 AES_RT2( MBEDTLS_BYTE_2( Y0 ) ) ^ \
822 AES_RT3( MBEDTLS_BYTE_3( Y3 ) ); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100823 \
Joe Subbianicd84d762021-07-08 14:59:52 +0100824 (X3) = *RK++ ^ AES_RT0( MBEDTLS_BYTE_0( Y3 ) ) ^ \
825 AES_RT1( MBEDTLS_BYTE_1( Y2 ) ) ^ \
826 AES_RT2( MBEDTLS_BYTE_2( Y1 ) ) ^ \
827 AES_RT3( MBEDTLS_BYTE_3( Y0 ) ); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100828 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000829
830/*
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200831 * AES-ECB block encryption
832 */
833#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Andres AGf5bf7182017-03-03 14:09:56 +0000834int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx,
835 const unsigned char input[16],
836 unsigned char output[16] )
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200837{
838 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100839 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine5197c662020-08-26 17:03:24 +0200840 struct
841 {
842 uint32_t X[4];
843 uint32_t Y[4];
844 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200845
Joe Subbiani6a506312021-07-07 16:56:29 +0100846 t.X[0] = MBEDTLS_GET_UINT32_LE( input, 0 ); t.X[0] ^= *RK++;
847 t.X[1] = MBEDTLS_GET_UINT32_LE( input, 4 ); t.X[1] ^= *RK++;
848 t.X[2] = MBEDTLS_GET_UINT32_LE( input, 8 ); t.X[2] ^= *RK++;
849 t.X[3] = MBEDTLS_GET_UINT32_LE( input, 12 ); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200850
851 for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- )
852 {
Gilles Peskine5197c662020-08-26 17:03:24 +0200853 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] );
854 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 +0200855 }
856
Gilles Peskine5197c662020-08-26 17:03:24 +0200857 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 +0200858
Gilles Peskine5197c662020-08-26 17:03:24 +0200859 t.X[0] = *RK++ ^ \
Joe Subbianicd84d762021-07-08 14:59:52 +0100860 ( (uint32_t) FSb[ MBEDTLS_BYTE_0( t.Y[0] ) ] ) ^
861 ( (uint32_t) FSb[ MBEDTLS_BYTE_1( t.Y[1] ) ] << 8 ) ^
862 ( (uint32_t) FSb[ MBEDTLS_BYTE_2( t.Y[2] ) ] << 16 ) ^
863 ( (uint32_t) FSb[ MBEDTLS_BYTE_3( t.Y[3] ) ] << 24 );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200864
Gilles Peskine5197c662020-08-26 17:03:24 +0200865 t.X[1] = *RK++ ^ \
Joe Subbianicd84d762021-07-08 14:59:52 +0100866 ( (uint32_t) FSb[ MBEDTLS_BYTE_0( t.Y[1] ) ] ) ^
867 ( (uint32_t) FSb[ MBEDTLS_BYTE_1( t.Y[2] ) ] << 8 ) ^
868 ( (uint32_t) FSb[ MBEDTLS_BYTE_2( t.Y[3] ) ] << 16 ) ^
869 ( (uint32_t) FSb[ MBEDTLS_BYTE_3( t.Y[0] ) ] << 24 );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200870
Gilles Peskine5197c662020-08-26 17:03:24 +0200871 t.X[2] = *RK++ ^ \
Joe Subbianicd84d762021-07-08 14:59:52 +0100872 ( (uint32_t) FSb[ MBEDTLS_BYTE_0( t.Y[2] ) ] ) ^
873 ( (uint32_t) FSb[ MBEDTLS_BYTE_1( t.Y[3] ) ] << 8 ) ^
874 ( (uint32_t) FSb[ MBEDTLS_BYTE_2( t.Y[0] ) ] << 16 ) ^
875 ( (uint32_t) FSb[ MBEDTLS_BYTE_3( t.Y[1] ) ] << 24 );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200876
Gilles Peskine5197c662020-08-26 17:03:24 +0200877 t.X[3] = *RK++ ^ \
Joe Subbianicd84d762021-07-08 14:59:52 +0100878 ( (uint32_t) FSb[ MBEDTLS_BYTE_0( t.Y[3] ) ] ) ^
879 ( (uint32_t) FSb[ MBEDTLS_BYTE_1( t.Y[0] ) ] << 8 ) ^
880 ( (uint32_t) FSb[ MBEDTLS_BYTE_2( t.Y[1] ) ] << 16 ) ^
881 ( (uint32_t) FSb[ MBEDTLS_BYTE_3( t.Y[2] ) ] << 24 );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200882
Joe Subbiani5ecac212021-06-24 13:00:03 +0100883 MBEDTLS_PUT_UINT32_LE( t.X[0], output, 0 );
884 MBEDTLS_PUT_UINT32_LE( t.X[1], output, 4 );
885 MBEDTLS_PUT_UINT32_LE( t.X[2], output, 8 );
886 MBEDTLS_PUT_UINT32_LE( t.X[3], output, 12 );
Andres AGf5bf7182017-03-03 14:09:56 +0000887
Gilles Peskine5197c662020-08-26 17:03:24 +0200888 mbedtls_platform_zeroize( &t, sizeof( t ) );
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500889
Andres AGf5bf7182017-03-03 14:09:56 +0000890 return( 0 );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200891}
892#endif /* !MBEDTLS_AES_ENCRYPT_ALT */
893
894/*
895 * AES-ECB block decryption
896 */
897#if !defined(MBEDTLS_AES_DECRYPT_ALT)
Andres AGf5bf7182017-03-03 14:09:56 +0000898int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx,
899 const unsigned char input[16],
900 unsigned char output[16] )
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200901{
902 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100903 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine5197c662020-08-26 17:03:24 +0200904 struct
905 {
906 uint32_t X[4];
907 uint32_t Y[4];
908 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200909
Joe Subbiani6a506312021-07-07 16:56:29 +0100910 t.X[0] = MBEDTLS_GET_UINT32_LE( input, 0 ); t.X[0] ^= *RK++;
911 t.X[1] = MBEDTLS_GET_UINT32_LE( input, 4 ); t.X[1] ^= *RK++;
912 t.X[2] = MBEDTLS_GET_UINT32_LE( input, 8 ); t.X[2] ^= *RK++;
913 t.X[3] = MBEDTLS_GET_UINT32_LE( input, 12 ); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200914
915 for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- )
916 {
Gilles Peskine5197c662020-08-26 17:03:24 +0200917 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] );
918 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 +0200919 }
920
Gilles Peskine5197c662020-08-26 17:03:24 +0200921 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 +0200922
Gilles Peskine5197c662020-08-26 17:03:24 +0200923 t.X[0] = *RK++ ^ \
Joe Subbianicd84d762021-07-08 14:59:52 +0100924 ( (uint32_t) RSb[ MBEDTLS_BYTE_0( t.Y[0] ) ] ) ^
925 ( (uint32_t) RSb[ MBEDTLS_BYTE_1( t.Y[3] ) ] << 8 ) ^
926 ( (uint32_t) RSb[ MBEDTLS_BYTE_2( t.Y[2] ) ] << 16 ) ^
927 ( (uint32_t) RSb[ MBEDTLS_BYTE_3( t.Y[1] ) ] << 24 );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200928
Gilles Peskine5197c662020-08-26 17:03:24 +0200929 t.X[1] = *RK++ ^ \
Joe Subbianicd84d762021-07-08 14:59:52 +0100930 ( (uint32_t) RSb[ MBEDTLS_BYTE_0( t.Y[1] ) ] ) ^
931 ( (uint32_t) RSb[ MBEDTLS_BYTE_1( t.Y[0] ) ] << 8 ) ^
932 ( (uint32_t) RSb[ MBEDTLS_BYTE_2( t.Y[3] ) ] << 16 ) ^
933 ( (uint32_t) RSb[ MBEDTLS_BYTE_3( t.Y[2] ) ] << 24 );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200934
Gilles Peskine5197c662020-08-26 17:03:24 +0200935 t.X[2] = *RK++ ^ \
Joe Subbianicd84d762021-07-08 14:59:52 +0100936 ( (uint32_t) RSb[ MBEDTLS_BYTE_0( t.Y[2] ) ] ) ^
937 ( (uint32_t) RSb[ MBEDTLS_BYTE_1( t.Y[1] ) ] << 8 ) ^
938 ( (uint32_t) RSb[ MBEDTLS_BYTE_2( t.Y[0] ) ] << 16 ) ^
939 ( (uint32_t) RSb[ MBEDTLS_BYTE_3( t.Y[3] ) ] << 24 );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200940
Gilles Peskine5197c662020-08-26 17:03:24 +0200941 t.X[3] = *RK++ ^ \
Joe Subbianicd84d762021-07-08 14:59:52 +0100942 ( (uint32_t) RSb[ MBEDTLS_BYTE_0( t.Y[3] ) ] ) ^
943 ( (uint32_t) RSb[ MBEDTLS_BYTE_1( t.Y[2] ) ] << 8 ) ^
944 ( (uint32_t) RSb[ MBEDTLS_BYTE_2( t.Y[1] ) ] << 16 ) ^
945 ( (uint32_t) RSb[ MBEDTLS_BYTE_3( t.Y[0] ) ] << 24 );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200946
Joe Subbiani5ecac212021-06-24 13:00:03 +0100947 MBEDTLS_PUT_UINT32_LE( t.X[0], output, 0 );
948 MBEDTLS_PUT_UINT32_LE( t.X[1], output, 4 );
949 MBEDTLS_PUT_UINT32_LE( t.X[2], output, 8 );
950 MBEDTLS_PUT_UINT32_LE( t.X[3], output, 12 );
Andres AGf5bf7182017-03-03 14:09:56 +0000951
Gilles Peskine5197c662020-08-26 17:03:24 +0200952 mbedtls_platform_zeroize( &t, sizeof( t ) );
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500953
Andres AGf5bf7182017-03-03 14:09:56 +0000954 return( 0 );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200955}
956#endif /* !MBEDTLS_AES_DECRYPT_ALT */
957
958/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000959 * AES-ECB block encryption/decryption
960 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200961int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx,
Manuel Pégourié-Gonnardeb6d3962018-12-18 09:59:35 +0100962 int mode,
963 const unsigned char input[16],
964 unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000965{
Manuel Pégourié-Gonnard1aca2602018-12-12 12:56:55 +0100966 AES_VALIDATE_RET( ctx != NULL );
967 AES_VALIDATE_RET( input != NULL );
968 AES_VALIDATE_RET( output != NULL );
969 AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
970 mode == MBEDTLS_AES_DECRYPT );
971
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200972#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100973 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200974 return( mbedtls_aesni_crypt_ecb( ctx, mode, input, output ) );
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +0100975#endif
976
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200977#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Xiang Xiao12e18362021-05-07 00:55:52 -0700978 if( aes_padlock_ace > 0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000979 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200980 if( mbedtls_padlock_xcryptecb( ctx, mode, input, output ) == 0 )
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000981 return( 0 );
982
983 // If padlock data misaligned, we just fall back to
984 // unaccelerated mode
985 //
Paul Bakker5121ce52009-01-03 21:22:43 +0000986 }
987#endif
988
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200989 if( mode == MBEDTLS_AES_ENCRYPT )
Andres AGf5bf7182017-03-03 14:09:56 +0000990 return( mbedtls_internal_aes_encrypt( ctx, input, output ) );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200991 else
Andres AGf5bf7182017-03-03 14:09:56 +0000992 return( mbedtls_internal_aes_decrypt( ctx, input, output ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000993}
994
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200995#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000996/*
997 * AES-CBC buffer encryption/decryption
998 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200999int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx,
Paul Bakker5121ce52009-01-03 21:22:43 +00001000 int mode,
Paul Bakker23986e52011-04-24 08:57:21 +00001001 size_t length,
Paul Bakker5121ce52009-01-03 21:22:43 +00001002 unsigned char iv[16],
Paul Bakkerff60ee62010-03-16 21:09:09 +00001003 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +00001004 unsigned char *output )
1005{
1006 int i;
Gilles Peskine7820a572021-07-07 21:08:28 +02001007 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +00001008 unsigned char temp[16];
1009
Manuel Pégourié-Gonnard3178d1a2018-12-12 13:05:00 +01001010 AES_VALIDATE_RET( ctx != NULL );
1011 AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
1012 mode == MBEDTLS_AES_DECRYPT );
1013 AES_VALIDATE_RET( iv != NULL );
1014 AES_VALIDATE_RET( input != NULL );
1015 AES_VALIDATE_RET( output != NULL );
1016
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001017 if( length % 16 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001018 return( MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH );
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001019
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001020#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Xiang Xiao12e18362021-05-07 00:55:52 -07001021 if( aes_padlock_ace > 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001022 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001023 if( mbedtls_padlock_xcryptcbc( ctx, mode, length, iv, input, output ) == 0 )
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001024 return( 0 );
Paul Bakker9af723c2014-05-01 13:03:14 +02001025
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001026 // If padlock data misaligned, we just fall back to
1027 // unaccelerated mode
1028 //
Paul Bakker5121ce52009-01-03 21:22:43 +00001029 }
1030#endif
1031
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001032 if( mode == MBEDTLS_AES_DECRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +00001033 {
1034 while( length > 0 )
1035 {
1036 memcpy( temp, input, 16 );
Gilles Peskine7820a572021-07-07 21:08:28 +02001037 ret = mbedtls_aes_crypt_ecb( ctx, mode, input, output );
1038 if( ret != 0 )
1039 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001040
1041 for( i = 0; i < 16; i++ )
1042 output[i] = (unsigned char)( output[i] ^ iv[i] );
1043
1044 memcpy( iv, temp, 16 );
1045
1046 input += 16;
1047 output += 16;
1048 length -= 16;
1049 }
1050 }
1051 else
1052 {
1053 while( length > 0 )
1054 {
1055 for( i = 0; i < 16; i++ )
1056 output[i] = (unsigned char)( input[i] ^ iv[i] );
1057
Gilles Peskine7820a572021-07-07 21:08:28 +02001058 ret = mbedtls_aes_crypt_ecb( ctx, mode, output, output );
1059 if( ret != 0 )
1060 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001061 memcpy( iv, output, 16 );
1062
1063 input += 16;
1064 output += 16;
1065 length -= 16;
1066 }
1067 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001068 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001069
Gilles Peskine7820a572021-07-07 21:08:28 +02001070exit:
1071 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001072}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001073#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001074
Aorimn5f778012016-06-09 23:22:58 +02001075#if defined(MBEDTLS_CIPHER_MODE_XTS)
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001076
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001077typedef unsigned char mbedtls_be128[16];
1078
1079/*
1080 * GF(2^128) multiplication function
1081 *
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001082 * This function multiplies a field element by x in the polynomial field
1083 * representation. It uses 64-bit word operations to gain speed but compensates
Shaun Case8b0ecbc2021-12-20 21:14:10 -08001084 * for machine endianness and hence works correctly on both big and little
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001085 * endian machines.
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001086 */
1087static void mbedtls_gf128mul_x_ble( unsigned char r[16],
Jaeden Amero8cfc75f2018-05-31 16:53:08 +01001088 const unsigned char x[16] )
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001089{
1090 uint64_t a, b, ra, rb;
1091
Joe Subbiani99edd6c2021-07-16 12:29:49 +01001092 a = MBEDTLS_GET_UINT64_LE( x, 0 );
1093 b = MBEDTLS_GET_UINT64_LE( x, 8 );
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001094
Jaeden Amero8cfc75f2018-05-31 16:53:08 +01001095 ra = ( a << 1 ) ^ 0x0087 >> ( 8 - ( ( b >> 63 ) << 3 ) );
1096 rb = ( a >> 63 ) | ( b << 1 );
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001097
Joe Subbiani99edd6c2021-07-16 12:29:49 +01001098 MBEDTLS_PUT_UINT64_LE( ra, r, 0 );
1099 MBEDTLS_PUT_UINT64_LE( rb, r, 8 );
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001100}
1101
Aorimn5f778012016-06-09 23:22:58 +02001102/*
1103 * AES-XTS buffer encryption/decryption
1104 */
Jaeden Amero9366feb2018-05-29 18:55:17 +01001105int mbedtls_aes_crypt_xts( mbedtls_aes_xts_context *ctx,
1106 int mode,
Jaeden Amero5162b932018-05-29 12:55:24 +01001107 size_t length,
Jaeden Amerocd9fc5e2018-05-30 15:23:24 +01001108 const unsigned char data_unit[16],
Jaeden Amero9366feb2018-05-29 18:55:17 +01001109 const unsigned char *input,
1110 unsigned char *output )
Aorimn5f778012016-06-09 23:22:58 +02001111{
Janos Follath24eed8d2019-11-22 13:21:35 +00001112 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amerod82cd862018-04-28 15:02:45 +01001113 size_t blocks = length / 16;
1114 size_t leftover = length % 16;
1115 unsigned char tweak[16];
1116 unsigned char prev_tweak[16];
1117 unsigned char tmp[16];
Aorimn5f778012016-06-09 23:22:58 +02001118
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01001119 AES_VALIDATE_RET( ctx != NULL );
1120 AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
1121 mode == MBEDTLS_AES_DECRYPT );
Manuel Pégourié-Gonnard998a3582018-12-18 10:03:13 +01001122 AES_VALIDATE_RET( data_unit != NULL );
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01001123 AES_VALIDATE_RET( input != NULL );
1124 AES_VALIDATE_RET( output != NULL );
1125
Jaeden Amero8381fcb2018-10-11 12:06:15 +01001126 /* Data units must be at least 16 bytes long. */
Aorimn5f778012016-06-09 23:22:58 +02001127 if( length < 16 )
Jaeden Amerod82cd862018-04-28 15:02:45 +01001128 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Aorimn5f778012016-06-09 23:22:58 +02001129
Jaeden Ameroa74faba2018-10-11 12:07:43 +01001130 /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */
Jaeden Amero0a8b0202018-05-30 15:36:06 +01001131 if( length > ( 1 << 20 ) * 16 )
1132 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Aorimn5f778012016-06-09 23:22:58 +02001133
Jaeden Amerod82cd862018-04-28 15:02:45 +01001134 /* Compute the tweak. */
Jaeden Amerocd9fc5e2018-05-30 15:23:24 +01001135 ret = mbedtls_aes_crypt_ecb( &ctx->tweak, MBEDTLS_AES_ENCRYPT,
1136 data_unit, tweak );
Jaeden Amerod82cd862018-04-28 15:02:45 +01001137 if( ret != 0 )
1138 return( ret );
Aorimn5f778012016-06-09 23:22:58 +02001139
Jaeden Amerod82cd862018-04-28 15:02:45 +01001140 while( blocks-- )
Aorimn5f778012016-06-09 23:22:58 +02001141 {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001142 size_t i;
1143
1144 if( leftover && ( mode == MBEDTLS_AES_DECRYPT ) && blocks == 0 )
1145 {
1146 /* We are on the last block in a decrypt operation that has
1147 * leftover bytes, so we need to use the next tweak for this block,
1148 * and this tweak for the lefover bytes. Save the current tweak for
1149 * the leftovers and then update the current tweak for use on this,
1150 * the last full block. */
1151 memcpy( prev_tweak, tweak, sizeof( tweak ) );
1152 mbedtls_gf128mul_x_ble( tweak, tweak );
1153 }
1154
1155 for( i = 0; i < 16; i++ )
1156 tmp[i] = input[i] ^ tweak[i];
1157
1158 ret = mbedtls_aes_crypt_ecb( &ctx->crypt, mode, tmp, tmp );
1159 if( ret != 0 )
1160 return( ret );
1161
1162 for( i = 0; i < 16; i++ )
1163 output[i] = tmp[i] ^ tweak[i];
1164
1165 /* Update the tweak for the next block. */
1166 mbedtls_gf128mul_x_ble( tweak, tweak );
1167
1168 output += 16;
1169 input += 16;
Aorimn5f778012016-06-09 23:22:58 +02001170 }
1171
Jaeden Amerod82cd862018-04-28 15:02:45 +01001172 if( leftover )
Aorimn5f778012016-06-09 23:22:58 +02001173 {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001174 /* If we are on the leftover bytes in a decrypt operation, we need to
1175 * use the previous tweak for these bytes (as saved in prev_tweak). */
1176 unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
Aorimn5f778012016-06-09 23:22:58 +02001177
Jaeden Amerod82cd862018-04-28 15:02:45 +01001178 /* We are now on the final part of the data unit, which doesn't divide
1179 * evenly by 16. It's time for ciphertext stealing. */
1180 size_t i;
1181 unsigned char *prev_output = output - 16;
Aorimn5f778012016-06-09 23:22:58 +02001182
Jaeden Amerod82cd862018-04-28 15:02:45 +01001183 /* Copy ciphertext bytes from the previous block to our output for each
Shaun Case8b0ecbc2021-12-20 21:14:10 -08001184 * byte of ciphertext we won't steal. At the same time, copy the
Jaeden Amerod82cd862018-04-28 15:02:45 +01001185 * remainder of the input for this final round (since the loop bounds
1186 * are the same). */
1187 for( i = 0; i < leftover; i++ )
Aorimn5f778012016-06-09 23:22:58 +02001188 {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001189 output[i] = prev_output[i];
1190 tmp[i] = input[i] ^ t[i];
Aorimn5f778012016-06-09 23:22:58 +02001191 }
Aorimn5f778012016-06-09 23:22:58 +02001192
Jaeden Amerod82cd862018-04-28 15:02:45 +01001193 /* Copy ciphertext bytes from the previous block for input in this
1194 * round. */
1195 for( ; i < 16; i++ )
1196 tmp[i] = prev_output[i] ^ t[i];
Aorimn5f778012016-06-09 23:22:58 +02001197
Jaeden Amerod82cd862018-04-28 15:02:45 +01001198 ret = mbedtls_aes_crypt_ecb( &ctx->crypt, mode, tmp, tmp );
1199 if( ret != 0 )
1200 return ret;
Aorimn5f778012016-06-09 23:22:58 +02001201
Jaeden Amerod82cd862018-04-28 15:02:45 +01001202 /* Write the result back to the previous block, overriding the previous
1203 * output we copied. */
1204 for( i = 0; i < 16; i++ )
1205 prev_output[i] = tmp[i] ^ t[i];
Aorimn5f778012016-06-09 23:22:58 +02001206 }
1207
1208 return( 0 );
1209}
1210#endif /* MBEDTLS_CIPHER_MODE_XTS */
1211
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001212#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001213/*
1214 * AES-CFB128 buffer encryption/decryption
1215 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001216int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx,
Paul Bakker5121ce52009-01-03 21:22:43 +00001217 int mode,
Paul Bakker23986e52011-04-24 08:57:21 +00001218 size_t length,
Paul Bakker27fdf462011-06-09 13:55:13 +00001219 size_t *iv_off,
Paul Bakker5121ce52009-01-03 21:22:43 +00001220 unsigned char iv[16],
Paul Bakkerff60ee62010-03-16 21:09:09 +00001221 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +00001222 unsigned char *output )
1223{
Paul Bakker27fdf462011-06-09 13:55:13 +00001224 int c;
Gilles Peskine7820a572021-07-07 21:08:28 +02001225 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001226 size_t n;
1227
1228 AES_VALIDATE_RET( ctx != NULL );
1229 AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
1230 mode == MBEDTLS_AES_DECRYPT );
1231 AES_VALIDATE_RET( iv_off != NULL );
1232 AES_VALIDATE_RET( iv != NULL );
1233 AES_VALIDATE_RET( input != NULL );
1234 AES_VALIDATE_RET( output != NULL );
1235
1236 n = *iv_off;
Paul Bakker5121ce52009-01-03 21:22:43 +00001237
Manuel Pégourié-Gonnarde55e1032018-12-18 12:09:02 +01001238 if( n > 15 )
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001239 return( MBEDTLS_ERR_AES_BAD_INPUT_DATA );
1240
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001241 if( mode == MBEDTLS_AES_DECRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +00001242 {
1243 while( length-- )
1244 {
1245 if( n == 0 )
Gilles Peskine7820a572021-07-07 21:08:28 +02001246 {
1247 ret = mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
1248 if( ret != 0 )
1249 goto exit;
1250 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001251
1252 c = *input++;
1253 *output++ = (unsigned char)( c ^ iv[n] );
1254 iv[n] = (unsigned char) c;
1255
Paul Bakker66d5d072014-06-17 16:39:18 +02001256 n = ( n + 1 ) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001257 }
1258 }
1259 else
1260 {
1261 while( length-- )
1262 {
1263 if( n == 0 )
Gilles Peskine7820a572021-07-07 21:08:28 +02001264 {
1265 ret = mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
1266 if( ret != 0 )
1267 goto exit;
1268 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001269
1270 iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ );
1271
Paul Bakker66d5d072014-06-17 16:39:18 +02001272 n = ( n + 1 ) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001273 }
1274 }
1275
1276 *iv_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001277 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001278
Gilles Peskine7820a572021-07-07 21:08:28 +02001279exit:
1280 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001281}
Paul Bakker556efba2014-01-24 15:38:12 +01001282
1283/*
1284 * AES-CFB8 buffer encryption/decryption
1285 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001286int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx,
Manuel Pégourié-Gonnardeb6d3962018-12-18 09:59:35 +01001287 int mode,
1288 size_t length,
1289 unsigned char iv[16],
1290 const unsigned char *input,
1291 unsigned char *output )
Paul Bakker556efba2014-01-24 15:38:12 +01001292{
Gilles Peskine7820a572021-07-07 21:08:28 +02001293 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker556efba2014-01-24 15:38:12 +01001294 unsigned char c;
1295 unsigned char ov[17];
1296
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001297 AES_VALIDATE_RET( ctx != NULL );
1298 AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
1299 mode == MBEDTLS_AES_DECRYPT );
1300 AES_VALIDATE_RET( iv != NULL );
1301 AES_VALIDATE_RET( input != NULL );
1302 AES_VALIDATE_RET( output != NULL );
Paul Bakker556efba2014-01-24 15:38:12 +01001303 while( length-- )
1304 {
Paul Bakker66d5d072014-06-17 16:39:18 +02001305 memcpy( ov, iv, 16 );
Gilles Peskine7820a572021-07-07 21:08:28 +02001306 ret = mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
1307 if( ret != 0 )
1308 goto exit;
Paul Bakker556efba2014-01-24 15:38:12 +01001309
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001310 if( mode == MBEDTLS_AES_DECRYPT )
Paul Bakker556efba2014-01-24 15:38:12 +01001311 ov[16] = *input;
1312
1313 c = *output++ = (unsigned char)( iv[0] ^ *input++ );
1314
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001315 if( mode == MBEDTLS_AES_ENCRYPT )
Paul Bakker556efba2014-01-24 15:38:12 +01001316 ov[16] = c;
1317
Paul Bakker66d5d072014-06-17 16:39:18 +02001318 memcpy( iv, ov + 1, 16 );
Paul Bakker556efba2014-01-24 15:38:12 +01001319 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001320 ret = 0;
Paul Bakker556efba2014-01-24 15:38:12 +01001321
Gilles Peskine7820a572021-07-07 21:08:28 +02001322exit:
1323 return( ret );
Paul Bakker556efba2014-01-24 15:38:12 +01001324}
Simon Butcher76a5b222018-04-22 22:57:27 +01001325#endif /* MBEDTLS_CIPHER_MODE_CFB */
1326
1327#if defined(MBEDTLS_CIPHER_MODE_OFB)
1328/*
1329 * AES-OFB (Output Feedback Mode) buffer encryption/decryption
1330 */
1331int mbedtls_aes_crypt_ofb( mbedtls_aes_context *ctx,
Simon Butcher00131442018-05-22 22:40:36 +01001332 size_t length,
1333 size_t *iv_off,
1334 unsigned char iv[16],
1335 const unsigned char *input,
1336 unsigned char *output )
Simon Butcher76a5b222018-04-22 22:57:27 +01001337{
Simon Butcherad4e4932018-04-29 00:43:47 +01001338 int ret = 0;
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001339 size_t n;
1340
1341 AES_VALIDATE_RET( ctx != NULL );
1342 AES_VALIDATE_RET( iv_off != NULL );
1343 AES_VALIDATE_RET( iv != NULL );
1344 AES_VALIDATE_RET( input != NULL );
1345 AES_VALIDATE_RET( output != NULL );
1346
1347 n = *iv_off;
Simon Butcher76a5b222018-04-22 22:57:27 +01001348
Manuel Pégourié-Gonnarde55e1032018-12-18 12:09:02 +01001349 if( n > 15 )
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001350 return( MBEDTLS_ERR_AES_BAD_INPUT_DATA );
1351
Simon Butcher76a5b222018-04-22 22:57:27 +01001352 while( length-- )
1353 {
1354 if( n == 0 )
Simon Butcherad4e4932018-04-29 00:43:47 +01001355 {
1356 ret = mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
1357 if( ret != 0 )
1358 goto exit;
1359 }
Simon Butcher76a5b222018-04-22 22:57:27 +01001360 *output++ = *input++ ^ iv[n];
1361
1362 n = ( n + 1 ) & 0x0F;
1363 }
1364
1365 *iv_off = n;
1366
Simon Butcherad4e4932018-04-29 00:43:47 +01001367exit:
1368 return( ret );
Simon Butcher76a5b222018-04-22 22:57:27 +01001369}
1370#endif /* MBEDTLS_CIPHER_MODE_OFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001371
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001372#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001373/*
1374 * AES-CTR buffer encryption/decryption
1375 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001376int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx,
Paul Bakker27fdf462011-06-09 13:55:13 +00001377 size_t length,
1378 size_t *nc_off,
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001379 unsigned char nonce_counter[16],
1380 unsigned char stream_block[16],
1381 const unsigned char *input,
1382 unsigned char *output )
1383{
Paul Bakker369e14b2012-04-18 14:16:09 +00001384 int c, i;
Gilles Peskine7820a572021-07-07 21:08:28 +02001385 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001386 size_t n;
1387
1388 AES_VALIDATE_RET( ctx != NULL );
1389 AES_VALIDATE_RET( nc_off != NULL );
1390 AES_VALIDATE_RET( nonce_counter != NULL );
1391 AES_VALIDATE_RET( stream_block != NULL );
1392 AES_VALIDATE_RET( input != NULL );
1393 AES_VALIDATE_RET( output != NULL );
1394
1395 n = *nc_off;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001396
Mohammad Azim Khan3f7f8172017-11-23 17:49:05 +00001397 if ( n > 0x0F )
1398 return( MBEDTLS_ERR_AES_BAD_INPUT_DATA );
1399
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001400 while( length-- )
1401 {
1402 if( n == 0 ) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001403 ret = mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block );
1404 if( ret != 0 )
1405 goto exit;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001406
Paul Bakker369e14b2012-04-18 14:16:09 +00001407 for( i = 16; i > 0; i-- )
1408 if( ++nonce_counter[i - 1] != 0 )
1409 break;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001410 }
1411 c = *input++;
1412 *output++ = (unsigned char)( c ^ stream_block[n] );
1413
Paul Bakker66d5d072014-06-17 16:39:18 +02001414 n = ( n + 1 ) & 0x0F;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001415 }
1416
1417 *nc_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001418 ret = 0;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001419
Gilles Peskine7820a572021-07-07 21:08:28 +02001420exit:
1421 return( ret );
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001422}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001423#endif /* MBEDTLS_CIPHER_MODE_CTR */
Manuel Pégourié-Gonnard1ec220b2014-03-10 11:20:17 +01001424
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001425#endif /* !MBEDTLS_AES_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001426
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001427#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001428/*
1429 * AES test vectors from:
1430 *
1431 * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
1432 */
1433static const unsigned char aes_test_ecb_dec[3][16] =
1434{
1435 { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
1436 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
1437 { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
1438 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
1439 { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
1440 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
1441};
1442
1443static const unsigned char aes_test_ecb_enc[3][16] =
1444{
1445 { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
1446 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
1447 { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
1448 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
1449 { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
1450 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
1451};
1452
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001453#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001454static const unsigned char aes_test_cbc_dec[3][16] =
1455{
1456 { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
1457 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
1458 { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
1459 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
1460 { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
1461 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
1462};
1463
1464static const unsigned char aes_test_cbc_enc[3][16] =
1465{
1466 { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
1467 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
1468 { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
1469 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
1470 { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
1471 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
1472};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001473#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001474
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001475#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001476/*
1477 * AES-CFB128 test vectors from:
1478 *
1479 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
1480 */
1481static const unsigned char aes_test_cfb128_key[3][32] =
1482{
1483 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1484 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
1485 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1486 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1487 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1488 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1489 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1490 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1491 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
1492};
1493
1494static const unsigned char aes_test_cfb128_iv[16] =
1495{
1496 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1497 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1498};
1499
1500static const unsigned char aes_test_cfb128_pt[64] =
1501{
1502 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1503 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1504 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1505 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1506 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1507 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1508 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1509 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1510};
1511
1512static const unsigned char aes_test_cfb128_ct[3][64] =
1513{
1514 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1515 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1516 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F,
1517 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B,
1518 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40,
1519 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF,
1520 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E,
1521 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 },
1522 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1523 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1524 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21,
1525 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A,
1526 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1,
1527 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9,
1528 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0,
1529 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF },
1530 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1531 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1532 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8,
1533 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B,
1534 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92,
1535 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9,
1536 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8,
1537 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 }
1538};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001539#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001540
Simon Butcherad4e4932018-04-29 00:43:47 +01001541#if defined(MBEDTLS_CIPHER_MODE_OFB)
1542/*
1543 * AES-OFB test vectors from:
1544 *
Simon Butcher5db13622018-06-04 22:11:25 +01001545 * https://csrc.nist.gov/publications/detail/sp/800-38a/final
Simon Butcherad4e4932018-04-29 00:43:47 +01001546 */
1547static const unsigned char aes_test_ofb_key[3][32] =
1548{
1549 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1550 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
1551 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1552 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1553 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1554 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1555 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1556 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1557 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
1558};
1559
1560static const unsigned char aes_test_ofb_iv[16] =
1561{
1562 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1563 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1564};
1565
1566static const unsigned char aes_test_ofb_pt[64] =
1567{
1568 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1569 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1570 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1571 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1572 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1573 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1574 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1575 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1576};
1577
1578static const unsigned char aes_test_ofb_ct[3][64] =
1579{
1580 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1581 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1582 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
1583 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
1584 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
1585 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
1586 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
1587 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e },
1588 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1589 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1590 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
1591 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
1592 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f,
1593 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
1594 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e,
1595 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a },
1596 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1597 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1598 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
1599 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
1600 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed,
1601 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
1602 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8,
1603 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 }
1604};
1605#endif /* MBEDTLS_CIPHER_MODE_OFB */
1606
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001607#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001608/*
1609 * AES-CTR test vectors from:
1610 *
1611 * http://www.faqs.org/rfcs/rfc3686.html
1612 */
1613
1614static const unsigned char aes_test_ctr_key[3][16] =
1615{
1616 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
1617 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
1618 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
1619 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
1620 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
1621 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
1622};
1623
1624static const unsigned char aes_test_ctr_nonce_counter[3][16] =
1625{
1626 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
1627 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
1628 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
1629 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
1630 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
1631 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
1632};
1633
1634static const unsigned char aes_test_ctr_pt[3][48] =
1635{
1636 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
1637 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
1638
1639 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1640 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1641 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1642 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
1643
1644 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1645 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1646 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1647 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
1648 0x20, 0x21, 0x22, 0x23 }
1649};
1650
1651static const unsigned char aes_test_ctr_ct[3][48] =
1652{
1653 { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79,
1654 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 },
1655 { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9,
1656 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88,
1657 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8,
1658 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 },
1659 { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
1660 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
1661 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
1662 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
1663 0x25, 0xB2, 0x07, 0x2F }
1664};
1665
1666static const int aes_test_ctr_len[3] =
1667 { 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001668#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00001669
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001670#if defined(MBEDTLS_CIPHER_MODE_XTS)
1671/*
1672 * AES-XTS test vectors from:
1673 *
1674 * IEEE P1619/D16 Annex B
1675 * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf
1676 * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf)
1677 */
1678static const unsigned char aes_test_xts_key[][32] =
1679{
1680 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1681 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1682 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1683 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1684 { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1685 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1686 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1687 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1688 { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
1689 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
1690 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1691 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1692};
1693
1694static const unsigned char aes_test_xts_pt32[][32] =
1695{
1696 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1697 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1698 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1699 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1700 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1701 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1702 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1703 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1704 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1705 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1706 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1707 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1708};
1709
1710static const unsigned char aes_test_xts_ct32[][32] =
1711{
1712 { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec,
1713 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92,
1714 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85,
1715 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e },
1716 { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e,
1717 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b,
1718 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4,
1719 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 },
1720 { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a,
1721 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2,
1722 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53,
1723 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 },
1724};
1725
1726static const unsigned char aes_test_xts_data_unit[][16] =
1727{
1728 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1729 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1730 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1731 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1732 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1733 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1734};
1735
1736#endif /* MBEDTLS_CIPHER_MODE_XTS */
1737
Paul Bakker5121ce52009-01-03 21:22:43 +00001738/*
1739 * Checkup routine
1740 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001741int mbedtls_aes_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +00001742{
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001743 int ret = 0, i, j, u, mode;
1744 unsigned int keybits;
Paul Bakker5121ce52009-01-03 21:22:43 +00001745 unsigned char key[32];
1746 unsigned char buf[64];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001747 const unsigned char *aes_tests;
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03001748#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001749 unsigned char iv[16];
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03001750#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001751#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +02001752 unsigned char prv[16];
1753#endif
Simon Butcher2ff0e522018-06-14 09:57:07 +01001754#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1755 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker27fdf462011-06-09 13:55:13 +00001756 size_t offset;
Paul Bakkere91d01e2011-04-19 15:55:50 +00001757#endif
Simon Butcher66a89032018-06-15 18:20:29 +01001758#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS)
Paul Bakkere91d01e2011-04-19 15:55:50 +00001759 int len;
Simon Butcher66a89032018-06-15 18:20:29 +01001760#endif
1761#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001762 unsigned char nonce_counter[16];
1763 unsigned char stream_block[16];
1764#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001765 mbedtls_aes_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001766
1767 memset( key, 0, 32 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001768 mbedtls_aes_init( &ctx );
Paul Bakker5121ce52009-01-03 21:22:43 +00001769
1770 /*
1771 * ECB mode
1772 */
1773 for( i = 0; i < 6; i++ )
1774 {
1775 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001776 keybits = 128 + u * 64;
1777 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001778
1779 if( verbose != 0 )
Kenneth Soerensen518d4352020-04-01 17:22:45 +02001780 mbedtls_printf( " AES-ECB-%3u (%s): ", keybits,
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001781 ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001782
1783 memset( buf, 0, 16 );
1784
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001785 if( mode == MBEDTLS_AES_DECRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +00001786 {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001787 ret = mbedtls_aes_setkey_dec( &ctx, key, keybits );
1788 aes_tests = aes_test_ecb_dec[u];
Paul Bakker5121ce52009-01-03 21:22:43 +00001789 }
1790 else
1791 {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001792 ret = mbedtls_aes_setkey_enc( &ctx, key, keybits );
1793 aes_tests = aes_test_ecb_enc[u];
1794 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001795
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01001796 /*
1797 * AES-192 is an optional feature that may be unavailable when
1798 * there is an alternative underlying implementation i.e. when
1799 * MBEDTLS_AES_ALT is defined.
1800 */
Ron Eldor9924bdc2018-10-04 10:59:13 +03001801 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 )
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001802 {
1803 mbedtls_printf( "skipped\n" );
1804 continue;
1805 }
1806 else if( ret != 0 )
1807 {
1808 goto exit;
1809 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001810
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001811 for( j = 0; j < 10000; j++ )
1812 {
1813 ret = mbedtls_aes_crypt_ecb( &ctx, mode, buf, buf );
1814 if( ret != 0 )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001815 goto exit;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001816 }
1817
1818 if( memcmp( buf, aes_tests, 16 ) != 0 )
1819 {
1820 ret = 1;
1821 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001822 }
1823
1824 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001825 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001826 }
1827
1828 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001829 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001830
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001831#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001832 /*
1833 * CBC mode
1834 */
1835 for( i = 0; i < 6; i++ )
1836 {
1837 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001838 keybits = 128 + u * 64;
1839 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001840
1841 if( verbose != 0 )
Kenneth Soerensen518d4352020-04-01 17:22:45 +02001842 mbedtls_printf( " AES-CBC-%3u (%s): ", keybits,
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001843 ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001844
1845 memset( iv , 0, 16 );
1846 memset( prv, 0, 16 );
1847 memset( buf, 0, 16 );
1848
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001849 if( mode == MBEDTLS_AES_DECRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +00001850 {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001851 ret = mbedtls_aes_setkey_dec( &ctx, key, keybits );
1852 aes_tests = aes_test_cbc_dec[u];
Paul Bakker5121ce52009-01-03 21:22:43 +00001853 }
1854 else
1855 {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001856 ret = mbedtls_aes_setkey_enc( &ctx, key, keybits );
1857 aes_tests = aes_test_cbc_enc[u];
1858 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001859
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01001860 /*
1861 * AES-192 is an optional feature that may be unavailable when
1862 * there is an alternative underlying implementation i.e. when
1863 * MBEDTLS_AES_ALT is defined.
1864 */
Ron Eldor9924bdc2018-10-04 10:59:13 +03001865 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 )
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001866 {
1867 mbedtls_printf( "skipped\n" );
1868 continue;
1869 }
1870 else if( ret != 0 )
1871 {
1872 goto exit;
1873 }
1874
1875 for( j = 0; j < 10000; j++ )
1876 {
1877 if( mode == MBEDTLS_AES_ENCRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +00001878 {
1879 unsigned char tmp[16];
1880
Paul Bakker5121ce52009-01-03 21:22:43 +00001881 memcpy( tmp, prv, 16 );
1882 memcpy( prv, buf, 16 );
1883 memcpy( buf, tmp, 16 );
1884 }
1885
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001886 ret = mbedtls_aes_crypt_cbc( &ctx, mode, 16, iv, buf, buf );
1887 if( ret != 0 )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001888 goto exit;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001889
1890 }
1891
1892 if( memcmp( buf, aes_tests, 16 ) != 0 )
1893 {
1894 ret = 1;
1895 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001896 }
1897
1898 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001899 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001900 }
1901
1902 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001903 mbedtls_printf( "\n" );
1904#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001905
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001906#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001907 /*
1908 * CFB128 mode
1909 */
1910 for( i = 0; i < 6; i++ )
1911 {
1912 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001913 keybits = 128 + u * 64;
1914 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001915
1916 if( verbose != 0 )
Kenneth Soerensen518d4352020-04-01 17:22:45 +02001917 mbedtls_printf( " AES-CFB128-%3u (%s): ", keybits,
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001918 ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001919
1920 memcpy( iv, aes_test_cfb128_iv, 16 );
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001921 memcpy( key, aes_test_cfb128_key[u], keybits / 8 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001922
1923 offset = 0;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001924 ret = mbedtls_aes_setkey_enc( &ctx, key, keybits );
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01001925 /*
1926 * AES-192 is an optional feature that may be unavailable when
1927 * there is an alternative underlying implementation i.e. when
1928 * MBEDTLS_AES_ALT is defined.
1929 */
Ron Eldor9924bdc2018-10-04 10:59:13 +03001930 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 )
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001931 {
1932 mbedtls_printf( "skipped\n" );
1933 continue;
1934 }
1935 else if( ret != 0 )
1936 {
1937 goto exit;
1938 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001939
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001940 if( mode == MBEDTLS_AES_DECRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +00001941 {
1942 memcpy( buf, aes_test_cfb128_ct[u], 64 );
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001943 aes_tests = aes_test_cfb128_pt;
Paul Bakker5121ce52009-01-03 21:22:43 +00001944 }
1945 else
1946 {
1947 memcpy( buf, aes_test_cfb128_pt, 64 );
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001948 aes_tests = aes_test_cfb128_ct[u];
1949 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001950
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001951 ret = mbedtls_aes_crypt_cfb128( &ctx, mode, 64, &offset, iv, buf, buf );
1952 if( ret != 0 )
1953 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001954
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001955 if( memcmp( buf, aes_tests, 64 ) != 0 )
1956 {
1957 ret = 1;
1958 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001959 }
1960
1961 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001962 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001963 }
1964
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001965 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001966 mbedtls_printf( "\n" );
1967#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001968
Simon Butcherad4e4932018-04-29 00:43:47 +01001969#if defined(MBEDTLS_CIPHER_MODE_OFB)
1970 /*
1971 * OFB mode
1972 */
1973 for( i = 0; i < 6; i++ )
1974 {
1975 u = i >> 1;
1976 keybits = 128 + u * 64;
1977 mode = i & 1;
1978
1979 if( verbose != 0 )
Kenneth Soerensen518d4352020-04-01 17:22:45 +02001980 mbedtls_printf( " AES-OFB-%3u (%s): ", keybits,
Simon Butcherad4e4932018-04-29 00:43:47 +01001981 ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
1982
1983 memcpy( iv, aes_test_ofb_iv, 16 );
1984 memcpy( key, aes_test_ofb_key[u], keybits / 8 );
1985
1986 offset = 0;
1987 ret = mbedtls_aes_setkey_enc( &ctx, key, keybits );
1988 /*
1989 * AES-192 is an optional feature that may be unavailable when
1990 * there is an alternative underlying implementation i.e. when
1991 * MBEDTLS_AES_ALT is defined.
1992 */
Ron Eldor9924bdc2018-10-04 10:59:13 +03001993 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 )
Simon Butcherad4e4932018-04-29 00:43:47 +01001994 {
1995 mbedtls_printf( "skipped\n" );
1996 continue;
1997 }
1998 else if( ret != 0 )
1999 {
2000 goto exit;
2001 }
2002
2003 if( mode == MBEDTLS_AES_DECRYPT )
2004 {
2005 memcpy( buf, aes_test_ofb_ct[u], 64 );
2006 aes_tests = aes_test_ofb_pt;
2007 }
2008 else
2009 {
2010 memcpy( buf, aes_test_ofb_pt, 64 );
2011 aes_tests = aes_test_ofb_ct[u];
2012 }
2013
2014 ret = mbedtls_aes_crypt_ofb( &ctx, 64, &offset, iv, buf, buf );
2015 if( ret != 0 )
2016 goto exit;
2017
2018 if( memcmp( buf, aes_tests, 64 ) != 0 )
2019 {
2020 ret = 1;
2021 goto exit;
2022 }
2023
2024 if( verbose != 0 )
2025 mbedtls_printf( "passed\n" );
2026 }
2027
2028 if( verbose != 0 )
2029 mbedtls_printf( "\n" );
2030#endif /* MBEDTLS_CIPHER_MODE_OFB */
2031
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002032#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002033 /*
2034 * CTR mode
2035 */
2036 for( i = 0; i < 6; i++ )
2037 {
2038 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002039 mode = i & 1;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002040
2041 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002042 mbedtls_printf( " AES-CTR-128 (%s): ",
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002043 ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002044
2045 memcpy( nonce_counter, aes_test_ctr_nonce_counter[u], 16 );
2046 memcpy( key, aes_test_ctr_key[u], 16 );
2047
2048 offset = 0;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002049 if( ( ret = mbedtls_aes_setkey_enc( &ctx, key, 128 ) ) != 0 )
2050 goto exit;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002051
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002052 len = aes_test_ctr_len[u];
2053
2054 if( mode == MBEDTLS_AES_DECRYPT )
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002055 {
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002056 memcpy( buf, aes_test_ctr_ct[u], len );
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002057 aes_tests = aes_test_ctr_pt[u];
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002058 }
2059 else
2060 {
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002061 memcpy( buf, aes_test_ctr_pt[u], len );
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002062 aes_tests = aes_test_ctr_ct[u];
2063 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002064
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002065 ret = mbedtls_aes_crypt_ctr( &ctx, len, &offset, nonce_counter,
2066 stream_block, buf, buf );
2067 if( ret != 0 )
2068 goto exit;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002069
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002070 if( memcmp( buf, aes_tests, len ) != 0 )
2071 {
2072 ret = 1;
2073 goto exit;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002074 }
2075
2076 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002077 mbedtls_printf( "passed\n" );
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002078 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002079
2080 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002081 mbedtls_printf( "\n" );
2082#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00002083
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002084#if defined(MBEDTLS_CIPHER_MODE_XTS)
2085 {
2086 static const int num_tests =
2087 sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key);
2088 mbedtls_aes_xts_context ctx_xts;
2089
2090 /*
2091 * XTS mode
2092 */
2093 mbedtls_aes_xts_init( &ctx_xts );
2094
2095 for( i = 0; i < num_tests << 1; i++ )
2096 {
2097 const unsigned char *data_unit;
2098 u = i >> 1;
2099 mode = i & 1;
2100
2101 if( verbose != 0 )
2102 mbedtls_printf( " AES-XTS-128 (%s): ",
2103 ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
2104
2105 memset( key, 0, sizeof( key ) );
2106 memcpy( key, aes_test_xts_key[u], 32 );
2107 data_unit = aes_test_xts_data_unit[u];
2108
2109 len = sizeof( *aes_test_xts_ct32 );
2110
2111 if( mode == MBEDTLS_AES_DECRYPT )
2112 {
2113 ret = mbedtls_aes_xts_setkey_dec( &ctx_xts, key, 256 );
2114 if( ret != 0)
2115 goto exit;
2116 memcpy( buf, aes_test_xts_ct32[u], len );
2117 aes_tests = aes_test_xts_pt32[u];
2118 }
2119 else
2120 {
2121 ret = mbedtls_aes_xts_setkey_enc( &ctx_xts, key, 256 );
2122 if( ret != 0)
2123 goto exit;
2124 memcpy( buf, aes_test_xts_pt32[u], len );
2125 aes_tests = aes_test_xts_ct32[u];
2126 }
2127
2128
2129 ret = mbedtls_aes_crypt_xts( &ctx_xts, mode, len, data_unit,
2130 buf, buf );
2131 if( ret != 0 )
2132 goto exit;
2133
2134 if( memcmp( buf, aes_tests, len ) != 0 )
2135 {
2136 ret = 1;
2137 goto exit;
2138 }
2139
2140 if( verbose != 0 )
2141 mbedtls_printf( "passed\n" );
2142 }
2143
2144 if( verbose != 0 )
2145 mbedtls_printf( "\n" );
2146
2147 mbedtls_aes_xts_free( &ctx_xts );
2148 }
2149#endif /* MBEDTLS_CIPHER_MODE_XTS */
2150
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002151 ret = 0;
2152
2153exit:
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002154 if( ret != 0 && verbose != 0 )
2155 mbedtls_printf( "failed\n" );
2156
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002157 mbedtls_aes_free( &ctx );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002158
2159 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002160}
2161
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002162#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002163
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002164#endif /* MBEDTLS_AES_C */