blob: ea6a69dd5482a4f6ca48181436306d19308987f6 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * FIPS-197 compliant AES implementation
3 *
Manuel Pégourié-Gonnard6fb81872015-07-27 11:11:48 +02004 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
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 Bakkerb96f1542010-07-18 20:36:00 +000018 *
Manuel Pégourié-Gonnardfe446432015-03-06 13:17:10 +000019 * This file is part of mbed TLS (https://tls.mbed.org)
Paul Bakker5121ce52009-01-03 21:22:43 +000020 */
21/*
22 * The AES block cipher was designed by Vincent Rijmen and Joan Daemen.
23 *
24 * http://csrc.nist.gov/encryption/aes/rijndael/Rijndael.pdf
25 * http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
26 */
27
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020028#if !defined(MBEDTLS_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000029#include "mbedtls/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020030#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020031#include MBEDTLS_CONFIG_FILE
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020032#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000033
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020034#if defined(MBEDTLS_AES_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000035
Rich Evans00ab4702015-02-06 13:43:58 +000036#include <string.h>
37
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000038#include "mbedtls/aes.h"
Ron Eldor9924bdc2018-10-04 10:59:13 +030039#include "mbedtls/platform.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050040#include "mbedtls/platform_util.h"
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020041#if defined(MBEDTLS_PADLOCK_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000042#include "mbedtls/padlock.h"
Paul Bakker67820bd2012-06-04 12:47:23 +000043#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020044#if defined(MBEDTLS_AESNI_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000045#include "mbedtls/aesni.h"
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +010046#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000047
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020048#if defined(MBEDTLS_SELF_TEST)
49#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000050#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010051#else
Rich Evans00ab4702015-02-06 13:43:58 +000052#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020053#define mbedtls_printf printf
54#endif /* MBEDTLS_PLATFORM_C */
55#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010056
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020057#if !defined(MBEDTLS_AES_ALT)
Paul Bakker90995b52013-06-24 19:20:35 +020058
Manuel Pégourié-Gonnard0e9cddb2018-12-10 16:37:51 +010059/* Parameter validation macros based on platform_util.h */
60#define AES_VALIDATE_RET( cond ) \
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +010061 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_AES_BAD_INPUT_DATA )
Manuel Pégourié-Gonnard0e9cddb2018-12-10 16:37:51 +010062#define AES_VALIDATE( cond ) \
63 MBEDTLS_INTERNAL_VALIDATE( cond )
64
Paul Bakker5121ce52009-01-03 21:22:43 +000065/*
66 * 32-bit integer manipulation macros (little endian)
67 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000068#ifndef GET_UINT32_LE
69#define GET_UINT32_LE(n,b,i) \
Paul Bakker5121ce52009-01-03 21:22:43 +000070{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000071 (n) = ( (uint32_t) (b)[(i) ] ) \
72 | ( (uint32_t) (b)[(i) + 1] << 8 ) \
73 | ( (uint32_t) (b)[(i) + 2] << 16 ) \
74 | ( (uint32_t) (b)[(i) + 3] << 24 ); \
Paul Bakker5121ce52009-01-03 21:22:43 +000075}
76#endif
77
Paul Bakker5c2364c2012-10-01 14:41:15 +000078#ifndef PUT_UINT32_LE
Manuel Pégourié-Gonnardceedb822015-01-23 15:02:43 +000079#define PUT_UINT32_LE(n,b,i) \
80{ \
81 (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \
82 (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \
83 (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \
84 (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \
Paul Bakker5121ce52009-01-03 21:22:43 +000085}
86#endif
87
Arto Kinnunen172836a2019-11-28 13:34:13 +020088/*
89 * Data structure for AES round data
90 */
Arto Kinnunenf44f7d42019-12-04 15:19:50 +020091typedef struct {
Arto Kinnunen172836a2019-11-28 13:34:13 +020092 uint32_t *rk_ptr; /* Round Key */
Arto Kinnunen34139ba2019-12-03 15:43:27 +020093 uint32_t xy_values[8]; /* X0, X1, X2, X3, Y0, Y1, Y2, Y3 */
Shelly Libermanc907c812020-11-17 11:33:25 +020094#if defined(MBEDTLS_AES_128_BIT_MASKED)
95 uint32_t round;
96#endif
Arto Kinnunen172836a2019-11-28 13:34:13 +020097} aes_r_data_t;
98
99#if defined(MBEDTLS_AES_SCA_COUNTERMEASURES)
Arto Kinnunen17540ab2020-01-20 11:46:34 +0200100/* Number of additional AES dummy rounds added for SCA countermeasures */
Arto Kinnunen98c93af2020-01-14 13:31:03 +0200101#define AES_SCA_CM_ROUNDS 5
Shelly Libermanc907c812020-11-17 11:33:25 +0200102
103#if defined (MBEDTLS_AES_128_BIT_MASKED)
104
105#define Nb (4) /* number of columns (32-bit words) comprising the state */
106#define Nk (4) /* number of 32-bit words comprising the key */
107#define Nr (10) /* number of rounds */
108
109// state - array holding the intermediate results during aes operation.
110typedef uint8_t masked_state_t[4][4];
111
112#endif
Arto Kinnunen172836a2019-11-28 13:34:13 +0200113#endif /* MBEDTLS_AES_SCA_COUNTERMEASURES */
114
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200115#if defined(MBEDTLS_PADLOCK_C) && \
116 ( defined(MBEDTLS_HAVE_X86) || defined(MBEDTLS_PADLOCK_ALIGN16) )
Paul Bakker048d04e2012-02-12 17:31:04 +0000117static int aes_padlock_ace = -1;
118#endif
119
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200120#if defined(MBEDTLS_AES_ROM_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +0000121/*
122 * Forward S-box
123 */
124static const unsigned char FSb[256] =
125{
126 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
127 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
128 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
129 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
130 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
131 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
132 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
133 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
134 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
135 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
136 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
137 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
138 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
139 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
140 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
141 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
142 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
143 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
144 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
145 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
146 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
147 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
148 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
149 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
150 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
151 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
152 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
153 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
154 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
155 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
156 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
157 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
158};
159
Shelly Libermanc907c812020-11-17 11:33:25 +0200160
161#if !defined(MBEDTLS_AES_128_BIT_MASKED)
Paul Bakker5121ce52009-01-03 21:22:43 +0000162/*
163 * Forward tables
164 */
165#define FT \
166\
167 V(A5,63,63,C6), V(84,7C,7C,F8), V(99,77,77,EE), V(8D,7B,7B,F6), \
168 V(0D,F2,F2,FF), V(BD,6B,6B,D6), V(B1,6F,6F,DE), V(54,C5,C5,91), \
169 V(50,30,30,60), V(03,01,01,02), V(A9,67,67,CE), V(7D,2B,2B,56), \
170 V(19,FE,FE,E7), V(62,D7,D7,B5), V(E6,AB,AB,4D), V(9A,76,76,EC), \
171 V(45,CA,CA,8F), V(9D,82,82,1F), V(40,C9,C9,89), V(87,7D,7D,FA), \
172 V(15,FA,FA,EF), V(EB,59,59,B2), V(C9,47,47,8E), V(0B,F0,F0,FB), \
173 V(EC,AD,AD,41), V(67,D4,D4,B3), V(FD,A2,A2,5F), V(EA,AF,AF,45), \
174 V(BF,9C,9C,23), V(F7,A4,A4,53), V(96,72,72,E4), V(5B,C0,C0,9B), \
175 V(C2,B7,B7,75), V(1C,FD,FD,E1), V(AE,93,93,3D), V(6A,26,26,4C), \
176 V(5A,36,36,6C), V(41,3F,3F,7E), V(02,F7,F7,F5), V(4F,CC,CC,83), \
177 V(5C,34,34,68), V(F4,A5,A5,51), V(34,E5,E5,D1), V(08,F1,F1,F9), \
178 V(93,71,71,E2), V(73,D8,D8,AB), V(53,31,31,62), V(3F,15,15,2A), \
179 V(0C,04,04,08), V(52,C7,C7,95), V(65,23,23,46), V(5E,C3,C3,9D), \
180 V(28,18,18,30), V(A1,96,96,37), V(0F,05,05,0A), V(B5,9A,9A,2F), \
181 V(09,07,07,0E), V(36,12,12,24), V(9B,80,80,1B), V(3D,E2,E2,DF), \
182 V(26,EB,EB,CD), V(69,27,27,4E), V(CD,B2,B2,7F), V(9F,75,75,EA), \
183 V(1B,09,09,12), V(9E,83,83,1D), V(74,2C,2C,58), V(2E,1A,1A,34), \
184 V(2D,1B,1B,36), V(B2,6E,6E,DC), V(EE,5A,5A,B4), V(FB,A0,A0,5B), \
185 V(F6,52,52,A4), V(4D,3B,3B,76), V(61,D6,D6,B7), V(CE,B3,B3,7D), \
186 V(7B,29,29,52), V(3E,E3,E3,DD), V(71,2F,2F,5E), V(97,84,84,13), \
187 V(F5,53,53,A6), V(68,D1,D1,B9), V(00,00,00,00), V(2C,ED,ED,C1), \
188 V(60,20,20,40), V(1F,FC,FC,E3), V(C8,B1,B1,79), V(ED,5B,5B,B6), \
189 V(BE,6A,6A,D4), V(46,CB,CB,8D), V(D9,BE,BE,67), V(4B,39,39,72), \
190 V(DE,4A,4A,94), V(D4,4C,4C,98), V(E8,58,58,B0), V(4A,CF,CF,85), \
191 V(6B,D0,D0,BB), V(2A,EF,EF,C5), V(E5,AA,AA,4F), V(16,FB,FB,ED), \
192 V(C5,43,43,86), V(D7,4D,4D,9A), V(55,33,33,66), V(94,85,85,11), \
193 V(CF,45,45,8A), V(10,F9,F9,E9), V(06,02,02,04), V(81,7F,7F,FE), \
194 V(F0,50,50,A0), V(44,3C,3C,78), V(BA,9F,9F,25), V(E3,A8,A8,4B), \
195 V(F3,51,51,A2), V(FE,A3,A3,5D), V(C0,40,40,80), V(8A,8F,8F,05), \
196 V(AD,92,92,3F), V(BC,9D,9D,21), V(48,38,38,70), V(04,F5,F5,F1), \
197 V(DF,BC,BC,63), V(C1,B6,B6,77), V(75,DA,DA,AF), V(63,21,21,42), \
198 V(30,10,10,20), V(1A,FF,FF,E5), V(0E,F3,F3,FD), V(6D,D2,D2,BF), \
199 V(4C,CD,CD,81), V(14,0C,0C,18), V(35,13,13,26), V(2F,EC,EC,C3), \
200 V(E1,5F,5F,BE), V(A2,97,97,35), V(CC,44,44,88), V(39,17,17,2E), \
201 V(57,C4,C4,93), V(F2,A7,A7,55), V(82,7E,7E,FC), V(47,3D,3D,7A), \
202 V(AC,64,64,C8), V(E7,5D,5D,BA), V(2B,19,19,32), V(95,73,73,E6), \
203 V(A0,60,60,C0), V(98,81,81,19), V(D1,4F,4F,9E), V(7F,DC,DC,A3), \
204 V(66,22,22,44), V(7E,2A,2A,54), V(AB,90,90,3B), V(83,88,88,0B), \
205 V(CA,46,46,8C), V(29,EE,EE,C7), V(D3,B8,B8,6B), V(3C,14,14,28), \
206 V(79,DE,DE,A7), V(E2,5E,5E,BC), V(1D,0B,0B,16), V(76,DB,DB,AD), \
207 V(3B,E0,E0,DB), V(56,32,32,64), V(4E,3A,3A,74), V(1E,0A,0A,14), \
208 V(DB,49,49,92), V(0A,06,06,0C), V(6C,24,24,48), V(E4,5C,5C,B8), \
209 V(5D,C2,C2,9F), V(6E,D3,D3,BD), V(EF,AC,AC,43), V(A6,62,62,C4), \
210 V(A8,91,91,39), V(A4,95,95,31), V(37,E4,E4,D3), V(8B,79,79,F2), \
211 V(32,E7,E7,D5), V(43,C8,C8,8B), V(59,37,37,6E), V(B7,6D,6D,DA), \
212 V(8C,8D,8D,01), V(64,D5,D5,B1), V(D2,4E,4E,9C), V(E0,A9,A9,49), \
213 V(B4,6C,6C,D8), V(FA,56,56,AC), V(07,F4,F4,F3), V(25,EA,EA,CF), \
214 V(AF,65,65,CA), V(8E,7A,7A,F4), V(E9,AE,AE,47), V(18,08,08,10), \
215 V(D5,BA,BA,6F), V(88,78,78,F0), V(6F,25,25,4A), V(72,2E,2E,5C), \
216 V(24,1C,1C,38), V(F1,A6,A6,57), V(C7,B4,B4,73), V(51,C6,C6,97), \
217 V(23,E8,E8,CB), V(7C,DD,DD,A1), V(9C,74,74,E8), V(21,1F,1F,3E), \
218 V(DD,4B,4B,96), V(DC,BD,BD,61), V(86,8B,8B,0D), V(85,8A,8A,0F), \
219 V(90,70,70,E0), V(42,3E,3E,7C), V(C4,B5,B5,71), V(AA,66,66,CC), \
220 V(D8,48,48,90), V(05,03,03,06), V(01,F6,F6,F7), V(12,0E,0E,1C), \
221 V(A3,61,61,C2), V(5F,35,35,6A), V(F9,57,57,AE), V(D0,B9,B9,69), \
222 V(91,86,86,17), V(58,C1,C1,99), V(27,1D,1D,3A), V(B9,9E,9E,27), \
223 V(38,E1,E1,D9), V(13,F8,F8,EB), V(B3,98,98,2B), V(33,11,11,22), \
224 V(BB,69,69,D2), V(70,D9,D9,A9), V(89,8E,8E,07), V(A7,94,94,33), \
225 V(B6,9B,9B,2D), V(22,1E,1E,3C), V(92,87,87,15), V(20,E9,E9,C9), \
226 V(49,CE,CE,87), V(FF,55,55,AA), V(78,28,28,50), V(7A,DF,DF,A5), \
227 V(8F,8C,8C,03), V(F8,A1,A1,59), V(80,89,89,09), V(17,0D,0D,1A), \
228 V(DA,BF,BF,65), V(31,E6,E6,D7), V(C6,42,42,84), V(B8,68,68,D0), \
229 V(C3,41,41,82), V(B0,99,99,29), V(77,2D,2D,5A), V(11,0F,0F,1E), \
230 V(CB,B0,B0,7B), V(FC,54,54,A8), V(D6,BB,BB,6D), V(3A,16,16,2C)
231
232#define V(a,b,c,d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000233static const uint32_t FT0[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000234#undef V
235
Hanno Beckerad049a92017-06-19 16:31:54 +0100236#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200237
Paul Bakker5121ce52009-01-03 21:22:43 +0000238#define V(a,b,c,d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000239static const uint32_t FT1[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000240#undef V
241
242#define V(a,b,c,d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000243static const uint32_t FT2[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000244#undef V
245
246#define V(a,b,c,d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000247static const uint32_t FT3[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000248#undef V
249
Hanno Becker177d3cf2017-06-07 15:52:48 +0100250#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200251
Paul Bakker5121ce52009-01-03 21:22:43 +0000252#undef FT
Shelly Libermanc907c812020-11-17 11:33:25 +0200253#endif //ifndef MBEDTLS_AES_128_BIT_MASKED
254
Paul Bakker5121ce52009-01-03 21:22:43 +0000255
Arto Kinnunen14804442019-10-16 13:43:59 +0300256#if !defined(MBEDTLS_AES_ONLY_ENCRYPT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000257/*
258 * Reverse S-box
259 */
260static const unsigned char RSb[256] =
261{
262 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
263 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
264 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
265 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
266 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
267 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
268 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
269 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
270 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
271 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
272 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
273 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
274 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
275 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
276 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
277 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
278 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
279 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
280 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
281 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
282 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
283 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
284 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
285 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
286 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
287 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
288 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
289 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
290 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
291 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
292 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
293 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
294};
Shelly Libermanc907c812020-11-17 11:33:25 +0200295
Arto Kinnunen14804442019-10-16 13:43:59 +0300296#endif /* !MBEDTLS_AES_ONLY_ENCRYPT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000297
298/*
299 * Reverse tables
300 */
301#define RT \
302\
303 V(50,A7,F4,51), V(53,65,41,7E), V(C3,A4,17,1A), V(96,5E,27,3A), \
304 V(CB,6B,AB,3B), V(F1,45,9D,1F), V(AB,58,FA,AC), V(93,03,E3,4B), \
305 V(55,FA,30,20), V(F6,6D,76,AD), V(91,76,CC,88), V(25,4C,02,F5), \
306 V(FC,D7,E5,4F), V(D7,CB,2A,C5), V(80,44,35,26), V(8F,A3,62,B5), \
307 V(49,5A,B1,DE), V(67,1B,BA,25), V(98,0E,EA,45), V(E1,C0,FE,5D), \
308 V(02,75,2F,C3), V(12,F0,4C,81), V(A3,97,46,8D), V(C6,F9,D3,6B), \
309 V(E7,5F,8F,03), V(95,9C,92,15), V(EB,7A,6D,BF), V(DA,59,52,95), \
310 V(2D,83,BE,D4), V(D3,21,74,58), V(29,69,E0,49), V(44,C8,C9,8E), \
311 V(6A,89,C2,75), V(78,79,8E,F4), V(6B,3E,58,99), V(DD,71,B9,27), \
312 V(B6,4F,E1,BE), V(17,AD,88,F0), V(66,AC,20,C9), V(B4,3A,CE,7D), \
313 V(18,4A,DF,63), V(82,31,1A,E5), V(60,33,51,97), V(45,7F,53,62), \
314 V(E0,77,64,B1), V(84,AE,6B,BB), V(1C,A0,81,FE), V(94,2B,08,F9), \
315 V(58,68,48,70), V(19,FD,45,8F), V(87,6C,DE,94), V(B7,F8,7B,52), \
316 V(23,D3,73,AB), V(E2,02,4B,72), V(57,8F,1F,E3), V(2A,AB,55,66), \
317 V(07,28,EB,B2), V(03,C2,B5,2F), V(9A,7B,C5,86), V(A5,08,37,D3), \
318 V(F2,87,28,30), V(B2,A5,BF,23), V(BA,6A,03,02), V(5C,82,16,ED), \
319 V(2B,1C,CF,8A), V(92,B4,79,A7), V(F0,F2,07,F3), V(A1,E2,69,4E), \
320 V(CD,F4,DA,65), V(D5,BE,05,06), V(1F,62,34,D1), V(8A,FE,A6,C4), \
321 V(9D,53,2E,34), V(A0,55,F3,A2), V(32,E1,8A,05), V(75,EB,F6,A4), \
322 V(39,EC,83,0B), V(AA,EF,60,40), V(06,9F,71,5E), V(51,10,6E,BD), \
323 V(F9,8A,21,3E), V(3D,06,DD,96), V(AE,05,3E,DD), V(46,BD,E6,4D), \
324 V(B5,8D,54,91), V(05,5D,C4,71), V(6F,D4,06,04), V(FF,15,50,60), \
325 V(24,FB,98,19), V(97,E9,BD,D6), V(CC,43,40,89), V(77,9E,D9,67), \
326 V(BD,42,E8,B0), V(88,8B,89,07), V(38,5B,19,E7), V(DB,EE,C8,79), \
327 V(47,0A,7C,A1), V(E9,0F,42,7C), V(C9,1E,84,F8), V(00,00,00,00), \
328 V(83,86,80,09), V(48,ED,2B,32), V(AC,70,11,1E), V(4E,72,5A,6C), \
329 V(FB,FF,0E,FD), V(56,38,85,0F), V(1E,D5,AE,3D), V(27,39,2D,36), \
330 V(64,D9,0F,0A), V(21,A6,5C,68), V(D1,54,5B,9B), V(3A,2E,36,24), \
331 V(B1,67,0A,0C), V(0F,E7,57,93), V(D2,96,EE,B4), V(9E,91,9B,1B), \
332 V(4F,C5,C0,80), V(A2,20,DC,61), V(69,4B,77,5A), V(16,1A,12,1C), \
333 V(0A,BA,93,E2), V(E5,2A,A0,C0), V(43,E0,22,3C), V(1D,17,1B,12), \
334 V(0B,0D,09,0E), V(AD,C7,8B,F2), V(B9,A8,B6,2D), V(C8,A9,1E,14), \
335 V(85,19,F1,57), V(4C,07,75,AF), V(BB,DD,99,EE), V(FD,60,7F,A3), \
336 V(9F,26,01,F7), V(BC,F5,72,5C), V(C5,3B,66,44), V(34,7E,FB,5B), \
337 V(76,29,43,8B), V(DC,C6,23,CB), V(68,FC,ED,B6), V(63,F1,E4,B8), \
338 V(CA,DC,31,D7), V(10,85,63,42), V(40,22,97,13), V(20,11,C6,84), \
339 V(7D,24,4A,85), V(F8,3D,BB,D2), V(11,32,F9,AE), V(6D,A1,29,C7), \
340 V(4B,2F,9E,1D), V(F3,30,B2,DC), V(EC,52,86,0D), V(D0,E3,C1,77), \
341 V(6C,16,B3,2B), V(99,B9,70,A9), V(FA,48,94,11), V(22,64,E9,47), \
342 V(C4,8C,FC,A8), V(1A,3F,F0,A0), V(D8,2C,7D,56), V(EF,90,33,22), \
343 V(C7,4E,49,87), V(C1,D1,38,D9), V(FE,A2,CA,8C), V(36,0B,D4,98), \
344 V(CF,81,F5,A6), V(28,DE,7A,A5), V(26,8E,B7,DA), V(A4,BF,AD,3F), \
345 V(E4,9D,3A,2C), V(0D,92,78,50), V(9B,CC,5F,6A), V(62,46,7E,54), \
346 V(C2,13,8D,F6), V(E8,B8,D8,90), V(5E,F7,39,2E), V(F5,AF,C3,82), \
347 V(BE,80,5D,9F), V(7C,93,D0,69), V(A9,2D,D5,6F), V(B3,12,25,CF), \
348 V(3B,99,AC,C8), V(A7,7D,18,10), V(6E,63,9C,E8), V(7B,BB,3B,DB), \
349 V(09,78,26,CD), V(F4,18,59,6E), V(01,B7,9A,EC), V(A8,9A,4F,83), \
350 V(65,6E,95,E6), V(7E,E6,FF,AA), V(08,CF,BC,21), V(E6,E8,15,EF), \
351 V(D9,9B,E7,BA), V(CE,36,6F,4A), V(D4,09,9F,EA), V(D6,7C,B0,29), \
352 V(AF,B2,A4,31), V(31,23,3F,2A), V(30,94,A5,C6), V(C0,66,A2,35), \
353 V(37,BC,4E,74), V(A6,CA,82,FC), V(B0,D0,90,E0), V(15,D8,A7,33), \
354 V(4A,98,04,F1), V(F7,DA,EC,41), V(0E,50,CD,7F), V(2F,F6,91,17), \
355 V(8D,D6,4D,76), V(4D,B0,EF,43), V(54,4D,AA,CC), V(DF,04,96,E4), \
356 V(E3,B5,D1,9E), V(1B,88,6A,4C), V(B8,1F,2C,C1), V(7F,51,65,46), \
357 V(04,EA,5E,9D), V(5D,35,8C,01), V(73,74,87,FA), V(2E,41,0B,FB), \
358 V(5A,1D,67,B3), V(52,D2,DB,92), V(33,56,10,E9), V(13,47,D6,6D), \
359 V(8C,61,D7,9A), V(7A,0C,A1,37), V(8E,14,F8,59), V(89,3C,13,EB), \
360 V(EE,27,A9,CE), V(35,C9,61,B7), V(ED,E5,1C,E1), V(3C,B1,47,7A), \
361 V(59,DF,D2,9C), V(3F,73,F2,55), V(79,CE,14,18), V(BF,37,C7,73), \
362 V(EA,CD,F7,53), V(5B,AA,FD,5F), V(14,6F,3D,DF), V(86,DB,44,78), \
363 V(81,F3,AF,CA), V(3E,C4,68,B9), V(2C,34,24,38), V(5F,40,A3,C2), \
364 V(72,C3,1D,16), V(0C,25,E2,BC), V(8B,49,3C,28), V(41,95,0D,FF), \
365 V(71,01,A8,39), V(DE,B3,0C,08), V(9C,E4,B4,D8), V(90,C1,56,64), \
366 V(61,84,CB,7B), V(70,B6,32,D5), V(74,5C,6C,48), V(42,57,B8,D0)
367
Arto Kinnunen14804442019-10-16 13:43:59 +0300368#if !defined(MBEDTLS_AES_ONLY_ENCRYPT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000369#define V(a,b,c,d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000370static const uint32_t RT0[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000371#undef V
372
Hanno Beckerad049a92017-06-19 16:31:54 +0100373#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200374
Paul Bakker5121ce52009-01-03 21:22:43 +0000375#define V(a,b,c,d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000376static const uint32_t RT1[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000377#undef V
378
379#define V(a,b,c,d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000380static const uint32_t RT2[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000381#undef V
382
383#define V(a,b,c,d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000384static const uint32_t RT3[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000385#undef V
386
Hanno Becker177d3cf2017-06-07 15:52:48 +0100387#endif /* !MBEDTLS_AES_FEWER_TABLES */
Arto Kinnunen0fa65aa2019-10-21 14:43:37 +0300388#endif /* !MBEDTLS_AES_ONLY_ENCRYPT */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200389
Paul Bakker5121ce52009-01-03 21:22:43 +0000390#undef RT
391
392/*
393 * Round constants
394 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000395static const uint32_t RCON[10] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000396{
397 0x00000001, 0x00000002, 0x00000004, 0x00000008,
398 0x00000010, 0x00000020, 0x00000040, 0x00000080,
399 0x0000001B, 0x00000036
400};
401
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200402#else /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000403
404/*
405 * Forward S-box & tables
406 */
407static unsigned char FSb[256];
Shelly Libermanc907c812020-11-17 11:33:25 +0200408#if !defined(MBEDTLS_AES_128_BIT_MASKED)
Paul Bakker9af723c2014-05-01 13:03:14 +0200409static uint32_t FT0[256];
Shelly Libermanc907c812020-11-17 11:33:25 +0200410#endif
Hanno Beckerad049a92017-06-19 16:31:54 +0100411#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker9af723c2014-05-01 13:03:14 +0200412static uint32_t FT1[256];
413static uint32_t FT2[256];
414static uint32_t FT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100415#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000416
417/*
418 * Reverse S-box & tables
419 */
Arto Kinnunen0fa65aa2019-10-21 14:43:37 +0300420#if !defined(MBEDTLS_AES_ONLY_ENCRYPT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000421static unsigned char RSb[256];
Shelly Libermanc907c812020-11-17 11:33:25 +0200422
Paul Bakker5c2364c2012-10-01 14:41:15 +0000423static uint32_t RT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100424#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker5c2364c2012-10-01 14:41:15 +0000425static uint32_t RT1[256];
426static uint32_t RT2[256];
427static uint32_t RT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100428#endif /* !MBEDTLS_AES_FEWER_TABLES */
Arto Kinnunen0fa65aa2019-10-21 14:43:37 +0300429#endif /* !MBEDTLS_AES_ONLY_ENCRYPT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000430
431/*
432 * Round constants
433 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000434static uint32_t RCON[10];
Paul Bakker5121ce52009-01-03 21:22:43 +0000435
436/*
437 * Tables generation code
438 */
Hanno Beckerd6028a12018-10-15 12:01:35 +0100439#define XTIME(x) ( ( (x) << 1 ) ^ ( ( (x) & 0x80 ) ? 0x1B : 0x00 ) )
Shelly Libermanc907c812020-11-17 11:33:25 +0200440#if !defined(MBEDTLS_AES_128_BIT_MASKED)
441#define ROTL8(x) ( ( (x) << 8 ) & 0xFFFFFFFF ) | ( (x) >> 24 )
Hanno Becker3ac21ac2018-10-26 09:13:26 +0100442#define MUL(x,y) ( ( (x) && (y) ) ? pow[(log[(x)]+log[(y)]) % 255] : 0 )
Shelly Libermanc907c812020-11-17 11:33:25 +0200443#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000444
445static int aes_init_done = 0;
446
447static void aes_gen_tables( void )
448{
Shelly Libermanc907c812020-11-17 11:33:25 +0200449 int i, x, y;
450#if !defined(MBEDTLS_AES_128_BIT_MASKED)
451 int z;
452#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000453 int pow[256];
454 int log[256];
455
456 /*
457 * compute pow and log tables over GF(2^8)
458 */
459 for( i = 0, x = 1; i < 256; i++ )
460 {
461 pow[i] = x;
462 log[x] = i;
463 x = ( x ^ XTIME( x ) ) & 0xFF;
464 }
465
466 /*
467 * calculate the round constants
468 */
469 for( i = 0, x = 1; i < 10; i++ )
470 {
Paul Bakker5c2364c2012-10-01 14:41:15 +0000471 RCON[i] = (uint32_t) x;
Paul Bakker5121ce52009-01-03 21:22:43 +0000472 x = XTIME( x ) & 0xFF;
473 }
474
475 /*
476 * generate the forward and reverse S-boxes
477 */
478 FSb[0x00] = 0x63;
Arto Kinnunen0fa65aa2019-10-21 14:43:37 +0300479#if !defined(MBEDTLS_AES_ONLY_ENCRYPT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000480 RSb[0x63] = 0x00;
Arto Kinnunen0fa65aa2019-10-21 14:43:37 +0300481#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000482
483 for( i = 1; i < 256; i++ )
484 {
485 x = pow[255 - log[i]];
486
Paul Bakker66d5d072014-06-17 16:39:18 +0200487 y = x; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF;
488 x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF;
489 x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF;
490 x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF;
Paul Bakker5121ce52009-01-03 21:22:43 +0000491 x ^= y ^ 0x63;
492
493 FSb[i] = (unsigned char) x;
Arto Kinnunen0fa65aa2019-10-21 14:43:37 +0300494#if !defined(MBEDTLS_AES_ONLY_ENCRYPT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000495 RSb[x] = (unsigned char) i;
Arto Kinnunen0fa65aa2019-10-21 14:43:37 +0300496#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000497 }
Shelly Libermanc907c812020-11-17 11:33:25 +0200498#if !defined(MBEDTLS_AES_128_BIT_MASKED)
Paul Bakker5121ce52009-01-03 21:22:43 +0000499 /*
500 * generate the forward and reverse tables
501 */
502 for( i = 0; i < 256; i++ )
503 {
504 x = FSb[i];
505 y = XTIME( x ) & 0xFF;
506 z = ( y ^ x ) & 0xFF;
507
Paul Bakker5c2364c2012-10-01 14:41:15 +0000508 FT0[i] = ( (uint32_t) y ) ^
509 ( (uint32_t) x << 8 ) ^
510 ( (uint32_t) x << 16 ) ^
511 ( (uint32_t) z << 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000512
Hanno Beckerad049a92017-06-19 16:31:54 +0100513#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +0000514 FT1[i] = ROTL8( FT0[i] );
515 FT2[i] = ROTL8( FT1[i] );
516 FT3[i] = ROTL8( FT2[i] );
Hanno Becker177d3cf2017-06-07 15:52:48 +0100517#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000518
Arto Kinnunen0fa65aa2019-10-21 14:43:37 +0300519#if !defined(MBEDTLS_AES_ONLY_ENCRYPT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000520 x = RSb[i];
521
Paul Bakker5c2364c2012-10-01 14:41:15 +0000522 RT0[i] = ( (uint32_t) MUL( 0x0E, x ) ) ^
523 ( (uint32_t) MUL( 0x09, x ) << 8 ) ^
524 ( (uint32_t) MUL( 0x0D, x ) << 16 ) ^
525 ( (uint32_t) MUL( 0x0B, x ) << 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000526
Hanno Beckerad049a92017-06-19 16:31:54 +0100527#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +0000528 RT1[i] = ROTL8( RT0[i] );
529 RT2[i] = ROTL8( RT1[i] );
530 RT3[i] = ROTL8( RT2[i] );
Hanno Becker177d3cf2017-06-07 15:52:48 +0100531#endif /* !MBEDTLS_AES_FEWER_TABLES */
Arto Kinnunen0fa65aa2019-10-21 14:43:37 +0300532#endif /* !MBEDTLS_AES_ONLY_ENCRYPT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000533 }
Shelly Libermanc907c812020-11-17 11:33:25 +0200534
535#endif //MBEDTLS_AES_128_BIT_MASKED
Paul Bakker5121ce52009-01-03 21:22:43 +0000536}
537
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200538#undef ROTL8
539
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200540#endif /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000541
Arto Kinnunen172836a2019-11-28 13:34:13 +0200542/**
Arto Kinnunen2eb678f2020-01-13 16:44:13 +0200543 * Randomize positions for AES SCA countermeasures if AES countermeasures are
Arto Kinnunen17540ab2020-01-20 11:46:34 +0200544 * enabled. If the countermeasures are not enabled then we fill the given table
545 * with only real AES rounds to be executed.
Arto Kinnunen2eb678f2020-01-13 16:44:13 +0200546 *
547 * Dummy rounds are added as follows:
548 * 1. One dummy round added to the initial round key addition (executed in
549 * random order).
550 * 2. Random number of dummy rounds added as first and/or last AES calculation
551 * round. Total number of dummy rounds is AES_SCA_CM_ROUNDS.
552 *
553 * Description of the bytes in the table are as follows:
554 * - 2 bytes for initial round key addition
555 * - remaining bytes for AES calculation with real or dummy data
556 *
557 * Each byte indicates one AES calculation round:
558 * -4 high bit = table to use 0x10 for dummy data, 0x00 real data
559 * -bit 2 = offset for even/odd rounds
560 * -bit 0-1: stop mark (0x03) to indicate calculation end
Arto Kinnunen172836a2019-11-28 13:34:13 +0200561 *
Arto Kinnunen6ce49882019-12-03 13:56:06 +0200562 * Return Number of additional AES rounds
563 *
564 * Example of the control bytes:
Arto Kinnunen17540ab2020-01-20 11:46:34 +0200565 * R = real data in actual AES calculation round
566 * Ri = Real data in initial round key addition phase
567 * F = fake data in actual AES calculation round
568 * Fi = fake data in initial round key addition phase
569 *
Arto Kinnunen2eb678f2020-01-13 16:44:13 +0200570 * 1. No countermeasures enabled and AES-128, only real data (R) used:
571 * | Ri | R | R | R | R | R | R | R | R | R | R |
572 * |0x03|0x04|0x00|0x04|0x00|0x04|0x00|0x04|0x00|0x07|0x03|
Arto Kinnunenf44f7d42019-12-04 15:19:50 +0200573 *
Arto Kinnunen2eb678f2020-01-13 16:44:13 +0200574 * 2. Countermeasures enabled, 3 (F) dummy rounds in start and 1 at end:
Arto Kinnunen17540ab2020-01-20 11:46:34 +0200575 * | Fi | Ri | F | F | F | R | R | ... | R | R | R | R | F |
576 * |0x10|0x03|0x10|0x10|0x10|0x04|0x00| ... |0x04|0x00|0x04|0x03|0x07|
Arto Kinnunen172836a2019-11-28 13:34:13 +0200577 */
Arto Kinnunen311ab592020-01-16 17:20:51 +0200578#if defined(MBEDTLS_AES_SCA_COUNTERMEASURES)
Kevin Braceya967a582020-11-04 16:28:48 +0200579static int aes_sca_cm_data_randomize( uint8_t *tbl, int tbl_len )
Arto Kinnunen172836a2019-11-28 13:34:13 +0200580{
Arto Kinnunen311ab592020-01-16 17:20:51 +0200581 int i = 0, j, is_even_pos, dummy_rounds, num;
Arto Kinnunen172836a2019-11-28 13:34:13 +0200582
Jarno Lamsa8f8c0bd2020-01-08 15:07:41 +0200583 mbedtls_platform_memset( tbl, 0, tbl_len );
Andrzej Kurek11ddf252020-06-24 17:33:39 -0400584 // get random from 0x0fff
Arto Kinnunen2b24f422020-01-16 15:04:11 +0200585 num = mbedtls_platform_random_in_range( 0x1000 );
Arto Kinnunen2eb678f2020-01-13 16:44:13 +0200586
587 // Randomize execution order of initial round key addition
Arto Kinnunen2b24f422020-01-16 15:04:11 +0200588 if ( ( num & 0x0100 ) == 0 )
Arto Kinnunen172836a2019-11-28 13:34:13 +0200589 {
Arto Kinnunen2eb678f2020-01-13 16:44:13 +0200590 tbl[i++] = 0x10; // dummy data
591 tbl[i++] = 0x00 | 0x03; // real data + stop marker
592 } else {
593 tbl[i++] = 0x00; // real data
594 tbl[i++] = 0x10 | 0x03; // dummy data + stop marker
Arto Kinnunen172836a2019-11-28 13:34:13 +0200595 }
596
Arto Kinnunen2b24f422020-01-16 15:04:11 +0200597 // Randomize number of dummy AES rounds
Arto Kinnunen17540ab2020-01-20 11:46:34 +0200598 dummy_rounds = AES_SCA_CM_ROUNDS - ( ( num & 0x0010 ) >> 4 );
Arto Kinnunen98c93af2020-01-14 13:31:03 +0200599 tbl_len = tbl_len - (AES_SCA_CM_ROUNDS - dummy_rounds);
Arto Kinnunen2eb678f2020-01-13 16:44:13 +0200600
Arto Kinnunen2b24f422020-01-16 15:04:11 +0200601 // randomize positions for the dummy rounds
Andrzej Kurek11ddf252020-06-24 17:33:39 -0400602 num = ( num & 0x0fff ) % ( dummy_rounds + 1 );
Arto Kinnunen2b24f422020-01-16 15:04:11 +0200603
604 // add dummy rounds after initial round key addition (if needed)
Arto Kinnunen2eb678f2020-01-13 16:44:13 +0200605 for ( ; i < num + 2; i++ )
Arto Kinnunen172836a2019-11-28 13:34:13 +0200606 {
Arto Kinnunen2eb678f2020-01-13 16:44:13 +0200607 tbl[i] = 0x10; // dummy data
Arto Kinnunen172836a2019-11-28 13:34:13 +0200608 }
Arto Kinnunen2eb678f2020-01-13 16:44:13 +0200609
Arto Kinnunen2b24f422020-01-16 15:04:11 +0200610 // add dummy rounds to the end, (AES_SCA_CM_ROUNDS - num) rounds if needed
Arto Kinnunen98c93af2020-01-14 13:31:03 +0200611 for ( j = tbl_len - dummy_rounds + num; j < tbl_len; j++ )
Arto Kinnunen2eb678f2020-01-13 16:44:13 +0200612 {
613 tbl[j] = 0x10; // dummy data
614 }
Arto Kinnunen172836a2019-11-28 13:34:13 +0200615
Arto Kinnunen2eb678f2020-01-13 16:44:13 +0200616 // Fill real AES data to the remaining places
Arto Kinnunen172836a2019-11-28 13:34:13 +0200617 is_even_pos = 1;
Arto Kinnunen2eb678f2020-01-13 16:44:13 +0200618 for( ; i < tbl_len; i++ )
Arto Kinnunen172836a2019-11-28 13:34:13 +0200619 {
Arto Kinnunen75439012019-12-03 14:12:10 +0200620 if( tbl[i] == 0 )
Arto Kinnunen172836a2019-11-28 13:34:13 +0200621 {
Arto Kinnunen75439012019-12-03 14:12:10 +0200622 if( is_even_pos == 1 )
Arto Kinnunen172836a2019-11-28 13:34:13 +0200623 {
Arto Kinnunen2eb678f2020-01-13 16:44:13 +0200624 tbl[i] = 0x04; // real data, offset for rounds 1,3,5, etc...
Arto Kinnunen172836a2019-11-28 13:34:13 +0200625 is_even_pos = 0;
626 }
627 else
628 {
Arto Kinnunen2eb678f2020-01-13 16:44:13 +0200629 tbl[i] = 0x00; // real data, offset for rounds 2,4,6,...
Arto Kinnunen172836a2019-11-28 13:34:13 +0200630 is_even_pos = 1;
631 }
Arto Kinnunen2eb678f2020-01-13 16:44:13 +0200632 j = i; // remember the final round position in table
Arto Kinnunen172836a2019-11-28 13:34:13 +0200633 }
634 }
Arto Kinnunen6ce49882019-12-03 13:56:06 +0200635
Arto Kinnunen2eb678f2020-01-13 16:44:13 +0200636 tbl[( tbl_len - 1)] |= 0x03; // Stop marker for the last item in tbl
637 tbl[( j - 1 )] |= 0x03; // stop marker for final - 1 real data
638
Arto Kinnunen98c93af2020-01-14 13:31:03 +0200639 return( dummy_rounds );
Arto Kinnunen172836a2019-11-28 13:34:13 +0200640}
Arto Kinnunen17540ab2020-01-20 11:46:34 +0200641#endif /* MBEDTLS_AES_SCA_COUNTERMEASURES */
Arto Kinnunen172836a2019-11-28 13:34:13 +0200642
Shelly Libermanc907c812020-11-17 11:33:25 +0200643#if !defined(MBEDTLS_AES_128_BIT_MASKED)
Hanno Beckerad049a92017-06-19 16:31:54 +0100644#if defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200645
646#define ROTL8(x) ( (uint32_t)( ( x ) << 8 ) + (uint32_t)( ( x ) >> 24 ) )
647#define ROTL16(x) ( (uint32_t)( ( x ) << 16 ) + (uint32_t)( ( x ) >> 16 ) )
648#define ROTL24(x) ( (uint32_t)( ( x ) << 24 ) + (uint32_t)( ( x ) >> 8 ) )
649
650#define AES_RT0(idx) RT0[idx]
651#define AES_RT1(idx) ROTL8( RT0[idx] )
652#define AES_RT2(idx) ROTL16( RT0[idx] )
653#define AES_RT3(idx) ROTL24( RT0[idx] )
654
655#define AES_FT0(idx) FT0[idx]
656#define AES_FT1(idx) ROTL8( FT0[idx] )
657#define AES_FT2(idx) ROTL16( FT0[idx] )
658#define AES_FT3(idx) ROTL24( FT0[idx] )
659
Hanno Becker177d3cf2017-06-07 15:52:48 +0100660#else /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200661
662#define AES_RT0(idx) RT0[idx]
663#define AES_RT1(idx) RT1[idx]
664#define AES_RT2(idx) RT2[idx]
665#define AES_RT3(idx) RT3[idx]
666
667#define AES_FT0(idx) FT0[idx]
668#define AES_FT1(idx) FT1[idx]
669#define AES_FT2(idx) FT2[idx]
670#define AES_FT3(idx) FT3[idx]
671
Hanno Becker177d3cf2017-06-07 15:52:48 +0100672#endif /* MBEDTLS_AES_FEWER_TABLES */
Shelly Libermanc907c812020-11-17 11:33:25 +0200673#endif
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200674
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200675void mbedtls_aes_init( mbedtls_aes_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200676{
Manuel Pégourié-Gonnard0e9cddb2018-12-10 16:37:51 +0100677 AES_VALIDATE( ctx != NULL );
Simon Butcher5201e412018-12-06 17:40:14 +0000678
Manuel Pégourié-Gonnard99419332019-10-03 10:40:57 +0200679 memset( ctx, 0, sizeof( mbedtls_aes_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200680}
681
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200682void mbedtls_aes_free( mbedtls_aes_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200683{
684 if( ctx == NULL )
685 return;
686
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500687 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_aes_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200688}
689
Jaeden Amero9366feb2018-05-29 18:55:17 +0100690#if defined(MBEDTLS_CIPHER_MODE_XTS)
691void mbedtls_aes_xts_init( mbedtls_aes_xts_context *ctx )
692{
Manuel Pégourié-Gonnard0e9cddb2018-12-10 16:37:51 +0100693 AES_VALIDATE( ctx != NULL );
Simon Butcher5201e412018-12-06 17:40:14 +0000694
Jaeden Amero9366feb2018-05-29 18:55:17 +0100695 mbedtls_aes_init( &ctx->crypt );
696 mbedtls_aes_init( &ctx->tweak );
697}
698
699void mbedtls_aes_xts_free( mbedtls_aes_xts_context *ctx )
700{
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100701 if( ctx == NULL )
702 return;
Simon Butcher5201e412018-12-06 17:40:14 +0000703
Jaeden Amero9366feb2018-05-29 18:55:17 +0100704 mbedtls_aes_free( &ctx->crypt );
705 mbedtls_aes_free( &ctx->tweak );
706}
707#endif /* MBEDTLS_CIPHER_MODE_XTS */
708
Andrzej Kurekfac2f9b2020-07-19 00:32:34 -0400709#if defined(MBEDTLS_AES_SCA_COUNTERMEASURES)
Andrzej Kureke78775e2020-07-02 10:57:00 -0400710static void mbedtls_generate_fake_key( unsigned int keybits, mbedtls_aes_context *ctx )
711{
712 unsigned int qword;
713
714 for( qword = keybits >> 5; qword > 0; qword-- )
715 {
716 ctx->frk[ qword - 1 ] = mbedtls_platform_random_uint32();
717 }
718}
Andrzej Kurekfac2f9b2020-07-19 00:32:34 -0400719#endif /* MBEDTLS_AES_SCA_COUNTERMEASURES */
Andrzej Kureke78775e2020-07-02 10:57:00 -0400720
Paul Bakker5121ce52009-01-03 21:22:43 +0000721/*
722 * AES key schedule (encryption)
723 */
Shelly Libermanc907c812020-11-17 11:33:25 +0200724
725
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200726#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200727int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key,
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200728 unsigned int keybits )
Paul Bakker5121ce52009-01-03 21:22:43 +0000729{
Arto Kinnunen6ce49882019-12-03 13:56:06 +0200730 unsigned int j = 0;
Jarno Lamsa282db8e2020-01-08 14:53:17 +0200731 unsigned int flow_ctrl = 0;
Arto Kinnunen6ce49882019-12-03 13:56:06 +0200732 volatile unsigned int i = 0;
733 volatile int ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000734 uint32_t *RK;
Jarno Lamsa282db8e2020-01-08 14:53:17 +0200735 uint32_t offset = 0;
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100736 AES_VALIDATE_RET( ctx != NULL );
737 AES_VALIDATE_RET( key != NULL );
Andrzej Kurekfba59212020-08-07 21:02:25 -0400738 (void) ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000739
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200740 switch( keybits )
Paul Bakker5121ce52009-01-03 21:22:43 +0000741 {
742 case 128: ctx->nr = 10; break;
Arto Kinnunen77b9cfc2019-08-30 11:43:21 +0300743#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000744 case 192: ctx->nr = 12; break;
745 case 256: ctx->nr = 14; break;
Arto Kinnunen77b9cfc2019-08-30 11:43:21 +0300746#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200747 default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000748 }
749
Simon Butcher5201e412018-12-06 17:40:14 +0000750#if !defined(MBEDTLS_AES_ROM_TABLES)
751 if( aes_init_done == 0 )
752 {
753 aes_gen_tables();
754 aes_init_done = 1;
Simon Butcher5201e412018-12-06 17:40:14 +0000755 }
756#endif
757
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200758#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_PADLOCK_ALIGN16)
Paul Bakker048d04e2012-02-12 17:31:04 +0000759 if( aes_padlock_ace == -1 )
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100760 aes_padlock_ace = mbedtls_padlock_has_support( MBEDTLS_PADLOCK_ACE );
Paul Bakker048d04e2012-02-12 17:31:04 +0000761
762 if( aes_padlock_ace )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200763 ctx->rk = RK = MBEDTLS_PADLOCK_ALIGN16( ctx->buf );
Paul Bakker048d04e2012-02-12 17:31:04 +0000764 else
Paul Bakker5121ce52009-01-03 21:22:43 +0000765#endif
Shelly Libermanc907c812020-11-17 11:33:25 +0200766
Paul Bakker048d04e2012-02-12 17:31:04 +0000767 ctx->rk = RK = ctx->buf;
Andrzej Kurekfac2f9b2020-07-19 00:32:34 -0400768#if defined(MBEDTLS_AES_SCA_COUNTERMEASURES)
Andrzej Kureke78775e2020-07-02 10:57:00 -0400769 mbedtls_generate_fake_key( keybits, ctx );
Andrzej Kurekfac2f9b2020-07-19 00:32:34 -0400770#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000771
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200772#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100773 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) )
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200774 return( mbedtls_aesni_setkey_enc( (unsigned char *) ctx->rk, key, keybits ) );
Manuel Pégourié-Gonnard47a35362013-12-28 20:45:04 +0100775#endif
776
Andrzej Kureka9a5ff52020-07-15 08:50:59 -0400777 /* Three least significant bits are truncated from keybits, which is
778 * expected to be a multiple of 8. */
Andrzej Kurek11ddf252020-06-24 17:33:39 -0400779 mbedtls_platform_memset( RK, 0, keybits >> 3 );
Jarno Lamsa282db8e2020-01-08 14:53:17 +0200780 offset = mbedtls_platform_random_in_range( keybits >> 5 );
781
782 for( j = offset; j < ( keybits >> 5 ); j++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000783 {
Arto Kinnunen6ce49882019-12-03 13:56:06 +0200784 GET_UINT32_LE( RK[j], key, j << 2 );
Jarno Lamsa282db8e2020-01-08 14:53:17 +0200785 flow_ctrl++;
786 }
787
788 for( j = 0; j < offset; j++ )
789 {
790 GET_UINT32_LE( RK[j], key, j << 2 );
791 flow_ctrl++;
Paul Bakker5121ce52009-01-03 21:22:43 +0000792 }
793
794 switch( ctx->nr )
795 {
796 case 10:
Paul Bakker5121ce52009-01-03 21:22:43 +0000797 for( i = 0; i < 10; i++, RK += 4 )
798 {
799 RK[4] = RK[0] ^ RCON[i] ^
Paul Bakker5c2364c2012-10-01 14:41:15 +0000800 ( (uint32_t) FSb[ ( RK[3] >> 8 ) & 0xFF ] ) ^
801 ( (uint32_t) FSb[ ( RK[3] >> 16 ) & 0xFF ] << 8 ) ^
802 ( (uint32_t) FSb[ ( RK[3] >> 24 ) & 0xFF ] << 16 ) ^
803 ( (uint32_t) FSb[ ( RK[3] ) & 0xFF ] << 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000804
805 RK[5] = RK[1] ^ RK[4];
806 RK[6] = RK[2] ^ RK[5];
807 RK[7] = RK[3] ^ RK[6];
Shelly Libermanc907c812020-11-17 11:33:25 +0200808 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000809 break;
Arto Kinnunen77b9cfc2019-08-30 11:43:21 +0300810#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000811 case 12:
812
813 for( i = 0; i < 8; i++, RK += 6 )
814 {
815 RK[6] = RK[0] ^ RCON[i] ^
Paul Bakker5c2364c2012-10-01 14:41:15 +0000816 ( (uint32_t) FSb[ ( RK[5] >> 8 ) & 0xFF ] ) ^
817 ( (uint32_t) FSb[ ( RK[5] >> 16 ) & 0xFF ] << 8 ) ^
818 ( (uint32_t) FSb[ ( RK[5] >> 24 ) & 0xFF ] << 16 ) ^
819 ( (uint32_t) FSb[ ( RK[5] ) & 0xFF ] << 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000820
821 RK[7] = RK[1] ^ RK[6];
822 RK[8] = RK[2] ^ RK[7];
823 RK[9] = RK[3] ^ RK[8];
824 RK[10] = RK[4] ^ RK[9];
825 RK[11] = RK[5] ^ RK[10];
826 }
827 break;
828
829 case 14:
830
831 for( i = 0; i < 7; i++, RK += 8 )
832 {
833 RK[8] = RK[0] ^ RCON[i] ^
Paul Bakker5c2364c2012-10-01 14:41:15 +0000834 ( (uint32_t) FSb[ ( RK[7] >> 8 ) & 0xFF ] ) ^
835 ( (uint32_t) FSb[ ( RK[7] >> 16 ) & 0xFF ] << 8 ) ^
836 ( (uint32_t) FSb[ ( RK[7] >> 24 ) & 0xFF ] << 16 ) ^
837 ( (uint32_t) FSb[ ( RK[7] ) & 0xFF ] << 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000838
839 RK[9] = RK[1] ^ RK[8];
840 RK[10] = RK[2] ^ RK[9];
841 RK[11] = RK[3] ^ RK[10];
842
843 RK[12] = RK[4] ^
Paul Bakker5c2364c2012-10-01 14:41:15 +0000844 ( (uint32_t) FSb[ ( RK[11] ) & 0xFF ] ) ^
845 ( (uint32_t) FSb[ ( RK[11] >> 8 ) & 0xFF ] << 8 ) ^
846 ( (uint32_t) FSb[ ( RK[11] >> 16 ) & 0xFF ] << 16 ) ^
847 ( (uint32_t) FSb[ ( RK[11] >> 24 ) & 0xFF ] << 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000848
849 RK[13] = RK[5] ^ RK[12];
850 RK[14] = RK[6] ^ RK[13];
851 RK[15] = RK[7] ^ RK[14];
852 }
853 break;
Arto Kinnunen77b9cfc2019-08-30 11:43:21 +0300854#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Paul Bakker5121ce52009-01-03 21:22:43 +0000855 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000856
Arto Kinnunen6ce49882019-12-03 13:56:06 +0200857 /* Validate execution path */
Jarno Lamsa282db8e2020-01-08 14:53:17 +0200858 if( ( flow_ctrl == keybits >> 5 ) && ( ( ctx->nr == 10 && i == 10 )
Arto Kinnunen6ce49882019-12-03 13:56:06 +0200859#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
860 || ( ctx->nr == 12 && i == 8 )
861 || ( ctx->nr == 14 && i == 7 )
862#endif
863 ) )
864 {
Andrzej Kurekfba59212020-08-07 21:02:25 -0400865#if defined(MBEDTLS_VALIDATE_AES_KEYS_INTEGRITY)
Andrzej Kurek9539f832020-08-10 15:58:13 -0400866 ctx->hash = mbedtls_hash( ctx->rk, keybits >> 3 );
Andrzej Kurekfba59212020-08-07 21:02:25 -0400867#endif
868 return 0;
Arto Kinnunen6ce49882019-12-03 13:56:06 +0200869 }
870
Andrzej Kurekca609372020-07-08 03:19:02 -0400871 mbedtls_platform_memset( RK, 0, ( keybits >> 5 ) * 4 );
Arto Kinnunen6ce49882019-12-03 13:56:06 +0200872 return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000873}
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200874#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000875
876/*
877 * AES key schedule (decryption)
878 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200879#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200880int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key,
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200881 unsigned int keybits )
Paul Bakker5121ce52009-01-03 21:22:43 +0000882{
Arto Kinnunen14804442019-10-16 13:43:59 +0300883#if defined(MBEDTLS_AES_ONLY_ENCRYPT)
884 (void) ctx;
885 (void) key;
886 (void) keybits;
887
888 return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
889#else /* */
Arto Kinnunen6ce49882019-12-03 13:56:06 +0200890 volatile unsigned int i = 0, j = 0;
891 volatile int ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200892 mbedtls_aes_context cty;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000893 uint32_t *RK;
894 uint32_t *SK;
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200895
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100896 AES_VALIDATE_RET( ctx != NULL );
897 AES_VALIDATE_RET( key != NULL );
Simon Butcher5201e412018-12-06 17:40:14 +0000898
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200899 mbedtls_aes_init( &cty );
Paul Bakker5121ce52009-01-03 21:22:43 +0000900
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200901#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_PADLOCK_ALIGN16)
Paul Bakker048d04e2012-02-12 17:31:04 +0000902 if( aes_padlock_ace == -1 )
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100903 aes_padlock_ace = mbedtls_padlock_has_support( MBEDTLS_PADLOCK_ACE );
Paul Bakker048d04e2012-02-12 17:31:04 +0000904
905 if( aes_padlock_ace )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200906 ctx->rk = RK = MBEDTLS_PADLOCK_ALIGN16( ctx->buf );
Paul Bakker048d04e2012-02-12 17:31:04 +0000907 else
Paul Bakker5121ce52009-01-03 21:22:43 +0000908#endif
Paul Bakker048d04e2012-02-12 17:31:04 +0000909 ctx->rk = RK = ctx->buf;
Andrzej Kurekfac2f9b2020-07-19 00:32:34 -0400910#if defined(MBEDTLS_AES_SCA_COUNTERMEASURES)
Andrzej Kureke78775e2020-07-02 10:57:00 -0400911 mbedtls_generate_fake_key( keybits, ctx );
Andrzej Kurekfac2f9b2020-07-19 00:32:34 -0400912#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000913
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200914 /* Also checks keybits */
915 if( ( ret = mbedtls_aes_setkey_enc( &cty, key, keybits ) ) != 0 )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200916 goto exit;
Paul Bakker2b222c82009-07-27 21:03:45 +0000917
Manuel Pégourié-Gonnardafd5a082014-05-28 21:52:59 +0200918 ctx->nr = cty.nr;
919
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200920#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100921 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) )
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100922 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200923 mbedtls_aesni_inverse_key( (unsigned char *) ctx->rk,
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100924 (const unsigned char *) cty.rk, ctx->nr );
Arto Kinnunen6ce49882019-12-03 13:56:06 +0200925 i = 0;
926 j = 4;
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200927 goto exit;
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100928 }
929#endif
930
Paul Bakker5121ce52009-01-03 21:22:43 +0000931 SK = cty.rk + cty.nr * 4;
932
933 *RK++ = *SK++;
934 *RK++ = *SK++;
935 *RK++ = *SK++;
936 *RK++ = *SK++;
937
938 for( i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8 )
939 {
940 for( j = 0; j < 4; j++, SK++ )
941 {
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200942 *RK++ = AES_RT0( FSb[ ( *SK ) & 0xFF ] ) ^
943 AES_RT1( FSb[ ( *SK >> 8 ) & 0xFF ] ) ^
944 AES_RT2( FSb[ ( *SK >> 16 ) & 0xFF ] ) ^
945 AES_RT3( FSb[ ( *SK >> 24 ) & 0xFF ] );
Paul Bakker5121ce52009-01-03 21:22:43 +0000946 }
947 }
948
949 *RK++ = *SK++;
950 *RK++ = *SK++;
951 *RK++ = *SK++;
952 *RK++ = *SK++;
953
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200954exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200955 mbedtls_aes_free( &cty );
Paul Bakker2b222c82009-07-27 21:03:45 +0000956
Arto Kinnunen6ce49882019-12-03 13:56:06 +0200957 if( ret != 0 )
958 {
959 return( ret );
960 }
961 else if( ( i == 0 ) && ( j == 4 ) )
962 {
Andrzej Kurekfba59212020-08-07 21:02:25 -0400963#if defined(MBEDTLS_VALIDATE_AES_KEYS_INTEGRITY)
Andrzej Kurek9539f832020-08-10 15:58:13 -0400964 ctx->hash = mbedtls_hash( ctx->rk, keybits >> 3 );
Andrzej Kurekfba59212020-08-07 21:02:25 -0400965#endif
Arto Kinnunen6ce49882019-12-03 13:56:06 +0200966 return( ret );
967 }
968 else
969 {
970 return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
971 }
972
Arto Kinnunen14804442019-10-16 13:43:59 +0300973#endif /* MBEDTLS_AES_ONLY_ENCRYPT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000974}
Jaeden Amero9366feb2018-05-29 18:55:17 +0100975
976#if defined(MBEDTLS_CIPHER_MODE_XTS)
977static int mbedtls_aes_xts_decode_keys( const unsigned char *key,
978 unsigned int keybits,
979 const unsigned char **key1,
980 unsigned int *key1bits,
981 const unsigned char **key2,
982 unsigned int *key2bits )
983{
984 const unsigned int half_keybits = keybits / 2;
985 const unsigned int half_keybytes = half_keybits / 8;
986
987 switch( keybits )
988 {
989 case 256: break;
990 case 512: break;
991 default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH );
992 }
993
994 *key1bits = half_keybits;
995 *key2bits = half_keybits;
996 *key1 = &key[0];
997 *key2 = &key[half_keybytes];
998
999 return 0;
1000}
1001
1002int mbedtls_aes_xts_setkey_enc( mbedtls_aes_xts_context *ctx,
1003 const unsigned char *key,
1004 unsigned int keybits)
1005{
1006 int ret;
1007 const unsigned char *key1, *key2;
1008 unsigned int key1bits, key2bits;
1009
Manuel Pégourié-Gonnard68e3dff2018-12-12 12:48:04 +01001010 AES_VALIDATE_RET( ctx != NULL );
1011 AES_VALIDATE_RET( key != NULL );
1012
Jaeden Amero9366feb2018-05-29 18:55:17 +01001013 ret = mbedtls_aes_xts_decode_keys( key, keybits, &key1, &key1bits,
1014 &key2, &key2bits );
1015 if( ret != 0 )
1016 return( ret );
1017
1018 /* Set the tweak key. Always set tweak key for the encryption mode. */
1019 ret = mbedtls_aes_setkey_enc( &ctx->tweak, key2, key2bits );
1020 if( ret != 0 )
1021 return( ret );
1022
1023 /* Set crypt key for encryption. */
1024 return mbedtls_aes_setkey_enc( &ctx->crypt, key1, key1bits );
1025}
1026
1027int mbedtls_aes_xts_setkey_dec( mbedtls_aes_xts_context *ctx,
1028 const unsigned char *key,
1029 unsigned int keybits)
1030{
1031 int ret;
1032 const unsigned char *key1, *key2;
1033 unsigned int key1bits, key2bits;
1034
Manuel Pégourié-Gonnard68e3dff2018-12-12 12:48:04 +01001035 AES_VALIDATE_RET( ctx != NULL );
1036 AES_VALIDATE_RET( key != NULL );
1037
Jaeden Amero9366feb2018-05-29 18:55:17 +01001038 ret = mbedtls_aes_xts_decode_keys( key, keybits, &key1, &key1bits,
1039 &key2, &key2bits );
1040 if( ret != 0 )
1041 return( ret );
1042
1043 /* Set the tweak key. Always set tweak key for encryption. */
1044 ret = mbedtls_aes_setkey_enc( &ctx->tweak, key2, key2bits );
1045 if( ret != 0 )
1046 return( ret );
1047
1048 /* Set crypt key for decryption. */
1049 return mbedtls_aes_setkey_dec( &ctx->crypt, key1, key1bits );
1050}
1051#endif /* MBEDTLS_CIPHER_MODE_XTS */
1052
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001053#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001054
Paul Bakker5121ce52009-01-03 21:22:43 +00001055/*
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001056 * AES-ECB block encryption
1057 */
1058#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Arto Kinnunenc3532c22019-11-29 15:07:11 +02001059
Arto Kinnunen311ab592020-01-16 17:20:51 +02001060#if defined(MBEDTLS_AES_SCA_COUNTERMEASURES)
Shelly Libermanc907c812020-11-17 11:33:25 +02001061
1062#if defined(MBEDTLS_AES_128_BIT_MASKED)
1063
1064static uint8_t xtime(uint8_t x)
1065{
1066 return ((x << 1) ^ (((x >> 7) & 1) * 0x1b));
1067}
1068
1069static int sub_bytes_masked(uint32_t *data, uint8_t sbox_masked[256])
1070{
1071 volatile unsigned int i;
1072
1073 for (i = 0; i < 4; i++) {
1074 data[i] = ( (uint32_t) sbox_masked[ ( data[i] ) & 0xFF ] ) ^
1075 ( (uint32_t) sbox_masked[ ( data[i] >> 8 ) & 0xFF ] << 8 ) ^
1076 ( (uint32_t) sbox_masked[ ( data[i] >> 16 ) & 0xFF ] << 16 ) ^
1077 ( (uint32_t) sbox_masked[ ( data[i] >> 24 ) & 0xFF ] << 24 );
1078 }
1079
1080 if (i == 4){
1081 return 0;
1082 }
1083
1084 return MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
1085}
1086
1087static int mix_columns(uint8_t *s)
1088{
1089 masked_state_t *state = (masked_state_t *) s;
1090 volatile unsigned int i = 0;
1091 uint8_t Tmp, Tm, t;
1092
1093 for (i = 0; i < 4; ++i)
1094 {
1095 t = (*state)[i][0];
1096 Tmp = (*state)[i][0] ^ (*state)[i][1] ^ (*state)[i][2] ^ (*state)[i][3];
1097 Tm = (*state)[i][0] ^ (*state)[i][1];
1098 Tm = xtime(Tm);
1099 (*state)[i][0] ^= Tm ^ Tmp;
1100 Tm = (*state)[i][1] ^ (*state)[i][2];
1101 Tm = xtime(Tm);
1102 (*state)[i][1] ^= Tm ^ Tmp;
1103 Tm = (*state)[i][2] ^ (*state)[i][3];
1104 Tm = xtime(Tm);
1105 (*state)[i][2] ^= Tm ^ Tmp;
1106 Tm = (*state)[i][3] ^ t;
1107 Tm = xtime(Tm);
1108 (*state)[i][3] ^= Tm ^ Tmp;
1109 }
1110
1111 if (i == 4) {
1112 return 0;
1113 }
1114
1115 return MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
1116}
1117
1118static void shift_rows(uint8_t *s)
1119{
1120 uint8_t temp;
1121 masked_state_t *state = (masked_state_t *) s;
1122 // Rotate first row 1 columns to left
1123 temp = (*state)[0][1];
1124 (*state)[0][1] = (*state)[1][1];
1125 (*state)[1][1] = (*state)[2][1];
1126 (*state)[2][1] = (*state)[3][1];
1127 (*state)[3][1] = temp;
1128
1129 // Rotate second row 2 columns to left
1130 temp = (*state)[0][2];
1131 (*state)[0][2] = (*state)[2][2];
1132 (*state)[2][2] = temp;
1133
1134 temp = (*state)[1][2];
1135 (*state)[1][2] = (*state)[3][2];
1136 (*state)[3][2] = temp;
1137
1138 // Rotate third row 3 columns to left
1139 temp = (*state)[0][3];
1140 (*state)[0][3] = (*state)[3][3];
1141 (*state)[3][3] = (*state)[2][3];
1142 (*state)[2][3] = (*state)[1][3];
1143 (*state)[1][3] = temp;
1144
1145}
1146
1147#define mul_02(num) ( (num << 1) ^ (0x11b & -(num >> 7)) )
1148#define mul_03(num) ( mul_02(num) ^ num )
1149
1150static void calcMixColmask(uint32_t mask[10])
1151{
1152 mask[6] = mul_02(mask[0]) ^ mul_03(mask[1]) ^ mask[2] ^ mask[3];
1153 mask[7] = mask[0] ^ mul_02(mask[1]) ^ mul_03(mask[2]) ^ mask[3];
1154 mask[8] = mask[0] ^ mask[1] ^ mul_02(mask[2]) ^ mul_03(mask[3]);
1155 mask[9] = mul_03(mask[0]) ^ mask[1] ^ mask[2] ^ mul_02(mask[3]);
1156}
1157
1158//Calculate the the invSbox to change from Mask m to Mask m'
1159static int calcSboxMasked(uint32_t mask[10], uint8_t sbox_masked[256])
1160{
1161 volatile unsigned int i = 0;
1162
1163 for ( i = 0; i < 256; i++ )
1164 {
1165 sbox_masked[i ^ mask[4]] = FSb[i] ^ mask[5];
1166 }
1167 if (i == 256) {
1168 return 0;
1169 }
1170
1171 return MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
1172}
1173
1174static int remask(uint32_t *data, uint32_t m1, uint32_t m2, uint32_t m3, uint32_t m4, uint32_t m5, uint32_t m6, uint32_t m7, uint32_t m8)
1175{
1176
1177 volatile unsigned int i = 0;
1178
1179 for ( i = 0; i < 4; i++)
1180 {
1181 data[i] = data[i] ^ ( (m1^m5) );
1182 data[i] = data[i] ^ ( (m2^m6) << 8 );
1183 data[i] = data[i] ^ ( (m3^m7) << 16 );
1184 data[i] = data[i] ^ ( (m4^m8) << 24 );
1185 }
1186
1187 if (i == 4) {
1188 return 0;
1189 }
1190
1191 return MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
1192}
1193
1194
1195static int init_masking_encrypt(const uint8_t *rk, uint8_t *rk_masked, uint32_t mask[10], uint8_t sbox_masked[256] )
1196{
1197 volatile int flow_control = 0;
1198 unsigned int i = 0;
1199
1200 mbedtls_platform_memcpy(rk_masked, rk, AES_128_EXPANDED_KEY_SIZE_IN_WORDS*4);
1201
1202
1203 //Randomly generate the masks: m1 m2 m3 m4 m m'
1204 for (i = 0; i < 6; i++)
1205 {
1206 mask[i] = mbedtls_platform_random_in_range( 0xFF );
1207 flow_control++;
1208 }
1209
1210 //Calculate m1',m2',m3',m4'
1211 calcMixColmask(mask);
1212 flow_control++;
1213
1214 //Calculate the masked Sbox
1215 if (calcSboxMasked(mask, sbox_masked) == 0){
1216 flow_control++;
1217 }
1218
1219#define MASK_INIT_CONTROL 19
1220 //Init masked key
1221 if (remask( (uint32_t *)&rk_masked[(Nr * Nb * 4)], 0, 0, 0, 0, mask[5], mask[5], mask[5], mask[5]) == 0) {
1222 flow_control++;
1223 }
1224
1225 // Mask change from M1',M2',M3',M4' to M
1226 for (i = 0; i < Nr; i++)
1227 {
1228 if ( remask( (uint32_t *)&rk_masked[( i * Nb * 4 )], mask[6], mask[7], mask[8], mask[9], mask[4], mask[4], mask[4], mask[4]) == 0 )
1229 flow_control++;
1230 }
1231
1232 if( flow_control == MASK_INIT_CONTROL ) {
1233 mbedtls_platform_random_delay();
1234 if( flow_control == MASK_INIT_CONTROL ) {
1235 return MASK_INIT_CONTROL;
1236 }
1237 }
1238
1239 return MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
1240}
1241
1242static int add_rk_masked(uint32_t round, uint32_t *data, const uint32_t * rk_masked)
1243{
1244 volatile unsigned int i;
1245 unsigned int offset = round*4;
1246 for( i = 0; i < 4; i++ )
1247 {
1248 data[i] ^= rk_masked[offset + i] ;
1249 }
1250
1251 if (i == 4) {
1252 return 0;
1253 }
1254 return MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
1255}
1256
1257
1258static int aes_masked_round(uint32_t *data, uint32_t *key, uint32_t round, uint32_t mask[10], uint8_t sbox_masked[256])
1259{
1260 volatile uint32_t flow_control = 0;
1261
1262// Mask changes from M to M'
1263 if ( sub_bytes_masked(data, sbox_masked) == 0 )
1264 flow_control++;
1265
1266 //No impact on mask
1267 shift_rows((uint8_t *)data);
1268
1269 //Change mask from M' to
1270 // M1 for first row
1271 // M2 for second row
1272 // M3 for third row
1273 // M4 for fourth row
1274 if ( remask(data, mask[0], mask[1], mask[2], mask[3], mask[5], mask[5], mask[5], mask[5]) == 0)
1275 flow_control++;
1276
1277 // Masks change from M1,M2,M3,M4 to M1',M2',M3',M4'
1278 if ( mix_columns((uint8_t *)data) == 0)
1279 flow_control++;
1280
1281 // Add the First round key to the state before starting the rounds.
1282 // Masks change from M1',M2',M3',M4' to M
1283 if ( add_rk_masked(round,data, key) == 0 )
1284 flow_control++;
1285
1286 if ( flow_control == 4 )
1287 return 0;
1288
1289 return MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
1290}
1291
1292static int aes_masked_round_final( uint32_t *data, uint32_t *key, uint8_t sbox_masked[256] )
1293{
1294 volatile uint32_t flow_control = 0;
1295
1296 if ( sub_bytes_masked(data, sbox_masked) == 0 )
1297 flow_control++;
1298
1299 shift_rows((uint8_t *)data);
1300
1301 // Mask are removed by the last addroundkey
1302 // From M' to 0
1303 if( add_rk_masked(Nr, data, key) == 0)
1304 flow_control++;
1305
1306 if ( flow_control == 2 )
1307 return 0;
1308
1309 return MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
1310}
1311#define MASKING_FLOW_CONTORL (MASK_INIT_CONTROL + 2) //2 comes from initial data remask of real and fake data
1312
1313#else // end of MBEDTLS_AES_128_BIT_MASKED
1314
1315#define MASKING_FLOW_CONTORL 0
1316
Arto Kinnunenc3532c22019-11-29 15:07:11 +02001317static uint32_t *aes_fround( uint32_t *R,
1318 uint32_t *X0, uint32_t *X1, uint32_t *X2, uint32_t *X3,
1319 uint32_t Y0, uint32_t Y1, uint32_t Y2, uint32_t Y3 )
1320{
1321 *X0 = *R++ ^ AES_FT0( ( Y0 ) & 0xFF ) ^
1322 AES_FT1( ( Y1 >> 8 ) & 0xFF ) ^
1323 AES_FT2( ( Y2 >> 16 ) & 0xFF ) ^
1324 AES_FT3( ( Y3 >> 24 ) & 0xFF );
1325
1326 *X1 = *R++ ^ AES_FT0( ( Y1 ) & 0xFF ) ^
1327 AES_FT1( ( Y2 >> 8 ) & 0xFF ) ^
1328 AES_FT2( ( Y3 >> 16 ) & 0xFF ) ^
1329 AES_FT3( ( Y0 >> 24 ) & 0xFF );
1330
1331 *X2 = *R++ ^ AES_FT0( ( Y2 ) & 0xFF ) ^
1332 AES_FT1( ( Y3 >> 8 ) & 0xFF ) ^
1333 AES_FT2( ( Y0 >> 16 ) & 0xFF ) ^
1334 AES_FT3( ( Y1 >> 24 ) & 0xFF );
1335
1336 *X3 = *R++ ^ AES_FT0( ( Y3 ) & 0xFF ) ^
1337 AES_FT1( ( Y0 >> 8 ) & 0xFF ) ^
1338 AES_FT2( ( Y1 >> 16 ) & 0xFF ) ^
1339 AES_FT3( ( Y2 >> 24 ) & 0xFF );
1340
1341 return R;
1342}
1343
Shelly Libermanc907c812020-11-17 11:33:25 +02001344
Arto Kinnunenc3532c22019-11-29 15:07:11 +02001345static void aes_fround_final( uint32_t *R,
1346 uint32_t *X0, uint32_t *X1, uint32_t *X2, uint32_t *X3,
1347 uint32_t Y0, uint32_t Y1, uint32_t Y2, uint32_t Y3 )
1348{
Shelly Libermanc907c812020-11-17 11:33:25 +02001349
Arto Kinnunenc3532c22019-11-29 15:07:11 +02001350 *X0 = *R++ ^ ( (uint32_t) FSb[ ( (Y0) ) & 0xFF ] ) ^
1351 ( (uint32_t) FSb[ ( (Y1) >> 8 ) & 0xFF ] << 8 ) ^
1352 ( (uint32_t) FSb[ ( (Y2) >> 16 ) & 0xFF ] << 16 ) ^
1353 ( (uint32_t) FSb[ ( (Y3) >> 24 ) & 0xFF ] << 24 );
1354
1355 *X1 = *R++ ^ ( (uint32_t) FSb[ ( (Y1) ) & 0xFF ] ) ^
1356 ( (uint32_t) FSb[ ( (Y2) >> 8 ) & 0xFF ] << 8 ) ^
1357 ( (uint32_t) FSb[ ( (Y3) >> 16 ) & 0xFF ] << 16 ) ^
1358 ( (uint32_t) FSb[ ( (Y0) >> 24 ) & 0xFF ] << 24 );
1359
1360 *X2 = *R++ ^ ( (uint32_t) FSb[ ( (Y2) ) & 0xFF ] ) ^
1361 ( (uint32_t) FSb[ ( (Y3) >> 8 ) & 0xFF ] << 8 ) ^
1362 ( (uint32_t) FSb[ ( (Y0) >> 16 ) & 0xFF ] << 16 ) ^
1363 ( (uint32_t) FSb[ ( (Y1) >> 24 ) & 0xFF ] << 24 );
1364
1365 *X3 = *R++ ^ ( (uint32_t) FSb[ ( (Y3) ) & 0xFF ] ) ^
1366 ( (uint32_t) FSb[ ( (Y0) >> 8 ) & 0xFF ] << 8 ) ^
1367 ( (uint32_t) FSb[ ( (Y1) >> 16 ) & 0xFF ] << 16 ) ^
1368 ( (uint32_t) FSb[ ( (Y2) >> 24 ) & 0xFF ] << 24 );
1369}
Shelly Libermanc907c812020-11-17 11:33:25 +02001370#endif // MBEDTLS_AES_128_BIT_MASKED
1371
Arto Kinnunenc3532c22019-11-29 15:07:11 +02001372
Andres AGf5bf7182017-03-03 14:09:56 +00001373int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx,
1374 const unsigned char input[16],
1375 unsigned char output[16] )
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001376{
Arto Kinnunen98c93af2020-01-14 13:31:03 +02001377 int i, tindex, offset, stop_mark, dummy_rounds;
Arto Kinnunen172836a2019-11-28 13:34:13 +02001378 aes_r_data_t aes_data_real; // real data
Arto Kinnunen172836a2019-11-28 13:34:13 +02001379 aes_r_data_t aes_data_fake; // fake data
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001380 aes_r_data_t *aes_data_ptr; // pointer to real or fake data
Shelly Libermanc907c812020-11-17 11:33:25 +02001381 aes_r_data_t *aes_data_table[2] = {0}; // pointers to real and fake data
Arto Kinnunen311ab592020-01-16 17:20:51 +02001382 int round_ctrl_table_len = ctx->nr + 2 + AES_SCA_CM_ROUNDS;
Shelly Libermanc907c812020-11-17 11:33:25 +02001383 volatile int flow_control = 0;
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001384 // control bytes for AES calculation rounds,
1385 // reserve based on max rounds + dummy rounds + 2 (for initial key addition)
1386 uint8_t round_ctrl_table[( 14 + AES_SCA_CM_ROUNDS + 2 )];
Arto Kinnunenf93d55e2019-10-11 11:15:57 +03001387
Shelly Libermanc907c812020-11-17 11:33:25 +02001388#if defined MBEDTLS_AES_128_BIT_MASKED
1389 uint32_t rk_masked[AES_128_EXPANDED_KEY_SIZE_IN_WORDS] = {0};
1390 static uint8_t sbox_masked[256] = {0};
1391 uint32_t mask[10] = {0};
1392#endif
1393
Andrzej Kurekfba59212020-08-07 21:02:25 -04001394#if defined(MBEDTLS_VALIDATE_AES_KEYS_INTEGRITY)
1395 unsigned key_bytes = 0;
Andrzej Kurek9539f832020-08-10 15:58:13 -04001396 uint32_t check_hash = 0;
Andrzej Kurekfba59212020-08-07 21:02:25 -04001397 switch( ctx->nr )
1398 {
1399 case 10: key_bytes = 16; break;
1400#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
1401 case 12: key_bytes = 24; break;
1402 case 14: key_bytes = 32; break;
1403#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
1404 default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH );
1405 }
Andrzej Kurek9539f832020-08-10 15:58:13 -04001406 check_hash = mbedtls_hash( ctx->rk, key_bytes );
Andrzej Kurekfba59212020-08-07 21:02:25 -04001407#endif
1408
Shelly Libermanc907c812020-11-17 11:33:25 +02001409#if defined (MBEDTLS_AES_128_BIT_MASKED)
1410 //Flow control should be MASK_INIT_CONTROL and it will be checked as a part last flow control verification
1411 flow_control = init_masking_encrypt((uint8_t*)ctx->rk, (uint8_t*)rk_masked, mask, sbox_masked);
1412 aes_data_real.rk_ptr = &rk_masked[0];
1413#else
Arto Kinnunen172836a2019-11-28 13:34:13 +02001414 aes_data_real.rk_ptr = ctx->rk;
Shelly Libermanc907c812020-11-17 11:33:25 +02001415#endif
1416
Andrzej Kureke78775e2020-07-02 10:57:00 -04001417 aes_data_fake.rk_ptr = ctx->frk;
Andrzej Kurekfac2f9b2020-07-19 00:32:34 -04001418
Arto Kinnunen311ab592020-01-16 17:20:51 +02001419 aes_data_table[0] = &aes_data_real;
1420 aes_data_table[1] = &aes_data_fake;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001421
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001422 // Get AES calculation control bytes
Arto Kinnunen2b24f422020-01-16 15:04:11 +02001423 dummy_rounds = aes_sca_cm_data_randomize( round_ctrl_table,
1424 round_ctrl_table_len );
Shelly Libermanc907c812020-11-17 11:33:25 +02001425 flow_control += dummy_rounds;
Arto Kinnunen172836a2019-11-28 13:34:13 +02001426
Arto Kinnunen17540ab2020-01-20 11:46:34 +02001427 // SCA countermeasure, safely clear the aes_data_real.xy_values
Jarno Lamsa282db8e2020-01-08 14:53:17 +02001428 mbedtls_platform_memset( aes_data_real.xy_values, 0, 16 );
Jarno Lamsa282db8e2020-01-08 14:53:17 +02001429
Arto Kinnunen17540ab2020-01-20 11:46:34 +02001430 // SCA countermeasure, randomize secret data location by initializing it in
1431 // a random order and writing randomized fake data between the real data
1432 // writes.
1433 offset = mbedtls_platform_random_in_range( 4 );
Arto Kinnunen2b24f422020-01-16 15:04:11 +02001434 i = offset;
1435 do
Arto Kinnunen172836a2019-11-28 13:34:13 +02001436 {
1437 GET_UINT32_LE( aes_data_real.xy_values[i], input, ( i * 4 ) );
Andrzej Kurek11ddf252020-06-24 17:33:39 -04001438 aes_data_fake.xy_values[i] = mbedtls_platform_random_uint32();
Arto Kinnunen2b24f422020-01-16 15:04:11 +02001439 flow_control++;
1440 } while( ( i = ( i + 1 ) % 4 ) != offset );
Jarno Lamsa282db8e2020-01-08 14:53:17 +02001441
Shelly Libermanc907c812020-11-17 11:33:25 +02001442#if defined (MBEDTLS_AES_128_BIT_MASKED)
1443 //Plain text masked with m1',m2',m3',m4'
1444 if (remask( &aes_data_real.xy_values[0], mask[6], mask[7], mask[8], mask[9], 0, 0, 0, 0) == 0)
1445 flow_control++;
1446
1447 if (remask( &aes_data_fake.xy_values[0], mask[6], mask[7], mask[8], mask[9], 0, 0, 0, 0) == 0)
1448 flow_control++;
1449#endif
1450
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001451 tindex = 0;
1452 do
Jarno Lamsa282db8e2020-01-08 14:53:17 +02001453 {
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001454 // Get pointer to the real or fake data
1455 aes_data_ptr = aes_data_table[round_ctrl_table[tindex] >> 4];
1456 stop_mark = round_ctrl_table[tindex] & 0x03;
Arto Kinnunen172836a2019-11-28 13:34:13 +02001457
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001458 // initial round key addition
Shelly Libermanc907c812020-11-17 11:33:25 +02001459#if defined (MBEDTLS_AES_128_BIT_MASKED)
1460 if ( add_rk_masked(0, &aes_data_ptr->xy_values[0], aes_data_ptr->rk_ptr) == 0)
1461 flow_control++;
1462 aes_data_ptr->round = 1;
1463#else
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001464 for( i = 0; i < 4; i++ )
1465 {
1466 aes_data_ptr->xy_values[i] ^= *aes_data_ptr->rk_ptr++;
1467 }
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001468 flow_control++;
Shelly Libermanc907c812020-11-17 11:33:25 +02001469#endif
1470
1471 tindex++;
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001472 } while( stop_mark == 0 );
1473
Shelly Libermanc907c812020-11-17 11:33:25 +02001474
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001475 // Calculate AES rounds (9, 11 or 13 rounds) + dummy rounds
1476 do
Arto Kinnunen172836a2019-11-28 13:34:13 +02001477 {
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001478 // Get pointer to the real or fake data
1479 aes_data_ptr = aes_data_table[round_ctrl_table[tindex] >> 4];
1480 offset = round_ctrl_table[tindex] & 0x04;
1481 stop_mark = round_ctrl_table[tindex] & 0x03;
Shelly Libermanc907c812020-11-17 11:33:25 +02001482#if defined (MBEDTLS_AES_128_BIT_MASKED)
1483 if (aes_masked_round( &aes_data_ptr->xy_values[0], aes_data_ptr->rk_ptr,
1484 aes_data_ptr->round, mask, sbox_masked) == 0)
1485 flow_control++;
1486 aes_data_ptr->round ++;
1487#else
Arto Kinnunenc3532c22019-11-29 15:07:11 +02001488 aes_data_ptr->rk_ptr = aes_fround( aes_data_ptr->rk_ptr,
1489 &aes_data_ptr->xy_values[0 + offset],
1490 &aes_data_ptr->xy_values[1 + offset],
1491 &aes_data_ptr->xy_values[2 + offset],
1492 &aes_data_ptr->xy_values[3 + offset],
Arto Kinnunen172836a2019-11-28 13:34:13 +02001493 aes_data_ptr->xy_values[4 - offset],
1494 aes_data_ptr->xy_values[5 - offset],
1495 aes_data_ptr->xy_values[6 - offset],
1496 aes_data_ptr->xy_values[7 - offset] );
Arto Kinnunen6ce49882019-12-03 13:56:06 +02001497 flow_control++;
Shelly Libermanc907c812020-11-17 11:33:25 +02001498#endif
1499 tindex++;
1500
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001501 } while( stop_mark == 0 );
Arto Kinnunen172836a2019-11-28 13:34:13 +02001502
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001503 // Calculate final AES round + dummy rounds
1504 do
Arto Kinnunen172836a2019-11-28 13:34:13 +02001505 {
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001506 aes_data_ptr = aes_data_table[round_ctrl_table[tindex] >> 4];
1507 stop_mark = round_ctrl_table[tindex] & 0x03;
Shelly Libermanc907c812020-11-17 11:33:25 +02001508#if defined (MBEDTLS_AES_128_BIT_MASKED)
1509 if ( aes_masked_round_final( &aes_data_ptr->xy_values[0],
1510 aes_data_ptr->rk_ptr, sbox_masked ) == 0)
1511 flow_control++;
1512 //Cleanup the masked key
1513 mbedtls_platform_memset(rk_masked, 0, sizeof(rk_masked));
1514#else
Arto Kinnunenc3532c22019-11-29 15:07:11 +02001515 aes_fround_final( aes_data_ptr->rk_ptr,
1516 &aes_data_ptr->xy_values[0],
1517 &aes_data_ptr->xy_values[1],
1518 &aes_data_ptr->xy_values[2],
1519 &aes_data_ptr->xy_values[3],
Arto Kinnunen172836a2019-11-28 13:34:13 +02001520 aes_data_ptr->xy_values[4],
1521 aes_data_ptr->xy_values[5],
1522 aes_data_ptr->xy_values[6],
1523 aes_data_ptr->xy_values[7] );
Arto Kinnunen6ce49882019-12-03 13:56:06 +02001524 flow_control++;
Shelly Libermanc907c812020-11-17 11:33:25 +02001525#endif
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001526 tindex++;
1527 } while( stop_mark == 0 );
Arto Kinnunen172836a2019-11-28 13:34:13 +02001528
Shelly Libermanc907c812020-11-17 11:33:25 +02001529
Arto Kinnunen17540ab2020-01-20 11:46:34 +02001530 // SCA countermeasure, safely clear the output
Jarno Lamsa282db8e2020-01-08 14:53:17 +02001531 mbedtls_platform_memset( output, 0, 16 );
Jarno Lamsa282db8e2020-01-08 14:53:17 +02001532
Arto Kinnunen17540ab2020-01-20 11:46:34 +02001533 // SCA countermeasure, randomize secret data location by writing to it in
1534 // a random order.
1535 offset = mbedtls_platform_random_in_range( 4 );
Arto Kinnunen2b24f422020-01-16 15:04:11 +02001536 i = offset;
1537 do
Jarno Lamsa282db8e2020-01-08 14:53:17 +02001538 {
1539 PUT_UINT32_LE( aes_data_real.xy_values[i], output, ( i * 4 ) );
1540 flow_control++;
Arto Kinnunen2b24f422020-01-16 15:04:11 +02001541 } while( ( i = ( i + 1 ) % 4 ) != offset );
Jarno Lamsa282db8e2020-01-08 14:53:17 +02001542
Shelly Libermanc907c812020-11-17 11:33:25 +02001543#if defined (MBEDTLS_AES_128_BIT_MASKED)
1544 mbedtls_platform_memset(rk_masked, 0, sizeof(rk_masked));
1545#endif
Andrzej Kurekfba59212020-08-07 21:02:25 -04001546 /* Double negation is used to silence an "extraneous parentheses" warning */
Shelly Libermanc907c812020-11-17 11:33:25 +02001547 if( ! ( flow_control != tindex + dummy_rounds + MASKING_FLOW_CONTORL + 8 )
Andrzej Kurekfba59212020-08-07 21:02:25 -04001548#if defined(MBEDTLS_VALIDATE_AES_KEYS_INTEGRITY)
Andrzej Kurek9539f832020-08-10 15:58:13 -04001549 && check_hash == ctx->hash
Andrzej Kurekfba59212020-08-07 21:02:25 -04001550#endif
1551 )
Arto Kinnunen6ce49882019-12-03 13:56:06 +02001552 {
Andrzej Kurekfba59212020-08-07 21:02:25 -04001553#if defined(MBEDTLS_VALIDATE_AES_KEYS_INTEGRITY)
1554 mbedtls_platform_random_delay();
Andrzej Kurek9539f832020-08-10 15:58:13 -04001555 if( mbedtls_hash( ctx->rk, key_bytes ) == ctx->hash )
Andrzej Kurekfba59212020-08-07 21:02:25 -04001556#endif
1557 {
1558 return 0;
1559 }
Arto Kinnunen6ce49882019-12-03 13:56:06 +02001560 }
1561
Andrzej Kurekca609372020-07-08 03:19:02 -04001562 // Clear the output in case of a FI
1563 mbedtls_platform_memset( output, 0, 16 );
Shelly Libermanc907c812020-11-17 11:33:25 +02001564 mbedtls_platform_memset( (uint8_t*)&aes_data_real, 0, sizeof(aes_data_real) );
1565 mbedtls_platform_memset (aes_data_table, 0, sizeof(aes_data_table));
1566#if defined (MBEDTLS_AES_128_BIT_MASKED)
1567 //Clear masked key, masked sbox and mask in case of a FI
1568 mbedtls_platform_memset(rk_masked, 0, sizeof(rk_masked));
1569 mbedtls_platform_memset(mask, 0, sizeof(mask));
1570 mbedtls_platform_memset(sbox_masked, 0, sizeof(sbox_masked));
1571#endif
Arto Kinnunen6ce49882019-12-03 13:56:06 +02001572 return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001573}
Arto Kinnunen311ab592020-01-16 17:20:51 +02001574
1575#else /* MBEDTLS_AES_SCA_COUNTERMEASURES */
1576
1577#define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \
1578 do \
1579 { \
1580 (X0) = *RK++ ^ AES_FT0( ( (Y0) ) & 0xFF ) ^ \
1581 AES_FT1( ( (Y1) >> 8 ) & 0xFF ) ^ \
1582 AES_FT2( ( (Y2) >> 16 ) & 0xFF ) ^ \
1583 AES_FT3( ( (Y3) >> 24 ) & 0xFF ); \
1584 \
1585 (X1) = *RK++ ^ AES_FT0( ( (Y1) ) & 0xFF ) ^ \
1586 AES_FT1( ( (Y2) >> 8 ) & 0xFF ) ^ \
1587 AES_FT2( ( (Y3) >> 16 ) & 0xFF ) ^ \
1588 AES_FT3( ( (Y0) >> 24 ) & 0xFF ); \
1589 \
1590 (X2) = *RK++ ^ AES_FT0( ( (Y2) ) & 0xFF ) ^ \
1591 AES_FT1( ( (Y3) >> 8 ) & 0xFF ) ^ \
1592 AES_FT2( ( (Y0) >> 16 ) & 0xFF ) ^ \
1593 AES_FT3( ( (Y1) >> 24 ) & 0xFF ); \
1594 \
1595 (X3) = *RK++ ^ AES_FT0( ( (Y3) ) & 0xFF ) ^ \
1596 AES_FT1( ( (Y0) >> 8 ) & 0xFF ) ^ \
1597 AES_FT2( ( (Y1) >> 16 ) & 0xFF ) ^ \
1598 AES_FT3( ( (Y2) >> 24 ) & 0xFF ); \
1599 } while( 0 )
1600
1601int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx,
1602 const unsigned char input[16],
1603 unsigned char output[16] )
1604{
1605 int i;
1606 uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3;
1607
1608 RK = ctx->rk;
1609
1610 GET_UINT32_LE( X0, input, 0 ); X0 ^= *RK++;
1611 GET_UINT32_LE( X1, input, 4 ); X1 ^= *RK++;
1612 GET_UINT32_LE( X2, input, 8 ); X2 ^= *RK++;
1613 GET_UINT32_LE( X3, input, 12 ); X3 ^= *RK++;
1614
1615 for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- )
1616 {
1617 AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
1618 AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 );
1619 }
1620
1621 AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
1622
1623 X0 = *RK++ ^ \
1624 ( (uint32_t) FSb[ ( Y0 ) & 0xFF ] ) ^
1625 ( (uint32_t) FSb[ ( Y1 >> 8 ) & 0xFF ] << 8 ) ^
1626 ( (uint32_t) FSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^
1627 ( (uint32_t) FSb[ ( Y3 >> 24 ) & 0xFF ] << 24 );
1628
1629 X1 = *RK++ ^ \
1630 ( (uint32_t) FSb[ ( Y1 ) & 0xFF ] ) ^
1631 ( (uint32_t) FSb[ ( Y2 >> 8 ) & 0xFF ] << 8 ) ^
1632 ( (uint32_t) FSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^
1633 ( (uint32_t) FSb[ ( Y0 >> 24 ) & 0xFF ] << 24 );
1634
1635 X2 = *RK++ ^ \
1636 ( (uint32_t) FSb[ ( Y2 ) & 0xFF ] ) ^
1637 ( (uint32_t) FSb[ ( Y3 >> 8 ) & 0xFF ] << 8 ) ^
1638 ( (uint32_t) FSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^
1639 ( (uint32_t) FSb[ ( Y1 >> 24 ) & 0xFF ] << 24 );
1640
1641 X3 = *RK++ ^ \
1642 ( (uint32_t) FSb[ ( Y3 ) & 0xFF ] ) ^
1643 ( (uint32_t) FSb[ ( Y0 >> 8 ) & 0xFF ] << 8 ) ^
1644 ( (uint32_t) FSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^
1645 ( (uint32_t) FSb[ ( Y2 >> 24 ) & 0xFF ] << 24 );
1646
1647 PUT_UINT32_LE( X0, output, 0 );
1648 PUT_UINT32_LE( X1, output, 4 );
1649 PUT_UINT32_LE( X2, output, 8 );
1650 PUT_UINT32_LE( X3, output, 12 );
1651
Andrzej Kureka8405442019-11-12 03:34:03 -05001652 mbedtls_platform_zeroize( &X0, sizeof( X0 ) );
1653 mbedtls_platform_zeroize( &X1, sizeof( X1 ) );
1654 mbedtls_platform_zeroize( &X2, sizeof( X2 ) );
1655 mbedtls_platform_zeroize( &X3, sizeof( X3 ) );
1656
1657 mbedtls_platform_zeroize( &Y0, sizeof( Y0 ) );
1658 mbedtls_platform_zeroize( &Y1, sizeof( Y1 ) );
1659 mbedtls_platform_zeroize( &Y2, sizeof( Y2 ) );
1660 mbedtls_platform_zeroize( &Y3, sizeof( Y3 ) );
1661
1662 mbedtls_platform_zeroize( &RK, sizeof( RK ) );
1663
Arto Kinnunen311ab592020-01-16 17:20:51 +02001664 return( 0 );
1665}
1666#endif /* MBEDTLS_AES_SCA_COUNTERMEASURES */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001667#endif /* !MBEDTLS_AES_ENCRYPT_ALT */
1668
Gilles Peskine8db3efb2018-02-21 19:16:20 +01001669#if !defined(MBEDTLS_DEPRECATED_REMOVED)
Hanno Beckerbedc2052017-06-26 12:46:56 +01001670void mbedtls_aes_encrypt( mbedtls_aes_context *ctx,
1671 const unsigned char input[16],
1672 unsigned char output[16] )
1673{
1674 mbedtls_internal_aes_encrypt( ctx, input, output );
1675}
Gilles Peskine8db3efb2018-02-21 19:16:20 +01001676#endif /* !MBEDTLS_DEPRECATED_REMOVED */
Hanno Beckerbedc2052017-06-26 12:46:56 +01001677
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001678/*
1679 * AES-ECB block decryption
1680 */
Arto Kinnunen14804442019-10-16 13:43:59 +03001681
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001682#if !defined(MBEDTLS_AES_DECRYPT_ALT)
Arto Kinnunen14804442019-10-16 13:43:59 +03001683#if !defined(MBEDTLS_AES_ONLY_ENCRYPT)
Arto Kinnunenc3532c22019-11-29 15:07:11 +02001684
Arto Kinnunen311ab592020-01-16 17:20:51 +02001685#if defined(MBEDTLS_AES_SCA_COUNTERMEASURES)
Arto Kinnunenc3532c22019-11-29 15:07:11 +02001686static uint32_t *aes_rround( uint32_t *R,
1687 uint32_t *X0, uint32_t *X1, uint32_t *X2, uint32_t *X3,
1688 uint32_t Y0, uint32_t Y1, uint32_t Y2, uint32_t Y3 )
1689{
1690 *X0 = *R++ ^ AES_RT0( ( Y0 ) & 0xFF ) ^
1691 AES_RT1( ( Y3 >> 8 ) & 0xFF ) ^
1692 AES_RT2( ( Y2 >> 16 ) & 0xFF ) ^
1693 AES_RT3( ( Y1 >> 24 ) & 0xFF );
1694
1695 *X1 = *R++ ^ AES_RT0( ( Y1 ) & 0xFF ) ^
1696 AES_RT1( ( Y0 >> 8 ) & 0xFF ) ^
1697 AES_RT2( ( Y3 >> 16 ) & 0xFF ) ^
1698 AES_RT3( ( Y2 >> 24 ) & 0xFF );
1699
1700 *X2 = *R++ ^ AES_RT0( ( Y2 ) & 0xFF ) ^
1701 AES_RT1( ( Y1 >> 8 ) & 0xFF ) ^
1702 AES_RT2( ( Y0 >> 16 ) & 0xFF ) ^
1703 AES_RT3( ( Y3 >> 24 ) & 0xFF );
1704
1705 *X3 = *R++ ^ AES_RT0( ( Y3 ) & 0xFF ) ^
1706 AES_RT1( ( Y2 >> 8 ) & 0xFF ) ^
1707 AES_RT2( ( Y1 >> 16 ) & 0xFF ) ^
1708 AES_RT3( ( Y0 >> 24 ) & 0xFF );
1709 return R;
1710}
1711
1712static void aes_rround_final( uint32_t *R,
1713 uint32_t *X0, uint32_t *X1, uint32_t *X2, uint32_t *X3,
1714 uint32_t Y0, uint32_t Y1, uint32_t Y2, uint32_t Y3 )
1715{
1716 *X0 = *R++ ^ ( (uint32_t) RSb[ ( (Y0) ) & 0xFF ] ) ^
1717 ( (uint32_t) RSb[ ( (Y3) >> 8 ) & 0xFF ] << 8 ) ^
1718 ( (uint32_t) RSb[ ( (Y2) >> 16 ) & 0xFF ] << 16 ) ^
1719 ( (uint32_t) RSb[ ( (Y1) >> 24 ) & 0xFF ] << 24 );
1720
1721 *X1 = *R++ ^ ( (uint32_t) RSb[ ( (Y1) ) & 0xFF ] ) ^
1722 ( (uint32_t) RSb[ ( (Y0) >> 8 ) & 0xFF ] << 8 ) ^
1723 ( (uint32_t) RSb[ ( (Y3) >> 16 ) & 0xFF ] << 16 ) ^
1724 ( (uint32_t) RSb[ ( (Y2) >> 24 ) & 0xFF ] << 24 );
1725
1726 *X2 = *R++ ^ ( (uint32_t) RSb[ ( (Y2) ) & 0xFF ] ) ^
1727 ( (uint32_t) RSb[ ( (Y1) >> 8 ) & 0xFF ] << 8 ) ^
1728 ( (uint32_t) RSb[ ( (Y0) >> 16 ) & 0xFF ] << 16 ) ^
1729 ( (uint32_t) RSb[ ( (Y3) >> 24 ) & 0xFF ] << 24 );
1730
1731 *X3 = *R++ ^ ( (uint32_t) RSb[ ( (Y3) ) & 0xFF ] ) ^
1732 ( (uint32_t) RSb[ ( (Y2) >> 8 ) & 0xFF ] << 8 ) ^
1733 ( (uint32_t) RSb[ ( (Y1) >> 16 ) & 0xFF ] << 16 ) ^
1734 ( (uint32_t) RSb[ ( (Y0) >> 24 ) & 0xFF ] << 24 );
1735}
1736
Andres AGf5bf7182017-03-03 14:09:56 +00001737int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx,
1738 const unsigned char input[16],
1739 unsigned char output[16] )
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001740{
Arto Kinnunen98c93af2020-01-14 13:31:03 +02001741 int i, tindex, offset, stop_mark, dummy_rounds;
Arto Kinnunen172836a2019-11-28 13:34:13 +02001742 aes_r_data_t aes_data_real; // real data
Arto Kinnunen172836a2019-11-28 13:34:13 +02001743 aes_r_data_t aes_data_fake; // fake data
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001744 aes_r_data_t *aes_data_ptr; // pointer to real or fake data
Arto Kinnunen172836a2019-11-28 13:34:13 +02001745 aes_r_data_t *aes_data_table[2]; // pointers to real and fake data
Arto Kinnunen311ab592020-01-16 17:20:51 +02001746 int round_ctrl_table_len = ctx->nr + 2 + AES_SCA_CM_ROUNDS;
Arto Kinnunen6ce49882019-12-03 13:56:06 +02001747 volatile int flow_control;
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001748 // control bytes for AES calculation rounds,
1749 // reserve based on max rounds + dummy rounds + 2 (for initial key addition)
1750 uint8_t round_ctrl_table[( 14 + AES_SCA_CM_ROUNDS + 2 )];
Arto Kinnunenf93d55e2019-10-11 11:15:57 +03001751
Andrzej Kurekfba59212020-08-07 21:02:25 -04001752#if defined(MBEDTLS_VALIDATE_AES_KEYS_INTEGRITY)
1753 unsigned key_bytes = 0;
Andrzej Kurek9539f832020-08-10 15:58:13 -04001754 uint32_t check_hash = 0;
Andrzej Kurekfba59212020-08-07 21:02:25 -04001755 switch( ctx->nr )
1756 {
1757 case 10: key_bytes = 16; break;
1758#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
1759 case 12: key_bytes = 24; break;
1760 case 14: key_bytes = 32; break;
1761#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
1762 default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH );
1763 }
Andrzej Kurek9539f832020-08-10 15:58:13 -04001764 check_hash = mbedtls_hash( ctx->rk, key_bytes );
Andrzej Kurekfba59212020-08-07 21:02:25 -04001765#endif
1766
Arto Kinnunen172836a2019-11-28 13:34:13 +02001767 aes_data_real.rk_ptr = ctx->rk;
Andrzej Kureke78775e2020-07-02 10:57:00 -04001768 aes_data_fake.rk_ptr = ctx->frk;
Andrzej Kurekfac2f9b2020-07-19 00:32:34 -04001769
Arto Kinnunen311ab592020-01-16 17:20:51 +02001770 aes_data_table[0] = &aes_data_real;
1771 aes_data_table[1] = &aes_data_fake;
Arto Kinnunenf93d55e2019-10-11 11:15:57 +03001772
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001773 // Get AES calculation control bytes
Arto Kinnunen98c93af2020-01-14 13:31:03 +02001774 dummy_rounds = aes_sca_cm_data_randomize( round_ctrl_table,
Arto Kinnunen2b24f422020-01-16 15:04:11 +02001775 round_ctrl_table_len );
Arto Kinnunen98c93af2020-01-14 13:31:03 +02001776 flow_control = dummy_rounds;
1777
Arto Kinnunen17540ab2020-01-20 11:46:34 +02001778 // SCA countermeasure, safely clear the aes_data_real.xy_values
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001779 mbedtls_platform_memset( aes_data_real.xy_values, 0, 16 );
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001780
Arto Kinnunen17540ab2020-01-20 11:46:34 +02001781 // SCA countermeasure, randomize secret data location by initializing it in
1782 // a random order and writing randomized fake data between the real data
1783 // writes.
1784 offset = mbedtls_platform_random_in_range( 4 );
Arto Kinnunen2b24f422020-01-16 15:04:11 +02001785 i = offset;
1786 do
Arto Kinnunenf93d55e2019-10-11 11:15:57 +03001787 {
Arto Kinnunen172836a2019-11-28 13:34:13 +02001788 GET_UINT32_LE( aes_data_real.xy_values[i], input, ( i * 4 ) );
Arto Kinnunen311ab592020-01-16 17:20:51 +02001789 aes_data_fake.xy_values[i] = mbedtls_platform_random_in_range( 0xffffffff );
Arto Kinnunen2b24f422020-01-16 15:04:11 +02001790 flow_control++;
1791 } while( ( i = ( i + 1 ) % 4 ) != offset );
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001792
1793 tindex = 0;
1794 do
1795 {
1796 // Get pointer to the real or fake data
1797 aes_data_ptr = aes_data_table[round_ctrl_table[tindex] >> 4];
1798 stop_mark = round_ctrl_table[tindex] & 0x03;
1799
1800 // initial round key addition
1801 for( i = 0; i < 4; i++ )
1802 {
1803 aes_data_ptr->xy_values[i] ^= *aes_data_ptr->rk_ptr++;
1804 }
1805 tindex++;
1806 flow_control++;
1807 } while( stop_mark == 0 );
1808
1809 // Calculate AES rounds (9, 11 or 13 rounds) + dummy rounds
1810 do
1811 {
1812 // Get pointer to the real or fake data
1813 aes_data_ptr = aes_data_table[round_ctrl_table[tindex] >> 4];
1814 offset = round_ctrl_table[tindex] & 0x04;
1815 stop_mark = round_ctrl_table[tindex] & 0x03;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001816
Arto Kinnunenc3532c22019-11-29 15:07:11 +02001817 aes_data_ptr->rk_ptr = aes_rround( aes_data_ptr->rk_ptr,
1818 &aes_data_ptr->xy_values[0 + offset],
1819 &aes_data_ptr->xy_values[1 + offset],
1820 &aes_data_ptr->xy_values[2 + offset],
1821 &aes_data_ptr->xy_values[3 + offset],
Arto Kinnunen172836a2019-11-28 13:34:13 +02001822 aes_data_ptr->xy_values[4 - offset],
1823 aes_data_ptr->xy_values[5 - offset],
1824 aes_data_ptr->xy_values[6 - offset],
1825 aes_data_ptr->xy_values[7 - offset] );
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001826 tindex++;
Arto Kinnunen6ce49882019-12-03 13:56:06 +02001827 flow_control++;
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001828 } while( stop_mark == 0 );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001829
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001830 // Calculate final AES round + dummy rounds
1831 do
Arto Kinnunen172836a2019-11-28 13:34:13 +02001832 {
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001833 aes_data_ptr = aes_data_table[round_ctrl_table[tindex] >> 4];
1834 stop_mark = round_ctrl_table[tindex] & 0x03;
Arto Kinnunenc3532c22019-11-29 15:07:11 +02001835 aes_rround_final( aes_data_ptr->rk_ptr,
1836 &aes_data_ptr->xy_values[0],
1837 &aes_data_ptr->xy_values[1],
1838 &aes_data_ptr->xy_values[2],
1839 &aes_data_ptr->xy_values[3],
Arto Kinnunen172836a2019-11-28 13:34:13 +02001840 aes_data_ptr->xy_values[4],
1841 aes_data_ptr->xy_values[5],
1842 aes_data_ptr->xy_values[6],
1843 aes_data_ptr->xy_values[7] );
Arto Kinnunen6ce49882019-12-03 13:56:06 +02001844 flow_control++;
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001845 tindex++;
1846 } while( stop_mark == 0 );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001847
Arto Kinnunen17540ab2020-01-20 11:46:34 +02001848 // SCA countermeasure, safely clear the output
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001849 mbedtls_platform_memset( output, 0, 16 );
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001850
Arto Kinnunen17540ab2020-01-20 11:46:34 +02001851 // SCA countermeasure, randomize secret data location by writing to it in
1852 // a random order.
1853 offset = mbedtls_platform_random_in_range( 4 );
Arto Kinnunen2b24f422020-01-16 15:04:11 +02001854 i = offset;
1855 do
Arto Kinnunen172836a2019-11-28 13:34:13 +02001856 {
1857 PUT_UINT32_LE( aes_data_real.xy_values[i], output, ( i * 4 ) );
Arto Kinnunen6ce49882019-12-03 13:56:06 +02001858 flow_control++;
Arto Kinnunen2b24f422020-01-16 15:04:11 +02001859 } while( ( i = ( i + 1 ) % 4 ) != offset );
Andres AGf5bf7182017-03-03 14:09:56 +00001860
Andrzej Kurekfba59212020-08-07 21:02:25 -04001861 /* Double negation is used to silence an "extraneous parentheses" warning */
1862 if( ! ( flow_control != tindex + dummy_rounds + 8 )
1863#if defined(MBEDTLS_VALIDATE_AES_KEYS_INTEGRITY)
Andrzej Kurek9539f832020-08-10 15:58:13 -04001864 && check_hash == ctx->hash
Andrzej Kurekfba59212020-08-07 21:02:25 -04001865#endif
1866 )
Arto Kinnunen6ce49882019-12-03 13:56:06 +02001867 {
Andrzej Kurekfba59212020-08-07 21:02:25 -04001868#if defined(MBEDTLS_VALIDATE_AES_KEYS_INTEGRITY)
1869 mbedtls_platform_random_delay();
Andrzej Kurek9539f832020-08-10 15:58:13 -04001870 if( mbedtls_hash( ctx->rk, key_bytes ) == ctx->hash )
Andrzej Kurekfba59212020-08-07 21:02:25 -04001871#endif
1872 {
1873 return 0;
1874 }
Arto Kinnunen6ce49882019-12-03 13:56:06 +02001875 }
1876
Andrzej Kurekca609372020-07-08 03:19:02 -04001877 // Clear the output in case of a FI
1878 mbedtls_platform_memset( output, 0, 16 );
Arto Kinnunen6ce49882019-12-03 13:56:06 +02001879 return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001880}
Arto Kinnunen311ab592020-01-16 17:20:51 +02001881
1882#else /* MBEDTLS_AES_SCA_COUNTERMEASURES */
1883
1884#define AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \
1885 do \
1886 { \
1887 (X0) = *RK++ ^ AES_RT0( ( (Y0) ) & 0xFF ) ^ \
1888 AES_RT1( ( (Y3) >> 8 ) & 0xFF ) ^ \
1889 AES_RT2( ( (Y2) >> 16 ) & 0xFF ) ^ \
1890 AES_RT3( ( (Y1) >> 24 ) & 0xFF ); \
1891 \
1892 (X1) = *RK++ ^ AES_RT0( ( (Y1) ) & 0xFF ) ^ \
1893 AES_RT1( ( (Y0) >> 8 ) & 0xFF ) ^ \
1894 AES_RT2( ( (Y3) >> 16 ) & 0xFF ) ^ \
1895 AES_RT3( ( (Y2) >> 24 ) & 0xFF ); \
1896 \
1897 (X2) = *RK++ ^ AES_RT0( ( (Y2) ) & 0xFF ) ^ \
1898 AES_RT1( ( (Y1) >> 8 ) & 0xFF ) ^ \
1899 AES_RT2( ( (Y0) >> 16 ) & 0xFF ) ^ \
1900 AES_RT3( ( (Y3) >> 24 ) & 0xFF ); \
1901 \
1902 (X3) = *RK++ ^ AES_RT0( ( (Y3) ) & 0xFF ) ^ \
1903 AES_RT1( ( (Y2) >> 8 ) & 0xFF ) ^ \
1904 AES_RT2( ( (Y1) >> 16 ) & 0xFF ) ^ \
1905 AES_RT3( ( (Y0) >> 24 ) & 0xFF ); \
1906 } while( 0 )
1907
1908int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx,
1909 const unsigned char input[16],
1910 unsigned char output[16] )
1911{
1912 int i;
1913 uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3;
1914
1915 RK = ctx->rk;
1916
1917 GET_UINT32_LE( X0, input, 0 ); X0 ^= *RK++;
1918 GET_UINT32_LE( X1, input, 4 ); X1 ^= *RK++;
1919 GET_UINT32_LE( X2, input, 8 ); X2 ^= *RK++;
1920 GET_UINT32_LE( X3, input, 12 ); X3 ^= *RK++;
1921
1922 for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- )
1923 {
1924 AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
1925 AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 );
1926 }
1927
1928 AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
1929
1930 X0 = *RK++ ^ \
1931 ( (uint32_t) RSb[ ( Y0 ) & 0xFF ] ) ^
1932 ( (uint32_t) RSb[ ( Y3 >> 8 ) & 0xFF ] << 8 ) ^
1933 ( (uint32_t) RSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^
1934 ( (uint32_t) RSb[ ( Y1 >> 24 ) & 0xFF ] << 24 );
1935
1936 X1 = *RK++ ^ \
1937 ( (uint32_t) RSb[ ( Y1 ) & 0xFF ] ) ^
1938 ( (uint32_t) RSb[ ( Y0 >> 8 ) & 0xFF ] << 8 ) ^
1939 ( (uint32_t) RSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^
1940 ( (uint32_t) RSb[ ( Y2 >> 24 ) & 0xFF ] << 24 );
1941
1942 X2 = *RK++ ^ \
1943 ( (uint32_t) RSb[ ( Y2 ) & 0xFF ] ) ^
1944 ( (uint32_t) RSb[ ( Y1 >> 8 ) & 0xFF ] << 8 ) ^
1945 ( (uint32_t) RSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^
1946 ( (uint32_t) RSb[ ( Y3 >> 24 ) & 0xFF ] << 24 );
1947
1948 X3 = *RK++ ^ \
1949 ( (uint32_t) RSb[ ( Y3 ) & 0xFF ] ) ^
1950 ( (uint32_t) RSb[ ( Y2 >> 8 ) & 0xFF ] << 8 ) ^
1951 ( (uint32_t) RSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^
1952 ( (uint32_t) RSb[ ( Y0 >> 24 ) & 0xFF ] << 24 );
1953
1954 PUT_UINT32_LE( X0, output, 0 );
1955 PUT_UINT32_LE( X1, output, 4 );
1956 PUT_UINT32_LE( X2, output, 8 );
1957 PUT_UINT32_LE( X3, output, 12 );
1958
Andrzej Kureka8405442019-11-12 03:34:03 -05001959 mbedtls_platform_zeroize( &X0, sizeof( X0 ) );
1960 mbedtls_platform_zeroize( &X1, sizeof( X1 ) );
1961 mbedtls_platform_zeroize( &X2, sizeof( X2 ) );
1962 mbedtls_platform_zeroize( &X3, sizeof( X3 ) );
1963
1964 mbedtls_platform_zeroize( &Y0, sizeof( Y0 ) );
1965 mbedtls_platform_zeroize( &Y1, sizeof( Y1 ) );
1966 mbedtls_platform_zeroize( &Y2, sizeof( Y2 ) );
1967 mbedtls_platform_zeroize( &Y3, sizeof( Y3 ) );
1968
1969 mbedtls_platform_zeroize( &RK, sizeof( RK ) );
1970
Arto Kinnunen311ab592020-01-16 17:20:51 +02001971 return( 0 );
1972}
Shelly Libermanc907c812020-11-17 11:33:25 +02001973#endif /* !MBEDTLS_AES_ONLY_ENCRYPT */
Arto Kinnunen311ab592020-01-16 17:20:51 +02001974#endif /* MBEDTLS_AES_SCA_COUNTERMEASURES */
1975
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001976#endif /* !MBEDTLS_AES_DECRYPT_ALT */
1977
Gilles Peskine8db3efb2018-02-21 19:16:20 +01001978#if !defined(MBEDTLS_DEPRECATED_REMOVED)
Hanno Beckerbedc2052017-06-26 12:46:56 +01001979void mbedtls_aes_decrypt( mbedtls_aes_context *ctx,
1980 const unsigned char input[16],
1981 unsigned char output[16] )
1982{
Arto Kinnunen14804442019-10-16 13:43:59 +03001983#if defined(MBEDTLS_AES_ONLY_ENCRYPT)
1984 (void) ctx;
1985 (void) input;
1986 (void) output;
1987#else /* MBEDTLS_AES_ONLY_ENCRYPT */
Hanno Beckerbedc2052017-06-26 12:46:56 +01001988 mbedtls_internal_aes_decrypt( ctx, input, output );
Arto Kinnunen14804442019-10-16 13:43:59 +03001989#endif /* MBEDTLS_AES_ONLY_ENCRYPT */
Hanno Beckerbedc2052017-06-26 12:46:56 +01001990}
Gilles Peskine8db3efb2018-02-21 19:16:20 +01001991#endif /* !MBEDTLS_DEPRECATED_REMOVED */
Hanno Beckerbedc2052017-06-26 12:46:56 +01001992
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001993/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001994 * AES-ECB block encryption/decryption
1995 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001996int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx,
Manuel Pégourié-Gonnardeb6d3962018-12-18 09:59:35 +01001997 int mode,
1998 const unsigned char input[16],
1999 unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +00002000{
Manuel Pégourié-Gonnard1aca2602018-12-12 12:56:55 +01002001 AES_VALIDATE_RET( ctx != NULL );
2002 AES_VALIDATE_RET( input != NULL );
2003 AES_VALIDATE_RET( output != NULL );
2004 AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
2005 mode == MBEDTLS_AES_DECRYPT );
Arto Kinnunen14804442019-10-16 13:43:59 +03002006 (void) mode;
Manuel Pégourié-Gonnard1aca2602018-12-12 12:56:55 +01002007
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002008#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +01002009 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002010 return( mbedtls_aesni_crypt_ecb( ctx, mode, input, output ) );
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +01002011#endif
2012
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002013#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Paul Bakker048d04e2012-02-12 17:31:04 +00002014 if( aes_padlock_ace )
Paul Bakker5121ce52009-01-03 21:22:43 +00002015 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002016 if( mbedtls_padlock_xcryptecb( ctx, mode, input, output ) == 0 )
Paul Bakkerf3ccc682010-03-18 21:21:02 +00002017 return( 0 );
2018
2019 // If padlock data misaligned, we just fall back to
2020 // unaccelerated mode
2021 //
Paul Bakker5121ce52009-01-03 21:22:43 +00002022 }
2023#endif
Arto Kinnunen6ce49882019-12-03 13:56:06 +02002024
Arto Kinnunen14804442019-10-16 13:43:59 +03002025#if defined(MBEDTLS_AES_ONLY_ENCRYPT)
2026 return( mbedtls_internal_aes_encrypt( ctx, input, output ) );
2027#else /* MBEDTLS_AES_ONLY_ENCRYPT */
Paul Bakker5121ce52009-01-03 21:22:43 +00002028
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02002029 if( mode == MBEDTLS_AES_ENCRYPT )
Andres AGf5bf7182017-03-03 14:09:56 +00002030 return( mbedtls_internal_aes_encrypt( ctx, input, output ) );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02002031 else
Andres AGf5bf7182017-03-03 14:09:56 +00002032 return( mbedtls_internal_aes_decrypt( ctx, input, output ) );
Arto Kinnunen14804442019-10-16 13:43:59 +03002033#endif /* MBEDTLS_AES_ONLY_ENCRYPT */
Paul Bakker5121ce52009-01-03 21:22:43 +00002034}
2035
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002036#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00002037/*
2038 * AES-CBC buffer encryption/decryption
2039 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002040int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx,
Paul Bakker5121ce52009-01-03 21:22:43 +00002041 int mode,
Paul Bakker23986e52011-04-24 08:57:21 +00002042 size_t length,
Paul Bakker5121ce52009-01-03 21:22:43 +00002043 unsigned char iv[16],
Paul Bakkerff60ee62010-03-16 21:09:09 +00002044 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +00002045 unsigned char *output )
2046{
2047 int i;
2048 unsigned char temp[16];
2049
Manuel Pégourié-Gonnard3178d1a2018-12-12 13:05:00 +01002050 AES_VALIDATE_RET( ctx != NULL );
2051 AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
2052 mode == MBEDTLS_AES_DECRYPT );
2053 AES_VALIDATE_RET( iv != NULL );
2054 AES_VALIDATE_RET( input != NULL );
2055 AES_VALIDATE_RET( output != NULL );
2056
Paul Bakkerf3ccc682010-03-18 21:21:02 +00002057 if( length % 16 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002058 return( MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH );
Paul Bakkerf3ccc682010-03-18 21:21:02 +00002059
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002060#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Paul Bakker048d04e2012-02-12 17:31:04 +00002061 if( aes_padlock_ace )
Paul Bakker5121ce52009-01-03 21:22:43 +00002062 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002063 if( mbedtls_padlock_xcryptcbc( ctx, mode, length, iv, input, output ) == 0 )
Paul Bakkerf3ccc682010-03-18 21:21:02 +00002064 return( 0 );
Paul Bakker9af723c2014-05-01 13:03:14 +02002065
Paul Bakkerf3ccc682010-03-18 21:21:02 +00002066 // If padlock data misaligned, we just fall back to
2067 // unaccelerated mode
2068 //
Paul Bakker5121ce52009-01-03 21:22:43 +00002069 }
2070#endif
2071
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002072 if( mode == MBEDTLS_AES_DECRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +00002073 {
2074 while( length > 0 )
2075 {
Teppo Järvelin91d79382019-10-02 09:09:31 +03002076 mbedtls_platform_memcpy( temp, input, 16 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002077 mbedtls_aes_crypt_ecb( ctx, mode, input, output );
Paul Bakker5121ce52009-01-03 21:22:43 +00002078
2079 for( i = 0; i < 16; i++ )
2080 output[i] = (unsigned char)( output[i] ^ iv[i] );
2081
Teppo Järvelin91d79382019-10-02 09:09:31 +03002082 mbedtls_platform_memcpy( iv, temp, 16 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002083
2084 input += 16;
2085 output += 16;
2086 length -= 16;
2087 }
2088 }
2089 else
2090 {
2091 while( length > 0 )
2092 {
2093 for( i = 0; i < 16; i++ )
2094 output[i] = (unsigned char)( input[i] ^ iv[i] );
2095
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002096 mbedtls_aes_crypt_ecb( ctx, mode, output, output );
Teppo Järvelin91d79382019-10-02 09:09:31 +03002097 mbedtls_platform_memcpy( iv, output, 16 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002098
2099 input += 16;
2100 output += 16;
2101 length -= 16;
2102 }
2103 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +00002104
2105 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002106}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002107#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00002108
Aorimn5f778012016-06-09 23:22:58 +02002109#if defined(MBEDTLS_CIPHER_MODE_XTS)
Jaeden Amero010c2cb2018-05-29 17:00:47 +01002110
2111/* Endianess with 64 bits values */
2112#ifndef GET_UINT64_LE
2113#define GET_UINT64_LE(n,b,i) \
2114{ \
2115 (n) = ( (uint64_t) (b)[(i) + 7] << 56 ) \
2116 | ( (uint64_t) (b)[(i) + 6] << 48 ) \
2117 | ( (uint64_t) (b)[(i) + 5] << 40 ) \
2118 | ( (uint64_t) (b)[(i) + 4] << 32 ) \
2119 | ( (uint64_t) (b)[(i) + 3] << 24 ) \
2120 | ( (uint64_t) (b)[(i) + 2] << 16 ) \
2121 | ( (uint64_t) (b)[(i) + 1] << 8 ) \
2122 | ( (uint64_t) (b)[(i) ] ); \
2123}
2124#endif
2125
2126#ifndef PUT_UINT64_LE
2127#define PUT_UINT64_LE(n,b,i) \
2128{ \
2129 (b)[(i) + 7] = (unsigned char) ( (n) >> 56 ); \
2130 (b)[(i) + 6] = (unsigned char) ( (n) >> 48 ); \
2131 (b)[(i) + 5] = (unsigned char) ( (n) >> 40 ); \
2132 (b)[(i) + 4] = (unsigned char) ( (n) >> 32 ); \
2133 (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \
2134 (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \
2135 (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \
2136 (b)[(i) ] = (unsigned char) ( (n) ); \
2137}
2138#endif
2139
2140typedef unsigned char mbedtls_be128[16];
2141
2142/*
2143 * GF(2^128) multiplication function
2144 *
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01002145 * This function multiplies a field element by x in the polynomial field
2146 * representation. It uses 64-bit word operations to gain speed but compensates
2147 * for machine endianess and hence works correctly on both big and little
2148 * endian machines.
Jaeden Amero010c2cb2018-05-29 17:00:47 +01002149 */
2150static void mbedtls_gf128mul_x_ble( unsigned char r[16],
Jaeden Amero8cfc75f2018-05-31 16:53:08 +01002151 const unsigned char x[16] )
Jaeden Amero010c2cb2018-05-29 17:00:47 +01002152{
2153 uint64_t a, b, ra, rb;
2154
Jaeden Amero8cfc75f2018-05-31 16:53:08 +01002155 GET_UINT64_LE( a, x, 0 );
2156 GET_UINT64_LE( b, x, 8 );
Jaeden Amero010c2cb2018-05-29 17:00:47 +01002157
Jaeden Amero8cfc75f2018-05-31 16:53:08 +01002158 ra = ( a << 1 ) ^ 0x0087 >> ( 8 - ( ( b >> 63 ) << 3 ) );
2159 rb = ( a >> 63 ) | ( b << 1 );
Jaeden Amero010c2cb2018-05-29 17:00:47 +01002160
Jaeden Amero8cfc75f2018-05-31 16:53:08 +01002161 PUT_UINT64_LE( ra, r, 0 );
2162 PUT_UINT64_LE( rb, r, 8 );
Jaeden Amero010c2cb2018-05-29 17:00:47 +01002163}
2164
Aorimn5f778012016-06-09 23:22:58 +02002165/*
2166 * AES-XTS buffer encryption/decryption
2167 */
Jaeden Amero9366feb2018-05-29 18:55:17 +01002168int mbedtls_aes_crypt_xts( mbedtls_aes_xts_context *ctx,
2169 int mode,
Jaeden Amero5162b932018-05-29 12:55:24 +01002170 size_t length,
Jaeden Amerocd9fc5e2018-05-30 15:23:24 +01002171 const unsigned char data_unit[16],
Jaeden Amero9366feb2018-05-29 18:55:17 +01002172 const unsigned char *input,
2173 unsigned char *output )
Aorimn5f778012016-06-09 23:22:58 +02002174{
Jaeden Amerod82cd862018-04-28 15:02:45 +01002175 int ret;
2176 size_t blocks = length / 16;
2177 size_t leftover = length % 16;
2178 unsigned char tweak[16];
2179 unsigned char prev_tweak[16];
2180 unsigned char tmp[16];
Aorimn5f778012016-06-09 23:22:58 +02002181
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01002182 AES_VALIDATE_RET( ctx != NULL );
2183 AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
2184 mode == MBEDTLS_AES_DECRYPT );
Manuel Pégourié-Gonnard998a3582018-12-18 10:03:13 +01002185 AES_VALIDATE_RET( data_unit != NULL );
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01002186 AES_VALIDATE_RET( input != NULL );
2187 AES_VALIDATE_RET( output != NULL );
2188
Jaeden Amero8381fcb2018-10-11 12:06:15 +01002189 /* Data units must be at least 16 bytes long. */
Aorimn5f778012016-06-09 23:22:58 +02002190 if( length < 16 )
Jaeden Amerod82cd862018-04-28 15:02:45 +01002191 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Aorimn5f778012016-06-09 23:22:58 +02002192
Jaeden Ameroa74faba2018-10-11 12:07:43 +01002193 /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */
Jaeden Amero0a8b0202018-05-30 15:36:06 +01002194 if( length > ( 1 << 20 ) * 16 )
2195 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Aorimn5f778012016-06-09 23:22:58 +02002196
Jaeden Amerod82cd862018-04-28 15:02:45 +01002197 /* Compute the tweak. */
Jaeden Amerocd9fc5e2018-05-30 15:23:24 +01002198 ret = mbedtls_aes_crypt_ecb( &ctx->tweak, MBEDTLS_AES_ENCRYPT,
2199 data_unit, tweak );
Jaeden Amerod82cd862018-04-28 15:02:45 +01002200 if( ret != 0 )
2201 return( ret );
Aorimn5f778012016-06-09 23:22:58 +02002202
Jaeden Amerod82cd862018-04-28 15:02:45 +01002203 while( blocks-- )
Aorimn5f778012016-06-09 23:22:58 +02002204 {
Jaeden Amerod82cd862018-04-28 15:02:45 +01002205 size_t i;
2206
2207 if( leftover && ( mode == MBEDTLS_AES_DECRYPT ) && blocks == 0 )
2208 {
2209 /* We are on the last block in a decrypt operation that has
2210 * leftover bytes, so we need to use the next tweak for this block,
2211 * and this tweak for the lefover bytes. Save the current tweak for
2212 * the leftovers and then update the current tweak for use on this,
2213 * the last full block. */
Teppo Järvelin91d79382019-10-02 09:09:31 +03002214 mbedtls_platform_memcpy( prev_tweak, tweak, sizeof( tweak ) );
Jaeden Amerod82cd862018-04-28 15:02:45 +01002215 mbedtls_gf128mul_x_ble( tweak, tweak );
2216 }
2217
2218 for( i = 0; i < 16; i++ )
2219 tmp[i] = input[i] ^ tweak[i];
2220
2221 ret = mbedtls_aes_crypt_ecb( &ctx->crypt, mode, tmp, tmp );
2222 if( ret != 0 )
2223 return( ret );
2224
2225 for( i = 0; i < 16; i++ )
2226 output[i] = tmp[i] ^ tweak[i];
2227
2228 /* Update the tweak for the next block. */
2229 mbedtls_gf128mul_x_ble( tweak, tweak );
2230
2231 output += 16;
2232 input += 16;
Aorimn5f778012016-06-09 23:22:58 +02002233 }
2234
Jaeden Amerod82cd862018-04-28 15:02:45 +01002235 if( leftover )
Aorimn5f778012016-06-09 23:22:58 +02002236 {
Jaeden Amerod82cd862018-04-28 15:02:45 +01002237 /* If we are on the leftover bytes in a decrypt operation, we need to
2238 * use the previous tweak for these bytes (as saved in prev_tweak). */
2239 unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
Aorimn5f778012016-06-09 23:22:58 +02002240
Jaeden Amerod82cd862018-04-28 15:02:45 +01002241 /* We are now on the final part of the data unit, which doesn't divide
2242 * evenly by 16. It's time for ciphertext stealing. */
2243 size_t i;
2244 unsigned char *prev_output = output - 16;
Aorimn5f778012016-06-09 23:22:58 +02002245
Jaeden Amerod82cd862018-04-28 15:02:45 +01002246 /* Copy ciphertext bytes from the previous block to our output for each
2247 * byte of cyphertext we won't steal. At the same time, copy the
2248 * remainder of the input for this final round (since the loop bounds
2249 * are the same). */
2250 for( i = 0; i < leftover; i++ )
Aorimn5f778012016-06-09 23:22:58 +02002251 {
Jaeden Amerod82cd862018-04-28 15:02:45 +01002252 output[i] = prev_output[i];
2253 tmp[i] = input[i] ^ t[i];
Aorimn5f778012016-06-09 23:22:58 +02002254 }
Aorimn5f778012016-06-09 23:22:58 +02002255
Jaeden Amerod82cd862018-04-28 15:02:45 +01002256 /* Copy ciphertext bytes from the previous block for input in this
2257 * round. */
2258 for( ; i < 16; i++ )
2259 tmp[i] = prev_output[i] ^ t[i];
Aorimn5f778012016-06-09 23:22:58 +02002260
Jaeden Amerod82cd862018-04-28 15:02:45 +01002261 ret = mbedtls_aes_crypt_ecb( &ctx->crypt, mode, tmp, tmp );
2262 if( ret != 0 )
2263 return ret;
Aorimn5f778012016-06-09 23:22:58 +02002264
Jaeden Amerod82cd862018-04-28 15:02:45 +01002265 /* Write the result back to the previous block, overriding the previous
2266 * output we copied. */
2267 for( i = 0; i < 16; i++ )
2268 prev_output[i] = tmp[i] ^ t[i];
Aorimn5f778012016-06-09 23:22:58 +02002269 }
2270
2271 return( 0 );
2272}
2273#endif /* MBEDTLS_CIPHER_MODE_XTS */
2274
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002275#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00002276/*
2277 * AES-CFB128 buffer encryption/decryption
2278 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002279int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx,
Paul Bakker5121ce52009-01-03 21:22:43 +00002280 int mode,
Paul Bakker23986e52011-04-24 08:57:21 +00002281 size_t length,
Paul Bakker27fdf462011-06-09 13:55:13 +00002282 size_t *iv_off,
Paul Bakker5121ce52009-01-03 21:22:43 +00002283 unsigned char iv[16],
Paul Bakkerff60ee62010-03-16 21:09:09 +00002284 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +00002285 unsigned char *output )
2286{
Paul Bakker27fdf462011-06-09 13:55:13 +00002287 int c;
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01002288 size_t n;
2289
2290 AES_VALIDATE_RET( ctx != NULL );
2291 AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
2292 mode == MBEDTLS_AES_DECRYPT );
2293 AES_VALIDATE_RET( iv_off != NULL );
2294 AES_VALIDATE_RET( iv != NULL );
2295 AES_VALIDATE_RET( input != NULL );
2296 AES_VALIDATE_RET( output != NULL );
2297
2298 n = *iv_off;
Paul Bakker5121ce52009-01-03 21:22:43 +00002299
Manuel Pégourié-Gonnarde55e1032018-12-18 12:09:02 +01002300 if( n > 15 )
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01002301 return( MBEDTLS_ERR_AES_BAD_INPUT_DATA );
2302
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002303 if( mode == MBEDTLS_AES_DECRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +00002304 {
2305 while( length-- )
2306 {
2307 if( n == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002308 mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
Paul Bakker5121ce52009-01-03 21:22:43 +00002309
2310 c = *input++;
2311 *output++ = (unsigned char)( c ^ iv[n] );
2312 iv[n] = (unsigned char) c;
2313
Paul Bakker66d5d072014-06-17 16:39:18 +02002314 n = ( n + 1 ) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00002315 }
2316 }
2317 else
2318 {
2319 while( length-- )
2320 {
2321 if( n == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002322 mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
Paul Bakker5121ce52009-01-03 21:22:43 +00002323
2324 iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ );
2325
Paul Bakker66d5d072014-06-17 16:39:18 +02002326 n = ( n + 1 ) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00002327 }
2328 }
2329
2330 *iv_off = n;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00002331
2332 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002333}
Paul Bakker556efba2014-01-24 15:38:12 +01002334
2335/*
2336 * AES-CFB8 buffer encryption/decryption
2337 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002338int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx,
Manuel Pégourié-Gonnardeb6d3962018-12-18 09:59:35 +01002339 int mode,
2340 size_t length,
2341 unsigned char iv[16],
2342 const unsigned char *input,
2343 unsigned char *output )
Paul Bakker556efba2014-01-24 15:38:12 +01002344{
2345 unsigned char c;
2346 unsigned char ov[17];
2347
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01002348 AES_VALIDATE_RET( ctx != NULL );
2349 AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
2350 mode == MBEDTLS_AES_DECRYPT );
2351 AES_VALIDATE_RET( iv != NULL );
2352 AES_VALIDATE_RET( input != NULL );
2353 AES_VALIDATE_RET( output != NULL );
Paul Bakker556efba2014-01-24 15:38:12 +01002354 while( length-- )
2355 {
Teppo Järvelin91d79382019-10-02 09:09:31 +03002356 mbedtls_platform_memcpy( ov, iv, 16 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002357 mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
Paul Bakker556efba2014-01-24 15:38:12 +01002358
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002359 if( mode == MBEDTLS_AES_DECRYPT )
Paul Bakker556efba2014-01-24 15:38:12 +01002360 ov[16] = *input;
2361
2362 c = *output++ = (unsigned char)( iv[0] ^ *input++ );
2363
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002364 if( mode == MBEDTLS_AES_ENCRYPT )
Paul Bakker556efba2014-01-24 15:38:12 +01002365 ov[16] = c;
2366
Teppo Järvelin91d79382019-10-02 09:09:31 +03002367 mbedtls_platform_memcpy( iv, ov + 1, 16 );
Paul Bakker556efba2014-01-24 15:38:12 +01002368 }
2369
2370 return( 0 );
2371}
Simon Butcher76a5b222018-04-22 22:57:27 +01002372#endif /* MBEDTLS_CIPHER_MODE_CFB */
2373
2374#if defined(MBEDTLS_CIPHER_MODE_OFB)
2375/*
2376 * AES-OFB (Output Feedback Mode) buffer encryption/decryption
2377 */
2378int mbedtls_aes_crypt_ofb( mbedtls_aes_context *ctx,
Simon Butcher00131442018-05-22 22:40:36 +01002379 size_t length,
2380 size_t *iv_off,
2381 unsigned char iv[16],
2382 const unsigned char *input,
2383 unsigned char *output )
Simon Butcher76a5b222018-04-22 22:57:27 +01002384{
Simon Butcherad4e4932018-04-29 00:43:47 +01002385 int ret = 0;
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01002386 size_t n;
2387
2388 AES_VALIDATE_RET( ctx != NULL );
2389 AES_VALIDATE_RET( iv_off != NULL );
2390 AES_VALIDATE_RET( iv != NULL );
2391 AES_VALIDATE_RET( input != NULL );
2392 AES_VALIDATE_RET( output != NULL );
2393
2394 n = *iv_off;
Simon Butcher76a5b222018-04-22 22:57:27 +01002395
Manuel Pégourié-Gonnarde55e1032018-12-18 12:09:02 +01002396 if( n > 15 )
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01002397 return( MBEDTLS_ERR_AES_BAD_INPUT_DATA );
2398
Simon Butcher76a5b222018-04-22 22:57:27 +01002399 while( length-- )
2400 {
2401 if( n == 0 )
Simon Butcherad4e4932018-04-29 00:43:47 +01002402 {
2403 ret = mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
2404 if( ret != 0 )
2405 goto exit;
2406 }
Simon Butcher76a5b222018-04-22 22:57:27 +01002407 *output++ = *input++ ^ iv[n];
2408
2409 n = ( n + 1 ) & 0x0F;
2410 }
2411
2412 *iv_off = n;
2413
Simon Butcherad4e4932018-04-29 00:43:47 +01002414exit:
2415 return( ret );
Simon Butcher76a5b222018-04-22 22:57:27 +01002416}
2417#endif /* MBEDTLS_CIPHER_MODE_OFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002418
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002419#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002420/*
2421 * AES-CTR buffer encryption/decryption
2422 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002423int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx,
Paul Bakker27fdf462011-06-09 13:55:13 +00002424 size_t length,
2425 size_t *nc_off,
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002426 unsigned char nonce_counter[16],
2427 unsigned char stream_block[16],
2428 const unsigned char *input,
2429 unsigned char *output )
2430{
Paul Bakker369e14b2012-04-18 14:16:09 +00002431 int c, i;
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01002432 size_t n;
2433
2434 AES_VALIDATE_RET( ctx != NULL );
2435 AES_VALIDATE_RET( nc_off != NULL );
2436 AES_VALIDATE_RET( nonce_counter != NULL );
2437 AES_VALIDATE_RET( stream_block != NULL );
2438 AES_VALIDATE_RET( input != NULL );
2439 AES_VALIDATE_RET( output != NULL );
2440
2441 n = *nc_off;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002442
Arto Kinnunen75439012019-12-03 14:12:10 +02002443 if( n > 0x0F )
Mohammad Azim Khan3f7f8172017-11-23 17:49:05 +00002444 return( MBEDTLS_ERR_AES_BAD_INPUT_DATA );
2445
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002446 while( length-- )
2447 {
2448 if( n == 0 ) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002449 mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block );
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002450
Paul Bakker369e14b2012-04-18 14:16:09 +00002451 for( i = 16; i > 0; i-- )
2452 if( ++nonce_counter[i - 1] != 0 )
2453 break;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002454 }
2455 c = *input++;
2456 *output++ = (unsigned char)( c ^ stream_block[n] );
2457
Paul Bakker66d5d072014-06-17 16:39:18 +02002458 n = ( n + 1 ) & 0x0F;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002459 }
2460
2461 *nc_off = n;
2462
2463 return( 0 );
2464}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002465#endif /* MBEDTLS_CIPHER_MODE_CTR */
Manuel Pégourié-Gonnard1ec220b2014-03-10 11:20:17 +01002466
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002467#endif /* !MBEDTLS_AES_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +00002468
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002469#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00002470/*
2471 * AES test vectors from:
2472 *
2473 * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
2474 */
2475static const unsigned char aes_test_ecb_dec[3][16] =
2476{
2477 { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
2478 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
2479 { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
2480 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
2481 { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
2482 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
2483};
2484
2485static const unsigned char aes_test_ecb_enc[3][16] =
2486{
2487 { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
2488 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
2489 { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
2490 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
2491 { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
2492 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
2493};
2494
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002495#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00002496static const unsigned char aes_test_cbc_dec[3][16] =
2497{
2498 { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
2499 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
2500 { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
2501 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
2502 { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
2503 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
2504};
2505
2506static const unsigned char aes_test_cbc_enc[3][16] =
2507{
2508 { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
2509 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
2510 { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
2511 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
2512 { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
2513 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
2514};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002515#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00002516
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002517#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00002518/*
2519 * AES-CFB128 test vectors from:
2520 *
2521 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
2522 */
2523static const unsigned char aes_test_cfb128_key[3][32] =
2524{
2525 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
2526 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
2527 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
2528 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
2529 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
2530 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
2531 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
2532 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
2533 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
2534};
2535
2536static const unsigned char aes_test_cfb128_iv[16] =
2537{
2538 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
2539 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
2540};
2541
2542static const unsigned char aes_test_cfb128_pt[64] =
2543{
2544 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
2545 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
2546 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
2547 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
2548 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
2549 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
2550 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
2551 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
2552};
2553
2554static const unsigned char aes_test_cfb128_ct[3][64] =
2555{
2556 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
2557 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
2558 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F,
2559 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B,
2560 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40,
2561 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF,
2562 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E,
2563 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 },
2564 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
2565 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
2566 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21,
2567 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A,
2568 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1,
2569 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9,
2570 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0,
2571 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF },
2572 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
2573 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
2574 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8,
2575 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B,
2576 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92,
2577 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9,
2578 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8,
2579 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 }
2580};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002581#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002582
Simon Butcherad4e4932018-04-29 00:43:47 +01002583#if defined(MBEDTLS_CIPHER_MODE_OFB)
2584/*
2585 * AES-OFB test vectors from:
2586 *
Simon Butcher5db13622018-06-04 22:11:25 +01002587 * https://csrc.nist.gov/publications/detail/sp/800-38a/final
Simon Butcherad4e4932018-04-29 00:43:47 +01002588 */
2589static const unsigned char aes_test_ofb_key[3][32] =
2590{
2591 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
2592 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
2593 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
2594 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
2595 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
2596 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
2597 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
2598 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
2599 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
2600};
2601
2602static const unsigned char aes_test_ofb_iv[16] =
2603{
2604 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
2605 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
2606};
2607
2608static const unsigned char aes_test_ofb_pt[64] =
2609{
2610 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
2611 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
2612 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
2613 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
2614 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
2615 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
2616 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
2617 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
2618};
2619
2620static const unsigned char aes_test_ofb_ct[3][64] =
2621{
2622 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
2623 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
2624 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
2625 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
2626 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
2627 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
2628 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
2629 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e },
2630 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
2631 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
2632 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
2633 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
2634 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f,
2635 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
2636 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e,
2637 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a },
2638 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
2639 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
2640 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
2641 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
2642 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed,
2643 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
2644 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8,
2645 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 }
2646};
2647#endif /* MBEDTLS_CIPHER_MODE_OFB */
2648
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002649#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002650/*
2651 * AES-CTR test vectors from:
2652 *
2653 * http://www.faqs.org/rfcs/rfc3686.html
2654 */
2655
2656static const unsigned char aes_test_ctr_key[3][16] =
2657{
2658 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
2659 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
2660 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
2661 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
2662 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
2663 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
2664};
2665
2666static const unsigned char aes_test_ctr_nonce_counter[3][16] =
2667{
2668 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
2669 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
2670 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
2671 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
2672 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
2673 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
2674};
2675
2676static const unsigned char aes_test_ctr_pt[3][48] =
2677{
2678 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
2679 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
2680
2681 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
2682 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
2683 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
2684 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
2685
2686 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
2687 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
2688 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
2689 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
2690 0x20, 0x21, 0x22, 0x23 }
2691};
2692
2693static const unsigned char aes_test_ctr_ct[3][48] =
2694{
2695 { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79,
2696 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 },
2697 { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9,
2698 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88,
2699 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8,
2700 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 },
2701 { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
2702 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
2703 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
2704 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
2705 0x25, 0xB2, 0x07, 0x2F }
2706};
2707
2708static const int aes_test_ctr_len[3] =
2709 { 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002710#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00002711
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002712#if defined(MBEDTLS_CIPHER_MODE_XTS)
2713/*
2714 * AES-XTS test vectors from:
2715 *
2716 * IEEE P1619/D16 Annex B
2717 * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf
2718 * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf)
2719 */
2720static const unsigned char aes_test_xts_key[][32] =
2721{
2722 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2723 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2724 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2725 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
2726 { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
2727 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
2728 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
2729 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
2730 { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
2731 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
2732 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
2733 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
2734};
2735
2736static const unsigned char aes_test_xts_pt32[][32] =
2737{
2738 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2739 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2740 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2741 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
2742 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2743 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2744 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2745 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
2746 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2747 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2748 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2749 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
2750};
2751
2752static const unsigned char aes_test_xts_ct32[][32] =
2753{
2754 { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec,
2755 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92,
2756 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85,
2757 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e },
2758 { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e,
2759 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b,
2760 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4,
2761 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 },
2762 { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a,
2763 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2,
2764 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53,
2765 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 },
2766};
2767
2768static const unsigned char aes_test_xts_data_unit[][16] =
2769{
2770 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2771 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
2772 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
2773 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
2774 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
2775 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
2776};
2777
2778#endif /* MBEDTLS_CIPHER_MODE_XTS */
2779
Paul Bakker5121ce52009-01-03 21:22:43 +00002780/*
2781 * Checkup routine
2782 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002783int mbedtls_aes_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +00002784{
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002785 int ret = 0, i, j, u, mode;
2786 unsigned int keybits;
Paul Bakker5121ce52009-01-03 21:22:43 +00002787 unsigned char key[32];
2788 unsigned char buf[64];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002789 const unsigned char *aes_tests;
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03002790#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00002791 unsigned char iv[16];
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03002792#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002793#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +02002794 unsigned char prv[16];
2795#endif
Simon Butcher2ff0e522018-06-14 09:57:07 +01002796#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
2797 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker27fdf462011-06-09 13:55:13 +00002798 size_t offset;
Paul Bakkere91d01e2011-04-19 15:55:50 +00002799#endif
Simon Butcher66a89032018-06-15 18:20:29 +01002800#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS)
Paul Bakkere91d01e2011-04-19 15:55:50 +00002801 int len;
Simon Butcher66a89032018-06-15 18:20:29 +01002802#endif
2803#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002804 unsigned char nonce_counter[16];
2805 unsigned char stream_block[16];
2806#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002807 mbedtls_aes_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00002808
Teppo Järvelind49d2b62019-10-30 13:48:12 +02002809 memset( key, 0, 32 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002810 mbedtls_aes_init( &ctx );
Paul Bakker5121ce52009-01-03 21:22:43 +00002811
2812 /*
2813 * ECB mode
2814 */
2815 for( i = 0; i < 6; i++ )
2816 {
2817 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002818 keybits = 128 + u * 64;
2819 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00002820
2821 if( verbose != 0 )
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002822 mbedtls_printf( " AES-ECB-%3d (%s): ", keybits,
2823 ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002824
Arto Kinnunen77b9cfc2019-08-30 11:43:21 +03002825#if defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
2826 if( keybits > 128 )
2827 {
2828 mbedtls_printf( "skipped\n" );
2829 continue;
2830 }
Arto Kinnunenc0a8bd42019-10-16 14:23:14 +03002831#endif /* MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
2832
2833#if defined(MBEDTLS_AES_ONLY_ENCRYPT)
2834 if( mode == MBEDTLS_AES_DECRYPT )
2835 {
2836 mbedtls_printf( "skipped\n" );
2837 continue;
2838 }
2839#endif /* MBEDTLS_AES_ONLY_ENCRYPT */
Arto Kinnunen77b9cfc2019-08-30 11:43:21 +03002840
Teppo Järvelind49d2b62019-10-30 13:48:12 +02002841 memset( buf, 0, 16 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002842
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002843 if( mode == MBEDTLS_AES_DECRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +00002844 {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002845 ret = mbedtls_aes_setkey_dec( &ctx, key, keybits );
2846 aes_tests = aes_test_ecb_dec[u];
Paul Bakker5121ce52009-01-03 21:22:43 +00002847 }
2848 else
2849 {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002850 ret = mbedtls_aes_setkey_enc( &ctx, key, keybits );
2851 aes_tests = aes_test_ecb_enc[u];
2852 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002853
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01002854 /*
2855 * AES-192 is an optional feature that may be unavailable when
2856 * there is an alternative underlying implementation i.e. when
2857 * MBEDTLS_AES_ALT is defined.
2858 */
Ron Eldor9924bdc2018-10-04 10:59:13 +03002859 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 )
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002860 {
2861 mbedtls_printf( "skipped\n" );
2862 continue;
2863 }
2864 else if( ret != 0 )
2865 {
2866 goto exit;
2867 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002868
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002869 for( j = 0; j < 10000; j++ )
2870 {
2871 ret = mbedtls_aes_crypt_ecb( &ctx, mode, buf, buf );
2872 if( ret != 0 )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002873 goto exit;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002874 }
2875
2876 if( memcmp( buf, aes_tests, 16 ) != 0 )
2877 {
2878 ret = 1;
2879 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00002880 }
2881
2882 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002883 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002884 }
2885
2886 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002887 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002888
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002889#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00002890 /*
2891 * CBC mode
2892 */
2893 for( i = 0; i < 6; i++ )
2894 {
2895 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002896 keybits = 128 + u * 64;
2897 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00002898
2899 if( verbose != 0 )
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002900 mbedtls_printf( " AES-CBC-%3d (%s): ", keybits,
2901 ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002902
Arto Kinnunen77b9cfc2019-08-30 11:43:21 +03002903#if defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
2904 if( keybits > 128 )
2905 {
2906 mbedtls_printf( "skipped\n" );
2907 continue;
2908 }
2909#endif
2910
Arto Kinnunenc0a8bd42019-10-16 14:23:14 +03002911#if defined(MBEDTLS_AES_ONLY_ENCRYPT)
2912 if( mode == MBEDTLS_AES_DECRYPT )
2913 {
2914 mbedtls_printf( "skipped\n" );
2915 continue;
2916 }
2917#endif /* MBEDTLS_AES_ONLY_ENCRYPT */
2918
Teppo Järvelind49d2b62019-10-30 13:48:12 +02002919 memset( iv , 0, 16 );
2920 memset( prv, 0, 16 );
2921 memset( buf, 0, 16 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002922
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002923 if( mode == MBEDTLS_AES_DECRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +00002924 {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002925 ret = mbedtls_aes_setkey_dec( &ctx, key, keybits );
2926 aes_tests = aes_test_cbc_dec[u];
Paul Bakker5121ce52009-01-03 21:22:43 +00002927 }
2928 else
2929 {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002930 ret = mbedtls_aes_setkey_enc( &ctx, key, keybits );
2931 aes_tests = aes_test_cbc_enc[u];
2932 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002933
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01002934 /*
2935 * AES-192 is an optional feature that may be unavailable when
2936 * there is an alternative underlying implementation i.e. when
2937 * MBEDTLS_AES_ALT is defined.
2938 */
Ron Eldor9924bdc2018-10-04 10:59:13 +03002939 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 )
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002940 {
2941 mbedtls_printf( "skipped\n" );
2942 continue;
2943 }
2944 else if( ret != 0 )
2945 {
2946 goto exit;
2947 }
2948
2949 for( j = 0; j < 10000; j++ )
2950 {
2951 if( mode == MBEDTLS_AES_ENCRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +00002952 {
2953 unsigned char tmp[16];
2954
Teppo Järvelinb5c46712019-10-04 13:35:55 +03002955 memcpy( tmp, prv, 16 );
2956 memcpy( prv, buf, 16 );
2957 memcpy( buf, tmp, 16 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002958 }
2959
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002960 ret = mbedtls_aes_crypt_cbc( &ctx, mode, 16, iv, buf, buf );
2961 if( ret != 0 )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002962 goto exit;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002963
2964 }
2965
2966 if( memcmp( buf, aes_tests, 16 ) != 0 )
2967 {
2968 ret = 1;
2969 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00002970 }
2971
2972 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002973 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002974 }
2975
2976 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002977 mbedtls_printf( "\n" );
2978#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00002979
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002980#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00002981 /*
2982 * CFB128 mode
2983 */
2984 for( i = 0; i < 6; i++ )
2985 {
2986 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002987 keybits = 128 + u * 64;
2988 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00002989
2990 if( verbose != 0 )
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002991 mbedtls_printf( " AES-CFB128-%3d (%s): ", keybits,
2992 ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002993
Arto Kinnunen77b9cfc2019-08-30 11:43:21 +03002994#if defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
2995 if( keybits > 128 )
2996 {
2997 mbedtls_printf( "skipped\n" );
2998 continue;
2999 }
3000#endif
3001
Arto Kinnunenc0a8bd42019-10-16 14:23:14 +03003002#if defined(MBEDTLS_AES_ONLY_ENCRYPT)
3003 if( mode == MBEDTLS_AES_DECRYPT )
3004 {
3005 mbedtls_printf( "skipped\n" );
3006 continue;
3007 }
3008#endif /* MBEDTLS_AES_ONLY_ENCRYPT */
3009
Paul Bakker5121ce52009-01-03 21:22:43 +00003010 memcpy( iv, aes_test_cfb128_iv, 16 );
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01003011 memcpy( key, aes_test_cfb128_key[u], keybits / 8 );
Paul Bakker5121ce52009-01-03 21:22:43 +00003012
3013 offset = 0;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01003014 ret = mbedtls_aes_setkey_enc( &ctx, key, keybits );
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01003015 /*
3016 * AES-192 is an optional feature that may be unavailable when
3017 * there is an alternative underlying implementation i.e. when
3018 * MBEDTLS_AES_ALT is defined.
3019 */
Ron Eldor9924bdc2018-10-04 10:59:13 +03003020 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 )
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01003021 {
3022 mbedtls_printf( "skipped\n" );
3023 continue;
3024 }
3025 else if( ret != 0 )
3026 {
3027 goto exit;
3028 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003029
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01003030 if( mode == MBEDTLS_AES_DECRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +00003031 {
Teppo Järvelinb5c46712019-10-04 13:35:55 +03003032 memcpy( buf, aes_test_cfb128_ct[u], 64 );
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01003033 aes_tests = aes_test_cfb128_pt;
Paul Bakker5121ce52009-01-03 21:22:43 +00003034 }
3035 else
3036 {
Teppo Järvelinb5c46712019-10-04 13:35:55 +03003037 memcpy( buf, aes_test_cfb128_pt, 64 );
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01003038 aes_tests = aes_test_cfb128_ct[u];
3039 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003040
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01003041 ret = mbedtls_aes_crypt_cfb128( &ctx, mode, 64, &offset, iv, buf, buf );
3042 if( ret != 0 )
3043 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00003044
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01003045 if( memcmp( buf, aes_tests, 64 ) != 0 )
3046 {
3047 ret = 1;
3048 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00003049 }
3050
3051 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003052 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00003053 }
3054
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00003055 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003056 mbedtls_printf( "\n" );
3057#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00003058
Simon Butcherad4e4932018-04-29 00:43:47 +01003059#if defined(MBEDTLS_CIPHER_MODE_OFB)
3060 /*
3061 * OFB mode
3062 */
3063 for( i = 0; i < 6; i++ )
3064 {
3065 u = i >> 1;
3066 keybits = 128 + u * 64;
3067 mode = i & 1;
3068
3069 if( verbose != 0 )
3070 mbedtls_printf( " AES-OFB-%3d (%s): ", keybits,
3071 ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
3072
Arto Kinnunen77b9cfc2019-08-30 11:43:21 +03003073#if defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
3074 if( keybits > 128 )
3075 {
3076 mbedtls_printf( "skipped\n" );
3077 continue;
3078 }
3079#endif
Arto Kinnunenc0a8bd42019-10-16 14:23:14 +03003080
3081#if defined(MBEDTLS_AES_ONLY_ENCRYPT)
3082 if( mode == MBEDTLS_AES_DECRYPT )
3083 {
3084 mbedtls_printf( "skipped\n" );
3085 continue;
3086 }
3087#endif /* MBEDTLS_AES_ONLY_ENCRYPT */
3088
Simon Butcherad4e4932018-04-29 00:43:47 +01003089 memcpy( iv, aes_test_ofb_iv, 16 );
3090 memcpy( key, aes_test_ofb_key[u], keybits / 8 );
3091
3092 offset = 0;
3093 ret = mbedtls_aes_setkey_enc( &ctx, key, keybits );
3094 /*
3095 * AES-192 is an optional feature that may be unavailable when
3096 * there is an alternative underlying implementation i.e. when
3097 * MBEDTLS_AES_ALT is defined.
3098 */
Ron Eldor9924bdc2018-10-04 10:59:13 +03003099 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 )
Simon Butcherad4e4932018-04-29 00:43:47 +01003100 {
3101 mbedtls_printf( "skipped\n" );
3102 continue;
3103 }
3104 else if( ret != 0 )
3105 {
3106 goto exit;
3107 }
3108
3109 if( mode == MBEDTLS_AES_DECRYPT )
3110 {
Teppo Järvelinb5c46712019-10-04 13:35:55 +03003111 memcpy( buf, aes_test_ofb_ct[u], 64 );
Simon Butcherad4e4932018-04-29 00:43:47 +01003112 aes_tests = aes_test_ofb_pt;
3113 }
3114 else
3115 {
Teppo Järvelinb5c46712019-10-04 13:35:55 +03003116 memcpy( buf, aes_test_ofb_pt, 64 );
Simon Butcherad4e4932018-04-29 00:43:47 +01003117 aes_tests = aes_test_ofb_ct[u];
3118 }
3119
3120 ret = mbedtls_aes_crypt_ofb( &ctx, 64, &offset, iv, buf, buf );
3121 if( ret != 0 )
3122 goto exit;
3123
3124 if( memcmp( buf, aes_tests, 64 ) != 0 )
3125 {
3126 ret = 1;
3127 goto exit;
3128 }
3129
3130 if( verbose != 0 )
3131 mbedtls_printf( "passed\n" );
3132 }
3133
3134 if( verbose != 0 )
3135 mbedtls_printf( "\n" );
3136#endif /* MBEDTLS_CIPHER_MODE_OFB */
3137
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003138#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00003139 /*
3140 * CTR mode
3141 */
3142 for( i = 0; i < 6; i++ )
3143 {
3144 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01003145 mode = i & 1;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00003146
3147 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003148 mbedtls_printf( " AES-CTR-128 (%s): ",
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01003149 ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00003150
Arto Kinnunen77b9cfc2019-08-30 11:43:21 +03003151#if defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
3152 if( keybits > 128 )
3153 {
3154 mbedtls_printf( "skipped\n" );
3155 continue;
3156 }
3157#endif
3158
Arto Kinnunenc0a8bd42019-10-16 14:23:14 +03003159#if defined(MBEDTLS_AES_ONLY_ENCRYPT)
3160 if( mode == MBEDTLS_AES_DECRYPT )
3161 {
3162 mbedtls_printf( "skipped\n" );
3163 continue;
3164 }
3165#endif /* MBEDTLS_AES_ONLY_ENCRYPT */
3166
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00003167 memcpy( nonce_counter, aes_test_ctr_nonce_counter[u], 16 );
3168 memcpy( key, aes_test_ctr_key[u], 16 );
3169
3170 offset = 0;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01003171 if( ( ret = mbedtls_aes_setkey_enc( &ctx, key, 128 ) ) != 0 )
3172 goto exit;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00003173
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01003174 len = aes_test_ctr_len[u];
3175
3176 if( mode == MBEDTLS_AES_DECRYPT )
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00003177 {
Teppo Järvelinb5c46712019-10-04 13:35:55 +03003178 memcpy( buf, aes_test_ctr_ct[u], len );
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01003179 aes_tests = aes_test_ctr_pt[u];
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00003180 }
3181 else
3182 {
Teppo Järvelinb5c46712019-10-04 13:35:55 +03003183 memcpy( buf, aes_test_ctr_pt[u], len );
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01003184 aes_tests = aes_test_ctr_ct[u];
3185 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00003186
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01003187 ret = mbedtls_aes_crypt_ctr( &ctx, len, &offset, nonce_counter,
3188 stream_block, buf, buf );
3189 if( ret != 0 )
3190 goto exit;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00003191
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01003192 if( memcmp( buf, aes_tests, len ) != 0 )
3193 {
3194 ret = 1;
3195 goto exit;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00003196 }
3197
3198 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003199 mbedtls_printf( "passed\n" );
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00003200 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003201
3202 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003203 mbedtls_printf( "\n" );
3204#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00003205
Jaeden Amero21d79cf2018-05-23 10:30:18 +01003206#if defined(MBEDTLS_CIPHER_MODE_XTS)
3207 {
3208 static const int num_tests =
3209 sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key);
3210 mbedtls_aes_xts_context ctx_xts;
3211
3212 /*
3213 * XTS mode
3214 */
3215 mbedtls_aes_xts_init( &ctx_xts );
3216
3217 for( i = 0; i < num_tests << 1; i++ )
3218 {
3219 const unsigned char *data_unit;
3220 u = i >> 1;
3221 mode = i & 1;
3222
3223 if( verbose != 0 )
3224 mbedtls_printf( " AES-XTS-128 (%s): ",
3225 ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
3226
Arto Kinnunenc0a8bd42019-10-16 14:23:14 +03003227#if defined(MBEDTLS_AES_ONLY_ENCRYPT)
3228 if( mode == MBEDTLS_AES_DECRYPT )
3229 {
3230 mbedtls_printf( "skipped\n" );
3231 continue;
3232 }
3233#endif /* MBEDTLS_AES_ONLY_ENCRYPT */
3234
Teppo Järvelind49d2b62019-10-30 13:48:12 +02003235 memset( key, 0, sizeof( key ) );
3236 memcpy( key, aes_test_xts_key[u], 32 );
Jaeden Amero21d79cf2018-05-23 10:30:18 +01003237 data_unit = aes_test_xts_data_unit[u];
3238
3239 len = sizeof( *aes_test_xts_ct32 );
3240
3241 if( mode == MBEDTLS_AES_DECRYPT )
3242 {
3243 ret = mbedtls_aes_xts_setkey_dec( &ctx_xts, key, 256 );
3244 if( ret != 0)
3245 goto exit;
Teppo Järvelinb5c46712019-10-04 13:35:55 +03003246 memcpy( buf, aes_test_xts_ct32[u], len );
Jaeden Amero21d79cf2018-05-23 10:30:18 +01003247 aes_tests = aes_test_xts_pt32[u];
3248 }
3249 else
3250 {
3251 ret = mbedtls_aes_xts_setkey_enc( &ctx_xts, key, 256 );
3252 if( ret != 0)
3253 goto exit;
Teppo Järvelinb5c46712019-10-04 13:35:55 +03003254 memcpy( buf, aes_test_xts_pt32[u], len );
Jaeden Amero21d79cf2018-05-23 10:30:18 +01003255 aes_tests = aes_test_xts_ct32[u];
3256 }
3257
3258
3259 ret = mbedtls_aes_crypt_xts( &ctx_xts, mode, len, data_unit,
3260 buf, buf );
3261 if( ret != 0 )
3262 goto exit;
3263
3264 if( memcmp( buf, aes_tests, len ) != 0 )
3265 {
3266 ret = 1;
3267 goto exit;
3268 }
3269
3270 if( verbose != 0 )
3271 mbedtls_printf( "passed\n" );
3272 }
3273
3274 if( verbose != 0 )
3275 mbedtls_printf( "\n" );
3276
3277 mbedtls_aes_xts_free( &ctx_xts );
3278 }
3279#endif /* MBEDTLS_CIPHER_MODE_XTS */
3280
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02003281 ret = 0;
3282
3283exit:
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01003284 if( ret != 0 && verbose != 0 )
3285 mbedtls_printf( "failed\n" );
3286
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003287 mbedtls_aes_free( &ctx );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02003288
3289 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00003290}
3291
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003292#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00003293
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003294#endif /* MBEDTLS_AES_C */