blob: 53c614661fc1a04f3e2cb0373c98bf5f275b93d7 [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 Libermancdebcfe2020-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 Libermancdebcfe2020-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 Libermancdebcfe2020-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 Libermancdebcfe2020-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 Libermancdebcfe2020-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 Libermancdebcfe2020-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 Libermancdebcfe2020-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 Libermancdebcfe2020-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 Libermancdebcfe2020-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 Libermancdebcfe2020-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 Libermancdebcfe2020-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 Libermancdebcfe2020-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 Libermancdebcfe2020-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 Libermancdebcfe2020-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 Libermancdebcfe2020-11-17 11:33:25 +0200673#endif
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200674
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200675void mbedtls_aes_init( mbedtls_aes_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200676{
Manuel Pégourié-Gonnard0e9cddb2018-12-10 16:37:51 +0100677 AES_VALIDATE( ctx != NULL );
Simon Butcher5201e412018-12-06 17:40:14 +0000678
Manuel Pégourié-Gonnard99419332019-10-03 10:40:57 +0200679 memset( ctx, 0, sizeof( mbedtls_aes_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200680}
681
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200682void mbedtls_aes_free( mbedtls_aes_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200683{
684 if( ctx == NULL )
685 return;
686
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500687 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_aes_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200688}
689
Jaeden Amero9366feb2018-05-29 18:55:17 +0100690#if defined(MBEDTLS_CIPHER_MODE_XTS)
691void mbedtls_aes_xts_init( mbedtls_aes_xts_context *ctx )
692{
Manuel Pégourié-Gonnard0e9cddb2018-12-10 16:37:51 +0100693 AES_VALIDATE( ctx != NULL );
Simon Butcher5201e412018-12-06 17:40:14 +0000694
Jaeden Amero9366feb2018-05-29 18:55:17 +0100695 mbedtls_aes_init( &ctx->crypt );
696 mbedtls_aes_init( &ctx->tweak );
697}
698
699void mbedtls_aes_xts_free( mbedtls_aes_xts_context *ctx )
700{
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100701 if( ctx == NULL )
702 return;
Simon Butcher5201e412018-12-06 17:40:14 +0000703
Jaeden Amero9366feb2018-05-29 18:55:17 +0100704 mbedtls_aes_free( &ctx->crypt );
705 mbedtls_aes_free( &ctx->tweak );
706}
707#endif /* MBEDTLS_CIPHER_MODE_XTS */
708
Andrzej Kurekfac2f9b2020-07-19 00:32:34 -0400709#if defined(MBEDTLS_AES_SCA_COUNTERMEASURES)
Andrzej Kureke78775e2020-07-02 10:57:00 -0400710static void mbedtls_generate_fake_key( unsigned int keybits, mbedtls_aes_context *ctx )
711{
712 unsigned int qword;
713
714 for( qword = keybits >> 5; qword > 0; qword-- )
715 {
716 ctx->frk[ qword - 1 ] = mbedtls_platform_random_uint32();
717 }
718}
Andrzej Kurekfac2f9b2020-07-19 00:32:34 -0400719#endif /* MBEDTLS_AES_SCA_COUNTERMEASURES */
Andrzej Kureke78775e2020-07-02 10:57:00 -0400720
Paul Bakker5121ce52009-01-03 21:22:43 +0000721/*
722 * AES key schedule (encryption)
723 */
Shelly Libermancdebcfe2020-11-17 11:33:25 +0200724
725
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200726#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200727int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key,
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200728 unsigned int keybits )
Paul Bakker5121ce52009-01-03 21:22:43 +0000729{
Arto Kinnunen6ce49882019-12-03 13:56:06 +0200730 unsigned int j = 0;
Jarno Lamsa282db8e2020-01-08 14:53:17 +0200731 unsigned int flow_ctrl = 0;
Arto Kinnunen6ce49882019-12-03 13:56:06 +0200732 volatile unsigned int i = 0;
733 volatile int ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000734 uint32_t *RK;
Jarno Lamsa282db8e2020-01-08 14:53:17 +0200735 uint32_t offset = 0;
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100736 AES_VALIDATE_RET( ctx != NULL );
737 AES_VALIDATE_RET( key != NULL );
Andrzej Kurekfba59212020-08-07 21:02:25 -0400738 (void) ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000739
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200740 switch( keybits )
Paul Bakker5121ce52009-01-03 21:22:43 +0000741 {
742 case 128: ctx->nr = 10; break;
Arto Kinnunen77b9cfc2019-08-30 11:43:21 +0300743#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000744 case 192: ctx->nr = 12; break;
745 case 256: ctx->nr = 14; break;
Arto Kinnunen77b9cfc2019-08-30 11:43:21 +0300746#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200747 default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000748 }
749
Simon Butcher5201e412018-12-06 17:40:14 +0000750#if !defined(MBEDTLS_AES_ROM_TABLES)
751 if( aes_init_done == 0 )
752 {
753 aes_gen_tables();
754 aes_init_done = 1;
Simon Butcher5201e412018-12-06 17:40:14 +0000755 }
756#endif
757
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200758#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_PADLOCK_ALIGN16)
Paul Bakker048d04e2012-02-12 17:31:04 +0000759 if( aes_padlock_ace == -1 )
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100760 aes_padlock_ace = mbedtls_padlock_has_support( MBEDTLS_PADLOCK_ACE );
Paul Bakker048d04e2012-02-12 17:31:04 +0000761
762 if( aes_padlock_ace )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200763 ctx->rk = RK = MBEDTLS_PADLOCK_ALIGN16( ctx->buf );
Paul Bakker048d04e2012-02-12 17:31:04 +0000764 else
Paul Bakker5121ce52009-01-03 21:22:43 +0000765#endif
Shelly Libermancdebcfe2020-11-17 11:33:25 +0200766
Paul Bakker048d04e2012-02-12 17:31:04 +0000767 ctx->rk = RK = ctx->buf;
Andrzej Kurekfac2f9b2020-07-19 00:32:34 -0400768#if defined(MBEDTLS_AES_SCA_COUNTERMEASURES)
Andrzej Kureke78775e2020-07-02 10:57:00 -0400769 mbedtls_generate_fake_key( keybits, ctx );
Andrzej Kurekfac2f9b2020-07-19 00:32:34 -0400770#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000771
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200772#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100773 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) )
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200774 return( mbedtls_aesni_setkey_enc( (unsigned char *) ctx->rk, key, keybits ) );
Manuel Pégourié-Gonnard47a35362013-12-28 20:45:04 +0100775#endif
776
Andrzej Kureka9a5ff52020-07-15 08:50:59 -0400777 /* Three least significant bits are truncated from keybits, which is
778 * expected to be a multiple of 8. */
Andrzej Kurek11ddf252020-06-24 17:33:39 -0400779 mbedtls_platform_memset( RK, 0, keybits >> 3 );
Jarno Lamsa282db8e2020-01-08 14:53:17 +0200780 offset = mbedtls_platform_random_in_range( keybits >> 5 );
781
782 for( j = offset; j < ( keybits >> 5 ); j++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000783 {
Arto Kinnunen6ce49882019-12-03 13:56:06 +0200784 GET_UINT32_LE( RK[j], key, j << 2 );
Jarno Lamsa282db8e2020-01-08 14:53:17 +0200785 flow_ctrl++;
786 }
787
788 for( j = 0; j < offset; j++ )
789 {
790 GET_UINT32_LE( RK[j], key, j << 2 );
791 flow_ctrl++;
Paul Bakker5121ce52009-01-03 21:22:43 +0000792 }
Shelly Libermancdebcfe2020-11-17 11:33:25 +0200793
Paul Bakker5121ce52009-01-03 21:22:43 +0000794 switch( ctx->nr )
795 {
796 case 10:
Paul Bakker5121ce52009-01-03 21:22:43 +0000797 for( i = 0; i < 10; i++, RK += 4 )
798 {
799 RK[4] = RK[0] ^ RCON[i] ^
Paul Bakker5c2364c2012-10-01 14:41:15 +0000800 ( (uint32_t) FSb[ ( RK[3] >> 8 ) & 0xFF ] ) ^
801 ( (uint32_t) FSb[ ( RK[3] >> 16 ) & 0xFF ] << 8 ) ^
802 ( (uint32_t) FSb[ ( RK[3] >> 24 ) & 0xFF ] << 16 ) ^
803 ( (uint32_t) FSb[ ( RK[3] ) & 0xFF ] << 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000804
805 RK[5] = RK[1] ^ RK[4];
806 RK[6] = RK[2] ^ RK[5];
807 RK[7] = RK[3] ^ RK[6];
Shelly Libermancdebcfe2020-11-17 11:33:25 +0200808 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000809 break;
Arto Kinnunen77b9cfc2019-08-30 11:43:21 +0300810#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000811 case 12:
812
813 for( i = 0; i < 8; i++, RK += 6 )
814 {
815 RK[6] = RK[0] ^ RCON[i] ^
Paul Bakker5c2364c2012-10-01 14:41:15 +0000816 ( (uint32_t) FSb[ ( RK[5] >> 8 ) & 0xFF ] ) ^
817 ( (uint32_t) FSb[ ( RK[5] >> 16 ) & 0xFF ] << 8 ) ^
818 ( (uint32_t) FSb[ ( RK[5] >> 24 ) & 0xFF ] << 16 ) ^
819 ( (uint32_t) FSb[ ( RK[5] ) & 0xFF ] << 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000820
821 RK[7] = RK[1] ^ RK[6];
822 RK[8] = RK[2] ^ RK[7];
823 RK[9] = RK[3] ^ RK[8];
824 RK[10] = RK[4] ^ RK[9];
825 RK[11] = RK[5] ^ RK[10];
826 }
827 break;
828
829 case 14:
830
831 for( i = 0; i < 7; i++, RK += 8 )
832 {
833 RK[8] = RK[0] ^ RCON[i] ^
Paul Bakker5c2364c2012-10-01 14:41:15 +0000834 ( (uint32_t) FSb[ ( RK[7] >> 8 ) & 0xFF ] ) ^
835 ( (uint32_t) FSb[ ( RK[7] >> 16 ) & 0xFF ] << 8 ) ^
836 ( (uint32_t) FSb[ ( RK[7] >> 24 ) & 0xFF ] << 16 ) ^
837 ( (uint32_t) FSb[ ( RK[7] ) & 0xFF ] << 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000838
839 RK[9] = RK[1] ^ RK[8];
840 RK[10] = RK[2] ^ RK[9];
841 RK[11] = RK[3] ^ RK[10];
842
843 RK[12] = RK[4] ^
Paul Bakker5c2364c2012-10-01 14:41:15 +0000844 ( (uint32_t) FSb[ ( RK[11] ) & 0xFF ] ) ^
845 ( (uint32_t) FSb[ ( RK[11] >> 8 ) & 0xFF ] << 8 ) ^
846 ( (uint32_t) FSb[ ( RK[11] >> 16 ) & 0xFF ] << 16 ) ^
847 ( (uint32_t) FSb[ ( RK[11] >> 24 ) & 0xFF ] << 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000848
849 RK[13] = RK[5] ^ RK[12];
850 RK[14] = RK[6] ^ RK[13];
851 RK[15] = RK[7] ^ RK[14];
852 }
853 break;
Arto Kinnunen77b9cfc2019-08-30 11:43:21 +0300854#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Paul Bakker5121ce52009-01-03 21:22:43 +0000855 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000856
Arto Kinnunen6ce49882019-12-03 13:56:06 +0200857 /* Validate execution path */
Jarno Lamsa282db8e2020-01-08 14:53:17 +0200858 if( ( flow_ctrl == keybits >> 5 ) && ( ( ctx->nr == 10 && i == 10 )
Arto Kinnunen6ce49882019-12-03 13:56:06 +0200859#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
860 || ( ctx->nr == 12 && i == 8 )
861 || ( ctx->nr == 14 && i == 7 )
862#endif
863 ) )
864 {
Andrzej Kurekfba59212020-08-07 21:02:25 -0400865#if defined(MBEDTLS_VALIDATE_AES_KEYS_INTEGRITY)
Andrzej Kurek9539f832020-08-10 15:58:13 -0400866 ctx->hash = mbedtls_hash( ctx->rk, keybits >> 3 );
Andrzej Kurekfba59212020-08-07 21:02:25 -0400867#endif
868 return 0;
Arto Kinnunen6ce49882019-12-03 13:56:06 +0200869 }
870
Andrzej Kurekca609372020-07-08 03:19:02 -0400871 mbedtls_platform_memset( RK, 0, ( keybits >> 5 ) * 4 );
Arto Kinnunen6ce49882019-12-03 13:56:06 +0200872 return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000873}
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200874#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000875
876/*
877 * AES key schedule (decryption)
878 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200879#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200880int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key,
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200881 unsigned int keybits )
Paul Bakker5121ce52009-01-03 21:22:43 +0000882{
Arto Kinnunen14804442019-10-16 13:43:59 +0300883#if defined(MBEDTLS_AES_ONLY_ENCRYPT)
884 (void) ctx;
885 (void) key;
886 (void) keybits;
887
888 return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
889#else /* */
Arto Kinnunen6ce49882019-12-03 13:56:06 +0200890 volatile unsigned int i = 0, j = 0;
891 volatile int ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200892 mbedtls_aes_context cty;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000893 uint32_t *RK;
894 uint32_t *SK;
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200895
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100896 AES_VALIDATE_RET( ctx != NULL );
897 AES_VALIDATE_RET( key != NULL );
Simon Butcher5201e412018-12-06 17:40:14 +0000898
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200899 mbedtls_aes_init( &cty );
Paul Bakker5121ce52009-01-03 21:22:43 +0000900
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200901#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_PADLOCK_ALIGN16)
Paul Bakker048d04e2012-02-12 17:31:04 +0000902 if( aes_padlock_ace == -1 )
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100903 aes_padlock_ace = mbedtls_padlock_has_support( MBEDTLS_PADLOCK_ACE );
Paul Bakker048d04e2012-02-12 17:31:04 +0000904
905 if( aes_padlock_ace )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200906 ctx->rk = RK = MBEDTLS_PADLOCK_ALIGN16( ctx->buf );
Paul Bakker048d04e2012-02-12 17:31:04 +0000907 else
Paul Bakker5121ce52009-01-03 21:22:43 +0000908#endif
Paul Bakker048d04e2012-02-12 17:31:04 +0000909 ctx->rk = RK = ctx->buf;
Andrzej Kurekfac2f9b2020-07-19 00:32:34 -0400910#if defined(MBEDTLS_AES_SCA_COUNTERMEASURES)
Andrzej Kureke78775e2020-07-02 10:57:00 -0400911 mbedtls_generate_fake_key( keybits, ctx );
Andrzej Kurekfac2f9b2020-07-19 00:32:34 -0400912#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000913
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200914 /* Also checks keybits */
915 if( ( ret = mbedtls_aes_setkey_enc( &cty, key, keybits ) ) != 0 )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200916 goto exit;
Paul Bakker2b222c82009-07-27 21:03:45 +0000917
Manuel Pégourié-Gonnardafd5a082014-05-28 21:52:59 +0200918 ctx->nr = cty.nr;
919
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200920#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100921 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) )
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100922 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200923 mbedtls_aesni_inverse_key( (unsigned char *) ctx->rk,
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100924 (const unsigned char *) cty.rk, ctx->nr );
Arto Kinnunen6ce49882019-12-03 13:56:06 +0200925 i = 0;
926 j = 4;
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200927 goto exit;
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100928 }
929#endif
930
Paul Bakker5121ce52009-01-03 21:22:43 +0000931 SK = cty.rk + cty.nr * 4;
932
933 *RK++ = *SK++;
934 *RK++ = *SK++;
935 *RK++ = *SK++;
936 *RK++ = *SK++;
937
938 for( i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8 )
939 {
940 for( j = 0; j < 4; j++, SK++ )
941 {
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200942 *RK++ = AES_RT0( FSb[ ( *SK ) & 0xFF ] ) ^
943 AES_RT1( FSb[ ( *SK >> 8 ) & 0xFF ] ) ^
944 AES_RT2( FSb[ ( *SK >> 16 ) & 0xFF ] ) ^
945 AES_RT3( FSb[ ( *SK >> 24 ) & 0xFF ] );
Paul Bakker5121ce52009-01-03 21:22:43 +0000946 }
947 }
948
949 *RK++ = *SK++;
950 *RK++ = *SK++;
951 *RK++ = *SK++;
952 *RK++ = *SK++;
953
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200954exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200955 mbedtls_aes_free( &cty );
Paul Bakker2b222c82009-07-27 21:03:45 +0000956
Arto Kinnunen6ce49882019-12-03 13:56:06 +0200957 if( ret != 0 )
958 {
959 return( ret );
960 }
961 else if( ( i == 0 ) && ( j == 4 ) )
962 {
Andrzej Kurekfba59212020-08-07 21:02:25 -0400963#if defined(MBEDTLS_VALIDATE_AES_KEYS_INTEGRITY)
Andrzej Kurek9539f832020-08-10 15:58:13 -0400964 ctx->hash = mbedtls_hash( ctx->rk, keybits >> 3 );
Andrzej Kurekfba59212020-08-07 21:02:25 -0400965#endif
Arto Kinnunen6ce49882019-12-03 13:56:06 +0200966 return( ret );
967 }
968 else
969 {
970 return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
971 }
972
Arto Kinnunen14804442019-10-16 13:43:59 +0300973#endif /* MBEDTLS_AES_ONLY_ENCRYPT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000974}
Jaeden Amero9366feb2018-05-29 18:55:17 +0100975
976#if defined(MBEDTLS_CIPHER_MODE_XTS)
977static int mbedtls_aes_xts_decode_keys( const unsigned char *key,
978 unsigned int keybits,
979 const unsigned char **key1,
980 unsigned int *key1bits,
981 const unsigned char **key2,
982 unsigned int *key2bits )
983{
984 const unsigned int half_keybits = keybits / 2;
985 const unsigned int half_keybytes = half_keybits / 8;
986
987 switch( keybits )
988 {
989 case 256: break;
990 case 512: break;
991 default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH );
992 }
993
994 *key1bits = half_keybits;
995 *key2bits = half_keybits;
996 *key1 = &key[0];
997 *key2 = &key[half_keybytes];
998
999 return 0;
1000}
1001
1002int mbedtls_aes_xts_setkey_enc( mbedtls_aes_xts_context *ctx,
1003 const unsigned char *key,
1004 unsigned int keybits)
1005{
1006 int ret;
1007 const unsigned char *key1, *key2;
1008 unsigned int key1bits, key2bits;
1009
Manuel Pégourié-Gonnard68e3dff2018-12-12 12:48:04 +01001010 AES_VALIDATE_RET( ctx != NULL );
1011 AES_VALIDATE_RET( key != NULL );
1012
Jaeden Amero9366feb2018-05-29 18:55:17 +01001013 ret = mbedtls_aes_xts_decode_keys( key, keybits, &key1, &key1bits,
1014 &key2, &key2bits );
1015 if( ret != 0 )
1016 return( ret );
1017
1018 /* Set the tweak key. Always set tweak key for the encryption mode. */
1019 ret = mbedtls_aes_setkey_enc( &ctx->tweak, key2, key2bits );
1020 if( ret != 0 )
1021 return( ret );
1022
1023 /* Set crypt key for encryption. */
1024 return mbedtls_aes_setkey_enc( &ctx->crypt, key1, key1bits );
1025}
1026
1027int mbedtls_aes_xts_setkey_dec( mbedtls_aes_xts_context *ctx,
1028 const unsigned char *key,
1029 unsigned int keybits)
1030{
1031 int ret;
1032 const unsigned char *key1, *key2;
1033 unsigned int key1bits, key2bits;
1034
Manuel Pégourié-Gonnard68e3dff2018-12-12 12:48:04 +01001035 AES_VALIDATE_RET( ctx != NULL );
1036 AES_VALIDATE_RET( key != NULL );
1037
Jaeden Amero9366feb2018-05-29 18:55:17 +01001038 ret = mbedtls_aes_xts_decode_keys( key, keybits, &key1, &key1bits,
1039 &key2, &key2bits );
1040 if( ret != 0 )
1041 return( ret );
1042
1043 /* Set the tweak key. Always set tweak key for encryption. */
1044 ret = mbedtls_aes_setkey_enc( &ctx->tweak, key2, key2bits );
1045 if( ret != 0 )
1046 return( ret );
1047
1048 /* Set crypt key for decryption. */
1049 return mbedtls_aes_setkey_dec( &ctx->crypt, key1, key1bits );
1050}
1051#endif /* MBEDTLS_CIPHER_MODE_XTS */
1052
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001053#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001054
Paul Bakker5121ce52009-01-03 21:22:43 +00001055/*
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001056 * AES-ECB block encryption
1057 */
1058#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Arto Kinnunenc3532c22019-11-29 15:07:11 +02001059
Arto Kinnunen311ab592020-01-16 17:20:51 +02001060#if defined(MBEDTLS_AES_SCA_COUNTERMEASURES)
Shelly Libermancdebcfe2020-11-17 11:33:25 +02001061
1062#if defined(MBEDTLS_AES_128_BIT_MASKED)
1063
1064static uint8_t xtime(uint8_t x)
1065{
1066 return ((x << 1) ^ (((x >> 7) & 1) * 0x1b));
1067}
1068
1069static int sub_bytes_masked(uint32_t *data, uint8_t sbox_masked[256])
1070{
1071 volatile unsigned int i;
1072
1073 for (i = 0; i < 4; i++) {
1074 data[i] = ( (uint32_t) sbox_masked[ ( data[i] ) & 0xFF ] ) ^
1075 ( (uint32_t) sbox_masked[ ( data[i] >> 8 ) & 0xFF ] << 8 ) ^
1076 ( (uint32_t) sbox_masked[ ( data[i] >> 16 ) & 0xFF ] << 16 ) ^
1077 ( (uint32_t) sbox_masked[ ( data[i] >> 24 ) & 0xFF ] << 24 );
1078 }
1079
1080 if (i == 4){
1081 return 0;
1082 }
1083
1084 return MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
1085}
1086
1087static int mix_columns(uint8_t *s)
1088{
1089 masked_state_t *state = (masked_state_t *) s;
1090 volatile unsigned int i = 0;
1091 uint8_t Tmp, Tm, t;
1092
1093 for (i = 0; i < 4; ++i)
1094 {
1095 t = (*state)[i][0];
1096 Tmp = (*state)[i][0] ^ (*state)[i][1] ^ (*state)[i][2] ^ (*state)[i][3];
1097 Tm = (*state)[i][0] ^ (*state)[i][1];
1098 Tm = xtime(Tm);
1099 (*state)[i][0] ^= Tm ^ Tmp;
1100 Tm = (*state)[i][1] ^ (*state)[i][2];
1101 Tm = xtime(Tm);
1102 (*state)[i][1] ^= Tm ^ Tmp;
1103 Tm = (*state)[i][2] ^ (*state)[i][3];
1104 Tm = xtime(Tm);
1105 (*state)[i][2] ^= Tm ^ Tmp;
1106 Tm = (*state)[i][3] ^ t;
1107 Tm = xtime(Tm);
1108 (*state)[i][3] ^= Tm ^ Tmp;
1109 }
1110
1111 if (i == 4) {
1112 return 0;
1113 }
1114
1115 return MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
1116}
1117
1118static void shift_rows(uint8_t *s)
1119{
1120 uint8_t temp;
1121 masked_state_t *state = (masked_state_t *) s;
1122 // Rotate first row 1 columns to left
1123 temp = (*state)[0][1];
1124 (*state)[0][1] = (*state)[1][1];
1125 (*state)[1][1] = (*state)[2][1];
1126 (*state)[2][1] = (*state)[3][1];
1127 (*state)[3][1] = temp;
1128
1129 // Rotate second row 2 columns to left
1130 temp = (*state)[0][2];
1131 (*state)[0][2] = (*state)[2][2];
1132 (*state)[2][2] = temp;
1133
1134 temp = (*state)[1][2];
1135 (*state)[1][2] = (*state)[3][2];
1136 (*state)[3][2] = temp;
1137
1138 // Rotate third row 3 columns to left
1139 temp = (*state)[0][3];
1140 (*state)[0][3] = (*state)[3][3];
1141 (*state)[3][3] = (*state)[2][3];
1142 (*state)[2][3] = (*state)[1][3];
1143 (*state)[1][3] = temp;
1144
1145}
1146
1147#define mul_02(num) ( (num << 1) ^ (0x11b & -(num >> 7)) )
1148#define mul_03(num) ( mul_02(num) ^ num )
1149
1150static void calcMixColmask(uint32_t mask[10])
1151{
1152 mask[6] = mul_02(mask[0]) ^ mul_03(mask[1]) ^ mask[2] ^ mask[3];
1153 mask[7] = mask[0] ^ mul_02(mask[1]) ^ mul_03(mask[2]) ^ mask[3];
1154 mask[8] = mask[0] ^ mask[1] ^ mul_02(mask[2]) ^ mul_03(mask[3]);
1155 mask[9] = mul_03(mask[0]) ^ mask[1] ^ mask[2] ^ mul_02(mask[3]);
1156}
1157
1158//Calculate the the invSbox to change from Mask m to Mask m'
1159static int calcSboxMasked(uint32_t mask[10], uint8_t sbox_masked[256])
1160{
1161 volatile unsigned int i = 0;
1162
1163 for ( i = 0; i < 256; i++ )
1164 {
1165 sbox_masked[i ^ mask[4]] = FSb[i] ^ mask[5];
1166 }
1167 if (i == 256) {
1168 return 0;
1169 }
1170
1171 return MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
1172}
1173
1174static int remask(uint32_t *data, uint32_t m1, uint32_t m2, uint32_t m3, uint32_t m4, uint32_t m5, uint32_t m6, uint32_t m7, uint32_t m8)
1175{
1176
1177 volatile unsigned int i = 0;
1178
1179 for ( i = 0; i < 4; i++)
1180 {
1181 data[i] = data[i] ^ ( (m1^m5) );
1182 data[i] = data[i] ^ ( (m2^m6) << 8 );
1183 data[i] = data[i] ^ ( (m3^m7) << 16 );
1184 data[i] = data[i] ^ ( (m4^m8) << 24 );
1185 }
1186
1187 if (i == 4) {
1188 return 0;
1189 }
1190
1191 return MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
1192}
1193
1194
1195static int init_masking_encrypt(const uint8_t *rk, uint8_t *rk_masked, uint32_t mask[10], uint8_t sbox_masked[256] )
1196{
1197 volatile int flow_control = 0;
1198 unsigned int i = 0;
1199
1200 mbedtls_platform_memcpy(rk_masked, rk, AES_128_EXPANDED_KEY_SIZE_IN_WORDS*4);
1201
1202
1203 //Randomly generate the masks: m1 m2 m3 m4 m m'
1204 for (i = 0; i < 6; i++)
1205 {
1206 mask[i] = mbedtls_platform_random_in_range( 0xFF );
1207 flow_control++;
1208 }
1209
1210 //Calculate m1',m2',m3',m4'
1211 calcMixColmask(mask);
1212 flow_control++;
1213
1214 //Calculate the masked Sbox
1215 if (calcSboxMasked(mask, sbox_masked) == 0){
1216 flow_control++;
1217 }
1218
1219#define MASK_INIT_CONTROL 19
1220 //Init masked key
1221 if (remask( (uint32_t *)&rk_masked[(Nr * Nb * 4)], 0, 0, 0, 0, mask[5], mask[5], mask[5], mask[5]) == 0) {
1222 flow_control++;
1223 }
1224
1225
1226 // Mask change from M1',M2',M3',M4' to M
1227 for (i = 0; i < Nr; i++)
1228 {
1229 if ( remask( (uint32_t *)&rk_masked[( i * Nb * 4 )], mask[6], mask[7], mask[8], mask[9], mask[4], mask[4], mask[4], mask[4]) == 0 )
1230 flow_control++;
1231 }
1232
1233 if( flow_control == MASK_INIT_CONTROL ) {
1234 mbedtls_platform_random_delay();
1235 if( flow_control == MASK_INIT_CONTROL ) {
1236 return MASK_INIT_CONTROL;
1237 }
1238 }
1239
1240 return MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
1241}
1242
1243static int add_rk_masked(uint32_t round, uint32_t *data, const uint32_t * rk_masked)
1244{
1245 volatile unsigned int i;
1246 unsigned int offset = round*4;
1247 for( i = 0; i < 4; i++ )
1248 {
1249 data[i] ^= rk_masked[offset + i] ;
1250 }
1251
1252 if (i == 4) {
1253 return 0;
1254 }
1255 return MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
1256}
1257
1258
1259static int aes_masked_round(uint32_t *data, uint32_t *key, uint32_t round, uint32_t mask[10], uint8_t sbox_masked[256])
1260{
1261 volatile uint32_t flow_control = 0;
1262
1263// Mask changes from M to M'
1264 if ( sub_bytes_masked(data, sbox_masked) == 0 )
1265 flow_control++;
1266
1267 //No impact on mask
1268 shift_rows((uint8_t *)data);
1269
1270 //Change mask from M' to
1271 // M1 for first row
1272 // M2 for second row
1273 // M3 for third row
1274 // M4 for fourth row
1275 if ( remask(data, mask[0], mask[1], mask[2], mask[3], mask[5], mask[5], mask[5], mask[5]) == 0)
1276 flow_control++;
1277
1278 // Masks change from M1,M2,M3,M4 to M1',M2',M3',M4'
1279 if ( mix_columns((uint8_t *)data) == 0)
1280 flow_control++;
1281
1282 // Add the First round key to the state before starting the rounds.
1283 // Masks change from M1',M2',M3',M4' to M
1284 if ( add_rk_masked(round,data, key) == 0 )
1285 flow_control++;
1286
1287 if ( flow_control == 4 )
1288 return 0;
1289
1290 return MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
1291}
1292
1293static int aes_masked_round_final( uint32_t *data, uint32_t *key, uint8_t sbox_masked[256] )
1294{
1295 volatile uint32_t flow_control = 0;
1296
1297 if ( sub_bytes_masked(data, sbox_masked) == 0 )
1298 flow_control++;
1299
1300 shift_rows((uint8_t *)data);
1301
1302 // Mask are removed by the last addroundkey
1303 // From M' to 0
1304 if( add_rk_masked(Nr, data, key) == 0)
1305 flow_control++;
1306
1307 if ( flow_control == 2 )
1308 return 0;
1309
1310 return MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
1311}
1312#define MASKING_FLOW_CONTORL (MASK_INIT_CONTROL + 2) //2 comes from initial data remask of real and fake data
1313
1314#else // end of MBEDTLS_AES_128_BIT_MASKED
1315
1316#define MASKING_FLOW_CONTORL 0
1317
Arto Kinnunenc3532c22019-11-29 15:07:11 +02001318static uint32_t *aes_fround( uint32_t *R,
1319 uint32_t *X0, uint32_t *X1, uint32_t *X2, uint32_t *X3,
1320 uint32_t Y0, uint32_t Y1, uint32_t Y2, uint32_t Y3 )
1321{
1322 *X0 = *R++ ^ AES_FT0( ( Y0 ) & 0xFF ) ^
1323 AES_FT1( ( Y1 >> 8 ) & 0xFF ) ^
1324 AES_FT2( ( Y2 >> 16 ) & 0xFF ) ^
1325 AES_FT3( ( Y3 >> 24 ) & 0xFF );
1326
1327 *X1 = *R++ ^ AES_FT0( ( Y1 ) & 0xFF ) ^
1328 AES_FT1( ( Y2 >> 8 ) & 0xFF ) ^
1329 AES_FT2( ( Y3 >> 16 ) & 0xFF ) ^
1330 AES_FT3( ( Y0 >> 24 ) & 0xFF );
1331
1332 *X2 = *R++ ^ AES_FT0( ( Y2 ) & 0xFF ) ^
1333 AES_FT1( ( Y3 >> 8 ) & 0xFF ) ^
1334 AES_FT2( ( Y0 >> 16 ) & 0xFF ) ^
1335 AES_FT3( ( Y1 >> 24 ) & 0xFF );
1336
1337 *X3 = *R++ ^ AES_FT0( ( Y3 ) & 0xFF ) ^
1338 AES_FT1( ( Y0 >> 8 ) & 0xFF ) ^
1339 AES_FT2( ( Y1 >> 16 ) & 0xFF ) ^
1340 AES_FT3( ( Y2 >> 24 ) & 0xFF );
1341
1342 return R;
1343}
1344
Shelly Libermancdebcfe2020-11-17 11:33:25 +02001345
Arto Kinnunenc3532c22019-11-29 15:07:11 +02001346static void aes_fround_final( uint32_t *R,
1347 uint32_t *X0, uint32_t *X1, uint32_t *X2, uint32_t *X3,
1348 uint32_t Y0, uint32_t Y1, uint32_t Y2, uint32_t Y3 )
1349{
Shelly Libermancdebcfe2020-11-17 11:33:25 +02001350
Arto Kinnunenc3532c22019-11-29 15:07:11 +02001351 *X0 = *R++ ^ ( (uint32_t) FSb[ ( (Y0) ) & 0xFF ] ) ^
1352 ( (uint32_t) FSb[ ( (Y1) >> 8 ) & 0xFF ] << 8 ) ^
1353 ( (uint32_t) FSb[ ( (Y2) >> 16 ) & 0xFF ] << 16 ) ^
1354 ( (uint32_t) FSb[ ( (Y3) >> 24 ) & 0xFF ] << 24 );
1355
1356 *X1 = *R++ ^ ( (uint32_t) FSb[ ( (Y1) ) & 0xFF ] ) ^
1357 ( (uint32_t) FSb[ ( (Y2) >> 8 ) & 0xFF ] << 8 ) ^
1358 ( (uint32_t) FSb[ ( (Y3) >> 16 ) & 0xFF ] << 16 ) ^
1359 ( (uint32_t) FSb[ ( (Y0) >> 24 ) & 0xFF ] << 24 );
1360
1361 *X2 = *R++ ^ ( (uint32_t) FSb[ ( (Y2) ) & 0xFF ] ) ^
1362 ( (uint32_t) FSb[ ( (Y3) >> 8 ) & 0xFF ] << 8 ) ^
1363 ( (uint32_t) FSb[ ( (Y0) >> 16 ) & 0xFF ] << 16 ) ^
1364 ( (uint32_t) FSb[ ( (Y1) >> 24 ) & 0xFF ] << 24 );
1365
1366 *X3 = *R++ ^ ( (uint32_t) FSb[ ( (Y3) ) & 0xFF ] ) ^
1367 ( (uint32_t) FSb[ ( (Y0) >> 8 ) & 0xFF ] << 8 ) ^
1368 ( (uint32_t) FSb[ ( (Y1) >> 16 ) & 0xFF ] << 16 ) ^
1369 ( (uint32_t) FSb[ ( (Y2) >> 24 ) & 0xFF ] << 24 );
1370}
Shelly Libermancdebcfe2020-11-17 11:33:25 +02001371#endif // MBEDTLS_AES_128_BIT_MASKED
Arto Kinnunenc3532c22019-11-29 15:07:11 +02001372
Shelly Libermancdebcfe2020-11-17 11:33:25 +02001373
Andres AGf5bf7182017-03-03 14:09:56 +00001374int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx,
1375 const unsigned char input[16],
1376 unsigned char output[16] )
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001377{
Arto Kinnunen98c93af2020-01-14 13:31:03 +02001378 int i, tindex, offset, stop_mark, dummy_rounds;
Shelly Libermancdebcfe2020-11-17 11:33:25 +02001379 aes_r_data_t aes_data_real = {0}; // real data
1380 aes_r_data_t aes_data_fake = {0}; // fake data
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001381 aes_r_data_t *aes_data_ptr; // pointer to real or fake data
Shelly Libermancdebcfe2020-11-17 11:33:25 +02001382 aes_r_data_t *aes_data_table[2] = {0}; // pointers to real and fake data
Arto Kinnunen311ab592020-01-16 17:20:51 +02001383 int round_ctrl_table_len = ctx->nr + 2 + AES_SCA_CM_ROUNDS;
Shelly Libermancdebcfe2020-11-17 11:33:25 +02001384 volatile int flow_control = 0;
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001385 // control bytes for AES calculation rounds,
1386 // reserve based on max rounds + dummy rounds + 2 (for initial key addition)
1387 uint8_t round_ctrl_table[( 14 + AES_SCA_CM_ROUNDS + 2 )];
Arto Kinnunenf93d55e2019-10-11 11:15:57 +03001388
Shelly Libermancdebcfe2020-11-17 11:33:25 +02001389#if defined MBEDTLS_AES_128_BIT_MASKED
1390 uint32_t rk_masked[AES_128_EXPANDED_KEY_SIZE_IN_WORDS] = {0};
1391 static uint8_t sbox_masked[256] = {0};
1392 uint32_t mask[10] = {0};
1393#endif
1394
Andrzej Kurekfba59212020-08-07 21:02:25 -04001395#if defined(MBEDTLS_VALIDATE_AES_KEYS_INTEGRITY)
1396 unsigned key_bytes = 0;
Andrzej Kurek9539f832020-08-10 15:58:13 -04001397 uint32_t check_hash = 0;
Andrzej Kurekfba59212020-08-07 21:02:25 -04001398 switch( ctx->nr )
1399 {
1400 case 10: key_bytes = 16; break;
1401#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
1402 case 12: key_bytes = 24; break;
1403 case 14: key_bytes = 32; break;
1404#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
1405 default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH );
1406 }
Andrzej Kurek9539f832020-08-10 15:58:13 -04001407 check_hash = mbedtls_hash( ctx->rk, key_bytes );
Andrzej Kurekfba59212020-08-07 21:02:25 -04001408#endif
1409
Shelly Libermancdebcfe2020-11-17 11:33:25 +02001410#if defined (MBEDTLS_AES_128_BIT_MASKED)
1411 //Flow control should be MASK_INIT_CONTROL and it will be checked as a part last flow control verification
1412 flow_control = init_masking_encrypt((uint8_t*)ctx->rk, (uint8_t*)rk_masked, mask, sbox_masked);
1413 aes_data_real.rk_ptr = &rk_masked[0];
1414#else
1415 aes_data_real.rk_ptr = ctx->rk;
1416#endif
1417
Andrzej Kureke78775e2020-07-02 10:57:00 -04001418 aes_data_fake.rk_ptr = ctx->frk;
Andrzej Kurekfac2f9b2020-07-19 00:32:34 -04001419
Arto Kinnunen311ab592020-01-16 17:20:51 +02001420 aes_data_table[0] = &aes_data_real;
1421 aes_data_table[1] = &aes_data_fake;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001422
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001423 // Get AES calculation control bytes
Arto Kinnunen2b24f422020-01-16 15:04:11 +02001424 dummy_rounds = aes_sca_cm_data_randomize( round_ctrl_table,
1425 round_ctrl_table_len );
Shelly Libermancdebcfe2020-11-17 11:33:25 +02001426 flow_control += dummy_rounds;
Arto Kinnunen172836a2019-11-28 13:34:13 +02001427
Arto Kinnunen17540ab2020-01-20 11:46:34 +02001428 // SCA countermeasure, safely clear the aes_data_real.xy_values
Jarno Lamsa282db8e2020-01-08 14:53:17 +02001429 mbedtls_platform_memset( aes_data_real.xy_values, 0, 16 );
Jarno Lamsa282db8e2020-01-08 14:53:17 +02001430
Arto Kinnunen17540ab2020-01-20 11:46:34 +02001431 // SCA countermeasure, randomize secret data location by initializing it in
1432 // a random order and writing randomized fake data between the real data
1433 // writes.
1434 offset = mbedtls_platform_random_in_range( 4 );
Arto Kinnunen2b24f422020-01-16 15:04:11 +02001435 i = offset;
1436 do
Arto Kinnunen172836a2019-11-28 13:34:13 +02001437 {
1438 GET_UINT32_LE( aes_data_real.xy_values[i], input, ( i * 4 ) );
Andrzej Kurek11ddf252020-06-24 17:33:39 -04001439 aes_data_fake.xy_values[i] = mbedtls_platform_random_uint32();
Arto Kinnunen2b24f422020-01-16 15:04:11 +02001440 flow_control++;
1441 } while( ( i = ( i + 1 ) % 4 ) != offset );
Jarno Lamsa282db8e2020-01-08 14:53:17 +02001442
Shelly Libermancdebcfe2020-11-17 11:33:25 +02001443#if defined (MBEDTLS_AES_128_BIT_MASKED)
1444 //Plain text masked with m1',m2',m3',m4'
1445 if (remask( &aes_data_real.xy_values[0], mask[6], mask[7], mask[8], mask[9], 0, 0, 0, 0) == 0)
1446 flow_control++;
1447
1448 if (remask( &aes_data_fake.xy_values[0], mask[6], mask[7], mask[8], mask[9], 0, 0, 0, 0) == 0)
1449 flow_control++;
1450
1451#endif
1452
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001453 tindex = 0;
1454 do
Jarno Lamsa282db8e2020-01-08 14:53:17 +02001455 {
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001456 // Get pointer to the real or fake data
1457 aes_data_ptr = aes_data_table[round_ctrl_table[tindex] >> 4];
1458 stop_mark = round_ctrl_table[tindex] & 0x03;
Shelly Libermancdebcfe2020-11-17 11:33:25 +02001459
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001460 // initial round key addition
Shelly Libermancdebcfe2020-11-17 11:33:25 +02001461#if defined (MBEDTLS_AES_128_BIT_MASKED)
1462 if ( add_rk_masked(0, &aes_data_ptr->xy_values[0], aes_data_ptr->rk_ptr) == 0)
1463 flow_control++;
1464 aes_data_ptr->round = 1;
1465#else
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001466 for( i = 0; i < 4; i++ )
1467 {
1468 aes_data_ptr->xy_values[i] ^= *aes_data_ptr->rk_ptr++;
1469 }
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001470 flow_control++;
Shelly Libermancdebcfe2020-11-17 11:33:25 +02001471#endif
1472
1473 tindex++;
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001474 } while( stop_mark == 0 );
Shelly Libermancdebcfe2020-11-17 11:33:25 +02001475
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001476
1477 // Calculate AES rounds (9, 11 or 13 rounds) + dummy rounds
1478 do
Arto Kinnunen172836a2019-11-28 13:34:13 +02001479 {
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001480 // Get pointer to the real or fake data
1481 aes_data_ptr = aes_data_table[round_ctrl_table[tindex] >> 4];
1482 offset = round_ctrl_table[tindex] & 0x04;
1483 stop_mark = round_ctrl_table[tindex] & 0x03;
Shelly Libermancdebcfe2020-11-17 11:33:25 +02001484#if defined (MBEDTLS_AES_128_BIT_MASKED)
1485 if (aes_masked_round( &aes_data_ptr->xy_values[0], aes_data_ptr->rk_ptr,
1486 aes_data_ptr->round, mask, sbox_masked) == 0)
1487 flow_control++;
1488 aes_data_ptr->round ++;
1489#else
Arto Kinnunenc3532c22019-11-29 15:07:11 +02001490 aes_data_ptr->rk_ptr = aes_fround( aes_data_ptr->rk_ptr,
1491 &aes_data_ptr->xy_values[0 + offset],
1492 &aes_data_ptr->xy_values[1 + offset],
1493 &aes_data_ptr->xy_values[2 + offset],
1494 &aes_data_ptr->xy_values[3 + offset],
Arto Kinnunen172836a2019-11-28 13:34:13 +02001495 aes_data_ptr->xy_values[4 - offset],
1496 aes_data_ptr->xy_values[5 - offset],
1497 aes_data_ptr->xy_values[6 - offset],
1498 aes_data_ptr->xy_values[7 - offset] );
Arto Kinnunen6ce49882019-12-03 13:56:06 +02001499 flow_control++;
Shelly Libermancdebcfe2020-11-17 11:33:25 +02001500#endif
1501 tindex++;
1502
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001503 } while( stop_mark == 0 );
Arto Kinnunen172836a2019-11-28 13:34:13 +02001504
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001505 // Calculate final AES round + dummy rounds
1506 do
Arto Kinnunen172836a2019-11-28 13:34:13 +02001507 {
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001508 aes_data_ptr = aes_data_table[round_ctrl_table[tindex] >> 4];
1509 stop_mark = round_ctrl_table[tindex] & 0x03;
Shelly Libermancdebcfe2020-11-17 11:33:25 +02001510#if defined (MBEDTLS_AES_128_BIT_MASKED)
1511 if ( aes_masked_round_final( &aes_data_ptr->xy_values[0],
1512 aes_data_ptr->rk_ptr, sbox_masked ) == 0)
1513 flow_control++;
1514 //Cleanup the masked key
1515 mbedtls_platform_memset(rk_masked, 0, sizeof(rk_masked));
1516#else
Arto Kinnunenc3532c22019-11-29 15:07:11 +02001517 aes_fround_final( aes_data_ptr->rk_ptr,
1518 &aes_data_ptr->xy_values[0],
1519 &aes_data_ptr->xy_values[1],
1520 &aes_data_ptr->xy_values[2],
1521 &aes_data_ptr->xy_values[3],
Arto Kinnunen172836a2019-11-28 13:34:13 +02001522 aes_data_ptr->xy_values[4],
1523 aes_data_ptr->xy_values[5],
1524 aes_data_ptr->xy_values[6],
1525 aes_data_ptr->xy_values[7] );
Arto Kinnunen6ce49882019-12-03 13:56:06 +02001526 flow_control++;
Shelly Libermancdebcfe2020-11-17 11:33:25 +02001527#endif
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001528 tindex++;
1529 } while( stop_mark == 0 );
Arto Kinnunen172836a2019-11-28 13:34:13 +02001530
Shelly Libermancdebcfe2020-11-17 11:33:25 +02001531
Arto Kinnunen17540ab2020-01-20 11:46:34 +02001532 // SCA countermeasure, safely clear the output
Jarno Lamsa282db8e2020-01-08 14:53:17 +02001533 mbedtls_platform_memset( output, 0, 16 );
Jarno Lamsa282db8e2020-01-08 14:53:17 +02001534
Arto Kinnunen17540ab2020-01-20 11:46:34 +02001535 // SCA countermeasure, randomize secret data location by writing to it in
1536 // a random order.
1537 offset = mbedtls_platform_random_in_range( 4 );
Arto Kinnunen2b24f422020-01-16 15:04:11 +02001538 i = offset;
1539 do
Jarno Lamsa282db8e2020-01-08 14:53:17 +02001540 {
1541 PUT_UINT32_LE( aes_data_real.xy_values[i], output, ( i * 4 ) );
1542 flow_control++;
Arto Kinnunen2b24f422020-01-16 15:04:11 +02001543 } while( ( i = ( i + 1 ) % 4 ) != offset );
Jarno Lamsa282db8e2020-01-08 14:53:17 +02001544
Shelly Libermancdebcfe2020-11-17 11:33:25 +02001545#if defined (MBEDTLS_AES_128_BIT_MASKED)
1546 mbedtls_platform_memset(rk_masked, 0, sizeof(rk_masked));
1547#endif
Andrzej Kurekfba59212020-08-07 21:02:25 -04001548 /* Double negation is used to silence an "extraneous parentheses" warning */
Shelly Libermancdebcfe2020-11-17 11:33:25 +02001549 if( ! ( flow_control != tindex + dummy_rounds + MASKING_FLOW_CONTORL + 8 )
Andrzej Kurekfba59212020-08-07 21:02:25 -04001550#if defined(MBEDTLS_VALIDATE_AES_KEYS_INTEGRITY)
Andrzej Kurek9539f832020-08-10 15:58:13 -04001551 && check_hash == ctx->hash
Andrzej Kurekfba59212020-08-07 21:02:25 -04001552#endif
1553 )
Arto Kinnunen6ce49882019-12-03 13:56:06 +02001554 {
Andrzej Kurekfba59212020-08-07 21:02:25 -04001555#if defined(MBEDTLS_VALIDATE_AES_KEYS_INTEGRITY)
1556 mbedtls_platform_random_delay();
Andrzej Kurek9539f832020-08-10 15:58:13 -04001557 if( mbedtls_hash( ctx->rk, key_bytes ) == ctx->hash )
Andrzej Kurekfba59212020-08-07 21:02:25 -04001558#endif
1559 {
1560 return 0;
1561 }
Arto Kinnunen6ce49882019-12-03 13:56:06 +02001562 }
Shelly Libermancdebcfe2020-11-17 11:33:25 +02001563
Andrzej Kurekca609372020-07-08 03:19:02 -04001564 // Clear the output in case of a FI
1565 mbedtls_platform_memset( output, 0, 16 );
Shelly Libermancdebcfe2020-11-17 11:33:25 +02001566 mbedtls_platform_memset( aes_data_real.xy_values, 0, 16 );
1567 mbedtls_platform_memset (aes_data_table, 0, sizeof(aes_data_table));
1568#if defined (MBEDTLS_AES_128_BIT_MASKED)
1569 //Clear masked key, masked sbox and mask in case of a FI
1570 mbedtls_platform_memset(rk_masked, 0, sizeof(rk_masked));
1571 mbedtls_platform_memset(mask, 0, sizeof(mask));
1572 mbedtls_platform_memset(sbox_masked, 0, sizeof(sbox_masked));
1573#endif
Arto Kinnunen6ce49882019-12-03 13:56:06 +02001574 return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001575}
Arto Kinnunen311ab592020-01-16 17:20:51 +02001576
1577#else /* MBEDTLS_AES_SCA_COUNTERMEASURES */
1578
1579#define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \
1580 do \
1581 { \
1582 (X0) = *RK++ ^ AES_FT0( ( (Y0) ) & 0xFF ) ^ \
1583 AES_FT1( ( (Y1) >> 8 ) & 0xFF ) ^ \
1584 AES_FT2( ( (Y2) >> 16 ) & 0xFF ) ^ \
1585 AES_FT3( ( (Y3) >> 24 ) & 0xFF ); \
1586 \
1587 (X1) = *RK++ ^ AES_FT0( ( (Y1) ) & 0xFF ) ^ \
1588 AES_FT1( ( (Y2) >> 8 ) & 0xFF ) ^ \
1589 AES_FT2( ( (Y3) >> 16 ) & 0xFF ) ^ \
1590 AES_FT3( ( (Y0) >> 24 ) & 0xFF ); \
1591 \
1592 (X2) = *RK++ ^ AES_FT0( ( (Y2) ) & 0xFF ) ^ \
1593 AES_FT1( ( (Y3) >> 8 ) & 0xFF ) ^ \
1594 AES_FT2( ( (Y0) >> 16 ) & 0xFF ) ^ \
1595 AES_FT3( ( (Y1) >> 24 ) & 0xFF ); \
1596 \
1597 (X3) = *RK++ ^ AES_FT0( ( (Y3) ) & 0xFF ) ^ \
1598 AES_FT1( ( (Y0) >> 8 ) & 0xFF ) ^ \
1599 AES_FT2( ( (Y1) >> 16 ) & 0xFF ) ^ \
1600 AES_FT3( ( (Y2) >> 24 ) & 0xFF ); \
1601 } while( 0 )
1602
1603int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx,
1604 const unsigned char input[16],
1605 unsigned char output[16] )
1606{
1607 int i;
1608 uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3;
1609
1610 RK = ctx->rk;
1611
1612 GET_UINT32_LE( X0, input, 0 ); X0 ^= *RK++;
1613 GET_UINT32_LE( X1, input, 4 ); X1 ^= *RK++;
1614 GET_UINT32_LE( X2, input, 8 ); X2 ^= *RK++;
1615 GET_UINT32_LE( X3, input, 12 ); X3 ^= *RK++;
1616
1617 for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- )
1618 {
1619 AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
1620 AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 );
1621 }
1622
1623 AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
1624
1625 X0 = *RK++ ^ \
1626 ( (uint32_t) FSb[ ( Y0 ) & 0xFF ] ) ^
1627 ( (uint32_t) FSb[ ( Y1 >> 8 ) & 0xFF ] << 8 ) ^
1628 ( (uint32_t) FSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^
1629 ( (uint32_t) FSb[ ( Y3 >> 24 ) & 0xFF ] << 24 );
1630
1631 X1 = *RK++ ^ \
1632 ( (uint32_t) FSb[ ( Y1 ) & 0xFF ] ) ^
1633 ( (uint32_t) FSb[ ( Y2 >> 8 ) & 0xFF ] << 8 ) ^
1634 ( (uint32_t) FSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^
1635 ( (uint32_t) FSb[ ( Y0 >> 24 ) & 0xFF ] << 24 );
1636
1637 X2 = *RK++ ^ \
1638 ( (uint32_t) FSb[ ( Y2 ) & 0xFF ] ) ^
1639 ( (uint32_t) FSb[ ( Y3 >> 8 ) & 0xFF ] << 8 ) ^
1640 ( (uint32_t) FSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^
1641 ( (uint32_t) FSb[ ( Y1 >> 24 ) & 0xFF ] << 24 );
1642
1643 X3 = *RK++ ^ \
1644 ( (uint32_t) FSb[ ( Y3 ) & 0xFF ] ) ^
1645 ( (uint32_t) FSb[ ( Y0 >> 8 ) & 0xFF ] << 8 ) ^
1646 ( (uint32_t) FSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^
1647 ( (uint32_t) FSb[ ( Y2 >> 24 ) & 0xFF ] << 24 );
1648
1649 PUT_UINT32_LE( X0, output, 0 );
1650 PUT_UINT32_LE( X1, output, 4 );
1651 PUT_UINT32_LE( X2, output, 8 );
1652 PUT_UINT32_LE( X3, output, 12 );
1653
Andrzej Kureka8405442019-11-12 03:34:03 -05001654 mbedtls_platform_zeroize( &X0, sizeof( X0 ) );
1655 mbedtls_platform_zeroize( &X1, sizeof( X1 ) );
1656 mbedtls_platform_zeroize( &X2, sizeof( X2 ) );
1657 mbedtls_platform_zeroize( &X3, sizeof( X3 ) );
1658
1659 mbedtls_platform_zeroize( &Y0, sizeof( Y0 ) );
1660 mbedtls_platform_zeroize( &Y1, sizeof( Y1 ) );
1661 mbedtls_platform_zeroize( &Y2, sizeof( Y2 ) );
1662 mbedtls_platform_zeroize( &Y3, sizeof( Y3 ) );
1663
1664 mbedtls_platform_zeroize( &RK, sizeof( RK ) );
1665
Arto Kinnunen311ab592020-01-16 17:20:51 +02001666 return( 0 );
1667}
1668#endif /* MBEDTLS_AES_SCA_COUNTERMEASURES */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001669#endif /* !MBEDTLS_AES_ENCRYPT_ALT */
1670
Gilles Peskine8db3efb2018-02-21 19:16:20 +01001671#if !defined(MBEDTLS_DEPRECATED_REMOVED)
Hanno Beckerbedc2052017-06-26 12:46:56 +01001672void mbedtls_aes_encrypt( mbedtls_aes_context *ctx,
1673 const unsigned char input[16],
1674 unsigned char output[16] )
1675{
1676 mbedtls_internal_aes_encrypt( ctx, input, output );
1677}
Gilles Peskine8db3efb2018-02-21 19:16:20 +01001678#endif /* !MBEDTLS_DEPRECATED_REMOVED */
Hanno Beckerbedc2052017-06-26 12:46:56 +01001679
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001680/*
1681 * AES-ECB block decryption
1682 */
Arto Kinnunen14804442019-10-16 13:43:59 +03001683
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001684#if !defined(MBEDTLS_AES_DECRYPT_ALT)
Arto Kinnunen14804442019-10-16 13:43:59 +03001685#if !defined(MBEDTLS_AES_ONLY_ENCRYPT)
Arto Kinnunenc3532c22019-11-29 15:07:11 +02001686
Arto Kinnunen311ab592020-01-16 17:20:51 +02001687#if defined(MBEDTLS_AES_SCA_COUNTERMEASURES)
Shelly Libermancdebcfe2020-11-17 11:33:25 +02001688static uint32_t *aes_fround( uint32_t *R,
Arto Kinnunenc3532c22019-11-29 15:07:11 +02001689 uint32_t *X0, uint32_t *X1, uint32_t *X2, uint32_t *X3,
1690 uint32_t Y0, uint32_t Y1, uint32_t Y2, uint32_t Y3 )
1691{
1692 *X0 = *R++ ^ AES_RT0( ( Y0 ) & 0xFF ) ^
1693 AES_RT1( ( Y3 >> 8 ) & 0xFF ) ^
1694 AES_RT2( ( Y2 >> 16 ) & 0xFF ) ^
1695 AES_RT3( ( Y1 >> 24 ) & 0xFF );
1696
1697 *X1 = *R++ ^ AES_RT0( ( Y1 ) & 0xFF ) ^
1698 AES_RT1( ( Y0 >> 8 ) & 0xFF ) ^
1699 AES_RT2( ( Y3 >> 16 ) & 0xFF ) ^
1700 AES_RT3( ( Y2 >> 24 ) & 0xFF );
1701
1702 *X2 = *R++ ^ AES_RT0( ( Y2 ) & 0xFF ) ^
1703 AES_RT1( ( Y1 >> 8 ) & 0xFF ) ^
1704 AES_RT2( ( Y0 >> 16 ) & 0xFF ) ^
1705 AES_RT3( ( Y3 >> 24 ) & 0xFF );
1706
1707 *X3 = *R++ ^ AES_RT0( ( Y3 ) & 0xFF ) ^
1708 AES_RT1( ( Y2 >> 8 ) & 0xFF ) ^
1709 AES_RT2( ( Y1 >> 16 ) & 0xFF ) ^
1710 AES_RT3( ( Y0 >> 24 ) & 0xFF );
1711 return R;
1712}
1713
1714static void aes_rround_final( uint32_t *R,
1715 uint32_t *X0, uint32_t *X1, uint32_t *X2, uint32_t *X3,
1716 uint32_t Y0, uint32_t Y1, uint32_t Y2, uint32_t Y3 )
1717{
1718 *X0 = *R++ ^ ( (uint32_t) RSb[ ( (Y0) ) & 0xFF ] ) ^
1719 ( (uint32_t) RSb[ ( (Y3) >> 8 ) & 0xFF ] << 8 ) ^
1720 ( (uint32_t) RSb[ ( (Y2) >> 16 ) & 0xFF ] << 16 ) ^
1721 ( (uint32_t) RSb[ ( (Y1) >> 24 ) & 0xFF ] << 24 );
1722
1723 *X1 = *R++ ^ ( (uint32_t) RSb[ ( (Y1) ) & 0xFF ] ) ^
1724 ( (uint32_t) RSb[ ( (Y0) >> 8 ) & 0xFF ] << 8 ) ^
1725 ( (uint32_t) RSb[ ( (Y3) >> 16 ) & 0xFF ] << 16 ) ^
1726 ( (uint32_t) RSb[ ( (Y2) >> 24 ) & 0xFF ] << 24 );
1727
1728 *X2 = *R++ ^ ( (uint32_t) RSb[ ( (Y2) ) & 0xFF ] ) ^
1729 ( (uint32_t) RSb[ ( (Y1) >> 8 ) & 0xFF ] << 8 ) ^
1730 ( (uint32_t) RSb[ ( (Y0) >> 16 ) & 0xFF ] << 16 ) ^
1731 ( (uint32_t) RSb[ ( (Y3) >> 24 ) & 0xFF ] << 24 );
1732
1733 *X3 = *R++ ^ ( (uint32_t) RSb[ ( (Y3) ) & 0xFF ] ) ^
1734 ( (uint32_t) RSb[ ( (Y2) >> 8 ) & 0xFF ] << 8 ) ^
1735 ( (uint32_t) RSb[ ( (Y1) >> 16 ) & 0xFF ] << 16 ) ^
1736 ( (uint32_t) RSb[ ( (Y0) >> 24 ) & 0xFF ] << 24 );
1737}
1738
Andres AGf5bf7182017-03-03 14:09:56 +00001739int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx,
1740 const unsigned char input[16],
1741 unsigned char output[16] )
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001742{
Arto Kinnunen98c93af2020-01-14 13:31:03 +02001743 int i, tindex, offset, stop_mark, dummy_rounds;
Arto Kinnunen172836a2019-11-28 13:34:13 +02001744 aes_r_data_t aes_data_real; // real data
Arto Kinnunen172836a2019-11-28 13:34:13 +02001745 aes_r_data_t aes_data_fake; // fake data
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001746 aes_r_data_t *aes_data_ptr; // pointer to real or fake data
Arto Kinnunen172836a2019-11-28 13:34:13 +02001747 aes_r_data_t *aes_data_table[2]; // pointers to real and fake data
Arto Kinnunen311ab592020-01-16 17:20:51 +02001748 int round_ctrl_table_len = ctx->nr + 2 + AES_SCA_CM_ROUNDS;
Arto Kinnunen6ce49882019-12-03 13:56:06 +02001749 volatile int flow_control;
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001750 // control bytes for AES calculation rounds,
1751 // reserve based on max rounds + dummy rounds + 2 (for initial key addition)
1752 uint8_t round_ctrl_table[( 14 + AES_SCA_CM_ROUNDS + 2 )];
Arto Kinnunenf93d55e2019-10-11 11:15:57 +03001753
Andrzej Kurekfba59212020-08-07 21:02:25 -04001754#if defined(MBEDTLS_VALIDATE_AES_KEYS_INTEGRITY)
1755 unsigned key_bytes = 0;
Andrzej Kurek9539f832020-08-10 15:58:13 -04001756 uint32_t check_hash = 0;
Andrzej Kurekfba59212020-08-07 21:02:25 -04001757 switch( ctx->nr )
1758 {
1759 case 10: key_bytes = 16; break;
1760#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
1761 case 12: key_bytes = 24; break;
1762 case 14: key_bytes = 32; break;
1763#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
1764 default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH );
1765 }
Andrzej Kurek9539f832020-08-10 15:58:13 -04001766 check_hash = mbedtls_hash( ctx->rk, key_bytes );
Andrzej Kurekfba59212020-08-07 21:02:25 -04001767#endif
1768
Arto Kinnunen172836a2019-11-28 13:34:13 +02001769 aes_data_real.rk_ptr = ctx->rk;
Andrzej Kureke78775e2020-07-02 10:57:00 -04001770 aes_data_fake.rk_ptr = ctx->frk;
Andrzej Kurekfac2f9b2020-07-19 00:32:34 -04001771
Arto Kinnunen311ab592020-01-16 17:20:51 +02001772 aes_data_table[0] = &aes_data_real;
1773 aes_data_table[1] = &aes_data_fake;
Arto Kinnunenf93d55e2019-10-11 11:15:57 +03001774
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001775 // Get AES calculation control bytes
Arto Kinnunen98c93af2020-01-14 13:31:03 +02001776 dummy_rounds = aes_sca_cm_data_randomize( round_ctrl_table,
Arto Kinnunen2b24f422020-01-16 15:04:11 +02001777 round_ctrl_table_len );
Arto Kinnunen98c93af2020-01-14 13:31:03 +02001778 flow_control = dummy_rounds;
1779
Arto Kinnunen17540ab2020-01-20 11:46:34 +02001780 // SCA countermeasure, safely clear the aes_data_real.xy_values
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001781 mbedtls_platform_memset( aes_data_real.xy_values, 0, 16 );
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001782
Arto Kinnunen17540ab2020-01-20 11:46:34 +02001783 // SCA countermeasure, randomize secret data location by initializing it in
1784 // a random order and writing randomized fake data between the real data
1785 // writes.
1786 offset = mbedtls_platform_random_in_range( 4 );
Arto Kinnunen2b24f422020-01-16 15:04:11 +02001787 i = offset;
1788 do
Arto Kinnunenf93d55e2019-10-11 11:15:57 +03001789 {
Arto Kinnunen172836a2019-11-28 13:34:13 +02001790 GET_UINT32_LE( aes_data_real.xy_values[i], input, ( i * 4 ) );
Arto Kinnunen311ab592020-01-16 17:20:51 +02001791 aes_data_fake.xy_values[i] = mbedtls_platform_random_in_range( 0xffffffff );
Arto Kinnunen2b24f422020-01-16 15:04:11 +02001792 flow_control++;
1793 } while( ( i = ( i + 1 ) % 4 ) != offset );
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001794
1795 tindex = 0;
1796 do
1797 {
1798 // Get pointer to the real or fake data
1799 aes_data_ptr = aes_data_table[round_ctrl_table[tindex] >> 4];
1800 stop_mark = round_ctrl_table[tindex] & 0x03;
1801
1802 // initial round key addition
1803 for( i = 0; i < 4; i++ )
1804 {
1805 aes_data_ptr->xy_values[i] ^= *aes_data_ptr->rk_ptr++;
1806 }
1807 tindex++;
1808 flow_control++;
1809 } while( stop_mark == 0 );
1810
1811 // Calculate AES rounds (9, 11 or 13 rounds) + dummy rounds
1812 do
1813 {
1814 // Get pointer to the real or fake data
1815 aes_data_ptr = aes_data_table[round_ctrl_table[tindex] >> 4];
1816 offset = round_ctrl_table[tindex] & 0x04;
1817 stop_mark = round_ctrl_table[tindex] & 0x03;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001818
Arto Kinnunenc3532c22019-11-29 15:07:11 +02001819 aes_data_ptr->rk_ptr = aes_rround( aes_data_ptr->rk_ptr,
1820 &aes_data_ptr->xy_values[0 + offset],
1821 &aes_data_ptr->xy_values[1 + offset],
1822 &aes_data_ptr->xy_values[2 + offset],
1823 &aes_data_ptr->xy_values[3 + offset],
Arto Kinnunen172836a2019-11-28 13:34:13 +02001824 aes_data_ptr->xy_values[4 - offset],
1825 aes_data_ptr->xy_values[5 - offset],
1826 aes_data_ptr->xy_values[6 - offset],
1827 aes_data_ptr->xy_values[7 - offset] );
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001828 tindex++;
Arto Kinnunen6ce49882019-12-03 13:56:06 +02001829 flow_control++;
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001830 } while( stop_mark == 0 );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001831
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001832 // Calculate final AES round + dummy rounds
1833 do
Arto Kinnunen172836a2019-11-28 13:34:13 +02001834 {
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001835 aes_data_ptr = aes_data_table[round_ctrl_table[tindex] >> 4];
1836 stop_mark = round_ctrl_table[tindex] & 0x03;
Arto Kinnunenc3532c22019-11-29 15:07:11 +02001837 aes_rround_final( aes_data_ptr->rk_ptr,
1838 &aes_data_ptr->xy_values[0],
1839 &aes_data_ptr->xy_values[1],
1840 &aes_data_ptr->xy_values[2],
1841 &aes_data_ptr->xy_values[3],
Arto Kinnunen172836a2019-11-28 13:34:13 +02001842 aes_data_ptr->xy_values[4],
1843 aes_data_ptr->xy_values[5],
1844 aes_data_ptr->xy_values[6],
1845 aes_data_ptr->xy_values[7] );
Arto Kinnunen6ce49882019-12-03 13:56:06 +02001846 flow_control++;
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001847 tindex++;
1848 } while( stop_mark == 0 );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001849
Arto Kinnunen17540ab2020-01-20 11:46:34 +02001850 // SCA countermeasure, safely clear the output
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001851 mbedtls_platform_memset( output, 0, 16 );
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001852
Arto Kinnunen17540ab2020-01-20 11:46:34 +02001853 // SCA countermeasure, randomize secret data location by writing to it in
1854 // a random order.
1855 offset = mbedtls_platform_random_in_range( 4 );
Arto Kinnunen2b24f422020-01-16 15:04:11 +02001856 i = offset;
1857 do
Arto Kinnunen172836a2019-11-28 13:34:13 +02001858 {
1859 PUT_UINT32_LE( aes_data_real.xy_values[i], output, ( i * 4 ) );
Arto Kinnunen6ce49882019-12-03 13:56:06 +02001860 flow_control++;
Arto Kinnunen2b24f422020-01-16 15:04:11 +02001861 } while( ( i = ( i + 1 ) % 4 ) != offset );
Andres AGf5bf7182017-03-03 14:09:56 +00001862
Andrzej Kurekfba59212020-08-07 21:02:25 -04001863 /* Double negation is used to silence an "extraneous parentheses" warning */
1864 if( ! ( flow_control != tindex + dummy_rounds + 8 )
1865#if defined(MBEDTLS_VALIDATE_AES_KEYS_INTEGRITY)
Andrzej Kurek9539f832020-08-10 15:58:13 -04001866 && check_hash == ctx->hash
Andrzej Kurekfba59212020-08-07 21:02:25 -04001867#endif
1868 )
Arto Kinnunen6ce49882019-12-03 13:56:06 +02001869 {
Andrzej Kurekfba59212020-08-07 21:02:25 -04001870#if defined(MBEDTLS_VALIDATE_AES_KEYS_INTEGRITY)
1871 mbedtls_platform_random_delay();
Andrzej Kurek9539f832020-08-10 15:58:13 -04001872 if( mbedtls_hash( ctx->rk, key_bytes ) == ctx->hash )
Andrzej Kurekfba59212020-08-07 21:02:25 -04001873#endif
1874 {
1875 return 0;
1876 }
Arto Kinnunen6ce49882019-12-03 13:56:06 +02001877 }
1878
Andrzej Kurekca609372020-07-08 03:19:02 -04001879 // Clear the output in case of a FI
1880 mbedtls_platform_memset( output, 0, 16 );
Arto Kinnunen6ce49882019-12-03 13:56:06 +02001881 return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001882}
Arto Kinnunen311ab592020-01-16 17:20:51 +02001883
1884#else /* MBEDTLS_AES_SCA_COUNTERMEASURES */
1885
1886#define AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \
1887 do \
1888 { \
1889 (X0) = *RK++ ^ AES_RT0( ( (Y0) ) & 0xFF ) ^ \
1890 AES_RT1( ( (Y3) >> 8 ) & 0xFF ) ^ \
1891 AES_RT2( ( (Y2) >> 16 ) & 0xFF ) ^ \
1892 AES_RT3( ( (Y1) >> 24 ) & 0xFF ); \
1893 \
1894 (X1) = *RK++ ^ AES_RT0( ( (Y1) ) & 0xFF ) ^ \
1895 AES_RT1( ( (Y0) >> 8 ) & 0xFF ) ^ \
1896 AES_RT2( ( (Y3) >> 16 ) & 0xFF ) ^ \
1897 AES_RT3( ( (Y2) >> 24 ) & 0xFF ); \
1898 \
1899 (X2) = *RK++ ^ AES_RT0( ( (Y2) ) & 0xFF ) ^ \
1900 AES_RT1( ( (Y1) >> 8 ) & 0xFF ) ^ \
1901 AES_RT2( ( (Y0) >> 16 ) & 0xFF ) ^ \
1902 AES_RT3( ( (Y3) >> 24 ) & 0xFF ); \
1903 \
1904 (X3) = *RK++ ^ AES_RT0( ( (Y3) ) & 0xFF ) ^ \
1905 AES_RT1( ( (Y2) >> 8 ) & 0xFF ) ^ \
1906 AES_RT2( ( (Y1) >> 16 ) & 0xFF ) ^ \
1907 AES_RT3( ( (Y0) >> 24 ) & 0xFF ); \
1908 } while( 0 )
1909
1910int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx,
1911 const unsigned char input[16],
1912 unsigned char output[16] )
1913{
1914 int i;
1915 uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3;
1916
1917 RK = ctx->rk;
1918
1919 GET_UINT32_LE( X0, input, 0 ); X0 ^= *RK++;
1920 GET_UINT32_LE( X1, input, 4 ); X1 ^= *RK++;
1921 GET_UINT32_LE( X2, input, 8 ); X2 ^= *RK++;
1922 GET_UINT32_LE( X3, input, 12 ); X3 ^= *RK++;
1923
1924 for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- )
1925 {
1926 AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
1927 AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 );
1928 }
1929
1930 AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
1931
1932 X0 = *RK++ ^ \
1933 ( (uint32_t) RSb[ ( Y0 ) & 0xFF ] ) ^
1934 ( (uint32_t) RSb[ ( Y3 >> 8 ) & 0xFF ] << 8 ) ^
1935 ( (uint32_t) RSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^
1936 ( (uint32_t) RSb[ ( Y1 >> 24 ) & 0xFF ] << 24 );
1937
1938 X1 = *RK++ ^ \
1939 ( (uint32_t) RSb[ ( Y1 ) & 0xFF ] ) ^
1940 ( (uint32_t) RSb[ ( Y0 >> 8 ) & 0xFF ] << 8 ) ^
1941 ( (uint32_t) RSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^
1942 ( (uint32_t) RSb[ ( Y2 >> 24 ) & 0xFF ] << 24 );
1943
1944 X2 = *RK++ ^ \
1945 ( (uint32_t) RSb[ ( Y2 ) & 0xFF ] ) ^
1946 ( (uint32_t) RSb[ ( Y1 >> 8 ) & 0xFF ] << 8 ) ^
1947 ( (uint32_t) RSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^
1948 ( (uint32_t) RSb[ ( Y3 >> 24 ) & 0xFF ] << 24 );
1949
1950 X3 = *RK++ ^ \
1951 ( (uint32_t) RSb[ ( Y3 ) & 0xFF ] ) ^
1952 ( (uint32_t) RSb[ ( Y2 >> 8 ) & 0xFF ] << 8 ) ^
1953 ( (uint32_t) RSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^
1954 ( (uint32_t) RSb[ ( Y0 >> 24 ) & 0xFF ] << 24 );
1955
1956 PUT_UINT32_LE( X0, output, 0 );
1957 PUT_UINT32_LE( X1, output, 4 );
1958 PUT_UINT32_LE( X2, output, 8 );
1959 PUT_UINT32_LE( X3, output, 12 );
1960
Andrzej Kureka8405442019-11-12 03:34:03 -05001961 mbedtls_platform_zeroize( &X0, sizeof( X0 ) );
1962 mbedtls_platform_zeroize( &X1, sizeof( X1 ) );
1963 mbedtls_platform_zeroize( &X2, sizeof( X2 ) );
1964 mbedtls_platform_zeroize( &X3, sizeof( X3 ) );
1965
1966 mbedtls_platform_zeroize( &Y0, sizeof( Y0 ) );
1967 mbedtls_platform_zeroize( &Y1, sizeof( Y1 ) );
1968 mbedtls_platform_zeroize( &Y2, sizeof( Y2 ) );
1969 mbedtls_platform_zeroize( &Y3, sizeof( Y3 ) );
1970
1971 mbedtls_platform_zeroize( &RK, sizeof( RK ) );
1972
Arto Kinnunen311ab592020-01-16 17:20:51 +02001973 return( 0 );
1974}
Shelly Libermancdebcfe2020-11-17 11:33:25 +02001975#endif /* !MBEDTLS_AES_ONLY_ENCRYPT */
Arto Kinnunen311ab592020-01-16 17:20:51 +02001976#endif /* MBEDTLS_AES_SCA_COUNTERMEASURES */
1977
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001978#endif /* !MBEDTLS_AES_DECRYPT_ALT */
1979
Gilles Peskine8db3efb2018-02-21 19:16:20 +01001980#if !defined(MBEDTLS_DEPRECATED_REMOVED)
Hanno Beckerbedc2052017-06-26 12:46:56 +01001981void mbedtls_aes_decrypt( mbedtls_aes_context *ctx,
1982 const unsigned char input[16],
1983 unsigned char output[16] )
1984{
Arto Kinnunen14804442019-10-16 13:43:59 +03001985#if defined(MBEDTLS_AES_ONLY_ENCRYPT)
1986 (void) ctx;
1987 (void) input;
1988 (void) output;
1989#else /* MBEDTLS_AES_ONLY_ENCRYPT */
Hanno Beckerbedc2052017-06-26 12:46:56 +01001990 mbedtls_internal_aes_decrypt( ctx, input, output );
Arto Kinnunen14804442019-10-16 13:43:59 +03001991#endif /* MBEDTLS_AES_ONLY_ENCRYPT */
Hanno Beckerbedc2052017-06-26 12:46:56 +01001992}
Gilles Peskine8db3efb2018-02-21 19:16:20 +01001993#endif /* !MBEDTLS_DEPRECATED_REMOVED */
Hanno Beckerbedc2052017-06-26 12:46:56 +01001994
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001995/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001996 * AES-ECB block encryption/decryption
1997 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001998int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx,
Manuel Pégourié-Gonnardeb6d3962018-12-18 09:59:35 +01001999 int mode,
2000 const unsigned char input[16],
2001 unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +00002002{
Manuel Pégourié-Gonnard1aca2602018-12-12 12:56:55 +01002003 AES_VALIDATE_RET( ctx != NULL );
2004 AES_VALIDATE_RET( input != NULL );
2005 AES_VALIDATE_RET( output != NULL );
2006 AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
2007 mode == MBEDTLS_AES_DECRYPT );
Arto Kinnunen14804442019-10-16 13:43:59 +03002008 (void) mode;
Manuel Pégourié-Gonnard1aca2602018-12-12 12:56:55 +01002009
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002010#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +01002011 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002012 return( mbedtls_aesni_crypt_ecb( ctx, mode, input, output ) );
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +01002013#endif
2014
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002015#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Paul Bakker048d04e2012-02-12 17:31:04 +00002016 if( aes_padlock_ace )
Paul Bakker5121ce52009-01-03 21:22:43 +00002017 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002018 if( mbedtls_padlock_xcryptecb( ctx, mode, input, output ) == 0 )
Paul Bakkerf3ccc682010-03-18 21:21:02 +00002019 return( 0 );
2020
2021 // If padlock data misaligned, we just fall back to
2022 // unaccelerated mode
2023 //
Paul Bakker5121ce52009-01-03 21:22:43 +00002024 }
2025#endif
Arto Kinnunen6ce49882019-12-03 13:56:06 +02002026
Arto Kinnunen14804442019-10-16 13:43:59 +03002027#if defined(MBEDTLS_AES_ONLY_ENCRYPT)
2028 return( mbedtls_internal_aes_encrypt( ctx, input, output ) );
2029#else /* MBEDTLS_AES_ONLY_ENCRYPT */
Paul Bakker5121ce52009-01-03 21:22:43 +00002030
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02002031 if( mode == MBEDTLS_AES_ENCRYPT )
Andres AGf5bf7182017-03-03 14:09:56 +00002032 return( mbedtls_internal_aes_encrypt( ctx, input, output ) );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02002033 else
Andres AGf5bf7182017-03-03 14:09:56 +00002034 return( mbedtls_internal_aes_decrypt( ctx, input, output ) );
Arto Kinnunen14804442019-10-16 13:43:59 +03002035#endif /* MBEDTLS_AES_ONLY_ENCRYPT */
Paul Bakker5121ce52009-01-03 21:22:43 +00002036}
2037
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002038#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00002039/*
2040 * AES-CBC buffer encryption/decryption
2041 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002042int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx,
Paul Bakker5121ce52009-01-03 21:22:43 +00002043 int mode,
Paul Bakker23986e52011-04-24 08:57:21 +00002044 size_t length,
Paul Bakker5121ce52009-01-03 21:22:43 +00002045 unsigned char iv[16],
Paul Bakkerff60ee62010-03-16 21:09:09 +00002046 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +00002047 unsigned char *output )
2048{
2049 int i;
2050 unsigned char temp[16];
2051
Manuel Pégourié-Gonnard3178d1a2018-12-12 13:05:00 +01002052 AES_VALIDATE_RET( ctx != NULL );
2053 AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
2054 mode == MBEDTLS_AES_DECRYPT );
2055 AES_VALIDATE_RET( iv != NULL );
2056 AES_VALIDATE_RET( input != NULL );
2057 AES_VALIDATE_RET( output != NULL );
2058
Paul Bakkerf3ccc682010-03-18 21:21:02 +00002059 if( length % 16 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002060 return( MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH );
Paul Bakkerf3ccc682010-03-18 21:21:02 +00002061
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_xcryptcbc( ctx, mode, length, iv, input, output ) == 0 )
Paul Bakkerf3ccc682010-03-18 21:21:02 +00002066 return( 0 );
Paul Bakker9af723c2014-05-01 13:03:14 +02002067
Paul Bakkerf3ccc682010-03-18 21:21:02 +00002068 // If padlock data misaligned, we just fall back to
2069 // unaccelerated mode
2070 //
Paul Bakker5121ce52009-01-03 21:22:43 +00002071 }
2072#endif
2073
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002074 if( mode == MBEDTLS_AES_DECRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +00002075 {
2076 while( length > 0 )
2077 {
Teppo Järvelin91d79382019-10-02 09:09:31 +03002078 mbedtls_platform_memcpy( temp, input, 16 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002079 mbedtls_aes_crypt_ecb( ctx, mode, input, output );
Paul Bakker5121ce52009-01-03 21:22:43 +00002080
2081 for( i = 0; i < 16; i++ )
2082 output[i] = (unsigned char)( output[i] ^ iv[i] );
2083
Teppo Järvelin91d79382019-10-02 09:09:31 +03002084 mbedtls_platform_memcpy( iv, temp, 16 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002085
2086 input += 16;
2087 output += 16;
2088 length -= 16;
2089 }
2090 }
2091 else
2092 {
2093 while( length > 0 )
2094 {
2095 for( i = 0; i < 16; i++ )
2096 output[i] = (unsigned char)( input[i] ^ iv[i] );
2097
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002098 mbedtls_aes_crypt_ecb( ctx, mode, output, output );
Teppo Järvelin91d79382019-10-02 09:09:31 +03002099 mbedtls_platform_memcpy( iv, output, 16 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002100
2101 input += 16;
2102 output += 16;
2103 length -= 16;
2104 }
2105 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +00002106
2107 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002108}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002109#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00002110
Aorimn5f778012016-06-09 23:22:58 +02002111#if defined(MBEDTLS_CIPHER_MODE_XTS)
Jaeden Amero010c2cb2018-05-29 17:00:47 +01002112
2113/* Endianess with 64 bits values */
2114#ifndef GET_UINT64_LE
2115#define GET_UINT64_LE(n,b,i) \
2116{ \
2117 (n) = ( (uint64_t) (b)[(i) + 7] << 56 ) \
2118 | ( (uint64_t) (b)[(i) + 6] << 48 ) \
2119 | ( (uint64_t) (b)[(i) + 5] << 40 ) \
2120 | ( (uint64_t) (b)[(i) + 4] << 32 ) \
2121 | ( (uint64_t) (b)[(i) + 3] << 24 ) \
2122 | ( (uint64_t) (b)[(i) + 2] << 16 ) \
2123 | ( (uint64_t) (b)[(i) + 1] << 8 ) \
2124 | ( (uint64_t) (b)[(i) ] ); \
2125}
2126#endif
2127
2128#ifndef PUT_UINT64_LE
2129#define PUT_UINT64_LE(n,b,i) \
2130{ \
2131 (b)[(i) + 7] = (unsigned char) ( (n) >> 56 ); \
2132 (b)[(i) + 6] = (unsigned char) ( (n) >> 48 ); \
2133 (b)[(i) + 5] = (unsigned char) ( (n) >> 40 ); \
2134 (b)[(i) + 4] = (unsigned char) ( (n) >> 32 ); \
2135 (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \
2136 (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \
2137 (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \
2138 (b)[(i) ] = (unsigned char) ( (n) ); \
2139}
2140#endif
2141
2142typedef unsigned char mbedtls_be128[16];
2143
2144/*
2145 * GF(2^128) multiplication function
2146 *
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01002147 * This function multiplies a field element by x in the polynomial field
2148 * representation. It uses 64-bit word operations to gain speed but compensates
2149 * for machine endianess and hence works correctly on both big and little
2150 * endian machines.
Jaeden Amero010c2cb2018-05-29 17:00:47 +01002151 */
2152static void mbedtls_gf128mul_x_ble( unsigned char r[16],
Jaeden Amero8cfc75f2018-05-31 16:53:08 +01002153 const unsigned char x[16] )
Jaeden Amero010c2cb2018-05-29 17:00:47 +01002154{
2155 uint64_t a, b, ra, rb;
2156
Jaeden Amero8cfc75f2018-05-31 16:53:08 +01002157 GET_UINT64_LE( a, x, 0 );
2158 GET_UINT64_LE( b, x, 8 );
Jaeden Amero010c2cb2018-05-29 17:00:47 +01002159
Jaeden Amero8cfc75f2018-05-31 16:53:08 +01002160 ra = ( a << 1 ) ^ 0x0087 >> ( 8 - ( ( b >> 63 ) << 3 ) );
2161 rb = ( a >> 63 ) | ( b << 1 );
Jaeden Amero010c2cb2018-05-29 17:00:47 +01002162
Jaeden Amero8cfc75f2018-05-31 16:53:08 +01002163 PUT_UINT64_LE( ra, r, 0 );
2164 PUT_UINT64_LE( rb, r, 8 );
Jaeden Amero010c2cb2018-05-29 17:00:47 +01002165}
2166
Aorimn5f778012016-06-09 23:22:58 +02002167/*
2168 * AES-XTS buffer encryption/decryption
2169 */
Jaeden Amero9366feb2018-05-29 18:55:17 +01002170int mbedtls_aes_crypt_xts( mbedtls_aes_xts_context *ctx,
2171 int mode,
Jaeden Amero5162b932018-05-29 12:55:24 +01002172 size_t length,
Jaeden Amerocd9fc5e2018-05-30 15:23:24 +01002173 const unsigned char data_unit[16],
Jaeden Amero9366feb2018-05-29 18:55:17 +01002174 const unsigned char *input,
2175 unsigned char *output )
Aorimn5f778012016-06-09 23:22:58 +02002176{
Jaeden Amerod82cd862018-04-28 15:02:45 +01002177 int ret;
2178 size_t blocks = length / 16;
2179 size_t leftover = length % 16;
2180 unsigned char tweak[16];
2181 unsigned char prev_tweak[16];
2182 unsigned char tmp[16];
Aorimn5f778012016-06-09 23:22:58 +02002183
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01002184 AES_VALIDATE_RET( ctx != NULL );
2185 AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
2186 mode == MBEDTLS_AES_DECRYPT );
Manuel Pégourié-Gonnard998a3582018-12-18 10:03:13 +01002187 AES_VALIDATE_RET( data_unit != NULL );
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01002188 AES_VALIDATE_RET( input != NULL );
2189 AES_VALIDATE_RET( output != NULL );
2190
Jaeden Amero8381fcb2018-10-11 12:06:15 +01002191 /* Data units must be at least 16 bytes long. */
Aorimn5f778012016-06-09 23:22:58 +02002192 if( length < 16 )
Jaeden Amerod82cd862018-04-28 15:02:45 +01002193 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Aorimn5f778012016-06-09 23:22:58 +02002194
Jaeden Ameroa74faba2018-10-11 12:07:43 +01002195 /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */
Jaeden Amero0a8b0202018-05-30 15:36:06 +01002196 if( length > ( 1 << 20 ) * 16 )
2197 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Aorimn5f778012016-06-09 23:22:58 +02002198
Jaeden Amerod82cd862018-04-28 15:02:45 +01002199 /* Compute the tweak. */
Jaeden Amerocd9fc5e2018-05-30 15:23:24 +01002200 ret = mbedtls_aes_crypt_ecb( &ctx->tweak, MBEDTLS_AES_ENCRYPT,
2201 data_unit, tweak );
Jaeden Amerod82cd862018-04-28 15:02:45 +01002202 if( ret != 0 )
2203 return( ret );
Aorimn5f778012016-06-09 23:22:58 +02002204
Jaeden Amerod82cd862018-04-28 15:02:45 +01002205 while( blocks-- )
Aorimn5f778012016-06-09 23:22:58 +02002206 {
Jaeden Amerod82cd862018-04-28 15:02:45 +01002207 size_t i;
2208
2209 if( leftover && ( mode == MBEDTLS_AES_DECRYPT ) && blocks == 0 )
2210 {
2211 /* We are on the last block in a decrypt operation that has
2212 * leftover bytes, so we need to use the next tweak for this block,
2213 * and this tweak for the lefover bytes. Save the current tweak for
2214 * the leftovers and then update the current tweak for use on this,
2215 * the last full block. */
Teppo Järvelin91d79382019-10-02 09:09:31 +03002216 mbedtls_platform_memcpy( prev_tweak, tweak, sizeof( tweak ) );
Jaeden Amerod82cd862018-04-28 15:02:45 +01002217 mbedtls_gf128mul_x_ble( tweak, tweak );
2218 }
2219
2220 for( i = 0; i < 16; i++ )
2221 tmp[i] = input[i] ^ tweak[i];
2222
2223 ret = mbedtls_aes_crypt_ecb( &ctx->crypt, mode, tmp, tmp );
2224 if( ret != 0 )
2225 return( ret );
2226
2227 for( i = 0; i < 16; i++ )
2228 output[i] = tmp[i] ^ tweak[i];
2229
2230 /* Update the tweak for the next block. */
2231 mbedtls_gf128mul_x_ble( tweak, tweak );
2232
2233 output += 16;
2234 input += 16;
Aorimn5f778012016-06-09 23:22:58 +02002235 }
2236
Jaeden Amerod82cd862018-04-28 15:02:45 +01002237 if( leftover )
Aorimn5f778012016-06-09 23:22:58 +02002238 {
Jaeden Amerod82cd862018-04-28 15:02:45 +01002239 /* If we are on the leftover bytes in a decrypt operation, we need to
2240 * use the previous tweak for these bytes (as saved in prev_tweak). */
2241 unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
Aorimn5f778012016-06-09 23:22:58 +02002242
Jaeden Amerod82cd862018-04-28 15:02:45 +01002243 /* We are now on the final part of the data unit, which doesn't divide
2244 * evenly by 16. It's time for ciphertext stealing. */
2245 size_t i;
2246 unsigned char *prev_output = output - 16;
Aorimn5f778012016-06-09 23:22:58 +02002247
Jaeden Amerod82cd862018-04-28 15:02:45 +01002248 /* Copy ciphertext bytes from the previous block to our output for each
2249 * byte of cyphertext we won't steal. At the same time, copy the
2250 * remainder of the input for this final round (since the loop bounds
2251 * are the same). */
2252 for( i = 0; i < leftover; i++ )
Aorimn5f778012016-06-09 23:22:58 +02002253 {
Jaeden Amerod82cd862018-04-28 15:02:45 +01002254 output[i] = prev_output[i];
2255 tmp[i] = input[i] ^ t[i];
Aorimn5f778012016-06-09 23:22:58 +02002256 }
Aorimn5f778012016-06-09 23:22:58 +02002257
Jaeden Amerod82cd862018-04-28 15:02:45 +01002258 /* Copy ciphertext bytes from the previous block for input in this
2259 * round. */
2260 for( ; i < 16; i++ )
2261 tmp[i] = prev_output[i] ^ t[i];
Aorimn5f778012016-06-09 23:22:58 +02002262
Jaeden Amerod82cd862018-04-28 15:02:45 +01002263 ret = mbedtls_aes_crypt_ecb( &ctx->crypt, mode, tmp, tmp );
2264 if( ret != 0 )
2265 return ret;
Aorimn5f778012016-06-09 23:22:58 +02002266
Jaeden Amerod82cd862018-04-28 15:02:45 +01002267 /* Write the result back to the previous block, overriding the previous
2268 * output we copied. */
2269 for( i = 0; i < 16; i++ )
2270 prev_output[i] = tmp[i] ^ t[i];
Aorimn5f778012016-06-09 23:22:58 +02002271 }
2272
2273 return( 0 );
2274}
2275#endif /* MBEDTLS_CIPHER_MODE_XTS */
2276
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002277#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00002278/*
2279 * AES-CFB128 buffer encryption/decryption
2280 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002281int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx,
Paul Bakker5121ce52009-01-03 21:22:43 +00002282 int mode,
Paul Bakker23986e52011-04-24 08:57:21 +00002283 size_t length,
Paul Bakker27fdf462011-06-09 13:55:13 +00002284 size_t *iv_off,
Paul Bakker5121ce52009-01-03 21:22:43 +00002285 unsigned char iv[16],
Paul Bakkerff60ee62010-03-16 21:09:09 +00002286 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +00002287 unsigned char *output )
2288{
Paul Bakker27fdf462011-06-09 13:55:13 +00002289 int c;
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01002290 size_t n;
2291
2292 AES_VALIDATE_RET( ctx != NULL );
2293 AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
2294 mode == MBEDTLS_AES_DECRYPT );
2295 AES_VALIDATE_RET( iv_off != NULL );
2296 AES_VALIDATE_RET( iv != NULL );
2297 AES_VALIDATE_RET( input != NULL );
2298 AES_VALIDATE_RET( output != NULL );
2299
2300 n = *iv_off;
Paul Bakker5121ce52009-01-03 21:22:43 +00002301
Manuel Pégourié-Gonnarde55e1032018-12-18 12:09:02 +01002302 if( n > 15 )
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01002303 return( MBEDTLS_ERR_AES_BAD_INPUT_DATA );
2304
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002305 if( mode == MBEDTLS_AES_DECRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +00002306 {
2307 while( length-- )
2308 {
2309 if( n == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002310 mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
Paul Bakker5121ce52009-01-03 21:22:43 +00002311
2312 c = *input++;
2313 *output++ = (unsigned char)( c ^ iv[n] );
2314 iv[n] = (unsigned char) c;
2315
Paul Bakker66d5d072014-06-17 16:39:18 +02002316 n = ( n + 1 ) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00002317 }
2318 }
2319 else
2320 {
2321 while( length-- )
2322 {
2323 if( n == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002324 mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
Paul Bakker5121ce52009-01-03 21:22:43 +00002325
2326 iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ );
2327
Paul Bakker66d5d072014-06-17 16:39:18 +02002328 n = ( n + 1 ) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00002329 }
2330 }
2331
2332 *iv_off = n;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00002333
2334 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002335}
Paul Bakker556efba2014-01-24 15:38:12 +01002336
2337/*
2338 * AES-CFB8 buffer encryption/decryption
2339 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002340int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx,
Manuel Pégourié-Gonnardeb6d3962018-12-18 09:59:35 +01002341 int mode,
2342 size_t length,
2343 unsigned char iv[16],
2344 const unsigned char *input,
2345 unsigned char *output )
Paul Bakker556efba2014-01-24 15:38:12 +01002346{
2347 unsigned char c;
2348 unsigned char ov[17];
2349
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01002350 AES_VALIDATE_RET( ctx != NULL );
2351 AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
2352 mode == MBEDTLS_AES_DECRYPT );
2353 AES_VALIDATE_RET( iv != NULL );
2354 AES_VALIDATE_RET( input != NULL );
2355 AES_VALIDATE_RET( output != NULL );
Paul Bakker556efba2014-01-24 15:38:12 +01002356 while( length-- )
2357 {
Teppo Järvelin91d79382019-10-02 09:09:31 +03002358 mbedtls_platform_memcpy( ov, iv, 16 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002359 mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
Paul Bakker556efba2014-01-24 15:38:12 +01002360
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002361 if( mode == MBEDTLS_AES_DECRYPT )
Paul Bakker556efba2014-01-24 15:38:12 +01002362 ov[16] = *input;
2363
2364 c = *output++ = (unsigned char)( iv[0] ^ *input++ );
2365
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002366 if( mode == MBEDTLS_AES_ENCRYPT )
Paul Bakker556efba2014-01-24 15:38:12 +01002367 ov[16] = c;
2368
Teppo Järvelin91d79382019-10-02 09:09:31 +03002369 mbedtls_platform_memcpy( iv, ov + 1, 16 );
Paul Bakker556efba2014-01-24 15:38:12 +01002370 }
2371
2372 return( 0 );
2373}
Simon Butcher76a5b222018-04-22 22:57:27 +01002374#endif /* MBEDTLS_CIPHER_MODE_CFB */
2375
2376#if defined(MBEDTLS_CIPHER_MODE_OFB)
2377/*
2378 * AES-OFB (Output Feedback Mode) buffer encryption/decryption
2379 */
2380int mbedtls_aes_crypt_ofb( mbedtls_aes_context *ctx,
Simon Butcher00131442018-05-22 22:40:36 +01002381 size_t length,
2382 size_t *iv_off,
2383 unsigned char iv[16],
2384 const unsigned char *input,
2385 unsigned char *output )
Simon Butcher76a5b222018-04-22 22:57:27 +01002386{
Simon Butcherad4e4932018-04-29 00:43:47 +01002387 int ret = 0;
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01002388 size_t n;
2389
2390 AES_VALIDATE_RET( ctx != NULL );
2391 AES_VALIDATE_RET( iv_off != NULL );
2392 AES_VALIDATE_RET( iv != NULL );
2393 AES_VALIDATE_RET( input != NULL );
2394 AES_VALIDATE_RET( output != NULL );
2395
2396 n = *iv_off;
Simon Butcher76a5b222018-04-22 22:57:27 +01002397
Manuel Pégourié-Gonnarde55e1032018-12-18 12:09:02 +01002398 if( n > 15 )
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01002399 return( MBEDTLS_ERR_AES_BAD_INPUT_DATA );
2400
Simon Butcher76a5b222018-04-22 22:57:27 +01002401 while( length-- )
2402 {
2403 if( n == 0 )
Simon Butcherad4e4932018-04-29 00:43:47 +01002404 {
2405 ret = mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
2406 if( ret != 0 )
2407 goto exit;
2408 }
Simon Butcher76a5b222018-04-22 22:57:27 +01002409 *output++ = *input++ ^ iv[n];
2410
2411 n = ( n + 1 ) & 0x0F;
2412 }
2413
2414 *iv_off = n;
2415
Simon Butcherad4e4932018-04-29 00:43:47 +01002416exit:
2417 return( ret );
Simon Butcher76a5b222018-04-22 22:57:27 +01002418}
2419#endif /* MBEDTLS_CIPHER_MODE_OFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002420
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002421#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002422/*
2423 * AES-CTR buffer encryption/decryption
2424 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002425int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx,
Paul Bakker27fdf462011-06-09 13:55:13 +00002426 size_t length,
2427 size_t *nc_off,
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002428 unsigned char nonce_counter[16],
2429 unsigned char stream_block[16],
2430 const unsigned char *input,
2431 unsigned char *output )
2432{
Paul Bakker369e14b2012-04-18 14:16:09 +00002433 int c, i;
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01002434 size_t n;
2435
2436 AES_VALIDATE_RET( ctx != NULL );
2437 AES_VALIDATE_RET( nc_off != NULL );
2438 AES_VALIDATE_RET( nonce_counter != NULL );
2439 AES_VALIDATE_RET( stream_block != NULL );
2440 AES_VALIDATE_RET( input != NULL );
2441 AES_VALIDATE_RET( output != NULL );
2442
2443 n = *nc_off;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002444
Arto Kinnunen75439012019-12-03 14:12:10 +02002445 if( n > 0x0F )
Mohammad Azim Khan3f7f8172017-11-23 17:49:05 +00002446 return( MBEDTLS_ERR_AES_BAD_INPUT_DATA );
2447
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002448 while( length-- )
2449 {
2450 if( n == 0 ) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002451 mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block );
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002452
Paul Bakker369e14b2012-04-18 14:16:09 +00002453 for( i = 16; i > 0; i-- )
2454 if( ++nonce_counter[i - 1] != 0 )
2455 break;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002456 }
2457 c = *input++;
2458 *output++ = (unsigned char)( c ^ stream_block[n] );
2459
Paul Bakker66d5d072014-06-17 16:39:18 +02002460 n = ( n + 1 ) & 0x0F;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002461 }
2462
2463 *nc_off = n;
2464
2465 return( 0 );
2466}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002467#endif /* MBEDTLS_CIPHER_MODE_CTR */
Manuel Pégourié-Gonnard1ec220b2014-03-10 11:20:17 +01002468
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002469#endif /* !MBEDTLS_AES_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +00002470
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002471#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00002472/*
2473 * AES test vectors from:
2474 *
2475 * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
2476 */
2477static const unsigned char aes_test_ecb_dec[3][16] =
2478{
2479 { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
2480 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
2481 { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
2482 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
2483 { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
2484 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
2485};
2486
2487static const unsigned char aes_test_ecb_enc[3][16] =
2488{
2489 { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
2490 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
2491 { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
2492 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
2493 { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
2494 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
2495};
2496
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002497#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00002498static const unsigned char aes_test_cbc_dec[3][16] =
2499{
2500 { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
2501 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
2502 { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
2503 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
2504 { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
2505 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
2506};
2507
2508static const unsigned char aes_test_cbc_enc[3][16] =
2509{
2510 { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
2511 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
2512 { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
2513 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
2514 { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
2515 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
2516};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002517#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00002518
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002519#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00002520/*
2521 * AES-CFB128 test vectors from:
2522 *
2523 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
2524 */
2525static const unsigned char aes_test_cfb128_key[3][32] =
2526{
2527 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
2528 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
2529 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
2530 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
2531 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
2532 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
2533 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
2534 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
2535 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
2536};
2537
2538static const unsigned char aes_test_cfb128_iv[16] =
2539{
2540 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
2541 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
2542};
2543
2544static const unsigned char aes_test_cfb128_pt[64] =
2545{
2546 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
2547 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
2548 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
2549 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
2550 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
2551 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
2552 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
2553 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
2554};
2555
2556static const unsigned char aes_test_cfb128_ct[3][64] =
2557{
2558 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
2559 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
2560 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F,
2561 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B,
2562 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40,
2563 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF,
2564 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E,
2565 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 },
2566 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
2567 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
2568 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21,
2569 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A,
2570 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1,
2571 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9,
2572 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0,
2573 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF },
2574 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
2575 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
2576 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8,
2577 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B,
2578 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92,
2579 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9,
2580 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8,
2581 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 }
2582};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002583#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002584
Simon Butcherad4e4932018-04-29 00:43:47 +01002585#if defined(MBEDTLS_CIPHER_MODE_OFB)
2586/*
2587 * AES-OFB test vectors from:
2588 *
Simon Butcher5db13622018-06-04 22:11:25 +01002589 * https://csrc.nist.gov/publications/detail/sp/800-38a/final
Simon Butcherad4e4932018-04-29 00:43:47 +01002590 */
2591static const unsigned char aes_test_ofb_key[3][32] =
2592{
2593 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
2594 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
2595 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
2596 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
2597 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
2598 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
2599 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
2600 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
2601 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
2602};
2603
2604static const unsigned char aes_test_ofb_iv[16] =
2605{
2606 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
2607 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
2608};
2609
2610static const unsigned char aes_test_ofb_pt[64] =
2611{
2612 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
2613 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
2614 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
2615 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
2616 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
2617 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
2618 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
2619 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
2620};
2621
2622static const unsigned char aes_test_ofb_ct[3][64] =
2623{
2624 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
2625 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
2626 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
2627 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
2628 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
2629 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
2630 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
2631 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e },
2632 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
2633 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
2634 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
2635 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
2636 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f,
2637 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
2638 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e,
2639 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a },
2640 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
2641 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
2642 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
2643 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
2644 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed,
2645 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
2646 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8,
2647 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 }
2648};
2649#endif /* MBEDTLS_CIPHER_MODE_OFB */
2650
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002651#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002652/*
2653 * AES-CTR test vectors from:
2654 *
2655 * http://www.faqs.org/rfcs/rfc3686.html
2656 */
2657
2658static const unsigned char aes_test_ctr_key[3][16] =
2659{
2660 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
2661 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
2662 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
2663 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
2664 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
2665 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
2666};
2667
2668static const unsigned char aes_test_ctr_nonce_counter[3][16] =
2669{
2670 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
2671 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
2672 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
2673 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
2674 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
2675 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
2676};
2677
2678static const unsigned char aes_test_ctr_pt[3][48] =
2679{
2680 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
2681 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
2682
2683 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
2684 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
2685 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
2686 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
2687
2688 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
2689 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
2690 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
2691 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
2692 0x20, 0x21, 0x22, 0x23 }
2693};
2694
2695static const unsigned char aes_test_ctr_ct[3][48] =
2696{
2697 { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79,
2698 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 },
2699 { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9,
2700 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88,
2701 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8,
2702 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 },
2703 { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
2704 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
2705 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
2706 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
2707 0x25, 0xB2, 0x07, 0x2F }
2708};
2709
2710static const int aes_test_ctr_len[3] =
2711 { 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002712#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00002713
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002714#if defined(MBEDTLS_CIPHER_MODE_XTS)
2715/*
2716 * AES-XTS test vectors from:
2717 *
2718 * IEEE P1619/D16 Annex B
2719 * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf
2720 * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf)
2721 */
2722static const unsigned char aes_test_xts_key[][32] =
2723{
2724 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2725 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2726 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2727 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
2728 { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
2729 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
2730 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
2731 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
2732 { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
2733 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
2734 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
2735 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
2736};
2737
2738static const unsigned char aes_test_xts_pt32[][32] =
2739{
2740 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2741 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2742 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2743 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
2744 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2745 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2746 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2747 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
2748 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2749 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2750 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2751 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
2752};
2753
2754static const unsigned char aes_test_xts_ct32[][32] =
2755{
2756 { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec,
2757 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92,
2758 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85,
2759 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e },
2760 { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e,
2761 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b,
2762 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4,
2763 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 },
2764 { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a,
2765 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2,
2766 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53,
2767 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 },
2768};
2769
2770static const unsigned char aes_test_xts_data_unit[][16] =
2771{
2772 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2773 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
2774 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
2775 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
2776 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
2777 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
2778};
2779
2780#endif /* MBEDTLS_CIPHER_MODE_XTS */
2781
Paul Bakker5121ce52009-01-03 21:22:43 +00002782/*
2783 * Checkup routine
2784 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002785int mbedtls_aes_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +00002786{
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002787 int ret = 0, i, j, u, mode;
2788 unsigned int keybits;
Paul Bakker5121ce52009-01-03 21:22:43 +00002789 unsigned char key[32];
2790 unsigned char buf[64];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002791 const unsigned char *aes_tests;
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03002792#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00002793 unsigned char iv[16];
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03002794#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002795#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +02002796 unsigned char prv[16];
2797#endif
Simon Butcher2ff0e522018-06-14 09:57:07 +01002798#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
2799 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker27fdf462011-06-09 13:55:13 +00002800 size_t offset;
Paul Bakkere91d01e2011-04-19 15:55:50 +00002801#endif
Simon Butcher66a89032018-06-15 18:20:29 +01002802#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS)
Paul Bakkere91d01e2011-04-19 15:55:50 +00002803 int len;
Simon Butcher66a89032018-06-15 18:20:29 +01002804#endif
2805#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002806 unsigned char nonce_counter[16];
2807 unsigned char stream_block[16];
2808#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002809 mbedtls_aes_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00002810
Teppo Järvelind49d2b62019-10-30 13:48:12 +02002811 memset( key, 0, 32 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002812 mbedtls_aes_init( &ctx );
Paul Bakker5121ce52009-01-03 21:22:43 +00002813
2814 /*
2815 * ECB mode
2816 */
2817 for( i = 0; i < 6; i++ )
2818 {
2819 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002820 keybits = 128 + u * 64;
2821 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00002822
2823 if( verbose != 0 )
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002824 mbedtls_printf( " AES-ECB-%3d (%s): ", keybits,
2825 ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002826
Arto Kinnunen77b9cfc2019-08-30 11:43:21 +03002827#if defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
2828 if( keybits > 128 )
2829 {
2830 mbedtls_printf( "skipped\n" );
2831 continue;
2832 }
Arto Kinnunenc0a8bd42019-10-16 14:23:14 +03002833#endif /* MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
2834
2835#if defined(MBEDTLS_AES_ONLY_ENCRYPT)
2836 if( mode == MBEDTLS_AES_DECRYPT )
2837 {
2838 mbedtls_printf( "skipped\n" );
2839 continue;
2840 }
2841#endif /* MBEDTLS_AES_ONLY_ENCRYPT */
Arto Kinnunen77b9cfc2019-08-30 11:43:21 +03002842
Teppo Järvelind49d2b62019-10-30 13:48:12 +02002843 memset( buf, 0, 16 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002844
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002845 if( mode == MBEDTLS_AES_DECRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +00002846 {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002847 ret = mbedtls_aes_setkey_dec( &ctx, key, keybits );
2848 aes_tests = aes_test_ecb_dec[u];
Paul Bakker5121ce52009-01-03 21:22:43 +00002849 }
2850 else
2851 {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002852 ret = mbedtls_aes_setkey_enc( &ctx, key, keybits );
2853 aes_tests = aes_test_ecb_enc[u];
2854 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002855
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01002856 /*
2857 * AES-192 is an optional feature that may be unavailable when
2858 * there is an alternative underlying implementation i.e. when
2859 * MBEDTLS_AES_ALT is defined.
2860 */
Ron Eldor9924bdc2018-10-04 10:59:13 +03002861 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 )
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002862 {
2863 mbedtls_printf( "skipped\n" );
2864 continue;
2865 }
2866 else if( ret != 0 )
2867 {
2868 goto exit;
2869 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002870
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002871 for( j = 0; j < 10000; j++ )
2872 {
2873 ret = mbedtls_aes_crypt_ecb( &ctx, mode, buf, buf );
2874 if( ret != 0 )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002875 goto exit;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002876 }
2877
2878 if( memcmp( buf, aes_tests, 16 ) != 0 )
2879 {
2880 ret = 1;
2881 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00002882 }
2883
2884 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002885 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002886 }
2887
2888 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002889 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002890
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002891#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00002892 /*
2893 * CBC mode
2894 */
2895 for( i = 0; i < 6; i++ )
2896 {
2897 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002898 keybits = 128 + u * 64;
2899 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00002900
2901 if( verbose != 0 )
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002902 mbedtls_printf( " AES-CBC-%3d (%s): ", keybits,
2903 ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002904
Arto Kinnunen77b9cfc2019-08-30 11:43:21 +03002905#if defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
2906 if( keybits > 128 )
2907 {
2908 mbedtls_printf( "skipped\n" );
2909 continue;
2910 }
2911#endif
2912
Arto Kinnunenc0a8bd42019-10-16 14:23:14 +03002913#if defined(MBEDTLS_AES_ONLY_ENCRYPT)
2914 if( mode == MBEDTLS_AES_DECRYPT )
2915 {
2916 mbedtls_printf( "skipped\n" );
2917 continue;
2918 }
2919#endif /* MBEDTLS_AES_ONLY_ENCRYPT */
2920
Teppo Järvelind49d2b62019-10-30 13:48:12 +02002921 memset( iv , 0, 16 );
2922 memset( prv, 0, 16 );
2923 memset( buf, 0, 16 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002924
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002925 if( mode == MBEDTLS_AES_DECRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +00002926 {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002927 ret = mbedtls_aes_setkey_dec( &ctx, key, keybits );
2928 aes_tests = aes_test_cbc_dec[u];
Paul Bakker5121ce52009-01-03 21:22:43 +00002929 }
2930 else
2931 {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002932 ret = mbedtls_aes_setkey_enc( &ctx, key, keybits );
2933 aes_tests = aes_test_cbc_enc[u];
2934 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002935
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01002936 /*
2937 * AES-192 is an optional feature that may be unavailable when
2938 * there is an alternative underlying implementation i.e. when
2939 * MBEDTLS_AES_ALT is defined.
2940 */
Ron Eldor9924bdc2018-10-04 10:59:13 +03002941 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 )
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002942 {
2943 mbedtls_printf( "skipped\n" );
2944 continue;
2945 }
2946 else if( ret != 0 )
2947 {
2948 goto exit;
2949 }
2950
2951 for( j = 0; j < 10000; j++ )
2952 {
2953 if( mode == MBEDTLS_AES_ENCRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +00002954 {
2955 unsigned char tmp[16];
2956
Teppo Järvelinb5c46712019-10-04 13:35:55 +03002957 memcpy( tmp, prv, 16 );
2958 memcpy( prv, buf, 16 );
2959 memcpy( buf, tmp, 16 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002960 }
2961
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002962 ret = mbedtls_aes_crypt_cbc( &ctx, mode, 16, iv, buf, buf );
2963 if( ret != 0 )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002964 goto exit;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002965
2966 }
2967
2968 if( memcmp( buf, aes_tests, 16 ) != 0 )
2969 {
2970 ret = 1;
2971 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00002972 }
2973
2974 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002975 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002976 }
2977
2978 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002979 mbedtls_printf( "\n" );
2980#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00002981
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002982#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00002983 /*
2984 * CFB128 mode
2985 */
2986 for( i = 0; i < 6; i++ )
2987 {
2988 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002989 keybits = 128 + u * 64;
2990 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00002991
2992 if( verbose != 0 )
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002993 mbedtls_printf( " AES-CFB128-%3d (%s): ", keybits,
2994 ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002995
Arto Kinnunen77b9cfc2019-08-30 11:43:21 +03002996#if defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
2997 if( keybits > 128 )
2998 {
2999 mbedtls_printf( "skipped\n" );
3000 continue;
3001 }
3002#endif
3003
Arto Kinnunenc0a8bd42019-10-16 14:23:14 +03003004#if defined(MBEDTLS_AES_ONLY_ENCRYPT)
3005 if( mode == MBEDTLS_AES_DECRYPT )
3006 {
3007 mbedtls_printf( "skipped\n" );
3008 continue;
3009 }
3010#endif /* MBEDTLS_AES_ONLY_ENCRYPT */
3011
Paul Bakker5121ce52009-01-03 21:22:43 +00003012 memcpy( iv, aes_test_cfb128_iv, 16 );
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01003013 memcpy( key, aes_test_cfb128_key[u], keybits / 8 );
Paul Bakker5121ce52009-01-03 21:22:43 +00003014
3015 offset = 0;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01003016 ret = mbedtls_aes_setkey_enc( &ctx, key, keybits );
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01003017 /*
3018 * AES-192 is an optional feature that may be unavailable when
3019 * there is an alternative underlying implementation i.e. when
3020 * MBEDTLS_AES_ALT is defined.
3021 */
Ron Eldor9924bdc2018-10-04 10:59:13 +03003022 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 )
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01003023 {
3024 mbedtls_printf( "skipped\n" );
3025 continue;
3026 }
3027 else if( ret != 0 )
3028 {
3029 goto exit;
3030 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003031
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01003032 if( mode == MBEDTLS_AES_DECRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +00003033 {
Teppo Järvelinb5c46712019-10-04 13:35:55 +03003034 memcpy( buf, aes_test_cfb128_ct[u], 64 );
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01003035 aes_tests = aes_test_cfb128_pt;
Paul Bakker5121ce52009-01-03 21:22:43 +00003036 }
3037 else
3038 {
Teppo Järvelinb5c46712019-10-04 13:35:55 +03003039 memcpy( buf, aes_test_cfb128_pt, 64 );
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01003040 aes_tests = aes_test_cfb128_ct[u];
3041 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003042
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01003043 ret = mbedtls_aes_crypt_cfb128( &ctx, mode, 64, &offset, iv, buf, buf );
3044 if( ret != 0 )
3045 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00003046
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01003047 if( memcmp( buf, aes_tests, 64 ) != 0 )
3048 {
3049 ret = 1;
3050 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00003051 }
3052
3053 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003054 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00003055 }
3056
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00003057 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003058 mbedtls_printf( "\n" );
3059#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00003060
Simon Butcherad4e4932018-04-29 00:43:47 +01003061#if defined(MBEDTLS_CIPHER_MODE_OFB)
3062 /*
3063 * OFB mode
3064 */
3065 for( i = 0; i < 6; i++ )
3066 {
3067 u = i >> 1;
3068 keybits = 128 + u * 64;
3069 mode = i & 1;
3070
3071 if( verbose != 0 )
3072 mbedtls_printf( " AES-OFB-%3d (%s): ", keybits,
3073 ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
3074
Arto Kinnunen77b9cfc2019-08-30 11:43:21 +03003075#if defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
3076 if( keybits > 128 )
3077 {
3078 mbedtls_printf( "skipped\n" );
3079 continue;
3080 }
3081#endif
Arto Kinnunenc0a8bd42019-10-16 14:23:14 +03003082
3083#if defined(MBEDTLS_AES_ONLY_ENCRYPT)
3084 if( mode == MBEDTLS_AES_DECRYPT )
3085 {
3086 mbedtls_printf( "skipped\n" );
3087 continue;
3088 }
3089#endif /* MBEDTLS_AES_ONLY_ENCRYPT */
3090
Simon Butcherad4e4932018-04-29 00:43:47 +01003091 memcpy( iv, aes_test_ofb_iv, 16 );
3092 memcpy( key, aes_test_ofb_key[u], keybits / 8 );
3093
3094 offset = 0;
3095 ret = mbedtls_aes_setkey_enc( &ctx, key, keybits );
3096 /*
3097 * AES-192 is an optional feature that may be unavailable when
3098 * there is an alternative underlying implementation i.e. when
3099 * MBEDTLS_AES_ALT is defined.
3100 */
Ron Eldor9924bdc2018-10-04 10:59:13 +03003101 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 )
Simon Butcherad4e4932018-04-29 00:43:47 +01003102 {
3103 mbedtls_printf( "skipped\n" );
3104 continue;
3105 }
3106 else if( ret != 0 )
3107 {
3108 goto exit;
3109 }
3110
3111 if( mode == MBEDTLS_AES_DECRYPT )
3112 {
Teppo Järvelinb5c46712019-10-04 13:35:55 +03003113 memcpy( buf, aes_test_ofb_ct[u], 64 );
Simon Butcherad4e4932018-04-29 00:43:47 +01003114 aes_tests = aes_test_ofb_pt;
3115 }
3116 else
3117 {
Teppo Järvelinb5c46712019-10-04 13:35:55 +03003118 memcpy( buf, aes_test_ofb_pt, 64 );
Simon Butcherad4e4932018-04-29 00:43:47 +01003119 aes_tests = aes_test_ofb_ct[u];
3120 }
3121
3122 ret = mbedtls_aes_crypt_ofb( &ctx, 64, &offset, iv, buf, buf );
3123 if( ret != 0 )
3124 goto exit;
3125
3126 if( memcmp( buf, aes_tests, 64 ) != 0 )
3127 {
3128 ret = 1;
3129 goto exit;
3130 }
3131
3132 if( verbose != 0 )
3133 mbedtls_printf( "passed\n" );
3134 }
3135
3136 if( verbose != 0 )
3137 mbedtls_printf( "\n" );
3138#endif /* MBEDTLS_CIPHER_MODE_OFB */
3139
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003140#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00003141 /*
3142 * CTR mode
3143 */
3144 for( i = 0; i < 6; i++ )
3145 {
3146 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01003147 mode = i & 1;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00003148
3149 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003150 mbedtls_printf( " AES-CTR-128 (%s): ",
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01003151 ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00003152
Arto Kinnunen77b9cfc2019-08-30 11:43:21 +03003153#if defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
3154 if( keybits > 128 )
3155 {
3156 mbedtls_printf( "skipped\n" );
3157 continue;
3158 }
3159#endif
3160
Arto Kinnunenc0a8bd42019-10-16 14:23:14 +03003161#if defined(MBEDTLS_AES_ONLY_ENCRYPT)
3162 if( mode == MBEDTLS_AES_DECRYPT )
3163 {
3164 mbedtls_printf( "skipped\n" );
3165 continue;
3166 }
3167#endif /* MBEDTLS_AES_ONLY_ENCRYPT */
3168
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00003169 memcpy( nonce_counter, aes_test_ctr_nonce_counter[u], 16 );
3170 memcpy( key, aes_test_ctr_key[u], 16 );
3171
3172 offset = 0;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01003173 if( ( ret = mbedtls_aes_setkey_enc( &ctx, key, 128 ) ) != 0 )
3174 goto exit;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00003175
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01003176 len = aes_test_ctr_len[u];
3177
3178 if( mode == MBEDTLS_AES_DECRYPT )
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00003179 {
Teppo Järvelinb5c46712019-10-04 13:35:55 +03003180 memcpy( buf, aes_test_ctr_ct[u], len );
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01003181 aes_tests = aes_test_ctr_pt[u];
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00003182 }
3183 else
3184 {
Teppo Järvelinb5c46712019-10-04 13:35:55 +03003185 memcpy( buf, aes_test_ctr_pt[u], len );
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01003186 aes_tests = aes_test_ctr_ct[u];
3187 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00003188
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01003189 ret = mbedtls_aes_crypt_ctr( &ctx, len, &offset, nonce_counter,
3190 stream_block, buf, buf );
3191 if( ret != 0 )
3192 goto exit;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00003193
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01003194 if( memcmp( buf, aes_tests, len ) != 0 )
3195 {
3196 ret = 1;
3197 goto exit;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00003198 }
3199
3200 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003201 mbedtls_printf( "passed\n" );
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00003202 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003203
3204 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003205 mbedtls_printf( "\n" );
3206#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00003207
Jaeden Amero21d79cf2018-05-23 10:30:18 +01003208#if defined(MBEDTLS_CIPHER_MODE_XTS)
3209 {
3210 static const int num_tests =
3211 sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key);
3212 mbedtls_aes_xts_context ctx_xts;
3213
3214 /*
3215 * XTS mode
3216 */
3217 mbedtls_aes_xts_init( &ctx_xts );
3218
3219 for( i = 0; i < num_tests << 1; i++ )
3220 {
3221 const unsigned char *data_unit;
3222 u = i >> 1;
3223 mode = i & 1;
3224
3225 if( verbose != 0 )
3226 mbedtls_printf( " AES-XTS-128 (%s): ",
3227 ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
3228
Arto Kinnunenc0a8bd42019-10-16 14:23:14 +03003229#if defined(MBEDTLS_AES_ONLY_ENCRYPT)
3230 if( mode == MBEDTLS_AES_DECRYPT )
3231 {
3232 mbedtls_printf( "skipped\n" );
3233 continue;
3234 }
3235#endif /* MBEDTLS_AES_ONLY_ENCRYPT */
3236
Teppo Järvelind49d2b62019-10-30 13:48:12 +02003237 memset( key, 0, sizeof( key ) );
3238 memcpy( key, aes_test_xts_key[u], 32 );
Jaeden Amero21d79cf2018-05-23 10:30:18 +01003239 data_unit = aes_test_xts_data_unit[u];
3240
3241 len = sizeof( *aes_test_xts_ct32 );
3242
3243 if( mode == MBEDTLS_AES_DECRYPT )
3244 {
3245 ret = mbedtls_aes_xts_setkey_dec( &ctx_xts, key, 256 );
3246 if( ret != 0)
3247 goto exit;
Teppo Järvelinb5c46712019-10-04 13:35:55 +03003248 memcpy( buf, aes_test_xts_ct32[u], len );
Jaeden Amero21d79cf2018-05-23 10:30:18 +01003249 aes_tests = aes_test_xts_pt32[u];
3250 }
3251 else
3252 {
3253 ret = mbedtls_aes_xts_setkey_enc( &ctx_xts, key, 256 );
3254 if( ret != 0)
3255 goto exit;
Teppo Järvelinb5c46712019-10-04 13:35:55 +03003256 memcpy( buf, aes_test_xts_pt32[u], len );
Jaeden Amero21d79cf2018-05-23 10:30:18 +01003257 aes_tests = aes_test_xts_ct32[u];
3258 }
3259
3260
3261 ret = mbedtls_aes_crypt_xts( &ctx_xts, mode, len, data_unit,
3262 buf, buf );
3263 if( ret != 0 )
3264 goto exit;
3265
3266 if( memcmp( buf, aes_tests, len ) != 0 )
3267 {
3268 ret = 1;
3269 goto exit;
3270 }
3271
3272 if( verbose != 0 )
3273 mbedtls_printf( "passed\n" );
3274 }
3275
3276 if( verbose != 0 )
3277 mbedtls_printf( "\n" );
3278
3279 mbedtls_aes_xts_free( &ctx_xts );
3280 }
3281#endif /* MBEDTLS_CIPHER_MODE_XTS */
3282
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02003283 ret = 0;
3284
3285exit:
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01003286 if( ret != 0 && verbose != 0 )
3287 mbedtls_printf( "failed\n" );
3288
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003289 mbedtls_aes_free( &ctx );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02003290
3291 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00003292}
3293
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003294#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00003295
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003296#endif /* MBEDTLS_AES_C */