blob: 72cfc104df56f9f304dda2f82d0c3faa2fe5f0d4 [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 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200724#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200725int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key,
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200726 unsigned int keybits )
Paul Bakker5121ce52009-01-03 21:22:43 +0000727{
Arto Kinnunen6ce49882019-12-03 13:56:06 +0200728 unsigned int j = 0;
Jarno Lamsa282db8e2020-01-08 14:53:17 +0200729 unsigned int flow_ctrl = 0;
Arto Kinnunen6ce49882019-12-03 13:56:06 +0200730 volatile unsigned int i = 0;
731 volatile int ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000732 uint32_t *RK;
Jarno Lamsa282db8e2020-01-08 14:53:17 +0200733 uint32_t offset = 0;
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100734 AES_VALIDATE_RET( ctx != NULL );
735 AES_VALIDATE_RET( key != NULL );
Andrzej Kurekfba59212020-08-07 21:02:25 -0400736 (void) ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000737
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200738 switch( keybits )
Paul Bakker5121ce52009-01-03 21:22:43 +0000739 {
740 case 128: ctx->nr = 10; break;
Arto Kinnunen77b9cfc2019-08-30 11:43:21 +0300741#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000742 case 192: ctx->nr = 12; break;
743 case 256: ctx->nr = 14; break;
Arto Kinnunen77b9cfc2019-08-30 11:43:21 +0300744#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200745 default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000746 }
747
Simon Butcher5201e412018-12-06 17:40:14 +0000748#if !defined(MBEDTLS_AES_ROM_TABLES)
749 if( aes_init_done == 0 )
750 {
751 aes_gen_tables();
752 aes_init_done = 1;
Simon Butcher5201e412018-12-06 17:40:14 +0000753 }
754#endif
755
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200756#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_PADLOCK_ALIGN16)
Paul Bakker048d04e2012-02-12 17:31:04 +0000757 if( aes_padlock_ace == -1 )
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100758 aes_padlock_ace = mbedtls_padlock_has_support( MBEDTLS_PADLOCK_ACE );
Paul Bakker048d04e2012-02-12 17:31:04 +0000759
760 if( aes_padlock_ace )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200761 ctx->rk = RK = MBEDTLS_PADLOCK_ALIGN16( ctx->buf );
Paul Bakker048d04e2012-02-12 17:31:04 +0000762 else
Paul Bakker5121ce52009-01-03 21:22:43 +0000763#endif
Shelly Libermanc907c812020-11-17 11:33:25 +0200764
Paul Bakker048d04e2012-02-12 17:31:04 +0000765 ctx->rk = RK = ctx->buf;
Andrzej Kurekfac2f9b2020-07-19 00:32:34 -0400766#if defined(MBEDTLS_AES_SCA_COUNTERMEASURES)
Andrzej Kureke78775e2020-07-02 10:57:00 -0400767 mbedtls_generate_fake_key( keybits, ctx );
Andrzej Kurekfac2f9b2020-07-19 00:32:34 -0400768#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000769
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200770#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100771 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) )
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200772 return( mbedtls_aesni_setkey_enc( (unsigned char *) ctx->rk, key, keybits ) );
Manuel Pégourié-Gonnard47a35362013-12-28 20:45:04 +0100773#endif
774
Andrzej Kureka9a5ff52020-07-15 08:50:59 -0400775 /* Three least significant bits are truncated from keybits, which is
776 * expected to be a multiple of 8. */
Andrzej Kurek11ddf252020-06-24 17:33:39 -0400777 mbedtls_platform_memset( RK, 0, keybits >> 3 );
Jarno Lamsa282db8e2020-01-08 14:53:17 +0200778 offset = mbedtls_platform_random_in_range( keybits >> 5 );
779
780 for( j = offset; j < ( keybits >> 5 ); j++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000781 {
Arto Kinnunen6ce49882019-12-03 13:56:06 +0200782 GET_UINT32_LE( RK[j], key, j << 2 );
Jarno Lamsa282db8e2020-01-08 14:53:17 +0200783 flow_ctrl++;
784 }
785
786 for( j = 0; j < offset; j++ )
787 {
788 GET_UINT32_LE( RK[j], key, j << 2 );
789 flow_ctrl++;
Paul Bakker5121ce52009-01-03 21:22:43 +0000790 }
791
792 switch( ctx->nr )
793 {
794 case 10:
Paul Bakker5121ce52009-01-03 21:22:43 +0000795 for( i = 0; i < 10; i++, RK += 4 )
796 {
797 RK[4] = RK[0] ^ RCON[i] ^
Paul Bakker5c2364c2012-10-01 14:41:15 +0000798 ( (uint32_t) FSb[ ( RK[3] >> 8 ) & 0xFF ] ) ^
799 ( (uint32_t) FSb[ ( RK[3] >> 16 ) & 0xFF ] << 8 ) ^
800 ( (uint32_t) FSb[ ( RK[3] >> 24 ) & 0xFF ] << 16 ) ^
801 ( (uint32_t) FSb[ ( RK[3] ) & 0xFF ] << 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000802
803 RK[5] = RK[1] ^ RK[4];
804 RK[6] = RK[2] ^ RK[5];
805 RK[7] = RK[3] ^ RK[6];
Shelly Liberman44b42292020-11-25 21:11:36 +0200806 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000807 break;
Arto Kinnunen77b9cfc2019-08-30 11:43:21 +0300808#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000809 case 12:
810
811 for( i = 0; i < 8; i++, RK += 6 )
812 {
813 RK[6] = RK[0] ^ RCON[i] ^
Paul Bakker5c2364c2012-10-01 14:41:15 +0000814 ( (uint32_t) FSb[ ( RK[5] >> 8 ) & 0xFF ] ) ^
815 ( (uint32_t) FSb[ ( RK[5] >> 16 ) & 0xFF ] << 8 ) ^
816 ( (uint32_t) FSb[ ( RK[5] >> 24 ) & 0xFF ] << 16 ) ^
817 ( (uint32_t) FSb[ ( RK[5] ) & 0xFF ] << 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000818
819 RK[7] = RK[1] ^ RK[6];
820 RK[8] = RK[2] ^ RK[7];
821 RK[9] = RK[3] ^ RK[8];
822 RK[10] = RK[4] ^ RK[9];
823 RK[11] = RK[5] ^ RK[10];
824 }
825 break;
826
827 case 14:
828
829 for( i = 0; i < 7; i++, RK += 8 )
830 {
831 RK[8] = RK[0] ^ RCON[i] ^
Paul Bakker5c2364c2012-10-01 14:41:15 +0000832 ( (uint32_t) FSb[ ( RK[7] >> 8 ) & 0xFF ] ) ^
833 ( (uint32_t) FSb[ ( RK[7] >> 16 ) & 0xFF ] << 8 ) ^
834 ( (uint32_t) FSb[ ( RK[7] >> 24 ) & 0xFF ] << 16 ) ^
835 ( (uint32_t) FSb[ ( RK[7] ) & 0xFF ] << 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000836
837 RK[9] = RK[1] ^ RK[8];
838 RK[10] = RK[2] ^ RK[9];
839 RK[11] = RK[3] ^ RK[10];
840
841 RK[12] = RK[4] ^
Paul Bakker5c2364c2012-10-01 14:41:15 +0000842 ( (uint32_t) FSb[ ( RK[11] ) & 0xFF ] ) ^
843 ( (uint32_t) FSb[ ( RK[11] >> 8 ) & 0xFF ] << 8 ) ^
844 ( (uint32_t) FSb[ ( RK[11] >> 16 ) & 0xFF ] << 16 ) ^
845 ( (uint32_t) FSb[ ( RK[11] >> 24 ) & 0xFF ] << 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000846
847 RK[13] = RK[5] ^ RK[12];
848 RK[14] = RK[6] ^ RK[13];
849 RK[15] = RK[7] ^ RK[14];
850 }
851 break;
Arto Kinnunen77b9cfc2019-08-30 11:43:21 +0300852#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Paul Bakker5121ce52009-01-03 21:22:43 +0000853 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000854
Arto Kinnunen6ce49882019-12-03 13:56:06 +0200855 /* Validate execution path */
Jarno Lamsa282db8e2020-01-08 14:53:17 +0200856 if( ( flow_ctrl == keybits >> 5 ) && ( ( ctx->nr == 10 && i == 10 )
Arto Kinnunen6ce49882019-12-03 13:56:06 +0200857#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
858 || ( ctx->nr == 12 && i == 8 )
859 || ( ctx->nr == 14 && i == 7 )
860#endif
861 ) )
862 {
Andrzej Kurekfba59212020-08-07 21:02:25 -0400863#if defined(MBEDTLS_VALIDATE_AES_KEYS_INTEGRITY)
Andrzej Kurek9539f832020-08-10 15:58:13 -0400864 ctx->hash = mbedtls_hash( ctx->rk, keybits >> 3 );
Andrzej Kurekfba59212020-08-07 21:02:25 -0400865#endif
866 return 0;
Arto Kinnunen6ce49882019-12-03 13:56:06 +0200867 }
868
Andrzej Kurekca609372020-07-08 03:19:02 -0400869 mbedtls_platform_memset( RK, 0, ( keybits >> 5 ) * 4 );
Arto Kinnunen6ce49882019-12-03 13:56:06 +0200870 return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000871}
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200872#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000873
874/*
875 * AES key schedule (decryption)
876 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200877#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200878int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key,
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200879 unsigned int keybits )
Paul Bakker5121ce52009-01-03 21:22:43 +0000880{
Arto Kinnunen14804442019-10-16 13:43:59 +0300881#if defined(MBEDTLS_AES_ONLY_ENCRYPT)
882 (void) ctx;
883 (void) key;
884 (void) keybits;
885
886 return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
887#else /* */
Arto Kinnunen6ce49882019-12-03 13:56:06 +0200888 volatile unsigned int i = 0, j = 0;
889 volatile int ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200890 mbedtls_aes_context cty;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000891 uint32_t *RK;
892 uint32_t *SK;
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200893
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100894 AES_VALIDATE_RET( ctx != NULL );
895 AES_VALIDATE_RET( key != NULL );
Simon Butcher5201e412018-12-06 17:40:14 +0000896
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200897 mbedtls_aes_init( &cty );
Paul Bakker5121ce52009-01-03 21:22:43 +0000898
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200899#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_PADLOCK_ALIGN16)
Paul Bakker048d04e2012-02-12 17:31:04 +0000900 if( aes_padlock_ace == -1 )
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100901 aes_padlock_ace = mbedtls_padlock_has_support( MBEDTLS_PADLOCK_ACE );
Paul Bakker048d04e2012-02-12 17:31:04 +0000902
903 if( aes_padlock_ace )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200904 ctx->rk = RK = MBEDTLS_PADLOCK_ALIGN16( ctx->buf );
Paul Bakker048d04e2012-02-12 17:31:04 +0000905 else
Paul Bakker5121ce52009-01-03 21:22:43 +0000906#endif
Paul Bakker048d04e2012-02-12 17:31:04 +0000907 ctx->rk = RK = ctx->buf;
Andrzej Kurekfac2f9b2020-07-19 00:32:34 -0400908#if defined(MBEDTLS_AES_SCA_COUNTERMEASURES)
Andrzej Kureke78775e2020-07-02 10:57:00 -0400909 mbedtls_generate_fake_key( keybits, ctx );
Andrzej Kurekfac2f9b2020-07-19 00:32:34 -0400910#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000911
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200912 /* Also checks keybits */
913 if( ( ret = mbedtls_aes_setkey_enc( &cty, key, keybits ) ) != 0 )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200914 goto exit;
Paul Bakker2b222c82009-07-27 21:03:45 +0000915
Manuel Pégourié-Gonnardafd5a082014-05-28 21:52:59 +0200916 ctx->nr = cty.nr;
917
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200918#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100919 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) )
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100920 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200921 mbedtls_aesni_inverse_key( (unsigned char *) ctx->rk,
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100922 (const unsigned char *) cty.rk, ctx->nr );
Arto Kinnunen6ce49882019-12-03 13:56:06 +0200923 i = 0;
924 j = 4;
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200925 goto exit;
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100926 }
927#endif
928
Paul Bakker5121ce52009-01-03 21:22:43 +0000929 SK = cty.rk + cty.nr * 4;
930
931 *RK++ = *SK++;
932 *RK++ = *SK++;
933 *RK++ = *SK++;
934 *RK++ = *SK++;
935
936 for( i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8 )
937 {
938 for( j = 0; j < 4; j++, SK++ )
939 {
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200940 *RK++ = AES_RT0( FSb[ ( *SK ) & 0xFF ] ) ^
941 AES_RT1( FSb[ ( *SK >> 8 ) & 0xFF ] ) ^
942 AES_RT2( FSb[ ( *SK >> 16 ) & 0xFF ] ) ^
943 AES_RT3( FSb[ ( *SK >> 24 ) & 0xFF ] );
Paul Bakker5121ce52009-01-03 21:22:43 +0000944 }
945 }
946
947 *RK++ = *SK++;
948 *RK++ = *SK++;
949 *RK++ = *SK++;
950 *RK++ = *SK++;
951
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200952exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200953 mbedtls_aes_free( &cty );
Paul Bakker2b222c82009-07-27 21:03:45 +0000954
Arto Kinnunen6ce49882019-12-03 13:56:06 +0200955 if( ret != 0 )
956 {
957 return( ret );
958 }
959 else if( ( i == 0 ) && ( j == 4 ) )
960 {
Andrzej Kurekfba59212020-08-07 21:02:25 -0400961#if defined(MBEDTLS_VALIDATE_AES_KEYS_INTEGRITY)
Andrzej Kurek9539f832020-08-10 15:58:13 -0400962 ctx->hash = mbedtls_hash( ctx->rk, keybits >> 3 );
Andrzej Kurekfba59212020-08-07 21:02:25 -0400963#endif
Arto Kinnunen6ce49882019-12-03 13:56:06 +0200964 return( ret );
965 }
966 else
967 {
968 return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
969 }
970
Arto Kinnunen14804442019-10-16 13:43:59 +0300971#endif /* MBEDTLS_AES_ONLY_ENCRYPT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000972}
Jaeden Amero9366feb2018-05-29 18:55:17 +0100973
974#if defined(MBEDTLS_CIPHER_MODE_XTS)
975static int mbedtls_aes_xts_decode_keys( const unsigned char *key,
976 unsigned int keybits,
977 const unsigned char **key1,
978 unsigned int *key1bits,
979 const unsigned char **key2,
980 unsigned int *key2bits )
981{
982 const unsigned int half_keybits = keybits / 2;
983 const unsigned int half_keybytes = half_keybits / 8;
984
985 switch( keybits )
986 {
987 case 256: break;
988 case 512: break;
989 default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH );
990 }
991
992 *key1bits = half_keybits;
993 *key2bits = half_keybits;
994 *key1 = &key[0];
995 *key2 = &key[half_keybytes];
996
997 return 0;
998}
999
1000int mbedtls_aes_xts_setkey_enc( mbedtls_aes_xts_context *ctx,
1001 const unsigned char *key,
1002 unsigned int keybits)
1003{
1004 int ret;
1005 const unsigned char *key1, *key2;
1006 unsigned int key1bits, key2bits;
1007
Manuel Pégourié-Gonnard68e3dff2018-12-12 12:48:04 +01001008 AES_VALIDATE_RET( ctx != NULL );
1009 AES_VALIDATE_RET( key != NULL );
1010
Jaeden Amero9366feb2018-05-29 18:55:17 +01001011 ret = mbedtls_aes_xts_decode_keys( key, keybits, &key1, &key1bits,
1012 &key2, &key2bits );
1013 if( ret != 0 )
1014 return( ret );
1015
1016 /* Set the tweak key. Always set tweak key for the encryption mode. */
1017 ret = mbedtls_aes_setkey_enc( &ctx->tweak, key2, key2bits );
1018 if( ret != 0 )
1019 return( ret );
1020
1021 /* Set crypt key for encryption. */
1022 return mbedtls_aes_setkey_enc( &ctx->crypt, key1, key1bits );
1023}
1024
1025int mbedtls_aes_xts_setkey_dec( mbedtls_aes_xts_context *ctx,
1026 const unsigned char *key,
1027 unsigned int keybits)
1028{
1029 int ret;
1030 const unsigned char *key1, *key2;
1031 unsigned int key1bits, key2bits;
1032
Manuel Pégourié-Gonnard68e3dff2018-12-12 12:48:04 +01001033 AES_VALIDATE_RET( ctx != NULL );
1034 AES_VALIDATE_RET( key != NULL );
1035
Jaeden Amero9366feb2018-05-29 18:55:17 +01001036 ret = mbedtls_aes_xts_decode_keys( key, keybits, &key1, &key1bits,
1037 &key2, &key2bits );
1038 if( ret != 0 )
1039 return( ret );
1040
1041 /* Set the tweak key. Always set tweak key for encryption. */
1042 ret = mbedtls_aes_setkey_enc( &ctx->tweak, key2, key2bits );
1043 if( ret != 0 )
1044 return( ret );
1045
1046 /* Set crypt key for decryption. */
1047 return mbedtls_aes_setkey_dec( &ctx->crypt, key1, key1bits );
1048}
1049#endif /* MBEDTLS_CIPHER_MODE_XTS */
1050
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001051#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001052
Paul Bakker5121ce52009-01-03 21:22:43 +00001053/*
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001054 * AES-ECB block encryption
1055 */
1056#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Arto Kinnunenc3532c22019-11-29 15:07:11 +02001057
Arto Kinnunen311ab592020-01-16 17:20:51 +02001058#if defined(MBEDTLS_AES_SCA_COUNTERMEASURES)
Shelly Libermanc907c812020-11-17 11:33:25 +02001059
1060#if defined(MBEDTLS_AES_128_BIT_MASKED)
1061
Shelly Liberman11c64882020-11-26 22:48:23 +02001062static uint8_t xtime( uint8_t x )
Shelly Libermanc907c812020-11-17 11:33:25 +02001063{
Shelly Liberman11c64882020-11-26 22:48:23 +02001064 return ( ( x << 1 ) ^ ( ( ( x >> 7 ) & 1 ) * 0x1b ) );
Shelly Libermanc907c812020-11-17 11:33:25 +02001065}
1066
Shelly Liberman11c64882020-11-26 22:48:23 +02001067static int sub_bytes_masked( uint32_t *data, uint8_t sbox_masked[256] )
Shelly Libermanc907c812020-11-17 11:33:25 +02001068{
1069 volatile unsigned int i;
1070
Shelly Liberman11c64882020-11-26 22:48:23 +02001071 for ( i = 0; i < 4; i++ )
1072 {
1073 data[i] = ( (uint32_t)sbox_masked[(data[i]) & 0xFF] ) ^
1074 ( (uint32_t)sbox_masked[(data[i] >> 8 ) & 0xFF] << 8 ) ^
1075 ( (uint32_t)sbox_masked[(data[i] >> 16 ) & 0xFF] << 16 ) ^
1076 ( (uint32_t)sbox_masked[(data[i] >> 24 ) & 0xFF] << 24 );
Shelly Libermanc907c812020-11-17 11:33:25 +02001077 }
1078
Shelly Liberman11c64882020-11-26 22:48:23 +02001079 if ( i == 4 )
1080 {
Shelly Libermanc907c812020-11-17 11:33:25 +02001081 return 0;
1082 }
1083
Shelly Liberman11c64882020-11-26 22:48:23 +02001084 return ( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
Shelly Libermanc907c812020-11-17 11:33:25 +02001085}
1086
Shelly Liberman11c64882020-11-26 22:48:23 +02001087static int mix_columns( uint8_t *s )
Shelly Libermanc907c812020-11-17 11:33:25 +02001088{
Shelly Liberman11c64882020-11-26 22:48:23 +02001089 masked_state_t *state = (masked_state_t *)s;
1090 volatile unsigned int i = 0;
1091 uint8_t Tmp, Tm, t;
Shelly Libermanc907c812020-11-17 11:33:25 +02001092
Shelly Liberman11c64882020-11-26 22:48:23 +02001093 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 }
Shelly Libermanc907c812020-11-17 11:33:25 +02001110
Shelly Liberman11c64882020-11-26 22:48:23 +02001111 if ( i == 4 )
1112 {
Shelly Libermanc907c812020-11-17 11:33:25 +02001113 return 0;
Shelly Liberman11c64882020-11-26 22:48:23 +02001114 }
Shelly Libermanc907c812020-11-17 11:33:25 +02001115
Shelly Liberman11c64882020-11-26 22:48:23 +02001116 return ( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
Shelly Libermanc907c812020-11-17 11:33:25 +02001117}
1118
Shelly Liberman11c64882020-11-26 22:48:23 +02001119static void shift_rows( uint8_t *s )
Shelly Libermanc907c812020-11-17 11:33:25 +02001120{
Shelly Liberman11c64882020-11-26 22:48:23 +02001121 uint8_t temp;
1122 masked_state_t *state = (masked_state_t *)s;
1123 // Rotate first row 1 columns to left
1124 temp = (*state)[0][1];
1125 (*state)[0][1] = (*state)[1][1];
1126 (*state)[1][1] = (*state)[2][1];
1127 (*state)[2][1] = (*state)[3][1];
1128 (*state)[3][1] = temp;
Shelly Libermanc907c812020-11-17 11:33:25 +02001129
Shelly Liberman11c64882020-11-26 22:48:23 +02001130 // Rotate second row 2 columns to left
1131 temp = (*state)[0][2];
1132 (*state)[0][2] = (*state)[2][2];
1133 (*state)[2][2] = temp;
Shelly Libermanc907c812020-11-17 11:33:25 +02001134
Shelly Liberman11c64882020-11-26 22:48:23 +02001135 temp = (*state)[1][2];
1136 (*state)[1][2] = (*state)[3][2];
1137 (*state)[3][2] = temp;
Shelly Libermanc907c812020-11-17 11:33:25 +02001138
Shelly Liberman11c64882020-11-26 22:48:23 +02001139 // Rotate third row 3 columns to left
1140 temp = (*state)[0][3];
1141 (*state)[0][3] = (*state)[3][3];
1142 (*state)[3][3] = (*state)[2][3];
1143 (*state)[2][3] = (*state)[1][3];
1144 (*state)[1][3] = temp;
Shelly Libermanc907c812020-11-17 11:33:25 +02001145}
1146
Shelly Liberman11c64882020-11-26 22:48:23 +02001147#define mul_02( num ) ( ( num << 1 ) ^ ( 0x11b & - ( num >> 7 ) ) )
1148#define mul_03( num ) ( mul_02( num ) ^ num )
Shelly Libermanc907c812020-11-17 11:33:25 +02001149
Shelly Liberman11c64882020-11-26 22:48:23 +02001150static void calc_mix_colmn_mask( uint32_t mask[10] )
Shelly Libermanc907c812020-11-17 11:33:25 +02001151{
Shelly Liberman11c64882020-11-26 22:48:23 +02001152 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] );
Shelly Libermanc907c812020-11-17 11:33:25 +02001156}
1157
1158//Calculate the the invSbox to change from Mask m to Mask m'
Shelly Liberman11c64882020-11-26 22:48:23 +02001159static int calc_sbox_masked( uint32_t mask[10], uint8_t sbox_masked[256] )
Shelly Libermanc907c812020-11-17 11:33:25 +02001160{
Shelly Liberman11c64882020-11-26 22:48:23 +02001161 volatile unsigned int i = 0;
Shelly Libermanc907c812020-11-17 11:33:25 +02001162
Shelly Liberman11c64882020-11-26 22:48:23 +02001163 for ( i = 0; i < 256; i++ )
1164 {
1165 sbox_masked[i ^ mask[4]] = FSb[i] ^ mask[5];
1166 }
1167 if ( i == 256 )
1168 {
Shelly Libermanc907c812020-11-17 11:33:25 +02001169 return 0;
Shelly Liberman11c64882020-11-26 22:48:23 +02001170 }
Shelly Libermanc907c812020-11-17 11:33:25 +02001171
Shelly Liberman11c64882020-11-26 22:48:23 +02001172 return ( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
Shelly Libermanc907c812020-11-17 11:33:25 +02001173}
1174
Shelly Liberman11c64882020-11-26 22:48:23 +02001175static int remask( uint32_t *data, uint32_t m1, uint32_t m2,
1176 uint32_t m3, uint32_t m4, uint32_t m5,
1177 uint32_t m6, uint32_t m7, uint32_t m8 )
Shelly Libermanc907c812020-11-17 11:33:25 +02001178{
Shelly Liberman11c64882020-11-26 22:48:23 +02001179 volatile unsigned int i = 0;
Shelly Libermanc907c812020-11-17 11:33:25 +02001180
Shelly Liberman11c64882020-11-26 22:48:23 +02001181 for ( i = 0; i < 4; i++ )
1182 {
1183 data[i] = data[i] ^ ( ( m1 ^ m5 ) );
1184 data[i] = data[i] ^ ( ( m2 ^ m6 ) << 8 );
1185 data[i] = data[i] ^ ( ( m3 ^ m7 ) << 16 );
1186 data[i] = data[i] ^ ( ( m4 ^ m8 ) << 24 );
1187 }
Shelly Libermanc907c812020-11-17 11:33:25 +02001188
Shelly Liberman11c64882020-11-26 22:48:23 +02001189 if ( i == 4 )
1190 {
Shelly Libermanc907c812020-11-17 11:33:25 +02001191 return 0;
Shelly Liberman11c64882020-11-26 22:48:23 +02001192 }
Shelly Libermanc907c812020-11-17 11:33:25 +02001193
Shelly Liberman11c64882020-11-26 22:48:23 +02001194 return ( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
Shelly Libermanc907c812020-11-17 11:33:25 +02001195}
1196
Shelly Libermanc907c812020-11-17 11:33:25 +02001197#define MASK_INIT_CONTROL 19
Shelly Libermanc907c812020-11-17 11:33:25 +02001198
Shelly Liberman11c64882020-11-26 22:48:23 +02001199static int init_masking_encrypt( const uint8_t *rk, uint8_t *rk_masked,
1200 uint32_t mask[10], uint8_t sbox_masked[256] )
Shelly Libermanc907c812020-11-17 11:33:25 +02001201{
Shelly Liberman11c64882020-11-26 22:48:23 +02001202 volatile int flow_control = 0;
1203 unsigned int i = 0;
Shelly Libermanc907c812020-11-17 11:33:25 +02001204
Shelly Liberman11c64882020-11-26 22:48:23 +02001205 mbedtls_platform_memcpy( rk_masked, rk,
1206 MBEDTLS_AES_128_EXPANDED_KEY_SIZE_IN_WORDS * 4 );
1207
1208 //Randomly generate the masks: m1 m2 m3 m4 m m'
1209 for ( i = 0; i < 6; i++ )
1210 {
1211 mask[i] = mbedtls_platform_random_in_range( 0xFF );
1212 flow_control++;
1213 }
1214
1215 //Calculate m1',m2',m3',m4'
1216 calc_mix_colmn_mask( mask );
1217 flow_control++;
1218
1219 //Calculate the masked Sbox
1220 if ( calc_sbox_masked( mask, sbox_masked ) == 0 )
1221 {
1222 flow_control++;
1223 }
1224
1225 //Init masked key
1226 if ( remask( (uint32_t *)&rk_masked[(Nr * Nb * 4)], 0, 0, 0, 0,
1227 mask[5], mask[5], mask[5], mask[5]) == 0 )
1228 {
1229 flow_control++;
1230 }
1231
1232 // Mask change from M1',M2',M3',M4' to M
1233 for ( i = 0; i < Nr; i++ )
1234 {
1235 if ( remask( (uint32_t *)&rk_masked[( i * Nb * 4 )], mask[6],
1236 mask[7], mask[8], mask[9], mask[4], mask[4], mask[4], mask[4]) == 0 )
1237 {
1238 flow_control++;
1239 }
1240 }
1241
1242 if ( flow_control == MASK_INIT_CONTROL )
1243 {
1244 mbedtls_platform_random_delay();
1245 if (flow_control == MASK_INIT_CONTROL)
1246 {
1247 return MASK_INIT_CONTROL;
1248 }
1249 }
1250
1251 return ( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
Shelly Libermanc907c812020-11-17 11:33:25 +02001252}
1253
Shelly Liberman11c64882020-11-26 22:48:23 +02001254static int add_rk_masked( uint32_t round, uint32_t *data,
1255 const uint32_t * rk_masked )
1256{
1257 volatile unsigned int i;
1258 unsigned int offset = round * 4;
Shelly Libermanc907c812020-11-17 11:33:25 +02001259
Shelly Liberman11c64882020-11-26 22:48:23 +02001260 for ( i = 0; i < 4; i++ )
1261 {
1262 data[i] ^= rk_masked[offset + i];
1263 }
1264
1265 if ( i == 4 )
1266 {
1267 return 0;
1268 }
1269 return ( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
1270}
1271
1272static int aes_masked_round( uint32_t *data, uint32_t *key, uint32_t round,
1273 uint32_t mask[10], uint8_t sbox_masked[256] )
Shelly Libermanc907c812020-11-17 11:33:25 +02001274{
1275 volatile uint32_t flow_control = 0;
1276
1277// Mask changes from M to M'
Shelly Liberman11c64882020-11-26 22:48:23 +02001278 if ( sub_bytes_masked( data, sbox_masked ) == 0 )
1279 {
Shelly Libermanc907c812020-11-17 11:33:25 +02001280 flow_control++;
Shelly Liberman11c64882020-11-26 22:48:23 +02001281 }
Shelly Libermanc907c812020-11-17 11:33:25 +02001282
1283 //No impact on mask
1284 shift_rows((uint8_t *)data);
1285
1286 //Change mask from M' to
1287 // M1 for first row
1288 // M2 for second row
1289 // M3 for third row
1290 // M4 for fourth row
Shelly Liberman11c64882020-11-26 22:48:23 +02001291 if ( remask( data, mask[0], mask[1], mask[2], mask[3],
1292 mask[5], mask[5], mask[5], mask[5]) == 0 )
1293 {
Shelly Libermanc907c812020-11-17 11:33:25 +02001294 flow_control++;
Shelly Liberman11c64882020-11-26 22:48:23 +02001295 }
Shelly Libermanc907c812020-11-17 11:33:25 +02001296
1297 // Masks change from M1,M2,M3,M4 to M1',M2',M3',M4'
Shelly Liberman11c64882020-11-26 22:48:23 +02001298 if ( mix_columns( (uint8_t *)data ) == 0 )
1299 {
Shelly Libermanc907c812020-11-17 11:33:25 +02001300 flow_control++;
Shelly Liberman11c64882020-11-26 22:48:23 +02001301 }
Shelly Libermanc907c812020-11-17 11:33:25 +02001302
1303 // Add the First round key to the state before starting the rounds.
1304 // Masks change from M1',M2',M3',M4' to M
Shelly Liberman11c64882020-11-26 22:48:23 +02001305 if ( add_rk_masked( round, data, key ) == 0 )
1306 {
Shelly Libermanc907c812020-11-17 11:33:25 +02001307 flow_control++;
Shelly Liberman11c64882020-11-26 22:48:23 +02001308 }
Shelly Libermanc907c812020-11-17 11:33:25 +02001309
1310 if ( flow_control == 4 )
Shelly Liberman11c64882020-11-26 22:48:23 +02001311 {
Shelly Libermanc907c812020-11-17 11:33:25 +02001312 return 0;
Shelly Liberman11c64882020-11-26 22:48:23 +02001313 }
Shelly Libermanc907c812020-11-17 11:33:25 +02001314
Shelly Liberman11c64882020-11-26 22:48:23 +02001315 return ( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
Shelly Libermanc907c812020-11-17 11:33:25 +02001316}
1317
Shelly Liberman11c64882020-11-26 22:48:23 +02001318static int aes_masked_round_final( uint32_t *data, uint32_t *key,
1319 uint8_t sbox_masked[256] )
Shelly Libermanc907c812020-11-17 11:33:25 +02001320{
1321 volatile uint32_t flow_control = 0;
1322
1323 if ( sub_bytes_masked(data, sbox_masked) == 0 )
Shelly Liberman11c64882020-11-26 22:48:23 +02001324 {
Shelly Libermanc907c812020-11-17 11:33:25 +02001325 flow_control++;
Shelly Liberman11c64882020-11-26 22:48:23 +02001326 }
Shelly Libermanc907c812020-11-17 11:33:25 +02001327
Shelly Liberman11c64882020-11-26 22:48:23 +02001328 shift_rows( (uint8_t *)data );
Shelly Libermanc907c812020-11-17 11:33:25 +02001329
1330 // Mask are removed by the last addroundkey
1331 // From M' to 0
Shelly Liberman11c64882020-11-26 22:48:23 +02001332 if( add_rk_masked( Nr, data, key ) == 0 )
1333 {
Shelly Libermanc907c812020-11-17 11:33:25 +02001334 flow_control++;
Shelly Liberman11c64882020-11-26 22:48:23 +02001335 }
Shelly Libermanc907c812020-11-17 11:33:25 +02001336
1337 if ( flow_control == 2 )
Shelly Liberman11c64882020-11-26 22:48:23 +02001338 {
Shelly Libermanc907c812020-11-17 11:33:25 +02001339 return 0;
Shelly Liberman11c64882020-11-26 22:48:23 +02001340 }
Shelly Libermanc907c812020-11-17 11:33:25 +02001341
Shelly Liberman11c64882020-11-26 22:48:23 +02001342 return ( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
Shelly Libermanc907c812020-11-17 11:33:25 +02001343}
Shelly Liberman11c64882020-11-26 22:48:23 +02001344
1345//2 comes from initial data remask of real and fake data
1346#define MASKING_FLOW_CONTORL ( MASK_INIT_CONTROL + 2 )
Shelly Libermanc907c812020-11-17 11:33:25 +02001347
1348#else // end of MBEDTLS_AES_128_BIT_MASKED
1349
1350#define MASKING_FLOW_CONTORL 0
1351
Arto Kinnunenc3532c22019-11-29 15:07:11 +02001352static uint32_t *aes_fround( uint32_t *R,
1353 uint32_t *X0, uint32_t *X1, uint32_t *X2, uint32_t *X3,
1354 uint32_t Y0, uint32_t Y1, uint32_t Y2, uint32_t Y3 )
1355{
1356 *X0 = *R++ ^ AES_FT0( ( Y0 ) & 0xFF ) ^
1357 AES_FT1( ( Y1 >> 8 ) & 0xFF ) ^
1358 AES_FT2( ( Y2 >> 16 ) & 0xFF ) ^
1359 AES_FT3( ( Y3 >> 24 ) & 0xFF );
1360
1361 *X1 = *R++ ^ AES_FT0( ( Y1 ) & 0xFF ) ^
1362 AES_FT1( ( Y2 >> 8 ) & 0xFF ) ^
1363 AES_FT2( ( Y3 >> 16 ) & 0xFF ) ^
1364 AES_FT3( ( Y0 >> 24 ) & 0xFF );
1365
1366 *X2 = *R++ ^ AES_FT0( ( Y2 ) & 0xFF ) ^
1367 AES_FT1( ( Y3 >> 8 ) & 0xFF ) ^
1368 AES_FT2( ( Y0 >> 16 ) & 0xFF ) ^
1369 AES_FT3( ( Y1 >> 24 ) & 0xFF );
1370
1371 *X3 = *R++ ^ AES_FT0( ( Y3 ) & 0xFF ) ^
1372 AES_FT1( ( Y0 >> 8 ) & 0xFF ) ^
1373 AES_FT2( ( Y1 >> 16 ) & 0xFF ) ^
1374 AES_FT3( ( Y2 >> 24 ) & 0xFF );
1375
1376 return R;
1377}
1378
Shelly Libermanc907c812020-11-17 11:33:25 +02001379
Arto Kinnunenc3532c22019-11-29 15:07:11 +02001380static void aes_fround_final( uint32_t *R,
1381 uint32_t *X0, uint32_t *X1, uint32_t *X2, uint32_t *X3,
1382 uint32_t Y0, uint32_t Y1, uint32_t Y2, uint32_t Y3 )
1383{
Shelly Libermanc907c812020-11-17 11:33:25 +02001384
Arto Kinnunenc3532c22019-11-29 15:07:11 +02001385 *X0 = *R++ ^ ( (uint32_t) FSb[ ( (Y0) ) & 0xFF ] ) ^
1386 ( (uint32_t) FSb[ ( (Y1) >> 8 ) & 0xFF ] << 8 ) ^
1387 ( (uint32_t) FSb[ ( (Y2) >> 16 ) & 0xFF ] << 16 ) ^
1388 ( (uint32_t) FSb[ ( (Y3) >> 24 ) & 0xFF ] << 24 );
1389
1390 *X1 = *R++ ^ ( (uint32_t) FSb[ ( (Y1) ) & 0xFF ] ) ^
1391 ( (uint32_t) FSb[ ( (Y2) >> 8 ) & 0xFF ] << 8 ) ^
1392 ( (uint32_t) FSb[ ( (Y3) >> 16 ) & 0xFF ] << 16 ) ^
1393 ( (uint32_t) FSb[ ( (Y0) >> 24 ) & 0xFF ] << 24 );
1394
1395 *X2 = *R++ ^ ( (uint32_t) FSb[ ( (Y2) ) & 0xFF ] ) ^
1396 ( (uint32_t) FSb[ ( (Y3) >> 8 ) & 0xFF ] << 8 ) ^
1397 ( (uint32_t) FSb[ ( (Y0) >> 16 ) & 0xFF ] << 16 ) ^
1398 ( (uint32_t) FSb[ ( (Y1) >> 24 ) & 0xFF ] << 24 );
1399
1400 *X3 = *R++ ^ ( (uint32_t) FSb[ ( (Y3) ) & 0xFF ] ) ^
1401 ( (uint32_t) FSb[ ( (Y0) >> 8 ) & 0xFF ] << 8 ) ^
1402 ( (uint32_t) FSb[ ( (Y1) >> 16 ) & 0xFF ] << 16 ) ^
1403 ( (uint32_t) FSb[ ( (Y2) >> 24 ) & 0xFF ] << 24 );
1404}
Shelly Libermanc907c812020-11-17 11:33:25 +02001405#endif // MBEDTLS_AES_128_BIT_MASKED
1406
Arto Kinnunenc3532c22019-11-29 15:07:11 +02001407
Andres AGf5bf7182017-03-03 14:09:56 +00001408int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx,
1409 const unsigned char input[16],
1410 unsigned char output[16] )
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001411{
Arto Kinnunen98c93af2020-01-14 13:31:03 +02001412 int i, tindex, offset, stop_mark, dummy_rounds;
Arto Kinnunen172836a2019-11-28 13:34:13 +02001413 aes_r_data_t aes_data_real; // real data
Arto Kinnunen172836a2019-11-28 13:34:13 +02001414 aes_r_data_t aes_data_fake; // fake data
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001415 aes_r_data_t *aes_data_ptr; // pointer to real or fake data
Shelly Libermanc907c812020-11-17 11:33:25 +02001416 aes_r_data_t *aes_data_table[2] = {0}; // pointers to real and fake data
Arto Kinnunen311ab592020-01-16 17:20:51 +02001417 int round_ctrl_table_len = ctx->nr + 2 + AES_SCA_CM_ROUNDS;
Shelly Libermanc907c812020-11-17 11:33:25 +02001418 volatile int flow_control = 0;
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001419 // control bytes for AES calculation rounds,
1420 // reserve based on max rounds + dummy rounds + 2 (for initial key addition)
1421 uint8_t round_ctrl_table[( 14 + AES_SCA_CM_ROUNDS + 2 )];
Arto Kinnunenf93d55e2019-10-11 11:15:57 +03001422
Shelly Libermanc907c812020-11-17 11:33:25 +02001423#if defined MBEDTLS_AES_128_BIT_MASKED
Tero Jääskö0241f812021-01-15 17:02:37 +02001424 uint32_t rk_masked[MBEDTLS_AES_128_EXPANDED_KEY_SIZE_IN_WORDS];
1425 uint8_t sbox_masked[256];
1426 uint32_t mask[10];
Shelly Libermanc907c812020-11-17 11:33:25 +02001427#endif
1428
Andrzej Kurekfba59212020-08-07 21:02:25 -04001429#if defined(MBEDTLS_VALIDATE_AES_KEYS_INTEGRITY)
1430 unsigned key_bytes = 0;
Andrzej Kurek9539f832020-08-10 15:58:13 -04001431 uint32_t check_hash = 0;
Andrzej Kurekfba59212020-08-07 21:02:25 -04001432 switch( ctx->nr )
1433 {
1434 case 10: key_bytes = 16; break;
1435#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
1436 case 12: key_bytes = 24; break;
1437 case 14: key_bytes = 32; break;
1438#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
1439 default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH );
1440 }
Andrzej Kurek9539f832020-08-10 15:58:13 -04001441 check_hash = mbedtls_hash( ctx->rk, key_bytes );
Andrzej Kurekfba59212020-08-07 21:02:25 -04001442#endif
1443
Shelly Libermanc907c812020-11-17 11:33:25 +02001444#if defined (MBEDTLS_AES_128_BIT_MASKED)
Shelly Liberman11c64882020-11-26 22:48:23 +02001445 /* Flow control should be MASK_INIT_CONTROL and it will be checked as
1446 a part last flow control verification */
1447 flow_control = init_masking_encrypt( (uint8_t *)ctx->rk,
1448 (uint8_t *)rk_masked, mask, sbox_masked );
1449
Shelly Libermanc907c812020-11-17 11:33:25 +02001450 aes_data_real.rk_ptr = &rk_masked[0];
1451#else
Arto Kinnunen172836a2019-11-28 13:34:13 +02001452 aes_data_real.rk_ptr = ctx->rk;
Shelly Libermanc907c812020-11-17 11:33:25 +02001453#endif
1454
Andrzej Kureke78775e2020-07-02 10:57:00 -04001455 aes_data_fake.rk_ptr = ctx->frk;
Andrzej Kurekfac2f9b2020-07-19 00:32:34 -04001456
Arto Kinnunen311ab592020-01-16 17:20:51 +02001457 aes_data_table[0] = &aes_data_real;
1458 aes_data_table[1] = &aes_data_fake;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001459
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001460 // Get AES calculation control bytes
Arto Kinnunen2b24f422020-01-16 15:04:11 +02001461 dummy_rounds = aes_sca_cm_data_randomize( round_ctrl_table,
1462 round_ctrl_table_len );
Shelly Libermanc907c812020-11-17 11:33:25 +02001463 flow_control += dummy_rounds;
Arto Kinnunen172836a2019-11-28 13:34:13 +02001464
Arto Kinnunen17540ab2020-01-20 11:46:34 +02001465 // SCA countermeasure, safely clear the aes_data_real.xy_values
Jarno Lamsa282db8e2020-01-08 14:53:17 +02001466 mbedtls_platform_memset( aes_data_real.xy_values, 0, 16 );
Jarno Lamsa282db8e2020-01-08 14:53:17 +02001467
Arto Kinnunen17540ab2020-01-20 11:46:34 +02001468 // SCA countermeasure, randomize secret data location by initializing it in
1469 // a random order and writing randomized fake data between the real data
1470 // writes.
1471 offset = mbedtls_platform_random_in_range( 4 );
Arto Kinnunen2b24f422020-01-16 15:04:11 +02001472 i = offset;
1473 do
Arto Kinnunen172836a2019-11-28 13:34:13 +02001474 {
1475 GET_UINT32_LE( aes_data_real.xy_values[i], input, ( i * 4 ) );
Andrzej Kurek11ddf252020-06-24 17:33:39 -04001476 aes_data_fake.xy_values[i] = mbedtls_platform_random_uint32();
Arto Kinnunen2b24f422020-01-16 15:04:11 +02001477 flow_control++;
1478 } while( ( i = ( i + 1 ) % 4 ) != offset );
Jarno Lamsa282db8e2020-01-08 14:53:17 +02001479
Shelly Libermanc907c812020-11-17 11:33:25 +02001480#if defined (MBEDTLS_AES_128_BIT_MASKED)
1481 //Plain text masked with m1',m2',m3',m4'
Shelly Liberman11c64882020-11-26 22:48:23 +02001482 if (remask( &aes_data_real.xy_values[0], mask[6],
1483 mask[7], mask[8], mask[9], 0, 0, 0, 0) == 0 )
1484 {
Shelly Libermanc907c812020-11-17 11:33:25 +02001485 flow_control++;
Shelly Liberman11c64882020-11-26 22:48:23 +02001486 }
Shelly Libermanc907c812020-11-17 11:33:25 +02001487
Shelly Liberman11c64882020-11-26 22:48:23 +02001488 if (remask( &aes_data_fake.xy_values[0], mask[6],
1489 mask[7], mask[8], mask[9], 0, 0, 0, 0) == 0 )
1490 {
Shelly Libermanc907c812020-11-17 11:33:25 +02001491 flow_control++;
Shelly Liberman11c64882020-11-26 22:48:23 +02001492 }
Shelly Libermanc907c812020-11-17 11:33:25 +02001493#endif
1494
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001495 tindex = 0;
1496 do
Jarno Lamsa282db8e2020-01-08 14:53:17 +02001497 {
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001498 // Get pointer to the real or fake data
1499 aes_data_ptr = aes_data_table[round_ctrl_table[tindex] >> 4];
1500 stop_mark = round_ctrl_table[tindex] & 0x03;
Arto Kinnunen172836a2019-11-28 13:34:13 +02001501
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001502 // initial round key addition
Shelly Libermanc907c812020-11-17 11:33:25 +02001503#if defined (MBEDTLS_AES_128_BIT_MASKED)
Shelly Liberman11c64882020-11-26 22:48:23 +02001504 if ( add_rk_masked( 0, &aes_data_ptr->xy_values[0],
1505 aes_data_ptr->rk_ptr ) == 0 )
1506 {
Shelly Libermanc907c812020-11-17 11:33:25 +02001507 flow_control++;
Shelly Liberman11c64882020-11-26 22:48:23 +02001508 }
Shelly Libermanc907c812020-11-17 11:33:25 +02001509 aes_data_ptr->round = 1;
1510#else
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001511 for( i = 0; i < 4; i++ )
1512 {
1513 aes_data_ptr->xy_values[i] ^= *aes_data_ptr->rk_ptr++;
1514 }
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001515 flow_control++;
Shelly Libermanc907c812020-11-17 11:33:25 +02001516#endif
1517
1518 tindex++;
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001519 } while( stop_mark == 0 );
1520
1521 // Calculate AES rounds (9, 11 or 13 rounds) + dummy rounds
1522 do
Arto Kinnunen172836a2019-11-28 13:34:13 +02001523 {
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001524 // Get pointer to the real or fake data
1525 aes_data_ptr = aes_data_table[round_ctrl_table[tindex] >> 4];
1526 offset = round_ctrl_table[tindex] & 0x04;
1527 stop_mark = round_ctrl_table[tindex] & 0x03;
Shelly Libermanc907c812020-11-17 11:33:25 +02001528#if defined (MBEDTLS_AES_128_BIT_MASKED)
Shelly Liberman11c64882020-11-26 22:48:23 +02001529 if ( aes_masked_round( &aes_data_ptr->xy_values[0],
1530 aes_data_ptr->rk_ptr,
1531 aes_data_ptr->round, mask, sbox_masked ) == 0 )
1532 {
Shelly Libermanc907c812020-11-17 11:33:25 +02001533 flow_control++;
Shelly Liberman11c64882020-11-26 22:48:23 +02001534 }
Shelly Libermanc907c812020-11-17 11:33:25 +02001535 aes_data_ptr->round ++;
1536#else
Arto Kinnunenc3532c22019-11-29 15:07:11 +02001537 aes_data_ptr->rk_ptr = aes_fround( aes_data_ptr->rk_ptr,
1538 &aes_data_ptr->xy_values[0 + offset],
1539 &aes_data_ptr->xy_values[1 + offset],
1540 &aes_data_ptr->xy_values[2 + offset],
1541 &aes_data_ptr->xy_values[3 + offset],
Arto Kinnunen172836a2019-11-28 13:34:13 +02001542 aes_data_ptr->xy_values[4 - offset],
1543 aes_data_ptr->xy_values[5 - offset],
1544 aes_data_ptr->xy_values[6 - offset],
1545 aes_data_ptr->xy_values[7 - offset] );
Arto Kinnunen6ce49882019-12-03 13:56:06 +02001546 flow_control++;
Shelly Liberman44b42292020-11-25 21:11:36 +02001547#endif
Shelly Libermanc907c812020-11-17 11:33:25 +02001548 tindex++;
1549
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001550 } while( stop_mark == 0 );
Arto Kinnunen172836a2019-11-28 13:34:13 +02001551
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001552 // Calculate final AES round + dummy rounds
1553 do
Arto Kinnunen172836a2019-11-28 13:34:13 +02001554 {
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001555 aes_data_ptr = aes_data_table[round_ctrl_table[tindex] >> 4];
1556 stop_mark = round_ctrl_table[tindex] & 0x03;
Shelly Libermanc907c812020-11-17 11:33:25 +02001557#if defined (MBEDTLS_AES_128_BIT_MASKED)
1558 if ( aes_masked_round_final( &aes_data_ptr->xy_values[0],
Shelly Liberman11c64882020-11-26 22:48:23 +02001559 aes_data_ptr->rk_ptr, sbox_masked ) == 0 )
1560 {
Shelly Libermanc907c812020-11-17 11:33:25 +02001561 flow_control++;
Shelly Liberman11c64882020-11-26 22:48:23 +02001562 }
Shelly Libermanc907c812020-11-17 11:33:25 +02001563#else
Arto Kinnunenc3532c22019-11-29 15:07:11 +02001564 aes_fround_final( aes_data_ptr->rk_ptr,
1565 &aes_data_ptr->xy_values[0],
1566 &aes_data_ptr->xy_values[1],
1567 &aes_data_ptr->xy_values[2],
1568 &aes_data_ptr->xy_values[3],
Arto Kinnunen172836a2019-11-28 13:34:13 +02001569 aes_data_ptr->xy_values[4],
1570 aes_data_ptr->xy_values[5],
1571 aes_data_ptr->xy_values[6],
1572 aes_data_ptr->xy_values[7] );
Arto Kinnunen6ce49882019-12-03 13:56:06 +02001573 flow_control++;
Shelly Libermanc907c812020-11-17 11:33:25 +02001574#endif
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001575 tindex++;
1576 } while( stop_mark == 0 );
Arto Kinnunen172836a2019-11-28 13:34:13 +02001577
Arto Kinnunen17540ab2020-01-20 11:46:34 +02001578 // SCA countermeasure, safely clear the output
Jarno Lamsa282db8e2020-01-08 14:53:17 +02001579 mbedtls_platform_memset( output, 0, 16 );
Jarno Lamsa282db8e2020-01-08 14:53:17 +02001580
Arto Kinnunen17540ab2020-01-20 11:46:34 +02001581 // SCA countermeasure, randomize secret data location by writing to it in
1582 // a random order.
1583 offset = mbedtls_platform_random_in_range( 4 );
Arto Kinnunen2b24f422020-01-16 15:04:11 +02001584 i = offset;
1585 do
Jarno Lamsa282db8e2020-01-08 14:53:17 +02001586 {
1587 PUT_UINT32_LE( aes_data_real.xy_values[i], output, ( i * 4 ) );
1588 flow_control++;
Arto Kinnunen2b24f422020-01-16 15:04:11 +02001589 } while( ( i = ( i + 1 ) % 4 ) != offset );
Jarno Lamsa282db8e2020-01-08 14:53:17 +02001590
Shelly Libermanc907c812020-11-17 11:33:25 +02001591#if defined (MBEDTLS_AES_128_BIT_MASKED)
Shelly Liberman11c64882020-11-26 22:48:23 +02001592 mbedtls_platform_memset( rk_masked, 0, sizeof(rk_masked) );
Shelly Libermanc907c812020-11-17 11:33:25 +02001593#endif
Andrzej Kurekfba59212020-08-07 21:02:25 -04001594 /* Double negation is used to silence an "extraneous parentheses" warning */
Shelly Libermanc907c812020-11-17 11:33:25 +02001595 if( ! ( flow_control != tindex + dummy_rounds + MASKING_FLOW_CONTORL + 8 )
Andrzej Kurekfba59212020-08-07 21:02:25 -04001596#if defined(MBEDTLS_VALIDATE_AES_KEYS_INTEGRITY)
Andrzej Kurek9539f832020-08-10 15:58:13 -04001597 && check_hash == ctx->hash
Andrzej Kurekfba59212020-08-07 21:02:25 -04001598#endif
1599 )
Arto Kinnunen6ce49882019-12-03 13:56:06 +02001600 {
Andrzej Kurekfba59212020-08-07 21:02:25 -04001601#if defined(MBEDTLS_VALIDATE_AES_KEYS_INTEGRITY)
1602 mbedtls_platform_random_delay();
Andrzej Kurek9539f832020-08-10 15:58:13 -04001603 if( mbedtls_hash( ctx->rk, key_bytes ) == ctx->hash )
Andrzej Kurekfba59212020-08-07 21:02:25 -04001604#endif
1605 {
1606 return 0;
1607 }
Arto Kinnunen6ce49882019-12-03 13:56:06 +02001608 }
1609
Andrzej Kurekca609372020-07-08 03:19:02 -04001610 // Clear the output in case of a FI
1611 mbedtls_platform_memset( output, 0, 16 );
Shelly Liberman11c64882020-11-26 22:48:23 +02001612 mbedtls_platform_memset( (uint8_t*)&aes_data_real, 0,
1613 sizeof(aes_data_real) );
1614 mbedtls_platform_memset ( aes_data_table, 0, sizeof(aes_data_table) );
Shelly Libermanc907c812020-11-17 11:33:25 +02001615#if defined (MBEDTLS_AES_128_BIT_MASKED)
1616 //Clear masked key, masked sbox and mask in case of a FI
Shelly Liberman11c64882020-11-26 22:48:23 +02001617 mbedtls_platform_memset( rk_masked, 0, sizeof(rk_masked) );
1618 mbedtls_platform_memset( mask, 0, sizeof(mask) );
1619 mbedtls_platform_memset( sbox_masked, 0, sizeof(sbox_masked) );
Shelly Libermanc907c812020-11-17 11:33:25 +02001620#endif
Arto Kinnunen6ce49882019-12-03 13:56:06 +02001621 return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001622}
Arto Kinnunen311ab592020-01-16 17:20:51 +02001623
1624#else /* MBEDTLS_AES_SCA_COUNTERMEASURES */
1625
1626#define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \
1627 do \
1628 { \
1629 (X0) = *RK++ ^ AES_FT0( ( (Y0) ) & 0xFF ) ^ \
1630 AES_FT1( ( (Y1) >> 8 ) & 0xFF ) ^ \
1631 AES_FT2( ( (Y2) >> 16 ) & 0xFF ) ^ \
1632 AES_FT3( ( (Y3) >> 24 ) & 0xFF ); \
1633 \
1634 (X1) = *RK++ ^ AES_FT0( ( (Y1) ) & 0xFF ) ^ \
1635 AES_FT1( ( (Y2) >> 8 ) & 0xFF ) ^ \
1636 AES_FT2( ( (Y3) >> 16 ) & 0xFF ) ^ \
1637 AES_FT3( ( (Y0) >> 24 ) & 0xFF ); \
1638 \
1639 (X2) = *RK++ ^ AES_FT0( ( (Y2) ) & 0xFF ) ^ \
1640 AES_FT1( ( (Y3) >> 8 ) & 0xFF ) ^ \
1641 AES_FT2( ( (Y0) >> 16 ) & 0xFF ) ^ \
1642 AES_FT3( ( (Y1) >> 24 ) & 0xFF ); \
1643 \
1644 (X3) = *RK++ ^ AES_FT0( ( (Y3) ) & 0xFF ) ^ \
1645 AES_FT1( ( (Y0) >> 8 ) & 0xFF ) ^ \
1646 AES_FT2( ( (Y1) >> 16 ) & 0xFF ) ^ \
1647 AES_FT3( ( (Y2) >> 24 ) & 0xFF ); \
1648 } while( 0 )
1649
1650int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx,
1651 const unsigned char input[16],
1652 unsigned char output[16] )
1653{
1654 int i;
1655 uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3;
1656
1657 RK = ctx->rk;
1658
1659 GET_UINT32_LE( X0, input, 0 ); X0 ^= *RK++;
1660 GET_UINT32_LE( X1, input, 4 ); X1 ^= *RK++;
1661 GET_UINT32_LE( X2, input, 8 ); X2 ^= *RK++;
1662 GET_UINT32_LE( X3, input, 12 ); X3 ^= *RK++;
1663
1664 for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- )
1665 {
1666 AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
1667 AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 );
1668 }
1669
1670 AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
1671
1672 X0 = *RK++ ^ \
1673 ( (uint32_t) FSb[ ( Y0 ) & 0xFF ] ) ^
1674 ( (uint32_t) FSb[ ( Y1 >> 8 ) & 0xFF ] << 8 ) ^
1675 ( (uint32_t) FSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^
1676 ( (uint32_t) FSb[ ( Y3 >> 24 ) & 0xFF ] << 24 );
1677
1678 X1 = *RK++ ^ \
1679 ( (uint32_t) FSb[ ( Y1 ) & 0xFF ] ) ^
1680 ( (uint32_t) FSb[ ( Y2 >> 8 ) & 0xFF ] << 8 ) ^
1681 ( (uint32_t) FSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^
1682 ( (uint32_t) FSb[ ( Y0 >> 24 ) & 0xFF ] << 24 );
1683
1684 X2 = *RK++ ^ \
1685 ( (uint32_t) FSb[ ( Y2 ) & 0xFF ] ) ^
1686 ( (uint32_t) FSb[ ( Y3 >> 8 ) & 0xFF ] << 8 ) ^
1687 ( (uint32_t) FSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^
1688 ( (uint32_t) FSb[ ( Y1 >> 24 ) & 0xFF ] << 24 );
1689
1690 X3 = *RK++ ^ \
1691 ( (uint32_t) FSb[ ( Y3 ) & 0xFF ] ) ^
1692 ( (uint32_t) FSb[ ( Y0 >> 8 ) & 0xFF ] << 8 ) ^
1693 ( (uint32_t) FSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^
1694 ( (uint32_t) FSb[ ( Y2 >> 24 ) & 0xFF ] << 24 );
1695
1696 PUT_UINT32_LE( X0, output, 0 );
1697 PUT_UINT32_LE( X1, output, 4 );
1698 PUT_UINT32_LE( X2, output, 8 );
1699 PUT_UINT32_LE( X3, output, 12 );
1700
Andrzej Kureka8405442019-11-12 03:34:03 -05001701 mbedtls_platform_zeroize( &X0, sizeof( X0 ) );
1702 mbedtls_platform_zeroize( &X1, sizeof( X1 ) );
1703 mbedtls_platform_zeroize( &X2, sizeof( X2 ) );
1704 mbedtls_platform_zeroize( &X3, sizeof( X3 ) );
1705
1706 mbedtls_platform_zeroize( &Y0, sizeof( Y0 ) );
1707 mbedtls_platform_zeroize( &Y1, sizeof( Y1 ) );
1708 mbedtls_platform_zeroize( &Y2, sizeof( Y2 ) );
1709 mbedtls_platform_zeroize( &Y3, sizeof( Y3 ) );
1710
1711 mbedtls_platform_zeroize( &RK, sizeof( RK ) );
1712
Arto Kinnunen311ab592020-01-16 17:20:51 +02001713 return( 0 );
1714}
1715#endif /* MBEDTLS_AES_SCA_COUNTERMEASURES */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001716#endif /* !MBEDTLS_AES_ENCRYPT_ALT */
1717
Gilles Peskine8db3efb2018-02-21 19:16:20 +01001718#if !defined(MBEDTLS_DEPRECATED_REMOVED)
Hanno Beckerbedc2052017-06-26 12:46:56 +01001719void mbedtls_aes_encrypt( mbedtls_aes_context *ctx,
1720 const unsigned char input[16],
1721 unsigned char output[16] )
1722{
1723 mbedtls_internal_aes_encrypt( ctx, input, output );
1724}
Gilles Peskine8db3efb2018-02-21 19:16:20 +01001725#endif /* !MBEDTLS_DEPRECATED_REMOVED */
Hanno Beckerbedc2052017-06-26 12:46:56 +01001726
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001727/*
1728 * AES-ECB block decryption
1729 */
Arto Kinnunen14804442019-10-16 13:43:59 +03001730
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001731#if !defined(MBEDTLS_AES_DECRYPT_ALT)
Arto Kinnunen14804442019-10-16 13:43:59 +03001732#if !defined(MBEDTLS_AES_ONLY_ENCRYPT)
Arto Kinnunenc3532c22019-11-29 15:07:11 +02001733
Arto Kinnunen311ab592020-01-16 17:20:51 +02001734#if defined(MBEDTLS_AES_SCA_COUNTERMEASURES)
Arto Kinnunenc3532c22019-11-29 15:07:11 +02001735static uint32_t *aes_rround( uint32_t *R,
1736 uint32_t *X0, uint32_t *X1, uint32_t *X2, uint32_t *X3,
1737 uint32_t Y0, uint32_t Y1, uint32_t Y2, uint32_t Y3 )
1738{
1739 *X0 = *R++ ^ AES_RT0( ( Y0 ) & 0xFF ) ^
1740 AES_RT1( ( Y3 >> 8 ) & 0xFF ) ^
1741 AES_RT2( ( Y2 >> 16 ) & 0xFF ) ^
1742 AES_RT3( ( Y1 >> 24 ) & 0xFF );
1743
1744 *X1 = *R++ ^ AES_RT0( ( Y1 ) & 0xFF ) ^
1745 AES_RT1( ( Y0 >> 8 ) & 0xFF ) ^
1746 AES_RT2( ( Y3 >> 16 ) & 0xFF ) ^
1747 AES_RT3( ( Y2 >> 24 ) & 0xFF );
1748
1749 *X2 = *R++ ^ AES_RT0( ( Y2 ) & 0xFF ) ^
1750 AES_RT1( ( Y1 >> 8 ) & 0xFF ) ^
1751 AES_RT2( ( Y0 >> 16 ) & 0xFF ) ^
1752 AES_RT3( ( Y3 >> 24 ) & 0xFF );
1753
1754 *X3 = *R++ ^ AES_RT0( ( Y3 ) & 0xFF ) ^
1755 AES_RT1( ( Y2 >> 8 ) & 0xFF ) ^
1756 AES_RT2( ( Y1 >> 16 ) & 0xFF ) ^
1757 AES_RT3( ( Y0 >> 24 ) & 0xFF );
1758 return R;
1759}
1760
1761static void aes_rround_final( uint32_t *R,
1762 uint32_t *X0, uint32_t *X1, uint32_t *X2, uint32_t *X3,
1763 uint32_t Y0, uint32_t Y1, uint32_t Y2, uint32_t Y3 )
1764{
1765 *X0 = *R++ ^ ( (uint32_t) RSb[ ( (Y0) ) & 0xFF ] ) ^
1766 ( (uint32_t) RSb[ ( (Y3) >> 8 ) & 0xFF ] << 8 ) ^
1767 ( (uint32_t) RSb[ ( (Y2) >> 16 ) & 0xFF ] << 16 ) ^
1768 ( (uint32_t) RSb[ ( (Y1) >> 24 ) & 0xFF ] << 24 );
1769
1770 *X1 = *R++ ^ ( (uint32_t) RSb[ ( (Y1) ) & 0xFF ] ) ^
1771 ( (uint32_t) RSb[ ( (Y0) >> 8 ) & 0xFF ] << 8 ) ^
1772 ( (uint32_t) RSb[ ( (Y3) >> 16 ) & 0xFF ] << 16 ) ^
1773 ( (uint32_t) RSb[ ( (Y2) >> 24 ) & 0xFF ] << 24 );
1774
1775 *X2 = *R++ ^ ( (uint32_t) RSb[ ( (Y2) ) & 0xFF ] ) ^
1776 ( (uint32_t) RSb[ ( (Y1) >> 8 ) & 0xFF ] << 8 ) ^
1777 ( (uint32_t) RSb[ ( (Y0) >> 16 ) & 0xFF ] << 16 ) ^
1778 ( (uint32_t) RSb[ ( (Y3) >> 24 ) & 0xFF ] << 24 );
1779
1780 *X3 = *R++ ^ ( (uint32_t) RSb[ ( (Y3) ) & 0xFF ] ) ^
1781 ( (uint32_t) RSb[ ( (Y2) >> 8 ) & 0xFF ] << 8 ) ^
1782 ( (uint32_t) RSb[ ( (Y1) >> 16 ) & 0xFF ] << 16 ) ^
1783 ( (uint32_t) RSb[ ( (Y0) >> 24 ) & 0xFF ] << 24 );
1784}
1785
Andres AGf5bf7182017-03-03 14:09:56 +00001786int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx,
1787 const unsigned char input[16],
1788 unsigned char output[16] )
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001789{
Arto Kinnunen98c93af2020-01-14 13:31:03 +02001790 int i, tindex, offset, stop_mark, dummy_rounds;
Arto Kinnunen172836a2019-11-28 13:34:13 +02001791 aes_r_data_t aes_data_real; // real data
Arto Kinnunen172836a2019-11-28 13:34:13 +02001792 aes_r_data_t aes_data_fake; // fake data
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001793 aes_r_data_t *aes_data_ptr; // pointer to real or fake data
Arto Kinnunen172836a2019-11-28 13:34:13 +02001794 aes_r_data_t *aes_data_table[2]; // pointers to real and fake data
Arto Kinnunen311ab592020-01-16 17:20:51 +02001795 int round_ctrl_table_len = ctx->nr + 2 + AES_SCA_CM_ROUNDS;
Arto Kinnunen6ce49882019-12-03 13:56:06 +02001796 volatile int flow_control;
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001797 // control bytes for AES calculation rounds,
1798 // reserve based on max rounds + dummy rounds + 2 (for initial key addition)
1799 uint8_t round_ctrl_table[( 14 + AES_SCA_CM_ROUNDS + 2 )];
Arto Kinnunenf93d55e2019-10-11 11:15:57 +03001800
Andrzej Kurekfba59212020-08-07 21:02:25 -04001801#if defined(MBEDTLS_VALIDATE_AES_KEYS_INTEGRITY)
1802 unsigned key_bytes = 0;
Andrzej Kurek9539f832020-08-10 15:58:13 -04001803 uint32_t check_hash = 0;
Andrzej Kurekfba59212020-08-07 21:02:25 -04001804 switch( ctx->nr )
1805 {
1806 case 10: key_bytes = 16; break;
1807#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
1808 case 12: key_bytes = 24; break;
1809 case 14: key_bytes = 32; break;
1810#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
1811 default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH );
1812 }
Andrzej Kurek9539f832020-08-10 15:58:13 -04001813 check_hash = mbedtls_hash( ctx->rk, key_bytes );
Andrzej Kurekfba59212020-08-07 21:02:25 -04001814#endif
1815
Arto Kinnunen172836a2019-11-28 13:34:13 +02001816 aes_data_real.rk_ptr = ctx->rk;
Andrzej Kureke78775e2020-07-02 10:57:00 -04001817 aes_data_fake.rk_ptr = ctx->frk;
Andrzej Kurekfac2f9b2020-07-19 00:32:34 -04001818
Arto Kinnunen311ab592020-01-16 17:20:51 +02001819 aes_data_table[0] = &aes_data_real;
1820 aes_data_table[1] = &aes_data_fake;
Arto Kinnunenf93d55e2019-10-11 11:15:57 +03001821
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001822 // Get AES calculation control bytes
Arto Kinnunen98c93af2020-01-14 13:31:03 +02001823 dummy_rounds = aes_sca_cm_data_randomize( round_ctrl_table,
Arto Kinnunen2b24f422020-01-16 15:04:11 +02001824 round_ctrl_table_len );
Arto Kinnunen98c93af2020-01-14 13:31:03 +02001825 flow_control = dummy_rounds;
1826
Arto Kinnunen17540ab2020-01-20 11:46:34 +02001827 // SCA countermeasure, safely clear the aes_data_real.xy_values
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001828 mbedtls_platform_memset( aes_data_real.xy_values, 0, 16 );
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001829
Arto Kinnunen17540ab2020-01-20 11:46:34 +02001830 // SCA countermeasure, randomize secret data location by initializing it in
1831 // a random order and writing randomized fake data between the real data
1832 // writes.
1833 offset = mbedtls_platform_random_in_range( 4 );
Arto Kinnunen2b24f422020-01-16 15:04:11 +02001834 i = offset;
1835 do
Arto Kinnunenf93d55e2019-10-11 11:15:57 +03001836 {
Arto Kinnunen172836a2019-11-28 13:34:13 +02001837 GET_UINT32_LE( aes_data_real.xy_values[i], input, ( i * 4 ) );
Arto Kinnunen311ab592020-01-16 17:20:51 +02001838 aes_data_fake.xy_values[i] = mbedtls_platform_random_in_range( 0xffffffff );
Arto Kinnunen2b24f422020-01-16 15:04:11 +02001839 flow_control++;
1840 } while( ( i = ( i + 1 ) % 4 ) != offset );
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001841
1842 tindex = 0;
1843 do
1844 {
1845 // Get pointer to the real or fake data
1846 aes_data_ptr = aes_data_table[round_ctrl_table[tindex] >> 4];
1847 stop_mark = round_ctrl_table[tindex] & 0x03;
1848
1849 // initial round key addition
1850 for( i = 0; i < 4; i++ )
1851 {
1852 aes_data_ptr->xy_values[i] ^= *aes_data_ptr->rk_ptr++;
1853 }
1854 tindex++;
1855 flow_control++;
1856 } while( stop_mark == 0 );
1857
1858 // Calculate AES rounds (9, 11 or 13 rounds) + dummy rounds
1859 do
1860 {
1861 // Get pointer to the real or fake data
1862 aes_data_ptr = aes_data_table[round_ctrl_table[tindex] >> 4];
1863 offset = round_ctrl_table[tindex] & 0x04;
1864 stop_mark = round_ctrl_table[tindex] & 0x03;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001865
Arto Kinnunenc3532c22019-11-29 15:07:11 +02001866 aes_data_ptr->rk_ptr = aes_rround( aes_data_ptr->rk_ptr,
1867 &aes_data_ptr->xy_values[0 + offset],
1868 &aes_data_ptr->xy_values[1 + offset],
1869 &aes_data_ptr->xy_values[2 + offset],
1870 &aes_data_ptr->xy_values[3 + offset],
Arto Kinnunen172836a2019-11-28 13:34:13 +02001871 aes_data_ptr->xy_values[4 - offset],
1872 aes_data_ptr->xy_values[5 - offset],
1873 aes_data_ptr->xy_values[6 - offset],
1874 aes_data_ptr->xy_values[7 - offset] );
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001875 tindex++;
Arto Kinnunen6ce49882019-12-03 13:56:06 +02001876 flow_control++;
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001877 } while( stop_mark == 0 );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001878
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001879 // Calculate final AES round + dummy rounds
1880 do
Arto Kinnunen172836a2019-11-28 13:34:13 +02001881 {
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001882 aes_data_ptr = aes_data_table[round_ctrl_table[tindex] >> 4];
1883 stop_mark = round_ctrl_table[tindex] & 0x03;
Arto Kinnunenc3532c22019-11-29 15:07:11 +02001884 aes_rround_final( aes_data_ptr->rk_ptr,
1885 &aes_data_ptr->xy_values[0],
1886 &aes_data_ptr->xy_values[1],
1887 &aes_data_ptr->xy_values[2],
1888 &aes_data_ptr->xy_values[3],
Arto Kinnunen172836a2019-11-28 13:34:13 +02001889 aes_data_ptr->xy_values[4],
1890 aes_data_ptr->xy_values[5],
1891 aes_data_ptr->xy_values[6],
1892 aes_data_ptr->xy_values[7] );
Arto Kinnunen6ce49882019-12-03 13:56:06 +02001893 flow_control++;
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001894 tindex++;
1895 } while( stop_mark == 0 );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001896
Arto Kinnunen17540ab2020-01-20 11:46:34 +02001897 // SCA countermeasure, safely clear the output
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001898 mbedtls_platform_memset( output, 0, 16 );
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001899
Arto Kinnunen17540ab2020-01-20 11:46:34 +02001900 // SCA countermeasure, randomize secret data location by writing to it in
1901 // a random order.
1902 offset = mbedtls_platform_random_in_range( 4 );
Arto Kinnunen2b24f422020-01-16 15:04:11 +02001903 i = offset;
1904 do
Arto Kinnunen172836a2019-11-28 13:34:13 +02001905 {
1906 PUT_UINT32_LE( aes_data_real.xy_values[i], output, ( i * 4 ) );
Arto Kinnunen6ce49882019-12-03 13:56:06 +02001907 flow_control++;
Arto Kinnunen2b24f422020-01-16 15:04:11 +02001908 } while( ( i = ( i + 1 ) % 4 ) != offset );
Andres AGf5bf7182017-03-03 14:09:56 +00001909
Andrzej Kurekfba59212020-08-07 21:02:25 -04001910 /* Double negation is used to silence an "extraneous parentheses" warning */
1911 if( ! ( flow_control != tindex + dummy_rounds + 8 )
1912#if defined(MBEDTLS_VALIDATE_AES_KEYS_INTEGRITY)
Andrzej Kurek9539f832020-08-10 15:58:13 -04001913 && check_hash == ctx->hash
Andrzej Kurekfba59212020-08-07 21:02:25 -04001914#endif
1915 )
Arto Kinnunen6ce49882019-12-03 13:56:06 +02001916 {
Andrzej Kurekfba59212020-08-07 21:02:25 -04001917#if defined(MBEDTLS_VALIDATE_AES_KEYS_INTEGRITY)
1918 mbedtls_platform_random_delay();
Andrzej Kurek9539f832020-08-10 15:58:13 -04001919 if( mbedtls_hash( ctx->rk, key_bytes ) == ctx->hash )
Andrzej Kurekfba59212020-08-07 21:02:25 -04001920#endif
1921 {
1922 return 0;
1923 }
Arto Kinnunen6ce49882019-12-03 13:56:06 +02001924 }
1925
Andrzej Kurekca609372020-07-08 03:19:02 -04001926 // Clear the output in case of a FI
1927 mbedtls_platform_memset( output, 0, 16 );
Arto Kinnunen6ce49882019-12-03 13:56:06 +02001928 return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001929}
Arto Kinnunen311ab592020-01-16 17:20:51 +02001930
1931#else /* MBEDTLS_AES_SCA_COUNTERMEASURES */
1932
1933#define AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \
1934 do \
1935 { \
1936 (X0) = *RK++ ^ AES_RT0( ( (Y0) ) & 0xFF ) ^ \
1937 AES_RT1( ( (Y3) >> 8 ) & 0xFF ) ^ \
1938 AES_RT2( ( (Y2) >> 16 ) & 0xFF ) ^ \
1939 AES_RT3( ( (Y1) >> 24 ) & 0xFF ); \
1940 \
1941 (X1) = *RK++ ^ AES_RT0( ( (Y1) ) & 0xFF ) ^ \
1942 AES_RT1( ( (Y0) >> 8 ) & 0xFF ) ^ \
1943 AES_RT2( ( (Y3) >> 16 ) & 0xFF ) ^ \
1944 AES_RT3( ( (Y2) >> 24 ) & 0xFF ); \
1945 \
1946 (X2) = *RK++ ^ AES_RT0( ( (Y2) ) & 0xFF ) ^ \
1947 AES_RT1( ( (Y1) >> 8 ) & 0xFF ) ^ \
1948 AES_RT2( ( (Y0) >> 16 ) & 0xFF ) ^ \
1949 AES_RT3( ( (Y3) >> 24 ) & 0xFF ); \
1950 \
1951 (X3) = *RK++ ^ AES_RT0( ( (Y3) ) & 0xFF ) ^ \
1952 AES_RT1( ( (Y2) >> 8 ) & 0xFF ) ^ \
1953 AES_RT2( ( (Y1) >> 16 ) & 0xFF ) ^ \
1954 AES_RT3( ( (Y0) >> 24 ) & 0xFF ); \
1955 } while( 0 )
1956
1957int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx,
1958 const unsigned char input[16],
1959 unsigned char output[16] )
1960{
1961 int i;
1962 uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3;
1963
1964 RK = ctx->rk;
1965
1966 GET_UINT32_LE( X0, input, 0 ); X0 ^= *RK++;
1967 GET_UINT32_LE( X1, input, 4 ); X1 ^= *RK++;
1968 GET_UINT32_LE( X2, input, 8 ); X2 ^= *RK++;
1969 GET_UINT32_LE( X3, input, 12 ); X3 ^= *RK++;
1970
1971 for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- )
1972 {
1973 AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
1974 AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 );
1975 }
1976
1977 AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
1978
1979 X0 = *RK++ ^ \
1980 ( (uint32_t) RSb[ ( Y0 ) & 0xFF ] ) ^
1981 ( (uint32_t) RSb[ ( Y3 >> 8 ) & 0xFF ] << 8 ) ^
1982 ( (uint32_t) RSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^
1983 ( (uint32_t) RSb[ ( Y1 >> 24 ) & 0xFF ] << 24 );
1984
1985 X1 = *RK++ ^ \
1986 ( (uint32_t) RSb[ ( Y1 ) & 0xFF ] ) ^
1987 ( (uint32_t) RSb[ ( Y0 >> 8 ) & 0xFF ] << 8 ) ^
1988 ( (uint32_t) RSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^
1989 ( (uint32_t) RSb[ ( Y2 >> 24 ) & 0xFF ] << 24 );
1990
1991 X2 = *RK++ ^ \
1992 ( (uint32_t) RSb[ ( Y2 ) & 0xFF ] ) ^
1993 ( (uint32_t) RSb[ ( Y1 >> 8 ) & 0xFF ] << 8 ) ^
1994 ( (uint32_t) RSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^
1995 ( (uint32_t) RSb[ ( Y3 >> 24 ) & 0xFF ] << 24 );
1996
1997 X3 = *RK++ ^ \
1998 ( (uint32_t) RSb[ ( Y3 ) & 0xFF ] ) ^
1999 ( (uint32_t) RSb[ ( Y2 >> 8 ) & 0xFF ] << 8 ) ^
2000 ( (uint32_t) RSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^
2001 ( (uint32_t) RSb[ ( Y0 >> 24 ) & 0xFF ] << 24 );
2002
2003 PUT_UINT32_LE( X0, output, 0 );
2004 PUT_UINT32_LE( X1, output, 4 );
2005 PUT_UINT32_LE( X2, output, 8 );
2006 PUT_UINT32_LE( X3, output, 12 );
2007
Andrzej Kureka8405442019-11-12 03:34:03 -05002008 mbedtls_platform_zeroize( &X0, sizeof( X0 ) );
2009 mbedtls_platform_zeroize( &X1, sizeof( X1 ) );
2010 mbedtls_platform_zeroize( &X2, sizeof( X2 ) );
2011 mbedtls_platform_zeroize( &X3, sizeof( X3 ) );
2012
2013 mbedtls_platform_zeroize( &Y0, sizeof( Y0 ) );
2014 mbedtls_platform_zeroize( &Y1, sizeof( Y1 ) );
2015 mbedtls_platform_zeroize( &Y2, sizeof( Y2 ) );
2016 mbedtls_platform_zeroize( &Y3, sizeof( Y3 ) );
2017
2018 mbedtls_platform_zeroize( &RK, sizeof( RK ) );
2019
Arto Kinnunen311ab592020-01-16 17:20:51 +02002020 return( 0 );
2021}
Shelly Libermanc907c812020-11-17 11:33:25 +02002022#endif /* !MBEDTLS_AES_ONLY_ENCRYPT */
Arto Kinnunen311ab592020-01-16 17:20:51 +02002023#endif /* MBEDTLS_AES_SCA_COUNTERMEASURES */
2024
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02002025#endif /* !MBEDTLS_AES_DECRYPT_ALT */
2026
Gilles Peskine8db3efb2018-02-21 19:16:20 +01002027#if !defined(MBEDTLS_DEPRECATED_REMOVED)
Hanno Beckerbedc2052017-06-26 12:46:56 +01002028void mbedtls_aes_decrypt( mbedtls_aes_context *ctx,
2029 const unsigned char input[16],
2030 unsigned char output[16] )
2031{
Arto Kinnunen14804442019-10-16 13:43:59 +03002032#if defined(MBEDTLS_AES_ONLY_ENCRYPT)
2033 (void) ctx;
2034 (void) input;
2035 (void) output;
2036#else /* MBEDTLS_AES_ONLY_ENCRYPT */
Hanno Beckerbedc2052017-06-26 12:46:56 +01002037 mbedtls_internal_aes_decrypt( ctx, input, output );
Arto Kinnunen14804442019-10-16 13:43:59 +03002038#endif /* MBEDTLS_AES_ONLY_ENCRYPT */
Hanno Beckerbedc2052017-06-26 12:46:56 +01002039}
Gilles Peskine8db3efb2018-02-21 19:16:20 +01002040#endif /* !MBEDTLS_DEPRECATED_REMOVED */
Hanno Beckerbedc2052017-06-26 12:46:56 +01002041
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02002042/*
Paul Bakker5121ce52009-01-03 21:22:43 +00002043 * AES-ECB block encryption/decryption
2044 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002045int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx,
Manuel Pégourié-Gonnardeb6d3962018-12-18 09:59:35 +01002046 int mode,
2047 const unsigned char input[16],
2048 unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +00002049{
Manuel Pégourié-Gonnard1aca2602018-12-12 12:56:55 +01002050 AES_VALIDATE_RET( ctx != NULL );
2051 AES_VALIDATE_RET( input != NULL );
2052 AES_VALIDATE_RET( output != NULL );
2053 AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
2054 mode == MBEDTLS_AES_DECRYPT );
Arto Kinnunen14804442019-10-16 13:43:59 +03002055 (void) mode;
Manuel Pégourié-Gonnard1aca2602018-12-12 12:56:55 +01002056
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002057#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +01002058 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002059 return( mbedtls_aesni_crypt_ecb( ctx, mode, input, output ) );
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +01002060#endif
2061
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002062#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Paul Bakker048d04e2012-02-12 17:31:04 +00002063 if( aes_padlock_ace )
Paul Bakker5121ce52009-01-03 21:22:43 +00002064 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002065 if( mbedtls_padlock_xcryptecb( ctx, mode, input, output ) == 0 )
Paul Bakkerf3ccc682010-03-18 21:21:02 +00002066 return( 0 );
2067
2068 // If padlock data misaligned, we just fall back to
2069 // unaccelerated mode
2070 //
Paul Bakker5121ce52009-01-03 21:22:43 +00002071 }
2072#endif
Arto Kinnunen6ce49882019-12-03 13:56:06 +02002073
Arto Kinnunen14804442019-10-16 13:43:59 +03002074#if defined(MBEDTLS_AES_ONLY_ENCRYPT)
2075 return( mbedtls_internal_aes_encrypt( ctx, input, output ) );
2076#else /* MBEDTLS_AES_ONLY_ENCRYPT */
Paul Bakker5121ce52009-01-03 21:22:43 +00002077
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02002078 if( mode == MBEDTLS_AES_ENCRYPT )
Andres AGf5bf7182017-03-03 14:09:56 +00002079 return( mbedtls_internal_aes_encrypt( ctx, input, output ) );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02002080 else
Andres AGf5bf7182017-03-03 14:09:56 +00002081 return( mbedtls_internal_aes_decrypt( ctx, input, output ) );
Arto Kinnunen14804442019-10-16 13:43:59 +03002082#endif /* MBEDTLS_AES_ONLY_ENCRYPT */
Paul Bakker5121ce52009-01-03 21:22:43 +00002083}
2084
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002085#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00002086/*
2087 * AES-CBC buffer encryption/decryption
2088 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002089int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx,
Paul Bakker5121ce52009-01-03 21:22:43 +00002090 int mode,
Paul Bakker23986e52011-04-24 08:57:21 +00002091 size_t length,
Paul Bakker5121ce52009-01-03 21:22:43 +00002092 unsigned char iv[16],
Paul Bakkerff60ee62010-03-16 21:09:09 +00002093 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +00002094 unsigned char *output )
2095{
2096 int i;
2097 unsigned char temp[16];
2098
Manuel Pégourié-Gonnard3178d1a2018-12-12 13:05:00 +01002099 AES_VALIDATE_RET( ctx != NULL );
2100 AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
2101 mode == MBEDTLS_AES_DECRYPT );
2102 AES_VALIDATE_RET( iv != NULL );
2103 AES_VALIDATE_RET( input != NULL );
2104 AES_VALIDATE_RET( output != NULL );
2105
Paul Bakkerf3ccc682010-03-18 21:21:02 +00002106 if( length % 16 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002107 return( MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH );
Paul Bakkerf3ccc682010-03-18 21:21:02 +00002108
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002109#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Paul Bakker048d04e2012-02-12 17:31:04 +00002110 if( aes_padlock_ace )
Paul Bakker5121ce52009-01-03 21:22:43 +00002111 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002112 if( mbedtls_padlock_xcryptcbc( ctx, mode, length, iv, input, output ) == 0 )
Paul Bakkerf3ccc682010-03-18 21:21:02 +00002113 return( 0 );
Paul Bakker9af723c2014-05-01 13:03:14 +02002114
Paul Bakkerf3ccc682010-03-18 21:21:02 +00002115 // If padlock data misaligned, we just fall back to
2116 // unaccelerated mode
2117 //
Paul Bakker5121ce52009-01-03 21:22:43 +00002118 }
2119#endif
2120
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002121 if( mode == MBEDTLS_AES_DECRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +00002122 {
2123 while( length > 0 )
2124 {
Teppo Järvelin91d79382019-10-02 09:09:31 +03002125 mbedtls_platform_memcpy( temp, input, 16 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002126 mbedtls_aes_crypt_ecb( ctx, mode, input, output );
Paul Bakker5121ce52009-01-03 21:22:43 +00002127
2128 for( i = 0; i < 16; i++ )
2129 output[i] = (unsigned char)( output[i] ^ iv[i] );
2130
Teppo Järvelin91d79382019-10-02 09:09:31 +03002131 mbedtls_platform_memcpy( iv, temp, 16 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002132
2133 input += 16;
2134 output += 16;
2135 length -= 16;
2136 }
2137 }
2138 else
2139 {
2140 while( length > 0 )
2141 {
2142 for( i = 0; i < 16; i++ )
2143 output[i] = (unsigned char)( input[i] ^ iv[i] );
2144
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002145 mbedtls_aes_crypt_ecb( ctx, mode, output, output );
Teppo Järvelin91d79382019-10-02 09:09:31 +03002146 mbedtls_platform_memcpy( iv, output, 16 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002147
2148 input += 16;
2149 output += 16;
2150 length -= 16;
2151 }
2152 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +00002153
2154 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002155}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002156#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00002157
Aorimn5f778012016-06-09 23:22:58 +02002158#if defined(MBEDTLS_CIPHER_MODE_XTS)
Jaeden Amero010c2cb2018-05-29 17:00:47 +01002159
2160/* Endianess with 64 bits values */
2161#ifndef GET_UINT64_LE
2162#define GET_UINT64_LE(n,b,i) \
2163{ \
2164 (n) = ( (uint64_t) (b)[(i) + 7] << 56 ) \
2165 | ( (uint64_t) (b)[(i) + 6] << 48 ) \
2166 | ( (uint64_t) (b)[(i) + 5] << 40 ) \
2167 | ( (uint64_t) (b)[(i) + 4] << 32 ) \
2168 | ( (uint64_t) (b)[(i) + 3] << 24 ) \
2169 | ( (uint64_t) (b)[(i) + 2] << 16 ) \
2170 | ( (uint64_t) (b)[(i) + 1] << 8 ) \
2171 | ( (uint64_t) (b)[(i) ] ); \
2172}
2173#endif
2174
2175#ifndef PUT_UINT64_LE
2176#define PUT_UINT64_LE(n,b,i) \
2177{ \
2178 (b)[(i) + 7] = (unsigned char) ( (n) >> 56 ); \
2179 (b)[(i) + 6] = (unsigned char) ( (n) >> 48 ); \
2180 (b)[(i) + 5] = (unsigned char) ( (n) >> 40 ); \
2181 (b)[(i) + 4] = (unsigned char) ( (n) >> 32 ); \
2182 (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \
2183 (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \
2184 (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \
2185 (b)[(i) ] = (unsigned char) ( (n) ); \
2186}
2187#endif
2188
2189typedef unsigned char mbedtls_be128[16];
2190
2191/*
2192 * GF(2^128) multiplication function
2193 *
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01002194 * This function multiplies a field element by x in the polynomial field
2195 * representation. It uses 64-bit word operations to gain speed but compensates
2196 * for machine endianess and hence works correctly on both big and little
2197 * endian machines.
Jaeden Amero010c2cb2018-05-29 17:00:47 +01002198 */
2199static void mbedtls_gf128mul_x_ble( unsigned char r[16],
Jaeden Amero8cfc75f2018-05-31 16:53:08 +01002200 const unsigned char x[16] )
Jaeden Amero010c2cb2018-05-29 17:00:47 +01002201{
2202 uint64_t a, b, ra, rb;
2203
Jaeden Amero8cfc75f2018-05-31 16:53:08 +01002204 GET_UINT64_LE( a, x, 0 );
2205 GET_UINT64_LE( b, x, 8 );
Jaeden Amero010c2cb2018-05-29 17:00:47 +01002206
Jaeden Amero8cfc75f2018-05-31 16:53:08 +01002207 ra = ( a << 1 ) ^ 0x0087 >> ( 8 - ( ( b >> 63 ) << 3 ) );
2208 rb = ( a >> 63 ) | ( b << 1 );
Jaeden Amero010c2cb2018-05-29 17:00:47 +01002209
Jaeden Amero8cfc75f2018-05-31 16:53:08 +01002210 PUT_UINT64_LE( ra, r, 0 );
2211 PUT_UINT64_LE( rb, r, 8 );
Jaeden Amero010c2cb2018-05-29 17:00:47 +01002212}
2213
Aorimn5f778012016-06-09 23:22:58 +02002214/*
2215 * AES-XTS buffer encryption/decryption
2216 */
Jaeden Amero9366feb2018-05-29 18:55:17 +01002217int mbedtls_aes_crypt_xts( mbedtls_aes_xts_context *ctx,
2218 int mode,
Jaeden Amero5162b932018-05-29 12:55:24 +01002219 size_t length,
Jaeden Amerocd9fc5e2018-05-30 15:23:24 +01002220 const unsigned char data_unit[16],
Jaeden Amero9366feb2018-05-29 18:55:17 +01002221 const unsigned char *input,
2222 unsigned char *output )
Aorimn5f778012016-06-09 23:22:58 +02002223{
Jaeden Amerod82cd862018-04-28 15:02:45 +01002224 int ret;
2225 size_t blocks = length / 16;
2226 size_t leftover = length % 16;
2227 unsigned char tweak[16];
2228 unsigned char prev_tweak[16];
2229 unsigned char tmp[16];
Aorimn5f778012016-06-09 23:22:58 +02002230
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01002231 AES_VALIDATE_RET( ctx != NULL );
2232 AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
2233 mode == MBEDTLS_AES_DECRYPT );
Manuel Pégourié-Gonnard998a3582018-12-18 10:03:13 +01002234 AES_VALIDATE_RET( data_unit != NULL );
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01002235 AES_VALIDATE_RET( input != NULL );
2236 AES_VALIDATE_RET( output != NULL );
2237
Jaeden Amero8381fcb2018-10-11 12:06:15 +01002238 /* Data units must be at least 16 bytes long. */
Aorimn5f778012016-06-09 23:22:58 +02002239 if( length < 16 )
Jaeden Amerod82cd862018-04-28 15:02:45 +01002240 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Aorimn5f778012016-06-09 23:22:58 +02002241
Jaeden Ameroa74faba2018-10-11 12:07:43 +01002242 /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */
Jaeden Amero0a8b0202018-05-30 15:36:06 +01002243 if( length > ( 1 << 20 ) * 16 )
2244 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Aorimn5f778012016-06-09 23:22:58 +02002245
Jaeden Amerod82cd862018-04-28 15:02:45 +01002246 /* Compute the tweak. */
Jaeden Amerocd9fc5e2018-05-30 15:23:24 +01002247 ret = mbedtls_aes_crypt_ecb( &ctx->tweak, MBEDTLS_AES_ENCRYPT,
2248 data_unit, tweak );
Jaeden Amerod82cd862018-04-28 15:02:45 +01002249 if( ret != 0 )
2250 return( ret );
Aorimn5f778012016-06-09 23:22:58 +02002251
Jaeden Amerod82cd862018-04-28 15:02:45 +01002252 while( blocks-- )
Aorimn5f778012016-06-09 23:22:58 +02002253 {
Jaeden Amerod82cd862018-04-28 15:02:45 +01002254 size_t i;
2255
2256 if( leftover && ( mode == MBEDTLS_AES_DECRYPT ) && blocks == 0 )
2257 {
2258 /* We are on the last block in a decrypt operation that has
2259 * leftover bytes, so we need to use the next tweak for this block,
2260 * and this tweak for the lefover bytes. Save the current tweak for
2261 * the leftovers and then update the current tweak for use on this,
2262 * the last full block. */
Teppo Järvelin91d79382019-10-02 09:09:31 +03002263 mbedtls_platform_memcpy( prev_tweak, tweak, sizeof( tweak ) );
Jaeden Amerod82cd862018-04-28 15:02:45 +01002264 mbedtls_gf128mul_x_ble( tweak, tweak );
2265 }
2266
2267 for( i = 0; i < 16; i++ )
2268 tmp[i] = input[i] ^ tweak[i];
2269
2270 ret = mbedtls_aes_crypt_ecb( &ctx->crypt, mode, tmp, tmp );
2271 if( ret != 0 )
2272 return( ret );
2273
2274 for( i = 0; i < 16; i++ )
2275 output[i] = tmp[i] ^ tweak[i];
2276
2277 /* Update the tweak for the next block. */
2278 mbedtls_gf128mul_x_ble( tweak, tweak );
2279
2280 output += 16;
2281 input += 16;
Aorimn5f778012016-06-09 23:22:58 +02002282 }
2283
Jaeden Amerod82cd862018-04-28 15:02:45 +01002284 if( leftover )
Aorimn5f778012016-06-09 23:22:58 +02002285 {
Jaeden Amerod82cd862018-04-28 15:02:45 +01002286 /* If we are on the leftover bytes in a decrypt operation, we need to
2287 * use the previous tweak for these bytes (as saved in prev_tweak). */
2288 unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
Aorimn5f778012016-06-09 23:22:58 +02002289
Jaeden Amerod82cd862018-04-28 15:02:45 +01002290 /* We are now on the final part of the data unit, which doesn't divide
2291 * evenly by 16. It's time for ciphertext stealing. */
2292 size_t i;
2293 unsigned char *prev_output = output - 16;
Aorimn5f778012016-06-09 23:22:58 +02002294
Jaeden Amerod82cd862018-04-28 15:02:45 +01002295 /* Copy ciphertext bytes from the previous block to our output for each
2296 * byte of cyphertext we won't steal. At the same time, copy the
2297 * remainder of the input for this final round (since the loop bounds
2298 * are the same). */
2299 for( i = 0; i < leftover; i++ )
Aorimn5f778012016-06-09 23:22:58 +02002300 {
Jaeden Amerod82cd862018-04-28 15:02:45 +01002301 output[i] = prev_output[i];
2302 tmp[i] = input[i] ^ t[i];
Aorimn5f778012016-06-09 23:22:58 +02002303 }
Aorimn5f778012016-06-09 23:22:58 +02002304
Jaeden Amerod82cd862018-04-28 15:02:45 +01002305 /* Copy ciphertext bytes from the previous block for input in this
2306 * round. */
2307 for( ; i < 16; i++ )
2308 tmp[i] = prev_output[i] ^ t[i];
Aorimn5f778012016-06-09 23:22:58 +02002309
Jaeden Amerod82cd862018-04-28 15:02:45 +01002310 ret = mbedtls_aes_crypt_ecb( &ctx->crypt, mode, tmp, tmp );
2311 if( ret != 0 )
2312 return ret;
Aorimn5f778012016-06-09 23:22:58 +02002313
Jaeden Amerod82cd862018-04-28 15:02:45 +01002314 /* Write the result back to the previous block, overriding the previous
2315 * output we copied. */
2316 for( i = 0; i < 16; i++ )
2317 prev_output[i] = tmp[i] ^ t[i];
Aorimn5f778012016-06-09 23:22:58 +02002318 }
2319
2320 return( 0 );
2321}
2322#endif /* MBEDTLS_CIPHER_MODE_XTS */
2323
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002324#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00002325/*
2326 * AES-CFB128 buffer encryption/decryption
2327 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002328int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx,
Paul Bakker5121ce52009-01-03 21:22:43 +00002329 int mode,
Paul Bakker23986e52011-04-24 08:57:21 +00002330 size_t length,
Paul Bakker27fdf462011-06-09 13:55:13 +00002331 size_t *iv_off,
Paul Bakker5121ce52009-01-03 21:22:43 +00002332 unsigned char iv[16],
Paul Bakkerff60ee62010-03-16 21:09:09 +00002333 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +00002334 unsigned char *output )
2335{
Paul Bakker27fdf462011-06-09 13:55:13 +00002336 int c;
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01002337 size_t n;
2338
2339 AES_VALIDATE_RET( ctx != NULL );
2340 AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
2341 mode == MBEDTLS_AES_DECRYPT );
2342 AES_VALIDATE_RET( iv_off != NULL );
2343 AES_VALIDATE_RET( iv != NULL );
2344 AES_VALIDATE_RET( input != NULL );
2345 AES_VALIDATE_RET( output != NULL );
2346
2347 n = *iv_off;
Paul Bakker5121ce52009-01-03 21:22:43 +00002348
Manuel Pégourié-Gonnarde55e1032018-12-18 12:09:02 +01002349 if( n > 15 )
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01002350 return( MBEDTLS_ERR_AES_BAD_INPUT_DATA );
2351
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002352 if( mode == MBEDTLS_AES_DECRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +00002353 {
2354 while( length-- )
2355 {
2356 if( n == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002357 mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
Paul Bakker5121ce52009-01-03 21:22:43 +00002358
2359 c = *input++;
2360 *output++ = (unsigned char)( c ^ iv[n] );
2361 iv[n] = (unsigned char) c;
2362
Paul Bakker66d5d072014-06-17 16:39:18 +02002363 n = ( n + 1 ) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00002364 }
2365 }
2366 else
2367 {
2368 while( length-- )
2369 {
2370 if( n == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002371 mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
Paul Bakker5121ce52009-01-03 21:22:43 +00002372
2373 iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ );
2374
Paul Bakker66d5d072014-06-17 16:39:18 +02002375 n = ( n + 1 ) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00002376 }
2377 }
2378
2379 *iv_off = n;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00002380
2381 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002382}
Paul Bakker556efba2014-01-24 15:38:12 +01002383
2384/*
2385 * AES-CFB8 buffer encryption/decryption
2386 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002387int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx,
Manuel Pégourié-Gonnardeb6d3962018-12-18 09:59:35 +01002388 int mode,
2389 size_t length,
2390 unsigned char iv[16],
2391 const unsigned char *input,
2392 unsigned char *output )
Paul Bakker556efba2014-01-24 15:38:12 +01002393{
2394 unsigned char c;
2395 unsigned char ov[17];
2396
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01002397 AES_VALIDATE_RET( ctx != NULL );
2398 AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
2399 mode == MBEDTLS_AES_DECRYPT );
2400 AES_VALIDATE_RET( iv != NULL );
2401 AES_VALIDATE_RET( input != NULL );
2402 AES_VALIDATE_RET( output != NULL );
Paul Bakker556efba2014-01-24 15:38:12 +01002403 while( length-- )
2404 {
Teppo Järvelin91d79382019-10-02 09:09:31 +03002405 mbedtls_platform_memcpy( ov, iv, 16 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002406 mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
Paul Bakker556efba2014-01-24 15:38:12 +01002407
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002408 if( mode == MBEDTLS_AES_DECRYPT )
Paul Bakker556efba2014-01-24 15:38:12 +01002409 ov[16] = *input;
2410
2411 c = *output++ = (unsigned char)( iv[0] ^ *input++ );
2412
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002413 if( mode == MBEDTLS_AES_ENCRYPT )
Paul Bakker556efba2014-01-24 15:38:12 +01002414 ov[16] = c;
2415
Teppo Järvelin91d79382019-10-02 09:09:31 +03002416 mbedtls_platform_memcpy( iv, ov + 1, 16 );
Paul Bakker556efba2014-01-24 15:38:12 +01002417 }
2418
2419 return( 0 );
2420}
Simon Butcher76a5b222018-04-22 22:57:27 +01002421#endif /* MBEDTLS_CIPHER_MODE_CFB */
2422
2423#if defined(MBEDTLS_CIPHER_MODE_OFB)
2424/*
2425 * AES-OFB (Output Feedback Mode) buffer encryption/decryption
2426 */
2427int mbedtls_aes_crypt_ofb( mbedtls_aes_context *ctx,
Simon Butcher00131442018-05-22 22:40:36 +01002428 size_t length,
2429 size_t *iv_off,
2430 unsigned char iv[16],
2431 const unsigned char *input,
2432 unsigned char *output )
Simon Butcher76a5b222018-04-22 22:57:27 +01002433{
Simon Butcherad4e4932018-04-29 00:43:47 +01002434 int ret = 0;
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01002435 size_t n;
2436
2437 AES_VALIDATE_RET( ctx != NULL );
2438 AES_VALIDATE_RET( iv_off != NULL );
2439 AES_VALIDATE_RET( iv != NULL );
2440 AES_VALIDATE_RET( input != NULL );
2441 AES_VALIDATE_RET( output != NULL );
2442
2443 n = *iv_off;
Simon Butcher76a5b222018-04-22 22:57:27 +01002444
Manuel Pégourié-Gonnarde55e1032018-12-18 12:09:02 +01002445 if( n > 15 )
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01002446 return( MBEDTLS_ERR_AES_BAD_INPUT_DATA );
2447
Simon Butcher76a5b222018-04-22 22:57:27 +01002448 while( length-- )
2449 {
2450 if( n == 0 )
Simon Butcherad4e4932018-04-29 00:43:47 +01002451 {
2452 ret = mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
2453 if( ret != 0 )
2454 goto exit;
2455 }
Simon Butcher76a5b222018-04-22 22:57:27 +01002456 *output++ = *input++ ^ iv[n];
2457
2458 n = ( n + 1 ) & 0x0F;
2459 }
2460
2461 *iv_off = n;
2462
Simon Butcherad4e4932018-04-29 00:43:47 +01002463exit:
2464 return( ret );
Simon Butcher76a5b222018-04-22 22:57:27 +01002465}
2466#endif /* MBEDTLS_CIPHER_MODE_OFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002467
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002468#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002469/*
2470 * AES-CTR buffer encryption/decryption
2471 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002472int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx,
Paul Bakker27fdf462011-06-09 13:55:13 +00002473 size_t length,
2474 size_t *nc_off,
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002475 unsigned char nonce_counter[16],
2476 unsigned char stream_block[16],
2477 const unsigned char *input,
2478 unsigned char *output )
2479{
Paul Bakker369e14b2012-04-18 14:16:09 +00002480 int c, i;
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01002481 size_t n;
2482
2483 AES_VALIDATE_RET( ctx != NULL );
2484 AES_VALIDATE_RET( nc_off != NULL );
2485 AES_VALIDATE_RET( nonce_counter != NULL );
2486 AES_VALIDATE_RET( stream_block != NULL );
2487 AES_VALIDATE_RET( input != NULL );
2488 AES_VALIDATE_RET( output != NULL );
2489
2490 n = *nc_off;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002491
Arto Kinnunen75439012019-12-03 14:12:10 +02002492 if( n > 0x0F )
Mohammad Azim Khan3f7f8172017-11-23 17:49:05 +00002493 return( MBEDTLS_ERR_AES_BAD_INPUT_DATA );
2494
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002495 while( length-- )
2496 {
2497 if( n == 0 ) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002498 mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block );
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002499
Paul Bakker369e14b2012-04-18 14:16:09 +00002500 for( i = 16; i > 0; i-- )
2501 if( ++nonce_counter[i - 1] != 0 )
2502 break;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002503 }
2504 c = *input++;
2505 *output++ = (unsigned char)( c ^ stream_block[n] );
2506
Paul Bakker66d5d072014-06-17 16:39:18 +02002507 n = ( n + 1 ) & 0x0F;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002508 }
2509
2510 *nc_off = n;
2511
2512 return( 0 );
2513}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002514#endif /* MBEDTLS_CIPHER_MODE_CTR */
Manuel Pégourié-Gonnard1ec220b2014-03-10 11:20:17 +01002515
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002516#endif /* !MBEDTLS_AES_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +00002517
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002518#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00002519/*
2520 * AES test vectors from:
2521 *
2522 * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
2523 */
2524static const unsigned char aes_test_ecb_dec[3][16] =
2525{
2526 { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
2527 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
2528 { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
2529 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
2530 { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
2531 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
2532};
2533
2534static const unsigned char aes_test_ecb_enc[3][16] =
2535{
2536 { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
2537 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
2538 { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
2539 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
2540 { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
2541 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
2542};
2543
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002544#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00002545static const unsigned char aes_test_cbc_dec[3][16] =
2546{
2547 { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
2548 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
2549 { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
2550 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
2551 { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
2552 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
2553};
2554
2555static const unsigned char aes_test_cbc_enc[3][16] =
2556{
2557 { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
2558 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
2559 { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
2560 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
2561 { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
2562 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
2563};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002564#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00002565
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002566#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00002567/*
2568 * AES-CFB128 test vectors from:
2569 *
2570 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
2571 */
2572static const unsigned char aes_test_cfb128_key[3][32] =
2573{
2574 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
2575 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
2576 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
2577 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
2578 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
2579 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
2580 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
2581 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
2582 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
2583};
2584
2585static const unsigned char aes_test_cfb128_iv[16] =
2586{
2587 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
2588 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
2589};
2590
2591static const unsigned char aes_test_cfb128_pt[64] =
2592{
2593 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
2594 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
2595 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
2596 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
2597 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
2598 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
2599 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
2600 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
2601};
2602
2603static const unsigned char aes_test_cfb128_ct[3][64] =
2604{
2605 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
2606 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
2607 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F,
2608 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B,
2609 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40,
2610 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF,
2611 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E,
2612 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 },
2613 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
2614 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
2615 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21,
2616 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A,
2617 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1,
2618 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9,
2619 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0,
2620 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF },
2621 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
2622 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
2623 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8,
2624 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B,
2625 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92,
2626 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9,
2627 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8,
2628 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 }
2629};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002630#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002631
Simon Butcherad4e4932018-04-29 00:43:47 +01002632#if defined(MBEDTLS_CIPHER_MODE_OFB)
2633/*
2634 * AES-OFB test vectors from:
2635 *
Simon Butcher5db13622018-06-04 22:11:25 +01002636 * https://csrc.nist.gov/publications/detail/sp/800-38a/final
Simon Butcherad4e4932018-04-29 00:43:47 +01002637 */
2638static const unsigned char aes_test_ofb_key[3][32] =
2639{
2640 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
2641 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
2642 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
2643 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
2644 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
2645 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
2646 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
2647 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
2648 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
2649};
2650
2651static const unsigned char aes_test_ofb_iv[16] =
2652{
2653 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
2654 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
2655};
2656
2657static const unsigned char aes_test_ofb_pt[64] =
2658{
2659 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
2660 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
2661 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
2662 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
2663 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
2664 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
2665 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
2666 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
2667};
2668
2669static const unsigned char aes_test_ofb_ct[3][64] =
2670{
2671 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
2672 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
2673 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
2674 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
2675 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
2676 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
2677 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
2678 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e },
2679 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
2680 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
2681 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
2682 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
2683 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f,
2684 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
2685 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e,
2686 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a },
2687 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
2688 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
2689 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
2690 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
2691 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed,
2692 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
2693 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8,
2694 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 }
2695};
2696#endif /* MBEDTLS_CIPHER_MODE_OFB */
2697
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002698#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002699/*
2700 * AES-CTR test vectors from:
2701 *
2702 * http://www.faqs.org/rfcs/rfc3686.html
2703 */
2704
2705static const unsigned char aes_test_ctr_key[3][16] =
2706{
2707 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
2708 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
2709 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
2710 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
2711 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
2712 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
2713};
2714
2715static const unsigned char aes_test_ctr_nonce_counter[3][16] =
2716{
2717 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
2718 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
2719 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
2720 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
2721 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
2722 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
2723};
2724
2725static const unsigned char aes_test_ctr_pt[3][48] =
2726{
2727 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
2728 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
2729
2730 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
2731 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
2732 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
2733 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
2734
2735 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
2736 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
2737 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
2738 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
2739 0x20, 0x21, 0x22, 0x23 }
2740};
2741
2742static const unsigned char aes_test_ctr_ct[3][48] =
2743{
2744 { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79,
2745 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 },
2746 { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9,
2747 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88,
2748 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8,
2749 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 },
2750 { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
2751 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
2752 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
2753 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
2754 0x25, 0xB2, 0x07, 0x2F }
2755};
2756
2757static const int aes_test_ctr_len[3] =
2758 { 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002759#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00002760
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002761#if defined(MBEDTLS_CIPHER_MODE_XTS)
2762/*
2763 * AES-XTS test vectors from:
2764 *
2765 * IEEE P1619/D16 Annex B
2766 * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf
2767 * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf)
2768 */
2769static const unsigned char aes_test_xts_key[][32] =
2770{
2771 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2772 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2773 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2774 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
2775 { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
2776 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
2777 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
2778 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
2779 { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
2780 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
2781 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
2782 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
2783};
2784
2785static const unsigned char aes_test_xts_pt32[][32] =
2786{
2787 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2788 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2789 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2790 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
2791 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2792 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2793 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2794 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
2795 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2796 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2797 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2798 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
2799};
2800
2801static const unsigned char aes_test_xts_ct32[][32] =
2802{
2803 { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec,
2804 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92,
2805 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85,
2806 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e },
2807 { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e,
2808 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b,
2809 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4,
2810 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 },
2811 { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a,
2812 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2,
2813 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53,
2814 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 },
2815};
2816
2817static const unsigned char aes_test_xts_data_unit[][16] =
2818{
2819 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2820 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
2821 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
2822 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
2823 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
2824 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
2825};
2826
2827#endif /* MBEDTLS_CIPHER_MODE_XTS */
2828
Paul Bakker5121ce52009-01-03 21:22:43 +00002829/*
2830 * Checkup routine
2831 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002832int mbedtls_aes_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +00002833{
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002834 int ret = 0, i, j, u, mode;
2835 unsigned int keybits;
Paul Bakker5121ce52009-01-03 21:22:43 +00002836 unsigned char key[32];
2837 unsigned char buf[64];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002838 const unsigned char *aes_tests;
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03002839#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00002840 unsigned char iv[16];
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03002841#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002842#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +02002843 unsigned char prv[16];
2844#endif
Simon Butcher2ff0e522018-06-14 09:57:07 +01002845#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
2846 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker27fdf462011-06-09 13:55:13 +00002847 size_t offset;
Paul Bakkere91d01e2011-04-19 15:55:50 +00002848#endif
Simon Butcher66a89032018-06-15 18:20:29 +01002849#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS)
Paul Bakkere91d01e2011-04-19 15:55:50 +00002850 int len;
Simon Butcher66a89032018-06-15 18:20:29 +01002851#endif
2852#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002853 unsigned char nonce_counter[16];
2854 unsigned char stream_block[16];
2855#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002856 mbedtls_aes_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00002857
Teppo Järvelind49d2b62019-10-30 13:48:12 +02002858 memset( key, 0, 32 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002859 mbedtls_aes_init( &ctx );
Paul Bakker5121ce52009-01-03 21:22:43 +00002860
2861 /*
2862 * ECB mode
2863 */
2864 for( i = 0; i < 6; i++ )
2865 {
2866 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002867 keybits = 128 + u * 64;
2868 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00002869
2870 if( verbose != 0 )
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002871 mbedtls_printf( " AES-ECB-%3d (%s): ", keybits,
2872 ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002873
Arto Kinnunen77b9cfc2019-08-30 11:43:21 +03002874#if defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
2875 if( keybits > 128 )
2876 {
2877 mbedtls_printf( "skipped\n" );
2878 continue;
2879 }
Arto Kinnunenc0a8bd42019-10-16 14:23:14 +03002880#endif /* MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
2881
2882#if defined(MBEDTLS_AES_ONLY_ENCRYPT)
2883 if( mode == MBEDTLS_AES_DECRYPT )
2884 {
2885 mbedtls_printf( "skipped\n" );
2886 continue;
2887 }
2888#endif /* MBEDTLS_AES_ONLY_ENCRYPT */
Arto Kinnunen77b9cfc2019-08-30 11:43:21 +03002889
Teppo Järvelind49d2b62019-10-30 13:48:12 +02002890 memset( buf, 0, 16 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002891
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002892 if( mode == MBEDTLS_AES_DECRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +00002893 {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002894 ret = mbedtls_aes_setkey_dec( &ctx, key, keybits );
2895 aes_tests = aes_test_ecb_dec[u];
Paul Bakker5121ce52009-01-03 21:22:43 +00002896 }
2897 else
2898 {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002899 ret = mbedtls_aes_setkey_enc( &ctx, key, keybits );
2900 aes_tests = aes_test_ecb_enc[u];
2901 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002902
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01002903 /*
2904 * AES-192 is an optional feature that may be unavailable when
2905 * there is an alternative underlying implementation i.e. when
2906 * MBEDTLS_AES_ALT is defined.
2907 */
Ron Eldor9924bdc2018-10-04 10:59:13 +03002908 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 )
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002909 {
2910 mbedtls_printf( "skipped\n" );
2911 continue;
2912 }
2913 else if( ret != 0 )
2914 {
2915 goto exit;
2916 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002917
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002918 for( j = 0; j < 10000; j++ )
2919 {
2920 ret = mbedtls_aes_crypt_ecb( &ctx, mode, buf, buf );
2921 if( ret != 0 )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002922 goto exit;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002923 }
2924
2925 if( memcmp( buf, aes_tests, 16 ) != 0 )
2926 {
2927 ret = 1;
2928 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00002929 }
2930
2931 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002932 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002933 }
2934
2935 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002936 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002937
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002938#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00002939 /*
2940 * CBC mode
2941 */
2942 for( i = 0; i < 6; i++ )
2943 {
2944 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002945 keybits = 128 + u * 64;
2946 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00002947
2948 if( verbose != 0 )
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002949 mbedtls_printf( " AES-CBC-%3d (%s): ", keybits,
2950 ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002951
Arto Kinnunen77b9cfc2019-08-30 11:43:21 +03002952#if defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
2953 if( keybits > 128 )
2954 {
2955 mbedtls_printf( "skipped\n" );
2956 continue;
2957 }
2958#endif
2959
Arto Kinnunenc0a8bd42019-10-16 14:23:14 +03002960#if defined(MBEDTLS_AES_ONLY_ENCRYPT)
2961 if( mode == MBEDTLS_AES_DECRYPT )
2962 {
2963 mbedtls_printf( "skipped\n" );
2964 continue;
2965 }
2966#endif /* MBEDTLS_AES_ONLY_ENCRYPT */
2967
Teppo Järvelind49d2b62019-10-30 13:48:12 +02002968 memset( iv , 0, 16 );
2969 memset( prv, 0, 16 );
2970 memset( buf, 0, 16 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002971
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002972 if( mode == MBEDTLS_AES_DECRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +00002973 {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002974 ret = mbedtls_aes_setkey_dec( &ctx, key, keybits );
2975 aes_tests = aes_test_cbc_dec[u];
Paul Bakker5121ce52009-01-03 21:22:43 +00002976 }
2977 else
2978 {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002979 ret = mbedtls_aes_setkey_enc( &ctx, key, keybits );
2980 aes_tests = aes_test_cbc_enc[u];
2981 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002982
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01002983 /*
2984 * AES-192 is an optional feature that may be unavailable when
2985 * there is an alternative underlying implementation i.e. when
2986 * MBEDTLS_AES_ALT is defined.
2987 */
Ron Eldor9924bdc2018-10-04 10:59:13 +03002988 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 )
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002989 {
2990 mbedtls_printf( "skipped\n" );
2991 continue;
2992 }
2993 else if( ret != 0 )
2994 {
2995 goto exit;
2996 }
2997
2998 for( j = 0; j < 10000; j++ )
2999 {
3000 if( mode == MBEDTLS_AES_ENCRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +00003001 {
3002 unsigned char tmp[16];
3003
Teppo Järvelinb5c46712019-10-04 13:35:55 +03003004 memcpy( tmp, prv, 16 );
3005 memcpy( prv, buf, 16 );
3006 memcpy( buf, tmp, 16 );
Paul Bakker5121ce52009-01-03 21:22:43 +00003007 }
3008
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01003009 ret = mbedtls_aes_crypt_cbc( &ctx, mode, 16, iv, buf, buf );
3010 if( ret != 0 )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02003011 goto exit;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01003012
3013 }
3014
3015 if( memcmp( buf, aes_tests, 16 ) != 0 )
3016 {
3017 ret = 1;
3018 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00003019 }
3020
3021 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003022 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00003023 }
3024
3025 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003026 mbedtls_printf( "\n" );
3027#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00003028
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003029#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00003030 /*
3031 * CFB128 mode
3032 */
3033 for( i = 0; i < 6; i++ )
3034 {
3035 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01003036 keybits = 128 + u * 64;
3037 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00003038
3039 if( verbose != 0 )
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01003040 mbedtls_printf( " AES-CFB128-%3d (%s): ", keybits,
3041 ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
Paul Bakker5121ce52009-01-03 21:22:43 +00003042
Arto Kinnunen77b9cfc2019-08-30 11:43:21 +03003043#if defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
3044 if( keybits > 128 )
3045 {
3046 mbedtls_printf( "skipped\n" );
3047 continue;
3048 }
3049#endif
3050
Arto Kinnunenc0a8bd42019-10-16 14:23:14 +03003051#if defined(MBEDTLS_AES_ONLY_ENCRYPT)
3052 if( mode == MBEDTLS_AES_DECRYPT )
3053 {
3054 mbedtls_printf( "skipped\n" );
3055 continue;
3056 }
3057#endif /* MBEDTLS_AES_ONLY_ENCRYPT */
3058
Paul Bakker5121ce52009-01-03 21:22:43 +00003059 memcpy( iv, aes_test_cfb128_iv, 16 );
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01003060 memcpy( key, aes_test_cfb128_key[u], keybits / 8 );
Paul Bakker5121ce52009-01-03 21:22:43 +00003061
3062 offset = 0;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01003063 ret = mbedtls_aes_setkey_enc( &ctx, key, keybits );
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01003064 /*
3065 * AES-192 is an optional feature that may be unavailable when
3066 * there is an alternative underlying implementation i.e. when
3067 * MBEDTLS_AES_ALT is defined.
3068 */
Ron Eldor9924bdc2018-10-04 10:59:13 +03003069 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 )
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01003070 {
3071 mbedtls_printf( "skipped\n" );
3072 continue;
3073 }
3074 else if( ret != 0 )
3075 {
3076 goto exit;
3077 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003078
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01003079 if( mode == MBEDTLS_AES_DECRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +00003080 {
Teppo Järvelinb5c46712019-10-04 13:35:55 +03003081 memcpy( buf, aes_test_cfb128_ct[u], 64 );
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01003082 aes_tests = aes_test_cfb128_pt;
Paul Bakker5121ce52009-01-03 21:22:43 +00003083 }
3084 else
3085 {
Teppo Järvelinb5c46712019-10-04 13:35:55 +03003086 memcpy( buf, aes_test_cfb128_pt, 64 );
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01003087 aes_tests = aes_test_cfb128_ct[u];
3088 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003089
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01003090 ret = mbedtls_aes_crypt_cfb128( &ctx, mode, 64, &offset, iv, buf, buf );
3091 if( ret != 0 )
3092 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00003093
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01003094 if( memcmp( buf, aes_tests, 64 ) != 0 )
3095 {
3096 ret = 1;
3097 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00003098 }
3099
3100 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003101 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00003102 }
3103
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00003104 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003105 mbedtls_printf( "\n" );
3106#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00003107
Simon Butcherad4e4932018-04-29 00:43:47 +01003108#if defined(MBEDTLS_CIPHER_MODE_OFB)
3109 /*
3110 * OFB mode
3111 */
3112 for( i = 0; i < 6; i++ )
3113 {
3114 u = i >> 1;
3115 keybits = 128 + u * 64;
3116 mode = i & 1;
3117
3118 if( verbose != 0 )
3119 mbedtls_printf( " AES-OFB-%3d (%s): ", keybits,
3120 ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
3121
Arto Kinnunen77b9cfc2019-08-30 11:43:21 +03003122#if defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
3123 if( keybits > 128 )
3124 {
3125 mbedtls_printf( "skipped\n" );
3126 continue;
3127 }
3128#endif
Arto Kinnunenc0a8bd42019-10-16 14:23:14 +03003129
3130#if defined(MBEDTLS_AES_ONLY_ENCRYPT)
3131 if( mode == MBEDTLS_AES_DECRYPT )
3132 {
3133 mbedtls_printf( "skipped\n" );
3134 continue;
3135 }
3136#endif /* MBEDTLS_AES_ONLY_ENCRYPT */
3137
Simon Butcherad4e4932018-04-29 00:43:47 +01003138 memcpy( iv, aes_test_ofb_iv, 16 );
3139 memcpy( key, aes_test_ofb_key[u], keybits / 8 );
3140
3141 offset = 0;
3142 ret = mbedtls_aes_setkey_enc( &ctx, key, keybits );
3143 /*
3144 * AES-192 is an optional feature that may be unavailable when
3145 * there is an alternative underlying implementation i.e. when
3146 * MBEDTLS_AES_ALT is defined.
3147 */
Ron Eldor9924bdc2018-10-04 10:59:13 +03003148 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 )
Simon Butcherad4e4932018-04-29 00:43:47 +01003149 {
3150 mbedtls_printf( "skipped\n" );
3151 continue;
3152 }
3153 else if( ret != 0 )
3154 {
3155 goto exit;
3156 }
3157
3158 if( mode == MBEDTLS_AES_DECRYPT )
3159 {
Teppo Järvelinb5c46712019-10-04 13:35:55 +03003160 memcpy( buf, aes_test_ofb_ct[u], 64 );
Simon Butcherad4e4932018-04-29 00:43:47 +01003161 aes_tests = aes_test_ofb_pt;
3162 }
3163 else
3164 {
Teppo Järvelinb5c46712019-10-04 13:35:55 +03003165 memcpy( buf, aes_test_ofb_pt, 64 );
Simon Butcherad4e4932018-04-29 00:43:47 +01003166 aes_tests = aes_test_ofb_ct[u];
3167 }
3168
3169 ret = mbedtls_aes_crypt_ofb( &ctx, 64, &offset, iv, buf, buf );
3170 if( ret != 0 )
3171 goto exit;
3172
3173 if( memcmp( buf, aes_tests, 64 ) != 0 )
3174 {
3175 ret = 1;
3176 goto exit;
3177 }
3178
3179 if( verbose != 0 )
3180 mbedtls_printf( "passed\n" );
3181 }
3182
3183 if( verbose != 0 )
3184 mbedtls_printf( "\n" );
3185#endif /* MBEDTLS_CIPHER_MODE_OFB */
3186
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003187#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00003188 /*
3189 * CTR mode
3190 */
3191 for( i = 0; i < 6; i++ )
3192 {
3193 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01003194 mode = i & 1;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00003195
3196 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003197 mbedtls_printf( " AES-CTR-128 (%s): ",
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01003198 ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00003199
Arto Kinnunen77b9cfc2019-08-30 11:43:21 +03003200#if defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
3201 if( keybits > 128 )
3202 {
3203 mbedtls_printf( "skipped\n" );
3204 continue;
3205 }
3206#endif
3207
Arto Kinnunenc0a8bd42019-10-16 14:23:14 +03003208#if defined(MBEDTLS_AES_ONLY_ENCRYPT)
3209 if( mode == MBEDTLS_AES_DECRYPT )
3210 {
3211 mbedtls_printf( "skipped\n" );
3212 continue;
3213 }
3214#endif /* MBEDTLS_AES_ONLY_ENCRYPT */
3215
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00003216 memcpy( nonce_counter, aes_test_ctr_nonce_counter[u], 16 );
3217 memcpy( key, aes_test_ctr_key[u], 16 );
3218
3219 offset = 0;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01003220 if( ( ret = mbedtls_aes_setkey_enc( &ctx, key, 128 ) ) != 0 )
3221 goto exit;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00003222
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01003223 len = aes_test_ctr_len[u];
3224
3225 if( mode == MBEDTLS_AES_DECRYPT )
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00003226 {
Teppo Järvelinb5c46712019-10-04 13:35:55 +03003227 memcpy( buf, aes_test_ctr_ct[u], len );
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01003228 aes_tests = aes_test_ctr_pt[u];
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00003229 }
3230 else
3231 {
Teppo Järvelinb5c46712019-10-04 13:35:55 +03003232 memcpy( buf, aes_test_ctr_pt[u], len );
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01003233 aes_tests = aes_test_ctr_ct[u];
3234 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00003235
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01003236 ret = mbedtls_aes_crypt_ctr( &ctx, len, &offset, nonce_counter,
3237 stream_block, buf, buf );
3238 if( ret != 0 )
3239 goto exit;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00003240
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01003241 if( memcmp( buf, aes_tests, len ) != 0 )
3242 {
3243 ret = 1;
3244 goto exit;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00003245 }
3246
3247 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003248 mbedtls_printf( "passed\n" );
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00003249 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003250
3251 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003252 mbedtls_printf( "\n" );
3253#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00003254
Jaeden Amero21d79cf2018-05-23 10:30:18 +01003255#if defined(MBEDTLS_CIPHER_MODE_XTS)
3256 {
3257 static const int num_tests =
3258 sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key);
3259 mbedtls_aes_xts_context ctx_xts;
3260
3261 /*
3262 * XTS mode
3263 */
3264 mbedtls_aes_xts_init( &ctx_xts );
3265
3266 for( i = 0; i < num_tests << 1; i++ )
3267 {
3268 const unsigned char *data_unit;
3269 u = i >> 1;
3270 mode = i & 1;
3271
3272 if( verbose != 0 )
3273 mbedtls_printf( " AES-XTS-128 (%s): ",
3274 ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
3275
Arto Kinnunenc0a8bd42019-10-16 14:23:14 +03003276#if defined(MBEDTLS_AES_ONLY_ENCRYPT)
3277 if( mode == MBEDTLS_AES_DECRYPT )
3278 {
3279 mbedtls_printf( "skipped\n" );
3280 continue;
3281 }
3282#endif /* MBEDTLS_AES_ONLY_ENCRYPT */
3283
Teppo Järvelind49d2b62019-10-30 13:48:12 +02003284 memset( key, 0, sizeof( key ) );
3285 memcpy( key, aes_test_xts_key[u], 32 );
Jaeden Amero21d79cf2018-05-23 10:30:18 +01003286 data_unit = aes_test_xts_data_unit[u];
3287
3288 len = sizeof( *aes_test_xts_ct32 );
3289
3290 if( mode == MBEDTLS_AES_DECRYPT )
3291 {
3292 ret = mbedtls_aes_xts_setkey_dec( &ctx_xts, key, 256 );
3293 if( ret != 0)
3294 goto exit;
Teppo Järvelinb5c46712019-10-04 13:35:55 +03003295 memcpy( buf, aes_test_xts_ct32[u], len );
Jaeden Amero21d79cf2018-05-23 10:30:18 +01003296 aes_tests = aes_test_xts_pt32[u];
3297 }
3298 else
3299 {
3300 ret = mbedtls_aes_xts_setkey_enc( &ctx_xts, key, 256 );
3301 if( ret != 0)
3302 goto exit;
Teppo Järvelinb5c46712019-10-04 13:35:55 +03003303 memcpy( buf, aes_test_xts_pt32[u], len );
Jaeden Amero21d79cf2018-05-23 10:30:18 +01003304 aes_tests = aes_test_xts_ct32[u];
3305 }
3306
3307
3308 ret = mbedtls_aes_crypt_xts( &ctx_xts, mode, len, data_unit,
3309 buf, buf );
3310 if( ret != 0 )
3311 goto exit;
3312
3313 if( memcmp( buf, aes_tests, len ) != 0 )
3314 {
3315 ret = 1;
3316 goto exit;
3317 }
3318
3319 if( verbose != 0 )
3320 mbedtls_printf( "passed\n" );
3321 }
3322
3323 if( verbose != 0 )
3324 mbedtls_printf( "\n" );
3325
3326 mbedtls_aes_xts_free( &ctx_xts );
3327 }
3328#endif /* MBEDTLS_CIPHER_MODE_XTS */
3329
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02003330 ret = 0;
3331
3332exit:
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01003333 if( ret != 0 && verbose != 0 )
3334 mbedtls_printf( "failed\n" );
3335
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003336 mbedtls_aes_free( &ctx );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02003337
3338 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00003339}
3340
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003341#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00003342
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003343#endif /* MBEDTLS_AES_C */