blob: 872930f2ac1d9e4619b063efe0a0d45a22d623d0 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * FIPS-197 compliant AES implementation
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Paul Bakker5121ce52009-01-03 21:22:43 +000018 */
19/*
20 * The AES block cipher was designed by Vincent Rijmen and Joan Daemen.
21 *
22 * http://csrc.nist.gov/encryption/aes/rijndael/Rijndael.pdf
23 * http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
24 */
25
Gilles Peskinedb09ef62020-06-03 01:43:33 +020026#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000027
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020028#if defined(MBEDTLS_AES_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000029
Rich Evans00ab4702015-02-06 13:43:58 +000030#include <string.h>
31
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000032#include "mbedtls/aes.h"
Ron Eldor9924bdc2018-10-04 10:59:13 +030033#include "mbedtls/platform.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050034#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000035#include "mbedtls/error.h"
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020036#if defined(MBEDTLS_PADLOCK_C)
Chris Jones16dbaeb2021-03-09 17:47:55 +000037#include "padlock.h"
Paul Bakker67820bd2012-06-04 12:47:23 +000038#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020039#if defined(MBEDTLS_AESNI_C)
Chris Jones187782f2021-03-09 17:28:35 +000040#include "aesni.h"
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +010041#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000042
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020043#if defined(MBEDTLS_SELF_TEST)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000044#include "mbedtls/platform.h"
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020045#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010046
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020047#if !defined(MBEDTLS_AES_ALT)
Paul Bakker90995b52013-06-24 19:20:35 +020048
Manuel Pégourié-Gonnard0e9cddb2018-12-10 16:37:51 +010049/* Parameter validation macros based on platform_util.h */
50#define AES_VALIDATE_RET( cond ) \
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +010051 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_AES_BAD_INPUT_DATA )
Manuel Pégourié-Gonnard0e9cddb2018-12-10 16:37:51 +010052#define AES_VALIDATE( cond ) \
53 MBEDTLS_INTERNAL_VALIDATE( cond )
54
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020055#if defined(MBEDTLS_PADLOCK_C) && \
56 ( defined(MBEDTLS_HAVE_X86) || defined(MBEDTLS_PADLOCK_ALIGN16) )
Paul Bakker048d04e2012-02-12 17:31:04 +000057static int aes_padlock_ace = -1;
58#endif
59
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020060#if defined(MBEDTLS_AES_ROM_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +000061/*
62 * Forward S-box
63 */
64static const unsigned char FSb[256] =
65{
66 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
67 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
68 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
69 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
70 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
71 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
72 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
73 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
74 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
75 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
76 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
77 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
78 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
79 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
80 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
81 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
82 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
83 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
84 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
85 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
86 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
87 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
88 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
89 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
90 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
91 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
92 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
93 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
94 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
95 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
96 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
97 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
98};
99
100/*
101 * Forward tables
102 */
103#define FT \
104\
105 V(A5,63,63,C6), V(84,7C,7C,F8), V(99,77,77,EE), V(8D,7B,7B,F6), \
106 V(0D,F2,F2,FF), V(BD,6B,6B,D6), V(B1,6F,6F,DE), V(54,C5,C5,91), \
107 V(50,30,30,60), V(03,01,01,02), V(A9,67,67,CE), V(7D,2B,2B,56), \
108 V(19,FE,FE,E7), V(62,D7,D7,B5), V(E6,AB,AB,4D), V(9A,76,76,EC), \
109 V(45,CA,CA,8F), V(9D,82,82,1F), V(40,C9,C9,89), V(87,7D,7D,FA), \
110 V(15,FA,FA,EF), V(EB,59,59,B2), V(C9,47,47,8E), V(0B,F0,F0,FB), \
111 V(EC,AD,AD,41), V(67,D4,D4,B3), V(FD,A2,A2,5F), V(EA,AF,AF,45), \
112 V(BF,9C,9C,23), V(F7,A4,A4,53), V(96,72,72,E4), V(5B,C0,C0,9B), \
113 V(C2,B7,B7,75), V(1C,FD,FD,E1), V(AE,93,93,3D), V(6A,26,26,4C), \
114 V(5A,36,36,6C), V(41,3F,3F,7E), V(02,F7,F7,F5), V(4F,CC,CC,83), \
115 V(5C,34,34,68), V(F4,A5,A5,51), V(34,E5,E5,D1), V(08,F1,F1,F9), \
116 V(93,71,71,E2), V(73,D8,D8,AB), V(53,31,31,62), V(3F,15,15,2A), \
117 V(0C,04,04,08), V(52,C7,C7,95), V(65,23,23,46), V(5E,C3,C3,9D), \
118 V(28,18,18,30), V(A1,96,96,37), V(0F,05,05,0A), V(B5,9A,9A,2F), \
119 V(09,07,07,0E), V(36,12,12,24), V(9B,80,80,1B), V(3D,E2,E2,DF), \
120 V(26,EB,EB,CD), V(69,27,27,4E), V(CD,B2,B2,7F), V(9F,75,75,EA), \
121 V(1B,09,09,12), V(9E,83,83,1D), V(74,2C,2C,58), V(2E,1A,1A,34), \
122 V(2D,1B,1B,36), V(B2,6E,6E,DC), V(EE,5A,5A,B4), V(FB,A0,A0,5B), \
123 V(F6,52,52,A4), V(4D,3B,3B,76), V(61,D6,D6,B7), V(CE,B3,B3,7D), \
124 V(7B,29,29,52), V(3E,E3,E3,DD), V(71,2F,2F,5E), V(97,84,84,13), \
125 V(F5,53,53,A6), V(68,D1,D1,B9), V(00,00,00,00), V(2C,ED,ED,C1), \
126 V(60,20,20,40), V(1F,FC,FC,E3), V(C8,B1,B1,79), V(ED,5B,5B,B6), \
127 V(BE,6A,6A,D4), V(46,CB,CB,8D), V(D9,BE,BE,67), V(4B,39,39,72), \
128 V(DE,4A,4A,94), V(D4,4C,4C,98), V(E8,58,58,B0), V(4A,CF,CF,85), \
129 V(6B,D0,D0,BB), V(2A,EF,EF,C5), V(E5,AA,AA,4F), V(16,FB,FB,ED), \
130 V(C5,43,43,86), V(D7,4D,4D,9A), V(55,33,33,66), V(94,85,85,11), \
131 V(CF,45,45,8A), V(10,F9,F9,E9), V(06,02,02,04), V(81,7F,7F,FE), \
132 V(F0,50,50,A0), V(44,3C,3C,78), V(BA,9F,9F,25), V(E3,A8,A8,4B), \
133 V(F3,51,51,A2), V(FE,A3,A3,5D), V(C0,40,40,80), V(8A,8F,8F,05), \
134 V(AD,92,92,3F), V(BC,9D,9D,21), V(48,38,38,70), V(04,F5,F5,F1), \
135 V(DF,BC,BC,63), V(C1,B6,B6,77), V(75,DA,DA,AF), V(63,21,21,42), \
136 V(30,10,10,20), V(1A,FF,FF,E5), V(0E,F3,F3,FD), V(6D,D2,D2,BF), \
137 V(4C,CD,CD,81), V(14,0C,0C,18), V(35,13,13,26), V(2F,EC,EC,C3), \
138 V(E1,5F,5F,BE), V(A2,97,97,35), V(CC,44,44,88), V(39,17,17,2E), \
139 V(57,C4,C4,93), V(F2,A7,A7,55), V(82,7E,7E,FC), V(47,3D,3D,7A), \
140 V(AC,64,64,C8), V(E7,5D,5D,BA), V(2B,19,19,32), V(95,73,73,E6), \
141 V(A0,60,60,C0), V(98,81,81,19), V(D1,4F,4F,9E), V(7F,DC,DC,A3), \
142 V(66,22,22,44), V(7E,2A,2A,54), V(AB,90,90,3B), V(83,88,88,0B), \
143 V(CA,46,46,8C), V(29,EE,EE,C7), V(D3,B8,B8,6B), V(3C,14,14,28), \
144 V(79,DE,DE,A7), V(E2,5E,5E,BC), V(1D,0B,0B,16), V(76,DB,DB,AD), \
145 V(3B,E0,E0,DB), V(56,32,32,64), V(4E,3A,3A,74), V(1E,0A,0A,14), \
146 V(DB,49,49,92), V(0A,06,06,0C), V(6C,24,24,48), V(E4,5C,5C,B8), \
147 V(5D,C2,C2,9F), V(6E,D3,D3,BD), V(EF,AC,AC,43), V(A6,62,62,C4), \
148 V(A8,91,91,39), V(A4,95,95,31), V(37,E4,E4,D3), V(8B,79,79,F2), \
149 V(32,E7,E7,D5), V(43,C8,C8,8B), V(59,37,37,6E), V(B7,6D,6D,DA), \
150 V(8C,8D,8D,01), V(64,D5,D5,B1), V(D2,4E,4E,9C), V(E0,A9,A9,49), \
151 V(B4,6C,6C,D8), V(FA,56,56,AC), V(07,F4,F4,F3), V(25,EA,EA,CF), \
152 V(AF,65,65,CA), V(8E,7A,7A,F4), V(E9,AE,AE,47), V(18,08,08,10), \
153 V(D5,BA,BA,6F), V(88,78,78,F0), V(6F,25,25,4A), V(72,2E,2E,5C), \
154 V(24,1C,1C,38), V(F1,A6,A6,57), V(C7,B4,B4,73), V(51,C6,C6,97), \
155 V(23,E8,E8,CB), V(7C,DD,DD,A1), V(9C,74,74,E8), V(21,1F,1F,3E), \
156 V(DD,4B,4B,96), V(DC,BD,BD,61), V(86,8B,8B,0D), V(85,8A,8A,0F), \
157 V(90,70,70,E0), V(42,3E,3E,7C), V(C4,B5,B5,71), V(AA,66,66,CC), \
158 V(D8,48,48,90), V(05,03,03,06), V(01,F6,F6,F7), V(12,0E,0E,1C), \
159 V(A3,61,61,C2), V(5F,35,35,6A), V(F9,57,57,AE), V(D0,B9,B9,69), \
160 V(91,86,86,17), V(58,C1,C1,99), V(27,1D,1D,3A), V(B9,9E,9E,27), \
161 V(38,E1,E1,D9), V(13,F8,F8,EB), V(B3,98,98,2B), V(33,11,11,22), \
162 V(BB,69,69,D2), V(70,D9,D9,A9), V(89,8E,8E,07), V(A7,94,94,33), \
163 V(B6,9B,9B,2D), V(22,1E,1E,3C), V(92,87,87,15), V(20,E9,E9,C9), \
164 V(49,CE,CE,87), V(FF,55,55,AA), V(78,28,28,50), V(7A,DF,DF,A5), \
165 V(8F,8C,8C,03), V(F8,A1,A1,59), V(80,89,89,09), V(17,0D,0D,1A), \
166 V(DA,BF,BF,65), V(31,E6,E6,D7), V(C6,42,42,84), V(B8,68,68,D0), \
167 V(C3,41,41,82), V(B0,99,99,29), V(77,2D,2D,5A), V(11,0F,0F,1E), \
168 V(CB,B0,B0,7B), V(FC,54,54,A8), V(D6,BB,BB,6D), V(3A,16,16,2C)
169
170#define V(a,b,c,d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000171static const uint32_t FT0[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000172#undef V
173
Hanno Beckerad049a92017-06-19 16:31:54 +0100174#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200175
Paul Bakker5121ce52009-01-03 21:22:43 +0000176#define V(a,b,c,d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000177static const uint32_t FT1[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000178#undef V
179
180#define V(a,b,c,d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000181static const uint32_t FT2[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000182#undef V
183
184#define V(a,b,c,d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000185static const uint32_t FT3[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000186#undef V
187
Hanno Becker177d3cf2017-06-07 15:52:48 +0100188#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200189
Paul Bakker5121ce52009-01-03 21:22:43 +0000190#undef FT
191
192/*
193 * Reverse S-box
194 */
195static const unsigned char RSb[256] =
196{
197 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
198 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
199 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
200 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
201 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
202 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
203 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
204 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
205 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
206 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
207 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
208 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
209 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
210 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
211 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
212 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
213 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
214 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
215 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
216 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
217 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
218 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
219 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
220 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
221 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
222 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
223 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
224 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
225 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
226 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
227 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
228 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
229};
230
231/*
232 * Reverse tables
233 */
234#define RT \
235\
236 V(50,A7,F4,51), V(53,65,41,7E), V(C3,A4,17,1A), V(96,5E,27,3A), \
237 V(CB,6B,AB,3B), V(F1,45,9D,1F), V(AB,58,FA,AC), V(93,03,E3,4B), \
238 V(55,FA,30,20), V(F6,6D,76,AD), V(91,76,CC,88), V(25,4C,02,F5), \
239 V(FC,D7,E5,4F), V(D7,CB,2A,C5), V(80,44,35,26), V(8F,A3,62,B5), \
240 V(49,5A,B1,DE), V(67,1B,BA,25), V(98,0E,EA,45), V(E1,C0,FE,5D), \
241 V(02,75,2F,C3), V(12,F0,4C,81), V(A3,97,46,8D), V(C6,F9,D3,6B), \
242 V(E7,5F,8F,03), V(95,9C,92,15), V(EB,7A,6D,BF), V(DA,59,52,95), \
243 V(2D,83,BE,D4), V(D3,21,74,58), V(29,69,E0,49), V(44,C8,C9,8E), \
244 V(6A,89,C2,75), V(78,79,8E,F4), V(6B,3E,58,99), V(DD,71,B9,27), \
245 V(B6,4F,E1,BE), V(17,AD,88,F0), V(66,AC,20,C9), V(B4,3A,CE,7D), \
246 V(18,4A,DF,63), V(82,31,1A,E5), V(60,33,51,97), V(45,7F,53,62), \
247 V(E0,77,64,B1), V(84,AE,6B,BB), V(1C,A0,81,FE), V(94,2B,08,F9), \
248 V(58,68,48,70), V(19,FD,45,8F), V(87,6C,DE,94), V(B7,F8,7B,52), \
249 V(23,D3,73,AB), V(E2,02,4B,72), V(57,8F,1F,E3), V(2A,AB,55,66), \
250 V(07,28,EB,B2), V(03,C2,B5,2F), V(9A,7B,C5,86), V(A5,08,37,D3), \
251 V(F2,87,28,30), V(B2,A5,BF,23), V(BA,6A,03,02), V(5C,82,16,ED), \
252 V(2B,1C,CF,8A), V(92,B4,79,A7), V(F0,F2,07,F3), V(A1,E2,69,4E), \
253 V(CD,F4,DA,65), V(D5,BE,05,06), V(1F,62,34,D1), V(8A,FE,A6,C4), \
254 V(9D,53,2E,34), V(A0,55,F3,A2), V(32,E1,8A,05), V(75,EB,F6,A4), \
255 V(39,EC,83,0B), V(AA,EF,60,40), V(06,9F,71,5E), V(51,10,6E,BD), \
256 V(F9,8A,21,3E), V(3D,06,DD,96), V(AE,05,3E,DD), V(46,BD,E6,4D), \
257 V(B5,8D,54,91), V(05,5D,C4,71), V(6F,D4,06,04), V(FF,15,50,60), \
258 V(24,FB,98,19), V(97,E9,BD,D6), V(CC,43,40,89), V(77,9E,D9,67), \
259 V(BD,42,E8,B0), V(88,8B,89,07), V(38,5B,19,E7), V(DB,EE,C8,79), \
260 V(47,0A,7C,A1), V(E9,0F,42,7C), V(C9,1E,84,F8), V(00,00,00,00), \
261 V(83,86,80,09), V(48,ED,2B,32), V(AC,70,11,1E), V(4E,72,5A,6C), \
262 V(FB,FF,0E,FD), V(56,38,85,0F), V(1E,D5,AE,3D), V(27,39,2D,36), \
263 V(64,D9,0F,0A), V(21,A6,5C,68), V(D1,54,5B,9B), V(3A,2E,36,24), \
264 V(B1,67,0A,0C), V(0F,E7,57,93), V(D2,96,EE,B4), V(9E,91,9B,1B), \
265 V(4F,C5,C0,80), V(A2,20,DC,61), V(69,4B,77,5A), V(16,1A,12,1C), \
266 V(0A,BA,93,E2), V(E5,2A,A0,C0), V(43,E0,22,3C), V(1D,17,1B,12), \
267 V(0B,0D,09,0E), V(AD,C7,8B,F2), V(B9,A8,B6,2D), V(C8,A9,1E,14), \
268 V(85,19,F1,57), V(4C,07,75,AF), V(BB,DD,99,EE), V(FD,60,7F,A3), \
269 V(9F,26,01,F7), V(BC,F5,72,5C), V(C5,3B,66,44), V(34,7E,FB,5B), \
270 V(76,29,43,8B), V(DC,C6,23,CB), V(68,FC,ED,B6), V(63,F1,E4,B8), \
271 V(CA,DC,31,D7), V(10,85,63,42), V(40,22,97,13), V(20,11,C6,84), \
272 V(7D,24,4A,85), V(F8,3D,BB,D2), V(11,32,F9,AE), V(6D,A1,29,C7), \
273 V(4B,2F,9E,1D), V(F3,30,B2,DC), V(EC,52,86,0D), V(D0,E3,C1,77), \
274 V(6C,16,B3,2B), V(99,B9,70,A9), V(FA,48,94,11), V(22,64,E9,47), \
275 V(C4,8C,FC,A8), V(1A,3F,F0,A0), V(D8,2C,7D,56), V(EF,90,33,22), \
276 V(C7,4E,49,87), V(C1,D1,38,D9), V(FE,A2,CA,8C), V(36,0B,D4,98), \
277 V(CF,81,F5,A6), V(28,DE,7A,A5), V(26,8E,B7,DA), V(A4,BF,AD,3F), \
278 V(E4,9D,3A,2C), V(0D,92,78,50), V(9B,CC,5F,6A), V(62,46,7E,54), \
279 V(C2,13,8D,F6), V(E8,B8,D8,90), V(5E,F7,39,2E), V(F5,AF,C3,82), \
280 V(BE,80,5D,9F), V(7C,93,D0,69), V(A9,2D,D5,6F), V(B3,12,25,CF), \
281 V(3B,99,AC,C8), V(A7,7D,18,10), V(6E,63,9C,E8), V(7B,BB,3B,DB), \
282 V(09,78,26,CD), V(F4,18,59,6E), V(01,B7,9A,EC), V(A8,9A,4F,83), \
283 V(65,6E,95,E6), V(7E,E6,FF,AA), V(08,CF,BC,21), V(E6,E8,15,EF), \
284 V(D9,9B,E7,BA), V(CE,36,6F,4A), V(D4,09,9F,EA), V(D6,7C,B0,29), \
285 V(AF,B2,A4,31), V(31,23,3F,2A), V(30,94,A5,C6), V(C0,66,A2,35), \
286 V(37,BC,4E,74), V(A6,CA,82,FC), V(B0,D0,90,E0), V(15,D8,A7,33), \
287 V(4A,98,04,F1), V(F7,DA,EC,41), V(0E,50,CD,7F), V(2F,F6,91,17), \
288 V(8D,D6,4D,76), V(4D,B0,EF,43), V(54,4D,AA,CC), V(DF,04,96,E4), \
289 V(E3,B5,D1,9E), V(1B,88,6A,4C), V(B8,1F,2C,C1), V(7F,51,65,46), \
290 V(04,EA,5E,9D), V(5D,35,8C,01), V(73,74,87,FA), V(2E,41,0B,FB), \
291 V(5A,1D,67,B3), V(52,D2,DB,92), V(33,56,10,E9), V(13,47,D6,6D), \
292 V(8C,61,D7,9A), V(7A,0C,A1,37), V(8E,14,F8,59), V(89,3C,13,EB), \
293 V(EE,27,A9,CE), V(35,C9,61,B7), V(ED,E5,1C,E1), V(3C,B1,47,7A), \
294 V(59,DF,D2,9C), V(3F,73,F2,55), V(79,CE,14,18), V(BF,37,C7,73), \
295 V(EA,CD,F7,53), V(5B,AA,FD,5F), V(14,6F,3D,DF), V(86,DB,44,78), \
296 V(81,F3,AF,CA), V(3E,C4,68,B9), V(2C,34,24,38), V(5F,40,A3,C2), \
297 V(72,C3,1D,16), V(0C,25,E2,BC), V(8B,49,3C,28), V(41,95,0D,FF), \
298 V(71,01,A8,39), V(DE,B3,0C,08), V(9C,E4,B4,D8), V(90,C1,56,64), \
299 V(61,84,CB,7B), V(70,B6,32,D5), V(74,5C,6C,48), V(42,57,B8,D0)
300
301#define V(a,b,c,d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000302static const uint32_t RT0[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000303#undef V
304
Hanno Beckerad049a92017-06-19 16:31:54 +0100305#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200306
Paul Bakker5121ce52009-01-03 21:22:43 +0000307#define V(a,b,c,d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000308static const uint32_t RT1[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000309#undef V
310
311#define V(a,b,c,d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000312static const uint32_t RT2[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000313#undef V
314
315#define V(a,b,c,d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000316static const uint32_t RT3[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000317#undef V
318
Hanno Becker177d3cf2017-06-07 15:52:48 +0100319#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200320
Paul Bakker5121ce52009-01-03 21:22:43 +0000321#undef RT
322
323/*
324 * Round constants
325 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000326static const uint32_t RCON[10] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000327{
328 0x00000001, 0x00000002, 0x00000004, 0x00000008,
329 0x00000010, 0x00000020, 0x00000040, 0x00000080,
330 0x0000001B, 0x00000036
331};
332
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200333#else /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000334
335/*
336 * Forward S-box & tables
337 */
338static unsigned char FSb[256];
Paul Bakker9af723c2014-05-01 13:03:14 +0200339static uint32_t FT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100340#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker9af723c2014-05-01 13:03:14 +0200341static uint32_t FT1[256];
342static uint32_t FT2[256];
343static uint32_t FT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100344#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000345
346/*
347 * Reverse S-box & tables
348 */
349static unsigned char RSb[256];
Paul Bakker5c2364c2012-10-01 14:41:15 +0000350static uint32_t RT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100351#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker5c2364c2012-10-01 14:41:15 +0000352static uint32_t RT1[256];
353static uint32_t RT2[256];
354static uint32_t RT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100355#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000356
357/*
358 * Round constants
359 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000360static uint32_t RCON[10];
Paul Bakker5121ce52009-01-03 21:22:43 +0000361
362/*
363 * Tables generation code
364 */
Hanno Becker1eeca412018-10-15 12:01:35 +0100365#define ROTL8(x) ( ( (x) << 8 ) & 0xFFFFFFFF ) | ( (x) >> 24 )
366#define XTIME(x) ( ( (x) << 1 ) ^ ( ( (x) & 0x80 ) ? 0x1B : 0x00 ) )
Hanno Becker818bac52018-10-26 09:13:26 +0100367#define MUL(x,y) ( ( (x) && (y) ) ? pow[(log[(x)]+log[(y)]) % 255] : 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000368
369static int aes_init_done = 0;
370
371static void aes_gen_tables( void )
372{
373 int i, x, y, z;
374 int pow[256];
375 int log[256];
376
377 /*
378 * compute pow and log tables over GF(2^8)
379 */
380 for( i = 0, x = 1; i < 256; i++ )
381 {
382 pow[i] = x;
383 log[x] = i;
Joe Subbianicd84d762021-07-08 14:59:52 +0100384 x = MBEDTLS_BYTE_0( x ^ XTIME( x ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000385 }
386
387 /*
388 * calculate the round constants
389 */
390 for( i = 0, x = 1; i < 10; i++ )
391 {
Paul Bakker5c2364c2012-10-01 14:41:15 +0000392 RCON[i] = (uint32_t) x;
Joe Subbianicd84d762021-07-08 14:59:52 +0100393 x = MBEDTLS_BYTE_0( XTIME( x ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000394 }
395
396 /*
397 * generate the forward and reverse S-boxes
398 */
399 FSb[0x00] = 0x63;
400 RSb[0x63] = 0x00;
401
402 for( i = 1; i < 256; i++ )
403 {
404 x = pow[255 - log[i]];
405
Joe Subbianicd84d762021-07-08 14:59:52 +0100406 y = x; y = MBEDTLS_BYTE_0( ( y << 1 ) | ( y >> 7 ) );
407 x ^= y; y = MBEDTLS_BYTE_0( ( y << 1 ) | ( y >> 7 ) );
408 x ^= y; y = MBEDTLS_BYTE_0( ( y << 1 ) | ( y >> 7 ) );
409 x ^= y; y = MBEDTLS_BYTE_0( ( y << 1 ) | ( y >> 7 ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000410 x ^= y ^ 0x63;
411
412 FSb[i] = (unsigned char) x;
413 RSb[x] = (unsigned char) i;
414 }
415
416 /*
417 * generate the forward and reverse tables
418 */
419 for( i = 0; i < 256; i++ )
420 {
421 x = FSb[i];
Joe Subbianicd84d762021-07-08 14:59:52 +0100422 y = MBEDTLS_BYTE_0( XTIME( x ) );
423 z = MBEDTLS_BYTE_0( y ^ x );
Paul Bakker5121ce52009-01-03 21:22:43 +0000424
Paul Bakker5c2364c2012-10-01 14:41:15 +0000425 FT0[i] = ( (uint32_t) y ) ^
426 ( (uint32_t) x << 8 ) ^
427 ( (uint32_t) x << 16 ) ^
428 ( (uint32_t) z << 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000429
Hanno Beckerad049a92017-06-19 16:31:54 +0100430#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +0000431 FT1[i] = ROTL8( FT0[i] );
432 FT2[i] = ROTL8( FT1[i] );
433 FT3[i] = ROTL8( FT2[i] );
Hanno Becker177d3cf2017-06-07 15:52:48 +0100434#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000435
436 x = RSb[i];
437
Paul Bakker5c2364c2012-10-01 14:41:15 +0000438 RT0[i] = ( (uint32_t) MUL( 0x0E, x ) ) ^
439 ( (uint32_t) MUL( 0x09, x ) << 8 ) ^
440 ( (uint32_t) MUL( 0x0D, x ) << 16 ) ^
441 ( (uint32_t) MUL( 0x0B, x ) << 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000442
Hanno Beckerad049a92017-06-19 16:31:54 +0100443#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +0000444 RT1[i] = ROTL8( RT0[i] );
445 RT2[i] = ROTL8( RT1[i] );
446 RT3[i] = ROTL8( RT2[i] );
Hanno Becker177d3cf2017-06-07 15:52:48 +0100447#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000448 }
449}
450
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200451#undef ROTL8
452
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200453#endif /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000454
Hanno Beckerad049a92017-06-19 16:31:54 +0100455#if defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200456
457#define ROTL8(x) ( (uint32_t)( ( x ) << 8 ) + (uint32_t)( ( x ) >> 24 ) )
458#define ROTL16(x) ( (uint32_t)( ( x ) << 16 ) + (uint32_t)( ( x ) >> 16 ) )
459#define ROTL24(x) ( (uint32_t)( ( x ) << 24 ) + (uint32_t)( ( x ) >> 8 ) )
460
461#define AES_RT0(idx) RT0[idx]
462#define AES_RT1(idx) ROTL8( RT0[idx] )
463#define AES_RT2(idx) ROTL16( RT0[idx] )
464#define AES_RT3(idx) ROTL24( RT0[idx] )
465
466#define AES_FT0(idx) FT0[idx]
467#define AES_FT1(idx) ROTL8( FT0[idx] )
468#define AES_FT2(idx) ROTL16( FT0[idx] )
469#define AES_FT3(idx) ROTL24( FT0[idx] )
470
Hanno Becker177d3cf2017-06-07 15:52:48 +0100471#else /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200472
473#define AES_RT0(idx) RT0[idx]
474#define AES_RT1(idx) RT1[idx]
475#define AES_RT2(idx) RT2[idx]
476#define AES_RT3(idx) RT3[idx]
477
478#define AES_FT0(idx) FT0[idx]
479#define AES_FT1(idx) FT1[idx]
480#define AES_FT2(idx) FT2[idx]
481#define AES_FT3(idx) FT3[idx]
482
Hanno Becker177d3cf2017-06-07 15:52:48 +0100483#endif /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200484
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200485void mbedtls_aes_init( mbedtls_aes_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200486{
Manuel Pégourié-Gonnard0e9cddb2018-12-10 16:37:51 +0100487 AES_VALIDATE( ctx != NULL );
Simon Butcher5201e412018-12-06 17:40:14 +0000488
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200489 memset( ctx, 0, sizeof( mbedtls_aes_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200490}
491
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200492void mbedtls_aes_free( mbedtls_aes_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200493{
494 if( ctx == NULL )
495 return;
496
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500497 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_aes_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200498}
499
Jaeden Amero9366feb2018-05-29 18:55:17 +0100500#if defined(MBEDTLS_CIPHER_MODE_XTS)
501void mbedtls_aes_xts_init( mbedtls_aes_xts_context *ctx )
502{
Manuel Pégourié-Gonnard0e9cddb2018-12-10 16:37:51 +0100503 AES_VALIDATE( ctx != NULL );
Simon Butcher5201e412018-12-06 17:40:14 +0000504
Jaeden Amero9366feb2018-05-29 18:55:17 +0100505 mbedtls_aes_init( &ctx->crypt );
506 mbedtls_aes_init( &ctx->tweak );
507}
508
509void mbedtls_aes_xts_free( mbedtls_aes_xts_context *ctx )
510{
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100511 if( ctx == NULL )
512 return;
Simon Butcher5201e412018-12-06 17:40:14 +0000513
Jaeden Amero9366feb2018-05-29 18:55:17 +0100514 mbedtls_aes_free( &ctx->crypt );
515 mbedtls_aes_free( &ctx->tweak );
516}
517#endif /* MBEDTLS_CIPHER_MODE_XTS */
518
Paul Bakker5121ce52009-01-03 21:22:43 +0000519/*
520 * AES key schedule (encryption)
521 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200522#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200523int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key,
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200524 unsigned int keybits )
Paul Bakker5121ce52009-01-03 21:22:43 +0000525{
Paul Bakker23986e52011-04-24 08:57:21 +0000526 unsigned int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000527 uint32_t *RK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000528
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100529 AES_VALIDATE_RET( ctx != NULL );
530 AES_VALIDATE_RET( key != NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000531
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200532 switch( keybits )
Paul Bakker5121ce52009-01-03 21:22:43 +0000533 {
534 case 128: ctx->nr = 10; break;
535 case 192: ctx->nr = 12; break;
536 case 256: ctx->nr = 14; break;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200537 default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000538 }
539
Simon Butcher5201e412018-12-06 17:40:14 +0000540#if !defined(MBEDTLS_AES_ROM_TABLES)
541 if( aes_init_done == 0 )
542 {
543 aes_gen_tables();
544 aes_init_done = 1;
Simon Butcher5201e412018-12-06 17:40:14 +0000545 }
546#endif
547
Werner Lewis7656a372022-06-13 12:28:20 +0100548 ctx->rk_offset = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200549#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_PADLOCK_ALIGN16)
Paul Bakker048d04e2012-02-12 17:31:04 +0000550 if( aes_padlock_ace == -1 )
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100551 aes_padlock_ace = mbedtls_padlock_has_support( MBEDTLS_PADLOCK_ACE );
Paul Bakker048d04e2012-02-12 17:31:04 +0000552
553 if( aes_padlock_ace )
Werner Lewisdd76ef32022-05-30 12:00:21 +0100554 ctx->rk_offset = MBEDTLS_PADLOCK_ALIGN16( ctx->buf ) - ctx->buf;
Paul Bakker5121ce52009-01-03 21:22:43 +0000555#endif
Werner Lewisdd76ef32022-05-30 12:00:21 +0100556 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000557
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200558#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100559 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) )
Werner Lewisdd76ef32022-05-30 12:00:21 +0100560 return( mbedtls_aesni_setkey_enc( (unsigned char *) RK, key, keybits ) );
Manuel Pégourié-Gonnard47a35362013-12-28 20:45:04 +0100561#endif
562
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200563 for( i = 0; i < ( keybits >> 5 ); i++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000564 {
Joe Subbiani6a506312021-07-07 16:56:29 +0100565 RK[i] = MBEDTLS_GET_UINT32_LE( key, i << 2 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000566 }
567
568 switch( ctx->nr )
569 {
570 case 10:
571
572 for( i = 0; i < 10; i++, RK += 4 )
573 {
574 RK[4] = RK[0] ^ RCON[i] ^
Joe Subbianicd84d762021-07-08 14:59:52 +0100575 ( (uint32_t) FSb[ MBEDTLS_BYTE_1( RK[3] ) ] ) ^
576 ( (uint32_t) FSb[ MBEDTLS_BYTE_2( RK[3] ) ] << 8 ) ^
577 ( (uint32_t) FSb[ MBEDTLS_BYTE_3( RK[3] ) ] << 16 ) ^
578 ( (uint32_t) FSb[ MBEDTLS_BYTE_0( RK[3] ) ] << 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000579
580 RK[5] = RK[1] ^ RK[4];
581 RK[6] = RK[2] ^ RK[5];
582 RK[7] = RK[3] ^ RK[6];
583 }
584 break;
585
586 case 12:
587
588 for( i = 0; i < 8; i++, RK += 6 )
589 {
590 RK[6] = RK[0] ^ RCON[i] ^
Joe Subbianicd84d762021-07-08 14:59:52 +0100591 ( (uint32_t) FSb[ MBEDTLS_BYTE_1( RK[5] ) ] ) ^
592 ( (uint32_t) FSb[ MBEDTLS_BYTE_2( RK[5] ) ] << 8 ) ^
593 ( (uint32_t) FSb[ MBEDTLS_BYTE_3( RK[5] ) ] << 16 ) ^
594 ( (uint32_t) FSb[ MBEDTLS_BYTE_0( RK[5] ) ] << 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000595
596 RK[7] = RK[1] ^ RK[6];
597 RK[8] = RK[2] ^ RK[7];
598 RK[9] = RK[3] ^ RK[8];
599 RK[10] = RK[4] ^ RK[9];
600 RK[11] = RK[5] ^ RK[10];
601 }
602 break;
603
604 case 14:
605
606 for( i = 0; i < 7; i++, RK += 8 )
607 {
608 RK[8] = RK[0] ^ RCON[i] ^
Joe Subbianicd84d762021-07-08 14:59:52 +0100609 ( (uint32_t) FSb[ MBEDTLS_BYTE_1( RK[7] ) ] ) ^
610 ( (uint32_t) FSb[ MBEDTLS_BYTE_2( RK[7] ) ] << 8 ) ^
611 ( (uint32_t) FSb[ MBEDTLS_BYTE_3( RK[7] ) ] << 16 ) ^
612 ( (uint32_t) FSb[ MBEDTLS_BYTE_0( RK[7] ) ] << 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000613
614 RK[9] = RK[1] ^ RK[8];
615 RK[10] = RK[2] ^ RK[9];
616 RK[11] = RK[3] ^ RK[10];
617
618 RK[12] = RK[4] ^
Joe Subbianicd84d762021-07-08 14:59:52 +0100619 ( (uint32_t) FSb[ MBEDTLS_BYTE_0( RK[11] ) ] ) ^
620 ( (uint32_t) FSb[ MBEDTLS_BYTE_1( RK[11] ) ] << 8 ) ^
621 ( (uint32_t) FSb[ MBEDTLS_BYTE_2( RK[11] ) ] << 16 ) ^
622 ( (uint32_t) FSb[ MBEDTLS_BYTE_3( RK[11] ) ] << 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000623
624 RK[13] = RK[5] ^ RK[12];
625 RK[14] = RK[6] ^ RK[13];
626 RK[15] = RK[7] ^ RK[14];
627 }
628 break;
Paul Bakker5121ce52009-01-03 21:22:43 +0000629 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000630
631 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000632}
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200633#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000634
635/*
636 * AES key schedule (decryption)
637 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200638#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200639int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key,
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200640 unsigned int keybits )
Paul Bakker5121ce52009-01-03 21:22:43 +0000641{
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200642 int i, j, ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200643 mbedtls_aes_context cty;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000644 uint32_t *RK;
645 uint32_t *SK;
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200646
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100647 AES_VALIDATE_RET( ctx != NULL );
648 AES_VALIDATE_RET( key != NULL );
Simon Butcher5201e412018-12-06 17:40:14 +0000649
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200650 mbedtls_aes_init( &cty );
Paul Bakker5121ce52009-01-03 21:22:43 +0000651
Werner Lewis7656a372022-06-13 12:28:20 +0100652 ctx->rk_offset = 0;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200653#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_PADLOCK_ALIGN16)
Paul Bakker048d04e2012-02-12 17:31:04 +0000654 if( aes_padlock_ace == -1 )
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100655 aes_padlock_ace = mbedtls_padlock_has_support( MBEDTLS_PADLOCK_ACE );
Paul Bakker048d04e2012-02-12 17:31:04 +0000656
657 if( aes_padlock_ace )
Werner Lewisdd76ef32022-05-30 12:00:21 +0100658 ctx->rk_offset = MBEDTLS_PADLOCK_ALIGN16( ctx->buf ) - ctx->buf;
Paul Bakker5121ce52009-01-03 21:22:43 +0000659#endif
Werner Lewisdd76ef32022-05-30 12:00:21 +0100660 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000661
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200662 /* Also checks keybits */
663 if( ( ret = mbedtls_aes_setkey_enc( &cty, key, keybits ) ) != 0 )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200664 goto exit;
Paul Bakker2b222c82009-07-27 21:03:45 +0000665
Manuel Pégourié-Gonnardafd5a082014-05-28 21:52:59 +0200666 ctx->nr = cty.nr;
667
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200668#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100669 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) )
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100670 {
Werner Lewisdd76ef32022-05-30 12:00:21 +0100671 mbedtls_aesni_inverse_key( (unsigned char *) RK,
672 (const unsigned char *) ( cty.buf + cty.rk_offset ), ctx->nr );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200673 goto exit;
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100674 }
675#endif
676
Werner Lewisdd76ef32022-05-30 12:00:21 +0100677 SK = cty.buf + cty.rk_offset + cty.nr * 4;
Paul Bakker5121ce52009-01-03 21:22:43 +0000678
679 *RK++ = *SK++;
680 *RK++ = *SK++;
681 *RK++ = *SK++;
682 *RK++ = *SK++;
683
684 for( i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8 )
685 {
686 for( j = 0; j < 4; j++, SK++ )
687 {
Joe Subbianicd84d762021-07-08 14:59:52 +0100688 *RK++ = AES_RT0( FSb[ MBEDTLS_BYTE_0( *SK ) ] ) ^
689 AES_RT1( FSb[ MBEDTLS_BYTE_1( *SK ) ] ) ^
690 AES_RT2( FSb[ MBEDTLS_BYTE_2( *SK ) ] ) ^
691 AES_RT3( FSb[ MBEDTLS_BYTE_3( *SK ) ] );
Paul Bakker5121ce52009-01-03 21:22:43 +0000692 }
693 }
694
695 *RK++ = *SK++;
696 *RK++ = *SK++;
697 *RK++ = *SK++;
698 *RK++ = *SK++;
699
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200700exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200701 mbedtls_aes_free( &cty );
Paul Bakker2b222c82009-07-27 21:03:45 +0000702
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200703 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000704}
gabor-mezei-arm95db3012020-10-26 11:35:23 +0100705#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */
Jaeden Amero9366feb2018-05-29 18:55:17 +0100706
707#if defined(MBEDTLS_CIPHER_MODE_XTS)
708static int mbedtls_aes_xts_decode_keys( const unsigned char *key,
709 unsigned int keybits,
710 const unsigned char **key1,
711 unsigned int *key1bits,
712 const unsigned char **key2,
713 unsigned int *key2bits )
714{
715 const unsigned int half_keybits = keybits / 2;
716 const unsigned int half_keybytes = half_keybits / 8;
717
718 switch( keybits )
719 {
720 case 256: break;
721 case 512: break;
722 default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH );
723 }
724
725 *key1bits = half_keybits;
726 *key2bits = half_keybits;
727 *key1 = &key[0];
728 *key2 = &key[half_keybytes];
729
730 return 0;
731}
732
733int mbedtls_aes_xts_setkey_enc( mbedtls_aes_xts_context *ctx,
734 const unsigned char *key,
735 unsigned int keybits)
736{
Janos Follath24eed8d2019-11-22 13:21:35 +0000737 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100738 const unsigned char *key1, *key2;
739 unsigned int key1bits, key2bits;
740
Manuel Pégourié-Gonnard68e3dff2018-12-12 12:48:04 +0100741 AES_VALIDATE_RET( ctx != NULL );
742 AES_VALIDATE_RET( key != NULL );
743
Jaeden Amero9366feb2018-05-29 18:55:17 +0100744 ret = mbedtls_aes_xts_decode_keys( key, keybits, &key1, &key1bits,
745 &key2, &key2bits );
746 if( ret != 0 )
747 return( ret );
748
749 /* Set the tweak key. Always set tweak key for the encryption mode. */
750 ret = mbedtls_aes_setkey_enc( &ctx->tweak, key2, key2bits );
751 if( ret != 0 )
752 return( ret );
753
754 /* Set crypt key for encryption. */
755 return mbedtls_aes_setkey_enc( &ctx->crypt, key1, key1bits );
756}
757
758int mbedtls_aes_xts_setkey_dec( mbedtls_aes_xts_context *ctx,
759 const unsigned char *key,
760 unsigned int keybits)
761{
Janos Follath24eed8d2019-11-22 13:21:35 +0000762 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100763 const unsigned char *key1, *key2;
764 unsigned int key1bits, key2bits;
765
Manuel Pégourié-Gonnard68e3dff2018-12-12 12:48:04 +0100766 AES_VALIDATE_RET( ctx != NULL );
767 AES_VALIDATE_RET( key != NULL );
768
Jaeden Amero9366feb2018-05-29 18:55:17 +0100769 ret = mbedtls_aes_xts_decode_keys( key, keybits, &key1, &key1bits,
770 &key2, &key2bits );
771 if( ret != 0 )
772 return( ret );
773
774 /* Set the tweak key. Always set tweak key for encryption. */
775 ret = mbedtls_aes_setkey_enc( &ctx->tweak, key2, key2bits );
776 if( ret != 0 )
777 return( ret );
778
779 /* Set crypt key for decryption. */
780 return mbedtls_aes_setkey_dec( &ctx->crypt, key1, key1bits );
781}
782#endif /* MBEDTLS_CIPHER_MODE_XTS */
783
Joe Subbianicd84d762021-07-08 14:59:52 +0100784#define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \
785 do \
786 { \
787 (X0) = *RK++ ^ AES_FT0( MBEDTLS_BYTE_0( Y0 ) ) ^ \
788 AES_FT1( MBEDTLS_BYTE_1( Y1 ) ) ^ \
789 AES_FT2( MBEDTLS_BYTE_2( Y2 ) ) ^ \
790 AES_FT3( MBEDTLS_BYTE_3( Y3 ) ); \
791 \
792 (X1) = *RK++ ^ AES_FT0( MBEDTLS_BYTE_0( Y1 ) ) ^ \
793 AES_FT1( MBEDTLS_BYTE_1( Y2 ) ) ^ \
794 AES_FT2( MBEDTLS_BYTE_2( Y3 ) ) ^ \
795 AES_FT3( MBEDTLS_BYTE_3( Y0 ) ); \
796 \
797 (X2) = *RK++ ^ AES_FT0( MBEDTLS_BYTE_0( Y2 ) ) ^ \
798 AES_FT1( MBEDTLS_BYTE_1( Y3 ) ) ^ \
799 AES_FT2( MBEDTLS_BYTE_2( Y0 ) ) ^ \
800 AES_FT3( MBEDTLS_BYTE_3( Y1 ) ); \
801 \
802 (X3) = *RK++ ^ AES_FT0( MBEDTLS_BYTE_0( Y3 ) ) ^ \
803 AES_FT1( MBEDTLS_BYTE_1( Y0 ) ) ^ \
804 AES_FT2( MBEDTLS_BYTE_2( Y1 ) ) ^ \
805 AES_FT3( MBEDTLS_BYTE_3( Y2 ) ); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100806 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000807
Hanno Becker1eeca412018-10-15 12:01:35 +0100808#define AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \
809 do \
810 { \
Joe Subbianicd84d762021-07-08 14:59:52 +0100811 (X0) = *RK++ ^ AES_RT0( MBEDTLS_BYTE_0( Y0 ) ) ^ \
812 AES_RT1( MBEDTLS_BYTE_1( Y3 ) ) ^ \
813 AES_RT2( MBEDTLS_BYTE_2( Y2 ) ) ^ \
814 AES_RT3( MBEDTLS_BYTE_3( Y1 ) ); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100815 \
Joe Subbianicd84d762021-07-08 14:59:52 +0100816 (X1) = *RK++ ^ AES_RT0( MBEDTLS_BYTE_0( Y1 ) ) ^ \
817 AES_RT1( MBEDTLS_BYTE_1( Y0 ) ) ^ \
818 AES_RT2( MBEDTLS_BYTE_2( Y3 ) ) ^ \
819 AES_RT3( MBEDTLS_BYTE_3( Y2 ) ); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100820 \
Joe Subbianicd84d762021-07-08 14:59:52 +0100821 (X2) = *RK++ ^ AES_RT0( MBEDTLS_BYTE_0( Y2 ) ) ^ \
822 AES_RT1( MBEDTLS_BYTE_1( Y1 ) ) ^ \
823 AES_RT2( MBEDTLS_BYTE_2( Y0 ) ) ^ \
824 AES_RT3( MBEDTLS_BYTE_3( Y3 ) ); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100825 \
Joe Subbianicd84d762021-07-08 14:59:52 +0100826 (X3) = *RK++ ^ AES_RT0( MBEDTLS_BYTE_0( Y3 ) ) ^ \
827 AES_RT1( MBEDTLS_BYTE_1( Y2 ) ) ^ \
828 AES_RT2( MBEDTLS_BYTE_2( Y1 ) ) ^ \
829 AES_RT3( MBEDTLS_BYTE_3( Y0 ) ); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100830 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000831
832/*
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200833 * AES-ECB block encryption
834 */
835#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Andres AGf5bf7182017-03-03 14:09:56 +0000836int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx,
837 const unsigned char input[16],
838 unsigned char output[16] )
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200839{
840 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100841 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine5197c662020-08-26 17:03:24 +0200842 struct
843 {
844 uint32_t X[4];
845 uint32_t Y[4];
846 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200847
Joe Subbiani6a506312021-07-07 16:56:29 +0100848 t.X[0] = MBEDTLS_GET_UINT32_LE( input, 0 ); t.X[0] ^= *RK++;
849 t.X[1] = MBEDTLS_GET_UINT32_LE( input, 4 ); t.X[1] ^= *RK++;
850 t.X[2] = MBEDTLS_GET_UINT32_LE( input, 8 ); t.X[2] ^= *RK++;
851 t.X[3] = MBEDTLS_GET_UINT32_LE( input, 12 ); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200852
853 for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- )
854 {
Gilles Peskine5197c662020-08-26 17:03:24 +0200855 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] );
856 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 +0200857 }
858
Gilles Peskine5197c662020-08-26 17:03:24 +0200859 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 +0200860
Gilles Peskine5197c662020-08-26 17:03:24 +0200861 t.X[0] = *RK++ ^ \
Joe Subbianicd84d762021-07-08 14:59:52 +0100862 ( (uint32_t) FSb[ MBEDTLS_BYTE_0( t.Y[0] ) ] ) ^
863 ( (uint32_t) FSb[ MBEDTLS_BYTE_1( t.Y[1] ) ] << 8 ) ^
864 ( (uint32_t) FSb[ MBEDTLS_BYTE_2( t.Y[2] ) ] << 16 ) ^
865 ( (uint32_t) FSb[ MBEDTLS_BYTE_3( t.Y[3] ) ] << 24 );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200866
Gilles Peskine5197c662020-08-26 17:03:24 +0200867 t.X[1] = *RK++ ^ \
Joe Subbianicd84d762021-07-08 14:59:52 +0100868 ( (uint32_t) FSb[ MBEDTLS_BYTE_0( t.Y[1] ) ] ) ^
869 ( (uint32_t) FSb[ MBEDTLS_BYTE_1( t.Y[2] ) ] << 8 ) ^
870 ( (uint32_t) FSb[ MBEDTLS_BYTE_2( t.Y[3] ) ] << 16 ) ^
871 ( (uint32_t) FSb[ MBEDTLS_BYTE_3( t.Y[0] ) ] << 24 );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200872
Gilles Peskine5197c662020-08-26 17:03:24 +0200873 t.X[2] = *RK++ ^ \
Joe Subbianicd84d762021-07-08 14:59:52 +0100874 ( (uint32_t) FSb[ MBEDTLS_BYTE_0( t.Y[2] ) ] ) ^
875 ( (uint32_t) FSb[ MBEDTLS_BYTE_1( t.Y[3] ) ] << 8 ) ^
876 ( (uint32_t) FSb[ MBEDTLS_BYTE_2( t.Y[0] ) ] << 16 ) ^
877 ( (uint32_t) FSb[ MBEDTLS_BYTE_3( t.Y[1] ) ] << 24 );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200878
Gilles Peskine5197c662020-08-26 17:03:24 +0200879 t.X[3] = *RK++ ^ \
Joe Subbianicd84d762021-07-08 14:59:52 +0100880 ( (uint32_t) FSb[ MBEDTLS_BYTE_0( t.Y[3] ) ] ) ^
881 ( (uint32_t) FSb[ MBEDTLS_BYTE_1( t.Y[0] ) ] << 8 ) ^
882 ( (uint32_t) FSb[ MBEDTLS_BYTE_2( t.Y[1] ) ] << 16 ) ^
883 ( (uint32_t) FSb[ MBEDTLS_BYTE_3( t.Y[2] ) ] << 24 );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200884
Joe Subbiani5ecac212021-06-24 13:00:03 +0100885 MBEDTLS_PUT_UINT32_LE( t.X[0], output, 0 );
886 MBEDTLS_PUT_UINT32_LE( t.X[1], output, 4 );
887 MBEDTLS_PUT_UINT32_LE( t.X[2], output, 8 );
888 MBEDTLS_PUT_UINT32_LE( t.X[3], output, 12 );
Andres AGf5bf7182017-03-03 14:09:56 +0000889
Gilles Peskine5197c662020-08-26 17:03:24 +0200890 mbedtls_platform_zeroize( &t, sizeof( t ) );
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500891
Andres AGf5bf7182017-03-03 14:09:56 +0000892 return( 0 );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200893}
894#endif /* !MBEDTLS_AES_ENCRYPT_ALT */
895
896/*
897 * AES-ECB block decryption
898 */
899#if !defined(MBEDTLS_AES_DECRYPT_ALT)
Andres AGf5bf7182017-03-03 14:09:56 +0000900int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx,
901 const unsigned char input[16],
902 unsigned char output[16] )
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200903{
904 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100905 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine5197c662020-08-26 17:03:24 +0200906 struct
907 {
908 uint32_t X[4];
909 uint32_t Y[4];
910 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200911
Joe Subbiani6a506312021-07-07 16:56:29 +0100912 t.X[0] = MBEDTLS_GET_UINT32_LE( input, 0 ); t.X[0] ^= *RK++;
913 t.X[1] = MBEDTLS_GET_UINT32_LE( input, 4 ); t.X[1] ^= *RK++;
914 t.X[2] = MBEDTLS_GET_UINT32_LE( input, 8 ); t.X[2] ^= *RK++;
915 t.X[3] = MBEDTLS_GET_UINT32_LE( input, 12 ); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200916
917 for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- )
918 {
Gilles Peskine5197c662020-08-26 17:03:24 +0200919 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] );
920 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 +0200921 }
922
Gilles Peskine5197c662020-08-26 17:03:24 +0200923 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 +0200924
Gilles Peskine5197c662020-08-26 17:03:24 +0200925 t.X[0] = *RK++ ^ \
Joe Subbianicd84d762021-07-08 14:59:52 +0100926 ( (uint32_t) RSb[ MBEDTLS_BYTE_0( t.Y[0] ) ] ) ^
927 ( (uint32_t) RSb[ MBEDTLS_BYTE_1( t.Y[3] ) ] << 8 ) ^
928 ( (uint32_t) RSb[ MBEDTLS_BYTE_2( t.Y[2] ) ] << 16 ) ^
929 ( (uint32_t) RSb[ MBEDTLS_BYTE_3( t.Y[1] ) ] << 24 );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200930
Gilles Peskine5197c662020-08-26 17:03:24 +0200931 t.X[1] = *RK++ ^ \
Joe Subbianicd84d762021-07-08 14:59:52 +0100932 ( (uint32_t) RSb[ MBEDTLS_BYTE_0( t.Y[1] ) ] ) ^
933 ( (uint32_t) RSb[ MBEDTLS_BYTE_1( t.Y[0] ) ] << 8 ) ^
934 ( (uint32_t) RSb[ MBEDTLS_BYTE_2( t.Y[3] ) ] << 16 ) ^
935 ( (uint32_t) RSb[ MBEDTLS_BYTE_3( t.Y[2] ) ] << 24 );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200936
Gilles Peskine5197c662020-08-26 17:03:24 +0200937 t.X[2] = *RK++ ^ \
Joe Subbianicd84d762021-07-08 14:59:52 +0100938 ( (uint32_t) RSb[ MBEDTLS_BYTE_0( t.Y[2] ) ] ) ^
939 ( (uint32_t) RSb[ MBEDTLS_BYTE_1( t.Y[1] ) ] << 8 ) ^
940 ( (uint32_t) RSb[ MBEDTLS_BYTE_2( t.Y[0] ) ] << 16 ) ^
941 ( (uint32_t) RSb[ MBEDTLS_BYTE_3( t.Y[3] ) ] << 24 );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200942
Gilles Peskine5197c662020-08-26 17:03:24 +0200943 t.X[3] = *RK++ ^ \
Joe Subbianicd84d762021-07-08 14:59:52 +0100944 ( (uint32_t) RSb[ MBEDTLS_BYTE_0( t.Y[3] ) ] ) ^
945 ( (uint32_t) RSb[ MBEDTLS_BYTE_1( t.Y[2] ) ] << 8 ) ^
946 ( (uint32_t) RSb[ MBEDTLS_BYTE_2( t.Y[1] ) ] << 16 ) ^
947 ( (uint32_t) RSb[ MBEDTLS_BYTE_3( t.Y[0] ) ] << 24 );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200948
Joe Subbiani5ecac212021-06-24 13:00:03 +0100949 MBEDTLS_PUT_UINT32_LE( t.X[0], output, 0 );
950 MBEDTLS_PUT_UINT32_LE( t.X[1], output, 4 );
951 MBEDTLS_PUT_UINT32_LE( t.X[2], output, 8 );
952 MBEDTLS_PUT_UINT32_LE( t.X[3], output, 12 );
Andres AGf5bf7182017-03-03 14:09:56 +0000953
Gilles Peskine5197c662020-08-26 17:03:24 +0200954 mbedtls_platform_zeroize( &t, sizeof( t ) );
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500955
Andres AGf5bf7182017-03-03 14:09:56 +0000956 return( 0 );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200957}
958#endif /* !MBEDTLS_AES_DECRYPT_ALT */
959
960/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000961 * AES-ECB block encryption/decryption
962 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200963int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx,
Manuel Pégourié-Gonnardeb6d3962018-12-18 09:59:35 +0100964 int mode,
965 const unsigned char input[16],
966 unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000967{
Manuel Pégourié-Gonnard1aca2602018-12-12 12:56:55 +0100968 AES_VALIDATE_RET( ctx != NULL );
969 AES_VALIDATE_RET( input != NULL );
970 AES_VALIDATE_RET( output != NULL );
971 AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
972 mode == MBEDTLS_AES_DECRYPT );
973
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200974#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100975 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200976 return( mbedtls_aesni_crypt_ecb( ctx, mode, input, output ) );
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +0100977#endif
978
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200979#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Xiang Xiao12e18362021-05-07 00:55:52 -0700980 if( aes_padlock_ace > 0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000981 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200982 if( mbedtls_padlock_xcryptecb( ctx, mode, input, output ) == 0 )
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000983 return( 0 );
984
985 // If padlock data misaligned, we just fall back to
986 // unaccelerated mode
987 //
Paul Bakker5121ce52009-01-03 21:22:43 +0000988 }
989#endif
990
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200991 if( mode == MBEDTLS_AES_ENCRYPT )
Andres AGf5bf7182017-03-03 14:09:56 +0000992 return( mbedtls_internal_aes_encrypt( ctx, input, output ) );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200993 else
Andres AGf5bf7182017-03-03 14:09:56 +0000994 return( mbedtls_internal_aes_decrypt( ctx, input, output ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000995}
996
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200997#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +0000998/*
999 * AES-CBC buffer encryption/decryption
1000 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001001int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx,
Paul Bakker5121ce52009-01-03 21:22:43 +00001002 int mode,
Paul Bakker23986e52011-04-24 08:57:21 +00001003 size_t length,
Paul Bakker5121ce52009-01-03 21:22:43 +00001004 unsigned char iv[16],
Paul Bakkerff60ee62010-03-16 21:09:09 +00001005 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +00001006 unsigned char *output )
1007{
1008 int i;
Gilles Peskine7820a572021-07-07 21:08:28 +02001009 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +00001010 unsigned char temp[16];
1011
Manuel Pégourié-Gonnard3178d1a2018-12-12 13:05:00 +01001012 AES_VALIDATE_RET( ctx != NULL );
1013 AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
1014 mode == MBEDTLS_AES_DECRYPT );
1015 AES_VALIDATE_RET( iv != NULL );
1016 AES_VALIDATE_RET( input != NULL );
1017 AES_VALIDATE_RET( output != NULL );
1018
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001019 if( length % 16 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001020 return( MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH );
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001021
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001022#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Xiang Xiao12e18362021-05-07 00:55:52 -07001023 if( aes_padlock_ace > 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001024 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001025 if( mbedtls_padlock_xcryptcbc( ctx, mode, length, iv, input, output ) == 0 )
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001026 return( 0 );
Paul Bakker9af723c2014-05-01 13:03:14 +02001027
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001028 // If padlock data misaligned, we just fall back to
1029 // unaccelerated mode
1030 //
Paul Bakker5121ce52009-01-03 21:22:43 +00001031 }
1032#endif
1033
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001034 if( mode == MBEDTLS_AES_DECRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +00001035 {
1036 while( length > 0 )
1037 {
1038 memcpy( temp, input, 16 );
Gilles Peskine7820a572021-07-07 21:08:28 +02001039 ret = mbedtls_aes_crypt_ecb( ctx, mode, input, output );
1040 if( ret != 0 )
1041 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001042
1043 for( i = 0; i < 16; i++ )
1044 output[i] = (unsigned char)( output[i] ^ iv[i] );
1045
1046 memcpy( iv, temp, 16 );
1047
1048 input += 16;
1049 output += 16;
1050 length -= 16;
1051 }
1052 }
1053 else
1054 {
1055 while( length > 0 )
1056 {
1057 for( i = 0; i < 16; i++ )
1058 output[i] = (unsigned char)( input[i] ^ iv[i] );
1059
Gilles Peskine7820a572021-07-07 21:08:28 +02001060 ret = mbedtls_aes_crypt_ecb( ctx, mode, output, output );
1061 if( ret != 0 )
1062 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001063 memcpy( iv, output, 16 );
1064
1065 input += 16;
1066 output += 16;
1067 length -= 16;
1068 }
1069 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001070 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001071
Gilles Peskine7820a572021-07-07 21:08:28 +02001072exit:
1073 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001074}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001075#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001076
Aorimn5f778012016-06-09 23:22:58 +02001077#if defined(MBEDTLS_CIPHER_MODE_XTS)
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001078
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001079typedef unsigned char mbedtls_be128[16];
1080
1081/*
1082 * GF(2^128) multiplication function
1083 *
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001084 * This function multiplies a field element by x in the polynomial field
1085 * representation. It uses 64-bit word operations to gain speed but compensates
Shaun Case8b0ecbc2021-12-20 21:14:10 -08001086 * for machine endianness and hence works correctly on both big and little
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001087 * endian machines.
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001088 */
1089static void mbedtls_gf128mul_x_ble( unsigned char r[16],
Jaeden Amero8cfc75f2018-05-31 16:53:08 +01001090 const unsigned char x[16] )
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001091{
1092 uint64_t a, b, ra, rb;
1093
Joe Subbiani99edd6c2021-07-16 12:29:49 +01001094 a = MBEDTLS_GET_UINT64_LE( x, 0 );
1095 b = MBEDTLS_GET_UINT64_LE( x, 8 );
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001096
Jaeden Amero8cfc75f2018-05-31 16:53:08 +01001097 ra = ( a << 1 ) ^ 0x0087 >> ( 8 - ( ( b >> 63 ) << 3 ) );
1098 rb = ( a >> 63 ) | ( b << 1 );
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001099
Joe Subbiani99edd6c2021-07-16 12:29:49 +01001100 MBEDTLS_PUT_UINT64_LE( ra, r, 0 );
1101 MBEDTLS_PUT_UINT64_LE( rb, r, 8 );
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001102}
1103
Aorimn5f778012016-06-09 23:22:58 +02001104/*
1105 * AES-XTS buffer encryption/decryption
1106 */
Jaeden Amero9366feb2018-05-29 18:55:17 +01001107int mbedtls_aes_crypt_xts( mbedtls_aes_xts_context *ctx,
1108 int mode,
Jaeden Amero5162b932018-05-29 12:55:24 +01001109 size_t length,
Jaeden Amerocd9fc5e2018-05-30 15:23:24 +01001110 const unsigned char data_unit[16],
Jaeden Amero9366feb2018-05-29 18:55:17 +01001111 const unsigned char *input,
1112 unsigned char *output )
Aorimn5f778012016-06-09 23:22:58 +02001113{
Janos Follath24eed8d2019-11-22 13:21:35 +00001114 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amerod82cd862018-04-28 15:02:45 +01001115 size_t blocks = length / 16;
1116 size_t leftover = length % 16;
1117 unsigned char tweak[16];
1118 unsigned char prev_tweak[16];
1119 unsigned char tmp[16];
Aorimn5f778012016-06-09 23:22:58 +02001120
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01001121 AES_VALIDATE_RET( ctx != NULL );
1122 AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
1123 mode == MBEDTLS_AES_DECRYPT );
Manuel Pégourié-Gonnard998a3582018-12-18 10:03:13 +01001124 AES_VALIDATE_RET( data_unit != NULL );
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01001125 AES_VALIDATE_RET( input != NULL );
1126 AES_VALIDATE_RET( output != NULL );
1127
Jaeden Amero8381fcb2018-10-11 12:06:15 +01001128 /* Data units must be at least 16 bytes long. */
Aorimn5f778012016-06-09 23:22:58 +02001129 if( length < 16 )
Jaeden Amerod82cd862018-04-28 15:02:45 +01001130 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Aorimn5f778012016-06-09 23:22:58 +02001131
Jaeden Ameroa74faba2018-10-11 12:07:43 +01001132 /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */
Jaeden Amero0a8b0202018-05-30 15:36:06 +01001133 if( length > ( 1 << 20 ) * 16 )
1134 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Aorimn5f778012016-06-09 23:22:58 +02001135
Jaeden Amerod82cd862018-04-28 15:02:45 +01001136 /* Compute the tweak. */
Jaeden Amerocd9fc5e2018-05-30 15:23:24 +01001137 ret = mbedtls_aes_crypt_ecb( &ctx->tweak, MBEDTLS_AES_ENCRYPT,
1138 data_unit, tweak );
Jaeden Amerod82cd862018-04-28 15:02:45 +01001139 if( ret != 0 )
1140 return( ret );
Aorimn5f778012016-06-09 23:22:58 +02001141
Jaeden Amerod82cd862018-04-28 15:02:45 +01001142 while( blocks-- )
Aorimn5f778012016-06-09 23:22:58 +02001143 {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001144 size_t i;
1145
1146 if( leftover && ( mode == MBEDTLS_AES_DECRYPT ) && blocks == 0 )
1147 {
1148 /* We are on the last block in a decrypt operation that has
1149 * leftover bytes, so we need to use the next tweak for this block,
1150 * and this tweak for the lefover bytes. Save the current tweak for
1151 * the leftovers and then update the current tweak for use on this,
1152 * the last full block. */
1153 memcpy( prev_tweak, tweak, sizeof( tweak ) );
1154 mbedtls_gf128mul_x_ble( tweak, tweak );
1155 }
1156
1157 for( i = 0; i < 16; i++ )
1158 tmp[i] = input[i] ^ tweak[i];
1159
1160 ret = mbedtls_aes_crypt_ecb( &ctx->crypt, mode, tmp, tmp );
1161 if( ret != 0 )
1162 return( ret );
1163
1164 for( i = 0; i < 16; i++ )
1165 output[i] = tmp[i] ^ tweak[i];
1166
1167 /* Update the tweak for the next block. */
1168 mbedtls_gf128mul_x_ble( tweak, tweak );
1169
1170 output += 16;
1171 input += 16;
Aorimn5f778012016-06-09 23:22:58 +02001172 }
1173
Jaeden Amerod82cd862018-04-28 15:02:45 +01001174 if( leftover )
Aorimn5f778012016-06-09 23:22:58 +02001175 {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001176 /* If we are on the leftover bytes in a decrypt operation, we need to
1177 * use the previous tweak for these bytes (as saved in prev_tweak). */
1178 unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
Aorimn5f778012016-06-09 23:22:58 +02001179
Jaeden Amerod82cd862018-04-28 15:02:45 +01001180 /* We are now on the final part of the data unit, which doesn't divide
1181 * evenly by 16. It's time for ciphertext stealing. */
1182 size_t i;
1183 unsigned char *prev_output = output - 16;
Aorimn5f778012016-06-09 23:22:58 +02001184
Jaeden Amerod82cd862018-04-28 15:02:45 +01001185 /* Copy ciphertext bytes from the previous block to our output for each
Shaun Case8b0ecbc2021-12-20 21:14:10 -08001186 * byte of ciphertext we won't steal. At the same time, copy the
Jaeden Amerod82cd862018-04-28 15:02:45 +01001187 * remainder of the input for this final round (since the loop bounds
1188 * are the same). */
1189 for( i = 0; i < leftover; i++ )
Aorimn5f778012016-06-09 23:22:58 +02001190 {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001191 output[i] = prev_output[i];
1192 tmp[i] = input[i] ^ t[i];
Aorimn5f778012016-06-09 23:22:58 +02001193 }
Aorimn5f778012016-06-09 23:22:58 +02001194
Jaeden Amerod82cd862018-04-28 15:02:45 +01001195 /* Copy ciphertext bytes from the previous block for input in this
1196 * round. */
1197 for( ; i < 16; i++ )
1198 tmp[i] = prev_output[i] ^ t[i];
Aorimn5f778012016-06-09 23:22:58 +02001199
Jaeden Amerod82cd862018-04-28 15:02:45 +01001200 ret = mbedtls_aes_crypt_ecb( &ctx->crypt, mode, tmp, tmp );
1201 if( ret != 0 )
1202 return ret;
Aorimn5f778012016-06-09 23:22:58 +02001203
Jaeden Amerod82cd862018-04-28 15:02:45 +01001204 /* Write the result back to the previous block, overriding the previous
1205 * output we copied. */
1206 for( i = 0; i < 16; i++ )
1207 prev_output[i] = tmp[i] ^ t[i];
Aorimn5f778012016-06-09 23:22:58 +02001208 }
1209
1210 return( 0 );
1211}
1212#endif /* MBEDTLS_CIPHER_MODE_XTS */
1213
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001214#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001215/*
1216 * AES-CFB128 buffer encryption/decryption
1217 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001218int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx,
Paul Bakker5121ce52009-01-03 21:22:43 +00001219 int mode,
Paul Bakker23986e52011-04-24 08:57:21 +00001220 size_t length,
Paul Bakker27fdf462011-06-09 13:55:13 +00001221 size_t *iv_off,
Paul Bakker5121ce52009-01-03 21:22:43 +00001222 unsigned char iv[16],
Paul Bakkerff60ee62010-03-16 21:09:09 +00001223 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +00001224 unsigned char *output )
1225{
Paul Bakker27fdf462011-06-09 13:55:13 +00001226 int c;
Gilles Peskine7820a572021-07-07 21:08:28 +02001227 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001228 size_t n;
1229
1230 AES_VALIDATE_RET( ctx != NULL );
1231 AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
1232 mode == MBEDTLS_AES_DECRYPT );
1233 AES_VALIDATE_RET( iv_off != NULL );
1234 AES_VALIDATE_RET( iv != NULL );
1235 AES_VALIDATE_RET( input != NULL );
1236 AES_VALIDATE_RET( output != NULL );
1237
1238 n = *iv_off;
Paul Bakker5121ce52009-01-03 21:22:43 +00001239
Manuel Pégourié-Gonnarde55e1032018-12-18 12:09:02 +01001240 if( n > 15 )
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001241 return( MBEDTLS_ERR_AES_BAD_INPUT_DATA );
1242
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001243 if( mode == MBEDTLS_AES_DECRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +00001244 {
1245 while( length-- )
1246 {
1247 if( n == 0 )
Gilles Peskine7820a572021-07-07 21:08:28 +02001248 {
1249 ret = mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
1250 if( ret != 0 )
1251 goto exit;
1252 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001253
1254 c = *input++;
1255 *output++ = (unsigned char)( c ^ iv[n] );
1256 iv[n] = (unsigned char) c;
1257
Paul Bakker66d5d072014-06-17 16:39:18 +02001258 n = ( n + 1 ) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001259 }
1260 }
1261 else
1262 {
1263 while( length-- )
1264 {
1265 if( n == 0 )
Gilles Peskine7820a572021-07-07 21:08:28 +02001266 {
1267 ret = mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
1268 if( ret != 0 )
1269 goto exit;
1270 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001271
1272 iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ );
1273
Paul Bakker66d5d072014-06-17 16:39:18 +02001274 n = ( n + 1 ) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001275 }
1276 }
1277
1278 *iv_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001279 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001280
Gilles Peskine7820a572021-07-07 21:08:28 +02001281exit:
1282 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001283}
Paul Bakker556efba2014-01-24 15:38:12 +01001284
1285/*
1286 * AES-CFB8 buffer encryption/decryption
1287 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001288int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx,
Manuel Pégourié-Gonnardeb6d3962018-12-18 09:59:35 +01001289 int mode,
1290 size_t length,
1291 unsigned char iv[16],
1292 const unsigned char *input,
1293 unsigned char *output )
Paul Bakker556efba2014-01-24 15:38:12 +01001294{
Gilles Peskine7820a572021-07-07 21:08:28 +02001295 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker556efba2014-01-24 15:38:12 +01001296 unsigned char c;
1297 unsigned char ov[17];
1298
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001299 AES_VALIDATE_RET( ctx != NULL );
1300 AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
1301 mode == MBEDTLS_AES_DECRYPT );
1302 AES_VALIDATE_RET( iv != NULL );
1303 AES_VALIDATE_RET( input != NULL );
1304 AES_VALIDATE_RET( output != NULL );
Paul Bakker556efba2014-01-24 15:38:12 +01001305 while( length-- )
1306 {
Paul Bakker66d5d072014-06-17 16:39:18 +02001307 memcpy( ov, iv, 16 );
Gilles Peskine7820a572021-07-07 21:08:28 +02001308 ret = mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
1309 if( ret != 0 )
1310 goto exit;
Paul Bakker556efba2014-01-24 15:38:12 +01001311
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001312 if( mode == MBEDTLS_AES_DECRYPT )
Paul Bakker556efba2014-01-24 15:38:12 +01001313 ov[16] = *input;
1314
1315 c = *output++ = (unsigned char)( iv[0] ^ *input++ );
1316
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001317 if( mode == MBEDTLS_AES_ENCRYPT )
Paul Bakker556efba2014-01-24 15:38:12 +01001318 ov[16] = c;
1319
Paul Bakker66d5d072014-06-17 16:39:18 +02001320 memcpy( iv, ov + 1, 16 );
Paul Bakker556efba2014-01-24 15:38:12 +01001321 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001322 ret = 0;
Paul Bakker556efba2014-01-24 15:38:12 +01001323
Gilles Peskine7820a572021-07-07 21:08:28 +02001324exit:
1325 return( ret );
Paul Bakker556efba2014-01-24 15:38:12 +01001326}
Simon Butcher76a5b222018-04-22 22:57:27 +01001327#endif /* MBEDTLS_CIPHER_MODE_CFB */
1328
1329#if defined(MBEDTLS_CIPHER_MODE_OFB)
1330/*
1331 * AES-OFB (Output Feedback Mode) buffer encryption/decryption
1332 */
1333int mbedtls_aes_crypt_ofb( mbedtls_aes_context *ctx,
Simon Butcher00131442018-05-22 22:40:36 +01001334 size_t length,
1335 size_t *iv_off,
1336 unsigned char iv[16],
1337 const unsigned char *input,
1338 unsigned char *output )
Simon Butcher76a5b222018-04-22 22:57:27 +01001339{
Simon Butcherad4e4932018-04-29 00:43:47 +01001340 int ret = 0;
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001341 size_t n;
1342
1343 AES_VALIDATE_RET( ctx != NULL );
1344 AES_VALIDATE_RET( iv_off != NULL );
1345 AES_VALIDATE_RET( iv != NULL );
1346 AES_VALIDATE_RET( input != NULL );
1347 AES_VALIDATE_RET( output != NULL );
1348
1349 n = *iv_off;
Simon Butcher76a5b222018-04-22 22:57:27 +01001350
Manuel Pégourié-Gonnarde55e1032018-12-18 12:09:02 +01001351 if( n > 15 )
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001352 return( MBEDTLS_ERR_AES_BAD_INPUT_DATA );
1353
Simon Butcher76a5b222018-04-22 22:57:27 +01001354 while( length-- )
1355 {
1356 if( n == 0 )
Simon Butcherad4e4932018-04-29 00:43:47 +01001357 {
1358 ret = mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
1359 if( ret != 0 )
1360 goto exit;
1361 }
Simon Butcher76a5b222018-04-22 22:57:27 +01001362 *output++ = *input++ ^ iv[n];
1363
1364 n = ( n + 1 ) & 0x0F;
1365 }
1366
1367 *iv_off = n;
1368
Simon Butcherad4e4932018-04-29 00:43:47 +01001369exit:
1370 return( ret );
Simon Butcher76a5b222018-04-22 22:57:27 +01001371}
1372#endif /* MBEDTLS_CIPHER_MODE_OFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001373
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001374#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001375/*
1376 * AES-CTR buffer encryption/decryption
1377 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001378int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx,
Paul Bakker27fdf462011-06-09 13:55:13 +00001379 size_t length,
1380 size_t *nc_off,
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001381 unsigned char nonce_counter[16],
1382 unsigned char stream_block[16],
1383 const unsigned char *input,
1384 unsigned char *output )
1385{
Paul Bakker369e14b2012-04-18 14:16:09 +00001386 int c, i;
Gilles Peskine7820a572021-07-07 21:08:28 +02001387 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001388 size_t n;
1389
1390 AES_VALIDATE_RET( ctx != NULL );
1391 AES_VALIDATE_RET( nc_off != NULL );
1392 AES_VALIDATE_RET( nonce_counter != NULL );
1393 AES_VALIDATE_RET( stream_block != NULL );
1394 AES_VALIDATE_RET( input != NULL );
1395 AES_VALIDATE_RET( output != NULL );
1396
1397 n = *nc_off;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001398
Mohammad Azim Khan3f7f8172017-11-23 17:49:05 +00001399 if ( n > 0x0F )
1400 return( MBEDTLS_ERR_AES_BAD_INPUT_DATA );
1401
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001402 while( length-- )
1403 {
1404 if( n == 0 ) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001405 ret = mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block );
1406 if( ret != 0 )
1407 goto exit;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001408
Paul Bakker369e14b2012-04-18 14:16:09 +00001409 for( i = 16; i > 0; i-- )
1410 if( ++nonce_counter[i - 1] != 0 )
1411 break;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001412 }
1413 c = *input++;
1414 *output++ = (unsigned char)( c ^ stream_block[n] );
1415
Paul Bakker66d5d072014-06-17 16:39:18 +02001416 n = ( n + 1 ) & 0x0F;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001417 }
1418
1419 *nc_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001420 ret = 0;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001421
Gilles Peskine7820a572021-07-07 21:08:28 +02001422exit:
1423 return( ret );
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001424}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001425#endif /* MBEDTLS_CIPHER_MODE_CTR */
Manuel Pégourié-Gonnard1ec220b2014-03-10 11:20:17 +01001426
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001427#endif /* !MBEDTLS_AES_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001428
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001429#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001430/*
1431 * AES test vectors from:
1432 *
1433 * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
1434 */
1435static const unsigned char aes_test_ecb_dec[3][16] =
1436{
1437 { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
1438 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
1439 { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
1440 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
1441 { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
1442 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
1443};
1444
1445static const unsigned char aes_test_ecb_enc[3][16] =
1446{
1447 { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
1448 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
1449 { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
1450 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
1451 { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
1452 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
1453};
1454
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001455#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001456static const unsigned char aes_test_cbc_dec[3][16] =
1457{
1458 { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
1459 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
1460 { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
1461 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
1462 { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
1463 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
1464};
1465
1466static const unsigned char aes_test_cbc_enc[3][16] =
1467{
1468 { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
1469 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
1470 { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
1471 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
1472 { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
1473 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
1474};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001475#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001476
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001477#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001478/*
1479 * AES-CFB128 test vectors from:
1480 *
1481 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
1482 */
1483static const unsigned char aes_test_cfb128_key[3][32] =
1484{
1485 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1486 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
1487 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1488 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1489 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1490 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1491 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1492 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1493 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
1494};
1495
1496static const unsigned char aes_test_cfb128_iv[16] =
1497{
1498 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1499 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1500};
1501
1502static const unsigned char aes_test_cfb128_pt[64] =
1503{
1504 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1505 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1506 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1507 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1508 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1509 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1510 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1511 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1512};
1513
1514static const unsigned char aes_test_cfb128_ct[3][64] =
1515{
1516 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1517 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1518 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F,
1519 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B,
1520 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40,
1521 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF,
1522 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E,
1523 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 },
1524 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1525 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1526 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21,
1527 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A,
1528 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1,
1529 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9,
1530 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0,
1531 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF },
1532 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1533 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1534 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8,
1535 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B,
1536 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92,
1537 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9,
1538 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8,
1539 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 }
1540};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001541#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001542
Simon Butcherad4e4932018-04-29 00:43:47 +01001543#if defined(MBEDTLS_CIPHER_MODE_OFB)
1544/*
1545 * AES-OFB test vectors from:
1546 *
Simon Butcher5db13622018-06-04 22:11:25 +01001547 * https://csrc.nist.gov/publications/detail/sp/800-38a/final
Simon Butcherad4e4932018-04-29 00:43:47 +01001548 */
1549static const unsigned char aes_test_ofb_key[3][32] =
1550{
1551 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1552 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
1553 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1554 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1555 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1556 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1557 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1558 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1559 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
1560};
1561
1562static const unsigned char aes_test_ofb_iv[16] =
1563{
1564 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1565 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1566};
1567
1568static const unsigned char aes_test_ofb_pt[64] =
1569{
1570 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1571 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1572 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1573 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1574 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1575 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1576 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1577 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1578};
1579
1580static const unsigned char aes_test_ofb_ct[3][64] =
1581{
1582 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1583 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1584 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
1585 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
1586 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
1587 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
1588 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
1589 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e },
1590 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1591 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1592 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
1593 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
1594 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f,
1595 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
1596 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e,
1597 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a },
1598 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1599 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1600 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
1601 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
1602 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed,
1603 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
1604 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8,
1605 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 }
1606};
1607#endif /* MBEDTLS_CIPHER_MODE_OFB */
1608
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001609#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001610/*
1611 * AES-CTR test vectors from:
1612 *
1613 * http://www.faqs.org/rfcs/rfc3686.html
1614 */
1615
1616static const unsigned char aes_test_ctr_key[3][16] =
1617{
1618 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
1619 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
1620 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
1621 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
1622 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
1623 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
1624};
1625
1626static const unsigned char aes_test_ctr_nonce_counter[3][16] =
1627{
1628 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
1629 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
1630 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
1631 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
1632 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
1633 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
1634};
1635
1636static const unsigned char aes_test_ctr_pt[3][48] =
1637{
1638 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
1639 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
1640
1641 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1642 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1643 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1644 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
1645
1646 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1647 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1648 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1649 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
1650 0x20, 0x21, 0x22, 0x23 }
1651};
1652
1653static const unsigned char aes_test_ctr_ct[3][48] =
1654{
1655 { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79,
1656 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 },
1657 { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9,
1658 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88,
1659 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8,
1660 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 },
1661 { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
1662 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
1663 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
1664 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
1665 0x25, 0xB2, 0x07, 0x2F }
1666};
1667
1668static const int aes_test_ctr_len[3] =
1669 { 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001670#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00001671
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001672#if defined(MBEDTLS_CIPHER_MODE_XTS)
1673/*
1674 * AES-XTS test vectors from:
1675 *
1676 * IEEE P1619/D16 Annex B
1677 * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf
1678 * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf)
1679 */
1680static const unsigned char aes_test_xts_key[][32] =
1681{
1682 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1683 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1684 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1685 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1686 { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1687 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1688 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1689 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1690 { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
1691 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
1692 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1693 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1694};
1695
1696static const unsigned char aes_test_xts_pt32[][32] =
1697{
1698 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1699 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1700 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1701 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
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 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1709 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1710};
1711
1712static const unsigned char aes_test_xts_ct32[][32] =
1713{
1714 { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec,
1715 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92,
1716 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85,
1717 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e },
1718 { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e,
1719 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b,
1720 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4,
1721 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 },
1722 { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a,
1723 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2,
1724 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53,
1725 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 },
1726};
1727
1728static const unsigned char aes_test_xts_data_unit[][16] =
1729{
1730 { 0x00, 0x00, 0x00, 0x00, 0x00, 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 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1735 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1736};
1737
1738#endif /* MBEDTLS_CIPHER_MODE_XTS */
1739
Paul Bakker5121ce52009-01-03 21:22:43 +00001740/*
1741 * Checkup routine
1742 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001743int mbedtls_aes_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +00001744{
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001745 int ret = 0, i, j, u, mode;
1746 unsigned int keybits;
Paul Bakker5121ce52009-01-03 21:22:43 +00001747 unsigned char key[32];
1748 unsigned char buf[64];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001749 const unsigned char *aes_tests;
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03001750#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001751 unsigned char iv[16];
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03001752#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001753#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +02001754 unsigned char prv[16];
1755#endif
Simon Butcher2ff0e522018-06-14 09:57:07 +01001756#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1757 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker27fdf462011-06-09 13:55:13 +00001758 size_t offset;
Paul Bakkere91d01e2011-04-19 15:55:50 +00001759#endif
Simon Butcher66a89032018-06-15 18:20:29 +01001760#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS)
Paul Bakkere91d01e2011-04-19 15:55:50 +00001761 int len;
Simon Butcher66a89032018-06-15 18:20:29 +01001762#endif
1763#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001764 unsigned char nonce_counter[16];
1765 unsigned char stream_block[16];
1766#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001767 mbedtls_aes_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001768
1769 memset( key, 0, 32 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001770 mbedtls_aes_init( &ctx );
Paul Bakker5121ce52009-01-03 21:22:43 +00001771
1772 /*
1773 * ECB mode
1774 */
1775 for( i = 0; i < 6; i++ )
1776 {
1777 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001778 keybits = 128 + u * 64;
1779 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001780
1781 if( verbose != 0 )
Kenneth Soerensen518d4352020-04-01 17:22:45 +02001782 mbedtls_printf( " AES-ECB-%3u (%s): ", keybits,
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001783 ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001784
1785 memset( buf, 0, 16 );
1786
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001787 if( mode == MBEDTLS_AES_DECRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +00001788 {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001789 ret = mbedtls_aes_setkey_dec( &ctx, key, keybits );
1790 aes_tests = aes_test_ecb_dec[u];
Paul Bakker5121ce52009-01-03 21:22:43 +00001791 }
1792 else
1793 {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001794 ret = mbedtls_aes_setkey_enc( &ctx, key, keybits );
1795 aes_tests = aes_test_ecb_enc[u];
1796 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001797
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01001798 /*
1799 * AES-192 is an optional feature that may be unavailable when
1800 * there is an alternative underlying implementation i.e. when
1801 * MBEDTLS_AES_ALT is defined.
1802 */
Ron Eldor9924bdc2018-10-04 10:59:13 +03001803 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 )
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001804 {
1805 mbedtls_printf( "skipped\n" );
1806 continue;
1807 }
1808 else if( ret != 0 )
1809 {
1810 goto exit;
1811 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001812
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001813 for( j = 0; j < 10000; j++ )
1814 {
1815 ret = mbedtls_aes_crypt_ecb( &ctx, mode, buf, buf );
1816 if( ret != 0 )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001817 goto exit;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001818 }
1819
1820 if( memcmp( buf, aes_tests, 16 ) != 0 )
1821 {
1822 ret = 1;
1823 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001824 }
1825
1826 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001827 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001828 }
1829
1830 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001831 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001832
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001833#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001834 /*
1835 * CBC mode
1836 */
1837 for( i = 0; i < 6; i++ )
1838 {
1839 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001840 keybits = 128 + u * 64;
1841 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001842
1843 if( verbose != 0 )
Kenneth Soerensen518d4352020-04-01 17:22:45 +02001844 mbedtls_printf( " AES-CBC-%3u (%s): ", keybits,
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001845 ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001846
1847 memset( iv , 0, 16 );
1848 memset( prv, 0, 16 );
1849 memset( buf, 0, 16 );
1850
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001851 if( mode == MBEDTLS_AES_DECRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +00001852 {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001853 ret = mbedtls_aes_setkey_dec( &ctx, key, keybits );
1854 aes_tests = aes_test_cbc_dec[u];
Paul Bakker5121ce52009-01-03 21:22:43 +00001855 }
1856 else
1857 {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001858 ret = mbedtls_aes_setkey_enc( &ctx, key, keybits );
1859 aes_tests = aes_test_cbc_enc[u];
1860 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001861
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01001862 /*
1863 * AES-192 is an optional feature that may be unavailable when
1864 * there is an alternative underlying implementation i.e. when
1865 * MBEDTLS_AES_ALT is defined.
1866 */
Ron Eldor9924bdc2018-10-04 10:59:13 +03001867 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 )
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001868 {
1869 mbedtls_printf( "skipped\n" );
1870 continue;
1871 }
1872 else if( ret != 0 )
1873 {
1874 goto exit;
1875 }
1876
1877 for( j = 0; j < 10000; j++ )
1878 {
1879 if( mode == MBEDTLS_AES_ENCRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +00001880 {
1881 unsigned char tmp[16];
1882
Paul Bakker5121ce52009-01-03 21:22:43 +00001883 memcpy( tmp, prv, 16 );
1884 memcpy( prv, buf, 16 );
1885 memcpy( buf, tmp, 16 );
1886 }
1887
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001888 ret = mbedtls_aes_crypt_cbc( &ctx, mode, 16, iv, buf, buf );
1889 if( ret != 0 )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001890 goto exit;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001891
1892 }
1893
1894 if( memcmp( buf, aes_tests, 16 ) != 0 )
1895 {
1896 ret = 1;
1897 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001898 }
1899
1900 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001901 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001902 }
1903
1904 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001905 mbedtls_printf( "\n" );
1906#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001907
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001908#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001909 /*
1910 * CFB128 mode
1911 */
1912 for( i = 0; i < 6; i++ )
1913 {
1914 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001915 keybits = 128 + u * 64;
1916 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001917
1918 if( verbose != 0 )
Kenneth Soerensen518d4352020-04-01 17:22:45 +02001919 mbedtls_printf( " AES-CFB128-%3u (%s): ", keybits,
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001920 ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001921
1922 memcpy( iv, aes_test_cfb128_iv, 16 );
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001923 memcpy( key, aes_test_cfb128_key[u], keybits / 8 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001924
1925 offset = 0;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001926 ret = mbedtls_aes_setkey_enc( &ctx, key, keybits );
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01001927 /*
1928 * AES-192 is an optional feature that may be unavailable when
1929 * there is an alternative underlying implementation i.e. when
1930 * MBEDTLS_AES_ALT is defined.
1931 */
Ron Eldor9924bdc2018-10-04 10:59:13 +03001932 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 )
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001933 {
1934 mbedtls_printf( "skipped\n" );
1935 continue;
1936 }
1937 else if( ret != 0 )
1938 {
1939 goto exit;
1940 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001941
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001942 if( mode == MBEDTLS_AES_DECRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +00001943 {
1944 memcpy( buf, aes_test_cfb128_ct[u], 64 );
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001945 aes_tests = aes_test_cfb128_pt;
Paul Bakker5121ce52009-01-03 21:22:43 +00001946 }
1947 else
1948 {
1949 memcpy( buf, aes_test_cfb128_pt, 64 );
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001950 aes_tests = aes_test_cfb128_ct[u];
1951 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001952
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001953 ret = mbedtls_aes_crypt_cfb128( &ctx, mode, 64, &offset, iv, buf, buf );
1954 if( ret != 0 )
1955 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001956
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001957 if( memcmp( buf, aes_tests, 64 ) != 0 )
1958 {
1959 ret = 1;
1960 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001961 }
1962
1963 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001964 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001965 }
1966
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001967 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001968 mbedtls_printf( "\n" );
1969#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001970
Simon Butcherad4e4932018-04-29 00:43:47 +01001971#if defined(MBEDTLS_CIPHER_MODE_OFB)
1972 /*
1973 * OFB mode
1974 */
1975 for( i = 0; i < 6; i++ )
1976 {
1977 u = i >> 1;
1978 keybits = 128 + u * 64;
1979 mode = i & 1;
1980
1981 if( verbose != 0 )
Kenneth Soerensen518d4352020-04-01 17:22:45 +02001982 mbedtls_printf( " AES-OFB-%3u (%s): ", keybits,
Simon Butcherad4e4932018-04-29 00:43:47 +01001983 ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
1984
1985 memcpy( iv, aes_test_ofb_iv, 16 );
1986 memcpy( key, aes_test_ofb_key[u], keybits / 8 );
1987
1988 offset = 0;
1989 ret = mbedtls_aes_setkey_enc( &ctx, key, keybits );
1990 /*
1991 * AES-192 is an optional feature that may be unavailable when
1992 * there is an alternative underlying implementation i.e. when
1993 * MBEDTLS_AES_ALT is defined.
1994 */
Ron Eldor9924bdc2018-10-04 10:59:13 +03001995 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 )
Simon Butcherad4e4932018-04-29 00:43:47 +01001996 {
1997 mbedtls_printf( "skipped\n" );
1998 continue;
1999 }
2000 else if( ret != 0 )
2001 {
2002 goto exit;
2003 }
2004
2005 if( mode == MBEDTLS_AES_DECRYPT )
2006 {
2007 memcpy( buf, aes_test_ofb_ct[u], 64 );
2008 aes_tests = aes_test_ofb_pt;
2009 }
2010 else
2011 {
2012 memcpy( buf, aes_test_ofb_pt, 64 );
2013 aes_tests = aes_test_ofb_ct[u];
2014 }
2015
2016 ret = mbedtls_aes_crypt_ofb( &ctx, 64, &offset, iv, buf, buf );
2017 if( ret != 0 )
2018 goto exit;
2019
2020 if( memcmp( buf, aes_tests, 64 ) != 0 )
2021 {
2022 ret = 1;
2023 goto exit;
2024 }
2025
2026 if( verbose != 0 )
2027 mbedtls_printf( "passed\n" );
2028 }
2029
2030 if( verbose != 0 )
2031 mbedtls_printf( "\n" );
2032#endif /* MBEDTLS_CIPHER_MODE_OFB */
2033
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002034#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002035 /*
2036 * CTR mode
2037 */
2038 for( i = 0; i < 6; i++ )
2039 {
2040 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002041 mode = i & 1;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002042
2043 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002044 mbedtls_printf( " AES-CTR-128 (%s): ",
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002045 ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002046
2047 memcpy( nonce_counter, aes_test_ctr_nonce_counter[u], 16 );
2048 memcpy( key, aes_test_ctr_key[u], 16 );
2049
2050 offset = 0;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002051 if( ( ret = mbedtls_aes_setkey_enc( &ctx, key, 128 ) ) != 0 )
2052 goto exit;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002053
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002054 len = aes_test_ctr_len[u];
2055
2056 if( mode == MBEDTLS_AES_DECRYPT )
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002057 {
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002058 memcpy( buf, aes_test_ctr_ct[u], len );
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002059 aes_tests = aes_test_ctr_pt[u];
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002060 }
2061 else
2062 {
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002063 memcpy( buf, aes_test_ctr_pt[u], len );
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002064 aes_tests = aes_test_ctr_ct[u];
2065 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002066
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002067 ret = mbedtls_aes_crypt_ctr( &ctx, len, &offset, nonce_counter,
2068 stream_block, buf, buf );
2069 if( ret != 0 )
2070 goto exit;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002071
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002072 if( memcmp( buf, aes_tests, len ) != 0 )
2073 {
2074 ret = 1;
2075 goto exit;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002076 }
2077
2078 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002079 mbedtls_printf( "passed\n" );
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002080 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002081
2082 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002083 mbedtls_printf( "\n" );
2084#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00002085
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002086#if defined(MBEDTLS_CIPHER_MODE_XTS)
2087 {
2088 static const int num_tests =
2089 sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key);
2090 mbedtls_aes_xts_context ctx_xts;
2091
2092 /*
2093 * XTS mode
2094 */
2095 mbedtls_aes_xts_init( &ctx_xts );
2096
2097 for( i = 0; i < num_tests << 1; i++ )
2098 {
2099 const unsigned char *data_unit;
2100 u = i >> 1;
2101 mode = i & 1;
2102
2103 if( verbose != 0 )
2104 mbedtls_printf( " AES-XTS-128 (%s): ",
2105 ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
2106
2107 memset( key, 0, sizeof( key ) );
2108 memcpy( key, aes_test_xts_key[u], 32 );
2109 data_unit = aes_test_xts_data_unit[u];
2110
2111 len = sizeof( *aes_test_xts_ct32 );
2112
2113 if( mode == MBEDTLS_AES_DECRYPT )
2114 {
2115 ret = mbedtls_aes_xts_setkey_dec( &ctx_xts, key, 256 );
2116 if( ret != 0)
2117 goto exit;
2118 memcpy( buf, aes_test_xts_ct32[u], len );
2119 aes_tests = aes_test_xts_pt32[u];
2120 }
2121 else
2122 {
2123 ret = mbedtls_aes_xts_setkey_enc( &ctx_xts, key, 256 );
2124 if( ret != 0)
2125 goto exit;
2126 memcpy( buf, aes_test_xts_pt32[u], len );
2127 aes_tests = aes_test_xts_ct32[u];
2128 }
2129
2130
2131 ret = mbedtls_aes_crypt_xts( &ctx_xts, mode, len, data_unit,
2132 buf, buf );
2133 if( ret != 0 )
2134 goto exit;
2135
2136 if( memcmp( buf, aes_tests, len ) != 0 )
2137 {
2138 ret = 1;
2139 goto exit;
2140 }
2141
2142 if( verbose != 0 )
2143 mbedtls_printf( "passed\n" );
2144 }
2145
2146 if( verbose != 0 )
2147 mbedtls_printf( "\n" );
2148
2149 mbedtls_aes_xts_free( &ctx_xts );
2150 }
2151#endif /* MBEDTLS_CIPHER_MODE_XTS */
2152
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002153 ret = 0;
2154
2155exit:
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002156 if( ret != 0 && verbose != 0 )
2157 mbedtls_printf( "failed\n" );
2158
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002159 mbedtls_aes_free( &ctx );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002160
2161 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002162}
2163
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002164#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002165
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002166#endif /* MBEDTLS_AES_C */