blob: f6c4fc33e3d799a3614a93fa00a55e042881b711 [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 */
Arto Kinnunen172836a2019-11-28 13:34:13 +020094} aes_r_data_t;
95
96#if defined(MBEDTLS_AES_SCA_COUNTERMEASURES)
Arto Kinnunen17540ab2020-01-20 11:46:34 +020097/* Number of additional AES dummy rounds added for SCA countermeasures */
Arto Kinnunen98c93af2020-01-14 13:31:03 +020098#define AES_SCA_CM_ROUNDS 5
Arto Kinnunen172836a2019-11-28 13:34:13 +020099#endif /* MBEDTLS_AES_SCA_COUNTERMEASURES */
100
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200101#if defined(MBEDTLS_PADLOCK_C) && \
102 ( defined(MBEDTLS_HAVE_X86) || defined(MBEDTLS_PADLOCK_ALIGN16) )
Paul Bakker048d04e2012-02-12 17:31:04 +0000103static int aes_padlock_ace = -1;
104#endif
105
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200106#if defined(MBEDTLS_AES_ROM_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +0000107/*
108 * Forward S-box
109 */
110static const unsigned char FSb[256] =
111{
112 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
113 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
114 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
115 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
116 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
117 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
118 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
119 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
120 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
121 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
122 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
123 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
124 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
125 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
126 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
127 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
128 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
129 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
130 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
131 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
132 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
133 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
134 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
135 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
136 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
137 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
138 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
139 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
140 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
141 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
142 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
143 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
144};
145
146/*
147 * Forward tables
148 */
149#define FT \
150\
151 V(A5,63,63,C6), V(84,7C,7C,F8), V(99,77,77,EE), V(8D,7B,7B,F6), \
152 V(0D,F2,F2,FF), V(BD,6B,6B,D6), V(B1,6F,6F,DE), V(54,C5,C5,91), \
153 V(50,30,30,60), V(03,01,01,02), V(A9,67,67,CE), V(7D,2B,2B,56), \
154 V(19,FE,FE,E7), V(62,D7,D7,B5), V(E6,AB,AB,4D), V(9A,76,76,EC), \
155 V(45,CA,CA,8F), V(9D,82,82,1F), V(40,C9,C9,89), V(87,7D,7D,FA), \
156 V(15,FA,FA,EF), V(EB,59,59,B2), V(C9,47,47,8E), V(0B,F0,F0,FB), \
157 V(EC,AD,AD,41), V(67,D4,D4,B3), V(FD,A2,A2,5F), V(EA,AF,AF,45), \
158 V(BF,9C,9C,23), V(F7,A4,A4,53), V(96,72,72,E4), V(5B,C0,C0,9B), \
159 V(C2,B7,B7,75), V(1C,FD,FD,E1), V(AE,93,93,3D), V(6A,26,26,4C), \
160 V(5A,36,36,6C), V(41,3F,3F,7E), V(02,F7,F7,F5), V(4F,CC,CC,83), \
161 V(5C,34,34,68), V(F4,A5,A5,51), V(34,E5,E5,D1), V(08,F1,F1,F9), \
162 V(93,71,71,E2), V(73,D8,D8,AB), V(53,31,31,62), V(3F,15,15,2A), \
163 V(0C,04,04,08), V(52,C7,C7,95), V(65,23,23,46), V(5E,C3,C3,9D), \
164 V(28,18,18,30), V(A1,96,96,37), V(0F,05,05,0A), V(B5,9A,9A,2F), \
165 V(09,07,07,0E), V(36,12,12,24), V(9B,80,80,1B), V(3D,E2,E2,DF), \
166 V(26,EB,EB,CD), V(69,27,27,4E), V(CD,B2,B2,7F), V(9F,75,75,EA), \
167 V(1B,09,09,12), V(9E,83,83,1D), V(74,2C,2C,58), V(2E,1A,1A,34), \
168 V(2D,1B,1B,36), V(B2,6E,6E,DC), V(EE,5A,5A,B4), V(FB,A0,A0,5B), \
169 V(F6,52,52,A4), V(4D,3B,3B,76), V(61,D6,D6,B7), V(CE,B3,B3,7D), \
170 V(7B,29,29,52), V(3E,E3,E3,DD), V(71,2F,2F,5E), V(97,84,84,13), \
171 V(F5,53,53,A6), V(68,D1,D1,B9), V(00,00,00,00), V(2C,ED,ED,C1), \
172 V(60,20,20,40), V(1F,FC,FC,E3), V(C8,B1,B1,79), V(ED,5B,5B,B6), \
173 V(BE,6A,6A,D4), V(46,CB,CB,8D), V(D9,BE,BE,67), V(4B,39,39,72), \
174 V(DE,4A,4A,94), V(D4,4C,4C,98), V(E8,58,58,B0), V(4A,CF,CF,85), \
175 V(6B,D0,D0,BB), V(2A,EF,EF,C5), V(E5,AA,AA,4F), V(16,FB,FB,ED), \
176 V(C5,43,43,86), V(D7,4D,4D,9A), V(55,33,33,66), V(94,85,85,11), \
177 V(CF,45,45,8A), V(10,F9,F9,E9), V(06,02,02,04), V(81,7F,7F,FE), \
178 V(F0,50,50,A0), V(44,3C,3C,78), V(BA,9F,9F,25), V(E3,A8,A8,4B), \
179 V(F3,51,51,A2), V(FE,A3,A3,5D), V(C0,40,40,80), V(8A,8F,8F,05), \
180 V(AD,92,92,3F), V(BC,9D,9D,21), V(48,38,38,70), V(04,F5,F5,F1), \
181 V(DF,BC,BC,63), V(C1,B6,B6,77), V(75,DA,DA,AF), V(63,21,21,42), \
182 V(30,10,10,20), V(1A,FF,FF,E5), V(0E,F3,F3,FD), V(6D,D2,D2,BF), \
183 V(4C,CD,CD,81), V(14,0C,0C,18), V(35,13,13,26), V(2F,EC,EC,C3), \
184 V(E1,5F,5F,BE), V(A2,97,97,35), V(CC,44,44,88), V(39,17,17,2E), \
185 V(57,C4,C4,93), V(F2,A7,A7,55), V(82,7E,7E,FC), V(47,3D,3D,7A), \
186 V(AC,64,64,C8), V(E7,5D,5D,BA), V(2B,19,19,32), V(95,73,73,E6), \
187 V(A0,60,60,C0), V(98,81,81,19), V(D1,4F,4F,9E), V(7F,DC,DC,A3), \
188 V(66,22,22,44), V(7E,2A,2A,54), V(AB,90,90,3B), V(83,88,88,0B), \
189 V(CA,46,46,8C), V(29,EE,EE,C7), V(D3,B8,B8,6B), V(3C,14,14,28), \
190 V(79,DE,DE,A7), V(E2,5E,5E,BC), V(1D,0B,0B,16), V(76,DB,DB,AD), \
191 V(3B,E0,E0,DB), V(56,32,32,64), V(4E,3A,3A,74), V(1E,0A,0A,14), \
192 V(DB,49,49,92), V(0A,06,06,0C), V(6C,24,24,48), V(E4,5C,5C,B8), \
193 V(5D,C2,C2,9F), V(6E,D3,D3,BD), V(EF,AC,AC,43), V(A6,62,62,C4), \
194 V(A8,91,91,39), V(A4,95,95,31), V(37,E4,E4,D3), V(8B,79,79,F2), \
195 V(32,E7,E7,D5), V(43,C8,C8,8B), V(59,37,37,6E), V(B7,6D,6D,DA), \
196 V(8C,8D,8D,01), V(64,D5,D5,B1), V(D2,4E,4E,9C), V(E0,A9,A9,49), \
197 V(B4,6C,6C,D8), V(FA,56,56,AC), V(07,F4,F4,F3), V(25,EA,EA,CF), \
198 V(AF,65,65,CA), V(8E,7A,7A,F4), V(E9,AE,AE,47), V(18,08,08,10), \
199 V(D5,BA,BA,6F), V(88,78,78,F0), V(6F,25,25,4A), V(72,2E,2E,5C), \
200 V(24,1C,1C,38), V(F1,A6,A6,57), V(C7,B4,B4,73), V(51,C6,C6,97), \
201 V(23,E8,E8,CB), V(7C,DD,DD,A1), V(9C,74,74,E8), V(21,1F,1F,3E), \
202 V(DD,4B,4B,96), V(DC,BD,BD,61), V(86,8B,8B,0D), V(85,8A,8A,0F), \
203 V(90,70,70,E0), V(42,3E,3E,7C), V(C4,B5,B5,71), V(AA,66,66,CC), \
204 V(D8,48,48,90), V(05,03,03,06), V(01,F6,F6,F7), V(12,0E,0E,1C), \
205 V(A3,61,61,C2), V(5F,35,35,6A), V(F9,57,57,AE), V(D0,B9,B9,69), \
206 V(91,86,86,17), V(58,C1,C1,99), V(27,1D,1D,3A), V(B9,9E,9E,27), \
207 V(38,E1,E1,D9), V(13,F8,F8,EB), V(B3,98,98,2B), V(33,11,11,22), \
208 V(BB,69,69,D2), V(70,D9,D9,A9), V(89,8E,8E,07), V(A7,94,94,33), \
209 V(B6,9B,9B,2D), V(22,1E,1E,3C), V(92,87,87,15), V(20,E9,E9,C9), \
210 V(49,CE,CE,87), V(FF,55,55,AA), V(78,28,28,50), V(7A,DF,DF,A5), \
211 V(8F,8C,8C,03), V(F8,A1,A1,59), V(80,89,89,09), V(17,0D,0D,1A), \
212 V(DA,BF,BF,65), V(31,E6,E6,D7), V(C6,42,42,84), V(B8,68,68,D0), \
213 V(C3,41,41,82), V(B0,99,99,29), V(77,2D,2D,5A), V(11,0F,0F,1E), \
214 V(CB,B0,B0,7B), V(FC,54,54,A8), V(D6,BB,BB,6D), V(3A,16,16,2C)
215
216#define V(a,b,c,d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000217static const uint32_t FT0[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000218#undef V
219
Hanno Beckerad049a92017-06-19 16:31:54 +0100220#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200221
Paul Bakker5121ce52009-01-03 21:22:43 +0000222#define V(a,b,c,d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000223static const uint32_t FT1[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000224#undef V
225
226#define V(a,b,c,d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000227static const uint32_t FT2[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000228#undef V
229
230#define V(a,b,c,d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000231static const uint32_t FT3[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000232#undef V
233
Hanno Becker177d3cf2017-06-07 15:52:48 +0100234#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200235
Paul Bakker5121ce52009-01-03 21:22:43 +0000236#undef FT
237
Arto Kinnunen14804442019-10-16 13:43:59 +0300238#if !defined(MBEDTLS_AES_ONLY_ENCRYPT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000239/*
240 * Reverse S-box
241 */
242static const unsigned char RSb[256] =
243{
244 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
245 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
246 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
247 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
248 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
249 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
250 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
251 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
252 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
253 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
254 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
255 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
256 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
257 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
258 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
259 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
260 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
261 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
262 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
263 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
264 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
265 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
266 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
267 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
268 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
269 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
270 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
271 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
272 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
273 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
274 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
275 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
276};
Arto Kinnunen14804442019-10-16 13:43:59 +0300277#endif /* !MBEDTLS_AES_ONLY_ENCRYPT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000278
279/*
280 * Reverse tables
281 */
282#define RT \
283\
284 V(50,A7,F4,51), V(53,65,41,7E), V(C3,A4,17,1A), V(96,5E,27,3A), \
285 V(CB,6B,AB,3B), V(F1,45,9D,1F), V(AB,58,FA,AC), V(93,03,E3,4B), \
286 V(55,FA,30,20), V(F6,6D,76,AD), V(91,76,CC,88), V(25,4C,02,F5), \
287 V(FC,D7,E5,4F), V(D7,CB,2A,C5), V(80,44,35,26), V(8F,A3,62,B5), \
288 V(49,5A,B1,DE), V(67,1B,BA,25), V(98,0E,EA,45), V(E1,C0,FE,5D), \
289 V(02,75,2F,C3), V(12,F0,4C,81), V(A3,97,46,8D), V(C6,F9,D3,6B), \
290 V(E7,5F,8F,03), V(95,9C,92,15), V(EB,7A,6D,BF), V(DA,59,52,95), \
291 V(2D,83,BE,D4), V(D3,21,74,58), V(29,69,E0,49), V(44,C8,C9,8E), \
292 V(6A,89,C2,75), V(78,79,8E,F4), V(6B,3E,58,99), V(DD,71,B9,27), \
293 V(B6,4F,E1,BE), V(17,AD,88,F0), V(66,AC,20,C9), V(B4,3A,CE,7D), \
294 V(18,4A,DF,63), V(82,31,1A,E5), V(60,33,51,97), V(45,7F,53,62), \
295 V(E0,77,64,B1), V(84,AE,6B,BB), V(1C,A0,81,FE), V(94,2B,08,F9), \
296 V(58,68,48,70), V(19,FD,45,8F), V(87,6C,DE,94), V(B7,F8,7B,52), \
297 V(23,D3,73,AB), V(E2,02,4B,72), V(57,8F,1F,E3), V(2A,AB,55,66), \
298 V(07,28,EB,B2), V(03,C2,B5,2F), V(9A,7B,C5,86), V(A5,08,37,D3), \
299 V(F2,87,28,30), V(B2,A5,BF,23), V(BA,6A,03,02), V(5C,82,16,ED), \
300 V(2B,1C,CF,8A), V(92,B4,79,A7), V(F0,F2,07,F3), V(A1,E2,69,4E), \
301 V(CD,F4,DA,65), V(D5,BE,05,06), V(1F,62,34,D1), V(8A,FE,A6,C4), \
302 V(9D,53,2E,34), V(A0,55,F3,A2), V(32,E1,8A,05), V(75,EB,F6,A4), \
303 V(39,EC,83,0B), V(AA,EF,60,40), V(06,9F,71,5E), V(51,10,6E,BD), \
304 V(F9,8A,21,3E), V(3D,06,DD,96), V(AE,05,3E,DD), V(46,BD,E6,4D), \
305 V(B5,8D,54,91), V(05,5D,C4,71), V(6F,D4,06,04), V(FF,15,50,60), \
306 V(24,FB,98,19), V(97,E9,BD,D6), V(CC,43,40,89), V(77,9E,D9,67), \
307 V(BD,42,E8,B0), V(88,8B,89,07), V(38,5B,19,E7), V(DB,EE,C8,79), \
308 V(47,0A,7C,A1), V(E9,0F,42,7C), V(C9,1E,84,F8), V(00,00,00,00), \
309 V(83,86,80,09), V(48,ED,2B,32), V(AC,70,11,1E), V(4E,72,5A,6C), \
310 V(FB,FF,0E,FD), V(56,38,85,0F), V(1E,D5,AE,3D), V(27,39,2D,36), \
311 V(64,D9,0F,0A), V(21,A6,5C,68), V(D1,54,5B,9B), V(3A,2E,36,24), \
312 V(B1,67,0A,0C), V(0F,E7,57,93), V(D2,96,EE,B4), V(9E,91,9B,1B), \
313 V(4F,C5,C0,80), V(A2,20,DC,61), V(69,4B,77,5A), V(16,1A,12,1C), \
314 V(0A,BA,93,E2), V(E5,2A,A0,C0), V(43,E0,22,3C), V(1D,17,1B,12), \
315 V(0B,0D,09,0E), V(AD,C7,8B,F2), V(B9,A8,B6,2D), V(C8,A9,1E,14), \
316 V(85,19,F1,57), V(4C,07,75,AF), V(BB,DD,99,EE), V(FD,60,7F,A3), \
317 V(9F,26,01,F7), V(BC,F5,72,5C), V(C5,3B,66,44), V(34,7E,FB,5B), \
318 V(76,29,43,8B), V(DC,C6,23,CB), V(68,FC,ED,B6), V(63,F1,E4,B8), \
319 V(CA,DC,31,D7), V(10,85,63,42), V(40,22,97,13), V(20,11,C6,84), \
320 V(7D,24,4A,85), V(F8,3D,BB,D2), V(11,32,F9,AE), V(6D,A1,29,C7), \
321 V(4B,2F,9E,1D), V(F3,30,B2,DC), V(EC,52,86,0D), V(D0,E3,C1,77), \
322 V(6C,16,B3,2B), V(99,B9,70,A9), V(FA,48,94,11), V(22,64,E9,47), \
323 V(C4,8C,FC,A8), V(1A,3F,F0,A0), V(D8,2C,7D,56), V(EF,90,33,22), \
324 V(C7,4E,49,87), V(C1,D1,38,D9), V(FE,A2,CA,8C), V(36,0B,D4,98), \
325 V(CF,81,F5,A6), V(28,DE,7A,A5), V(26,8E,B7,DA), V(A4,BF,AD,3F), \
326 V(E4,9D,3A,2C), V(0D,92,78,50), V(9B,CC,5F,6A), V(62,46,7E,54), \
327 V(C2,13,8D,F6), V(E8,B8,D8,90), V(5E,F7,39,2E), V(F5,AF,C3,82), \
328 V(BE,80,5D,9F), V(7C,93,D0,69), V(A9,2D,D5,6F), V(B3,12,25,CF), \
329 V(3B,99,AC,C8), V(A7,7D,18,10), V(6E,63,9C,E8), V(7B,BB,3B,DB), \
330 V(09,78,26,CD), V(F4,18,59,6E), V(01,B7,9A,EC), V(A8,9A,4F,83), \
331 V(65,6E,95,E6), V(7E,E6,FF,AA), V(08,CF,BC,21), V(E6,E8,15,EF), \
332 V(D9,9B,E7,BA), V(CE,36,6F,4A), V(D4,09,9F,EA), V(D6,7C,B0,29), \
333 V(AF,B2,A4,31), V(31,23,3F,2A), V(30,94,A5,C6), V(C0,66,A2,35), \
334 V(37,BC,4E,74), V(A6,CA,82,FC), V(B0,D0,90,E0), V(15,D8,A7,33), \
335 V(4A,98,04,F1), V(F7,DA,EC,41), V(0E,50,CD,7F), V(2F,F6,91,17), \
336 V(8D,D6,4D,76), V(4D,B0,EF,43), V(54,4D,AA,CC), V(DF,04,96,E4), \
337 V(E3,B5,D1,9E), V(1B,88,6A,4C), V(B8,1F,2C,C1), V(7F,51,65,46), \
338 V(04,EA,5E,9D), V(5D,35,8C,01), V(73,74,87,FA), V(2E,41,0B,FB), \
339 V(5A,1D,67,B3), V(52,D2,DB,92), V(33,56,10,E9), V(13,47,D6,6D), \
340 V(8C,61,D7,9A), V(7A,0C,A1,37), V(8E,14,F8,59), V(89,3C,13,EB), \
341 V(EE,27,A9,CE), V(35,C9,61,B7), V(ED,E5,1C,E1), V(3C,B1,47,7A), \
342 V(59,DF,D2,9C), V(3F,73,F2,55), V(79,CE,14,18), V(BF,37,C7,73), \
343 V(EA,CD,F7,53), V(5B,AA,FD,5F), V(14,6F,3D,DF), V(86,DB,44,78), \
344 V(81,F3,AF,CA), V(3E,C4,68,B9), V(2C,34,24,38), V(5F,40,A3,C2), \
345 V(72,C3,1D,16), V(0C,25,E2,BC), V(8B,49,3C,28), V(41,95,0D,FF), \
346 V(71,01,A8,39), V(DE,B3,0C,08), V(9C,E4,B4,D8), V(90,C1,56,64), \
347 V(61,84,CB,7B), V(70,B6,32,D5), V(74,5C,6C,48), V(42,57,B8,D0)
348
Arto Kinnunen14804442019-10-16 13:43:59 +0300349#if !defined(MBEDTLS_AES_ONLY_ENCRYPT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000350#define V(a,b,c,d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000351static const uint32_t RT0[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000352#undef V
353
Hanno Beckerad049a92017-06-19 16:31:54 +0100354#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200355
Paul Bakker5121ce52009-01-03 21:22:43 +0000356#define V(a,b,c,d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000357static const uint32_t RT1[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000358#undef V
359
360#define V(a,b,c,d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000361static const uint32_t RT2[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000362#undef V
363
364#define V(a,b,c,d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000365static const uint32_t RT3[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000366#undef V
367
Hanno Becker177d3cf2017-06-07 15:52:48 +0100368#endif /* !MBEDTLS_AES_FEWER_TABLES */
Arto Kinnunen0fa65aa2019-10-21 14:43:37 +0300369#endif /* !MBEDTLS_AES_ONLY_ENCRYPT */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200370
Paul Bakker5121ce52009-01-03 21:22:43 +0000371#undef RT
372
373/*
374 * Round constants
375 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000376static const uint32_t RCON[10] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000377{
378 0x00000001, 0x00000002, 0x00000004, 0x00000008,
379 0x00000010, 0x00000020, 0x00000040, 0x00000080,
380 0x0000001B, 0x00000036
381};
382
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200383#else /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000384
385/*
386 * Forward S-box & tables
387 */
388static unsigned char FSb[256];
Paul Bakker9af723c2014-05-01 13:03:14 +0200389static uint32_t FT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100390#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker9af723c2014-05-01 13:03:14 +0200391static uint32_t FT1[256];
392static uint32_t FT2[256];
393static uint32_t FT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100394#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000395
396/*
397 * Reverse S-box & tables
398 */
Arto Kinnunen0fa65aa2019-10-21 14:43:37 +0300399#if !defined(MBEDTLS_AES_ONLY_ENCRYPT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000400static unsigned char RSb[256];
Paul Bakker5c2364c2012-10-01 14:41:15 +0000401static uint32_t RT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100402#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker5c2364c2012-10-01 14:41:15 +0000403static uint32_t RT1[256];
404static uint32_t RT2[256];
405static uint32_t RT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100406#endif /* !MBEDTLS_AES_FEWER_TABLES */
Arto Kinnunen0fa65aa2019-10-21 14:43:37 +0300407#endif /* !MBEDTLS_AES_ONLY_ENCRYPT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000408
409/*
410 * Round constants
411 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000412static uint32_t RCON[10];
Paul Bakker5121ce52009-01-03 21:22:43 +0000413
414/*
415 * Tables generation code
416 */
Hanno Beckerd6028a12018-10-15 12:01:35 +0100417#define ROTL8(x) ( ( (x) << 8 ) & 0xFFFFFFFF ) | ( (x) >> 24 )
418#define XTIME(x) ( ( (x) << 1 ) ^ ( ( (x) & 0x80 ) ? 0x1B : 0x00 ) )
Hanno Becker3ac21ac2018-10-26 09:13:26 +0100419#define MUL(x,y) ( ( (x) && (y) ) ? pow[(log[(x)]+log[(y)]) % 255] : 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000420
421static int aes_init_done = 0;
422
423static void aes_gen_tables( void )
424{
425 int i, x, y, z;
426 int pow[256];
427 int log[256];
428
429 /*
430 * compute pow and log tables over GF(2^8)
431 */
432 for( i = 0, x = 1; i < 256; i++ )
433 {
434 pow[i] = x;
435 log[x] = i;
436 x = ( x ^ XTIME( x ) ) & 0xFF;
437 }
438
439 /*
440 * calculate the round constants
441 */
442 for( i = 0, x = 1; i < 10; i++ )
443 {
Paul Bakker5c2364c2012-10-01 14:41:15 +0000444 RCON[i] = (uint32_t) x;
Paul Bakker5121ce52009-01-03 21:22:43 +0000445 x = XTIME( x ) & 0xFF;
446 }
447
448 /*
449 * generate the forward and reverse S-boxes
450 */
451 FSb[0x00] = 0x63;
Arto Kinnunen0fa65aa2019-10-21 14:43:37 +0300452#if !defined(MBEDTLS_AES_ONLY_ENCRYPT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000453 RSb[0x63] = 0x00;
Arto Kinnunen0fa65aa2019-10-21 14:43:37 +0300454#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000455
456 for( i = 1; i < 256; i++ )
457 {
458 x = pow[255 - log[i]];
459
Paul Bakker66d5d072014-06-17 16:39:18 +0200460 y = x; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF;
461 x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF;
462 x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF;
463 x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF;
Paul Bakker5121ce52009-01-03 21:22:43 +0000464 x ^= y ^ 0x63;
465
466 FSb[i] = (unsigned char) x;
Arto Kinnunen0fa65aa2019-10-21 14:43:37 +0300467#if !defined(MBEDTLS_AES_ONLY_ENCRYPT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000468 RSb[x] = (unsigned char) i;
Arto Kinnunen0fa65aa2019-10-21 14:43:37 +0300469#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000470 }
471
472 /*
473 * generate the forward and reverse tables
474 */
475 for( i = 0; i < 256; i++ )
476 {
477 x = FSb[i];
478 y = XTIME( x ) & 0xFF;
479 z = ( y ^ x ) & 0xFF;
480
Paul Bakker5c2364c2012-10-01 14:41:15 +0000481 FT0[i] = ( (uint32_t) y ) ^
482 ( (uint32_t) x << 8 ) ^
483 ( (uint32_t) x << 16 ) ^
484 ( (uint32_t) z << 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000485
Hanno Beckerad049a92017-06-19 16:31:54 +0100486#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +0000487 FT1[i] = ROTL8( FT0[i] );
488 FT2[i] = ROTL8( FT1[i] );
489 FT3[i] = ROTL8( FT2[i] );
Hanno Becker177d3cf2017-06-07 15:52:48 +0100490#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000491
Arto Kinnunen0fa65aa2019-10-21 14:43:37 +0300492#if !defined(MBEDTLS_AES_ONLY_ENCRYPT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000493 x = RSb[i];
494
Paul Bakker5c2364c2012-10-01 14:41:15 +0000495 RT0[i] = ( (uint32_t) MUL( 0x0E, x ) ) ^
496 ( (uint32_t) MUL( 0x09, x ) << 8 ) ^
497 ( (uint32_t) MUL( 0x0D, x ) << 16 ) ^
498 ( (uint32_t) MUL( 0x0B, x ) << 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000499
Hanno Beckerad049a92017-06-19 16:31:54 +0100500#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +0000501 RT1[i] = ROTL8( RT0[i] );
502 RT2[i] = ROTL8( RT1[i] );
503 RT3[i] = ROTL8( RT2[i] );
Hanno Becker177d3cf2017-06-07 15:52:48 +0100504#endif /* !MBEDTLS_AES_FEWER_TABLES */
Arto Kinnunen0fa65aa2019-10-21 14:43:37 +0300505#endif /* !MBEDTLS_AES_ONLY_ENCRYPT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000506 }
507}
508
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200509#undef ROTL8
510
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200511#endif /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000512
Arto Kinnunen172836a2019-11-28 13:34:13 +0200513/**
Arto Kinnunen2eb678f2020-01-13 16:44:13 +0200514 * Randomize positions for AES SCA countermeasures if AES countermeasures are
Arto Kinnunen17540ab2020-01-20 11:46:34 +0200515 * enabled. If the countermeasures are not enabled then we fill the given table
516 * with only real AES rounds to be executed.
Arto Kinnunen2eb678f2020-01-13 16:44:13 +0200517 *
518 * Dummy rounds are added as follows:
519 * 1. One dummy round added to the initial round key addition (executed in
520 * random order).
521 * 2. Random number of dummy rounds added as first and/or last AES calculation
522 * round. Total number of dummy rounds is AES_SCA_CM_ROUNDS.
523 *
524 * Description of the bytes in the table are as follows:
525 * - 2 bytes for initial round key addition
526 * - remaining bytes for AES calculation with real or dummy data
527 *
528 * Each byte indicates one AES calculation round:
529 * -4 high bit = table to use 0x10 for dummy data, 0x00 real data
530 * -bit 2 = offset for even/odd rounds
531 * -bit 0-1: stop mark (0x03) to indicate calculation end
Arto Kinnunen172836a2019-11-28 13:34:13 +0200532 *
Arto Kinnunen6ce49882019-12-03 13:56:06 +0200533 * Return Number of additional AES rounds
534 *
535 * Example of the control bytes:
Arto Kinnunen17540ab2020-01-20 11:46:34 +0200536 * R = real data in actual AES calculation round
537 * Ri = Real data in initial round key addition phase
538 * F = fake data in actual AES calculation round
539 * Fi = fake data in initial round key addition phase
540 *
Arto Kinnunen2eb678f2020-01-13 16:44:13 +0200541 * 1. No countermeasures enabled and AES-128, only real data (R) used:
542 * | Ri | R | R | R | R | R | R | R | R | R | R |
543 * |0x03|0x04|0x00|0x04|0x00|0x04|0x00|0x04|0x00|0x07|0x03|
Arto Kinnunenf44f7d42019-12-04 15:19:50 +0200544 *
Arto Kinnunen2eb678f2020-01-13 16:44:13 +0200545 * 2. Countermeasures enabled, 3 (F) dummy rounds in start and 1 at end:
Arto Kinnunen17540ab2020-01-20 11:46:34 +0200546 * | Fi | Ri | F | F | F | R | R | ... | R | R | R | R | F |
547 * |0x10|0x03|0x10|0x10|0x10|0x04|0x00| ... |0x04|0x00|0x04|0x03|0x07|
Arto Kinnunen172836a2019-11-28 13:34:13 +0200548 */
Arto Kinnunen311ab592020-01-16 17:20:51 +0200549#if defined(MBEDTLS_AES_SCA_COUNTERMEASURES)
Arto Kinnunen6ce49882019-12-03 13:56:06 +0200550static int aes_sca_cm_data_randomize( uint8_t *tbl, uint8_t tbl_len )
Arto Kinnunen172836a2019-11-28 13:34:13 +0200551{
Arto Kinnunen311ab592020-01-16 17:20:51 +0200552 int i = 0, j, is_even_pos, dummy_rounds, num;
Arto Kinnunen172836a2019-11-28 13:34:13 +0200553
Jarno Lamsa8f8c0bd2020-01-08 15:07:41 +0200554 mbedtls_platform_memset( tbl, 0, tbl_len );
Arto Kinnunen17540ab2020-01-20 11:46:34 +0200555 // get random from 0x0fff (each f will be used separately)
Arto Kinnunen2b24f422020-01-16 15:04:11 +0200556 num = mbedtls_platform_random_in_range( 0x1000 );
Arto Kinnunen2eb678f2020-01-13 16:44:13 +0200557
558 // Randomize execution order of initial round key addition
Arto Kinnunen2b24f422020-01-16 15:04:11 +0200559 if ( ( num & 0x0100 ) == 0 )
Arto Kinnunen172836a2019-11-28 13:34:13 +0200560 {
Arto Kinnunen2eb678f2020-01-13 16:44:13 +0200561 tbl[i++] = 0x10; // dummy data
562 tbl[i++] = 0x00 | 0x03; // real data + stop marker
563 } else {
564 tbl[i++] = 0x00; // real data
565 tbl[i++] = 0x10 | 0x03; // dummy data + stop marker
Arto Kinnunen172836a2019-11-28 13:34:13 +0200566 }
567
Arto Kinnunen2b24f422020-01-16 15:04:11 +0200568 // Randomize number of dummy AES rounds
Arto Kinnunen17540ab2020-01-20 11:46:34 +0200569 dummy_rounds = AES_SCA_CM_ROUNDS - ( ( num & 0x0010 ) >> 4 );
Arto Kinnunen98c93af2020-01-14 13:31:03 +0200570 tbl_len = tbl_len - (AES_SCA_CM_ROUNDS - dummy_rounds);
Arto Kinnunen2eb678f2020-01-13 16:44:13 +0200571
Arto Kinnunen2b24f422020-01-16 15:04:11 +0200572 // randomize positions for the dummy rounds
Arto Kinnunen17540ab2020-01-20 11:46:34 +0200573 num = ( num & 0x000f ) % ( dummy_rounds + 1 );
Arto Kinnunen2b24f422020-01-16 15:04:11 +0200574
575 // add dummy rounds after initial round key addition (if needed)
Arto Kinnunen2eb678f2020-01-13 16:44:13 +0200576 for ( ; i < num + 2; i++ )
Arto Kinnunen172836a2019-11-28 13:34:13 +0200577 {
Arto Kinnunen2eb678f2020-01-13 16:44:13 +0200578 tbl[i] = 0x10; // dummy data
Arto Kinnunen172836a2019-11-28 13:34:13 +0200579 }
Arto Kinnunen2eb678f2020-01-13 16:44:13 +0200580
Arto Kinnunen2b24f422020-01-16 15:04:11 +0200581 // add dummy rounds to the end, (AES_SCA_CM_ROUNDS - num) rounds if needed
Arto Kinnunen98c93af2020-01-14 13:31:03 +0200582 for ( j = tbl_len - dummy_rounds + num; j < tbl_len; j++ )
Arto Kinnunen2eb678f2020-01-13 16:44:13 +0200583 {
584 tbl[j] = 0x10; // dummy data
585 }
Arto Kinnunen172836a2019-11-28 13:34:13 +0200586
Arto Kinnunen2eb678f2020-01-13 16:44:13 +0200587 // Fill real AES data to the remaining places
Arto Kinnunen172836a2019-11-28 13:34:13 +0200588 is_even_pos = 1;
Arto Kinnunen2eb678f2020-01-13 16:44:13 +0200589 for( ; i < tbl_len; i++ )
Arto Kinnunen172836a2019-11-28 13:34:13 +0200590 {
Arto Kinnunen75439012019-12-03 14:12:10 +0200591 if( tbl[i] == 0 )
Arto Kinnunen172836a2019-11-28 13:34:13 +0200592 {
Arto Kinnunen75439012019-12-03 14:12:10 +0200593 if( is_even_pos == 1 )
Arto Kinnunen172836a2019-11-28 13:34:13 +0200594 {
Arto Kinnunen2eb678f2020-01-13 16:44:13 +0200595 tbl[i] = 0x04; // real data, offset for rounds 1,3,5, etc...
Arto Kinnunen172836a2019-11-28 13:34:13 +0200596 is_even_pos = 0;
597 }
598 else
599 {
Arto Kinnunen2eb678f2020-01-13 16:44:13 +0200600 tbl[i] = 0x00; // real data, offset for rounds 2,4,6,...
Arto Kinnunen172836a2019-11-28 13:34:13 +0200601 is_even_pos = 1;
602 }
Arto Kinnunen2eb678f2020-01-13 16:44:13 +0200603 j = i; // remember the final round position in table
Arto Kinnunen172836a2019-11-28 13:34:13 +0200604 }
605 }
Arto Kinnunen6ce49882019-12-03 13:56:06 +0200606
Arto Kinnunen2eb678f2020-01-13 16:44:13 +0200607 tbl[( tbl_len - 1)] |= 0x03; // Stop marker for the last item in tbl
608 tbl[( j - 1 )] |= 0x03; // stop marker for final - 1 real data
609
Arto Kinnunen98c93af2020-01-14 13:31:03 +0200610 return( dummy_rounds );
Arto Kinnunen172836a2019-11-28 13:34:13 +0200611}
Arto Kinnunen17540ab2020-01-20 11:46:34 +0200612#endif /* MBEDTLS_AES_SCA_COUNTERMEASURES */
Arto Kinnunen172836a2019-11-28 13:34:13 +0200613
Hanno Beckerad049a92017-06-19 16:31:54 +0100614#if defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200615
616#define ROTL8(x) ( (uint32_t)( ( x ) << 8 ) + (uint32_t)( ( x ) >> 24 ) )
617#define ROTL16(x) ( (uint32_t)( ( x ) << 16 ) + (uint32_t)( ( x ) >> 16 ) )
618#define ROTL24(x) ( (uint32_t)( ( x ) << 24 ) + (uint32_t)( ( x ) >> 8 ) )
619
620#define AES_RT0(idx) RT0[idx]
621#define AES_RT1(idx) ROTL8( RT0[idx] )
622#define AES_RT2(idx) ROTL16( RT0[idx] )
623#define AES_RT3(idx) ROTL24( RT0[idx] )
624
625#define AES_FT0(idx) FT0[idx]
626#define AES_FT1(idx) ROTL8( FT0[idx] )
627#define AES_FT2(idx) ROTL16( FT0[idx] )
628#define AES_FT3(idx) ROTL24( FT0[idx] )
629
Hanno Becker177d3cf2017-06-07 15:52:48 +0100630#else /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200631
632#define AES_RT0(idx) RT0[idx]
633#define AES_RT1(idx) RT1[idx]
634#define AES_RT2(idx) RT2[idx]
635#define AES_RT3(idx) RT3[idx]
636
637#define AES_FT0(idx) FT0[idx]
638#define AES_FT1(idx) FT1[idx]
639#define AES_FT2(idx) FT2[idx]
640#define AES_FT3(idx) FT3[idx]
641
Hanno Becker177d3cf2017-06-07 15:52:48 +0100642#endif /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200643
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200644void mbedtls_aes_init( mbedtls_aes_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200645{
Manuel Pégourié-Gonnard0e9cddb2018-12-10 16:37:51 +0100646 AES_VALIDATE( ctx != NULL );
Simon Butcher5201e412018-12-06 17:40:14 +0000647
Manuel Pégourié-Gonnard99419332019-10-03 10:40:57 +0200648 memset( ctx, 0, sizeof( mbedtls_aes_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200649}
650
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200651void mbedtls_aes_free( mbedtls_aes_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200652{
653 if( ctx == NULL )
654 return;
655
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500656 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_aes_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200657}
658
Jaeden Amero9366feb2018-05-29 18:55:17 +0100659#if defined(MBEDTLS_CIPHER_MODE_XTS)
660void mbedtls_aes_xts_init( mbedtls_aes_xts_context *ctx )
661{
Manuel Pégourié-Gonnard0e9cddb2018-12-10 16:37:51 +0100662 AES_VALIDATE( ctx != NULL );
Simon Butcher5201e412018-12-06 17:40:14 +0000663
Jaeden Amero9366feb2018-05-29 18:55:17 +0100664 mbedtls_aes_init( &ctx->crypt );
665 mbedtls_aes_init( &ctx->tweak );
666}
667
668void mbedtls_aes_xts_free( mbedtls_aes_xts_context *ctx )
669{
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100670 if( ctx == NULL )
671 return;
Simon Butcher5201e412018-12-06 17:40:14 +0000672
Jaeden Amero9366feb2018-05-29 18:55:17 +0100673 mbedtls_aes_free( &ctx->crypt );
674 mbedtls_aes_free( &ctx->tweak );
675}
676#endif /* MBEDTLS_CIPHER_MODE_XTS */
677
Paul Bakker5121ce52009-01-03 21:22:43 +0000678/*
679 * AES key schedule (encryption)
680 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200681#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200682int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key,
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200683 unsigned int keybits )
Paul Bakker5121ce52009-01-03 21:22:43 +0000684{
Arto Kinnunen6ce49882019-12-03 13:56:06 +0200685 unsigned int j = 0;
Jarno Lamsa282db8e2020-01-08 14:53:17 +0200686 unsigned int flow_ctrl = 0;
Arto Kinnunen6ce49882019-12-03 13:56:06 +0200687 volatile unsigned int i = 0;
688 volatile int ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000689 uint32_t *RK;
Jarno Lamsa282db8e2020-01-08 14:53:17 +0200690 uint32_t offset = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000691
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100692 AES_VALIDATE_RET( ctx != NULL );
693 AES_VALIDATE_RET( key != NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000694
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200695 switch( keybits )
Paul Bakker5121ce52009-01-03 21:22:43 +0000696 {
697 case 128: ctx->nr = 10; break;
Arto Kinnunen77b9cfc2019-08-30 11:43:21 +0300698#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000699 case 192: ctx->nr = 12; break;
700 case 256: ctx->nr = 14; break;
Arto Kinnunen77b9cfc2019-08-30 11:43:21 +0300701#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200702 default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000703 }
704
Simon Butcher5201e412018-12-06 17:40:14 +0000705#if !defined(MBEDTLS_AES_ROM_TABLES)
706 if( aes_init_done == 0 )
707 {
708 aes_gen_tables();
709 aes_init_done = 1;
Simon Butcher5201e412018-12-06 17:40:14 +0000710 }
711#endif
712
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200713#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_PADLOCK_ALIGN16)
Paul Bakker048d04e2012-02-12 17:31:04 +0000714 if( aes_padlock_ace == -1 )
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100715 aes_padlock_ace = mbedtls_padlock_has_support( MBEDTLS_PADLOCK_ACE );
Paul Bakker048d04e2012-02-12 17:31:04 +0000716
717 if( aes_padlock_ace )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200718 ctx->rk = RK = MBEDTLS_PADLOCK_ALIGN16( ctx->buf );
Paul Bakker048d04e2012-02-12 17:31:04 +0000719 else
Paul Bakker5121ce52009-01-03 21:22:43 +0000720#endif
Paul Bakker048d04e2012-02-12 17:31:04 +0000721 ctx->rk = RK = ctx->buf;
Paul Bakker5121ce52009-01-03 21:22:43 +0000722
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200723#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100724 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) )
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200725 return( mbedtls_aesni_setkey_enc( (unsigned char *) ctx->rk, key, keybits ) );
Manuel Pégourié-Gonnard47a35362013-12-28 20:45:04 +0100726#endif
727
Jarno Lamsa282db8e2020-01-08 14:53:17 +0200728 mbedtls_platform_memset( RK, 0, ( keybits >> 5 ) * 4 );
729 offset = mbedtls_platform_random_in_range( keybits >> 5 );
730
731 for( j = offset; j < ( keybits >> 5 ); j++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000732 {
Arto Kinnunen6ce49882019-12-03 13:56:06 +0200733 GET_UINT32_LE( RK[j], key, j << 2 );
Jarno Lamsa282db8e2020-01-08 14:53:17 +0200734 flow_ctrl++;
735 }
736
737 for( j = 0; j < offset; j++ )
738 {
739 GET_UINT32_LE( RK[j], key, j << 2 );
740 flow_ctrl++;
Paul Bakker5121ce52009-01-03 21:22:43 +0000741 }
742
743 switch( ctx->nr )
744 {
745 case 10:
746
747 for( i = 0; i < 10; i++, RK += 4 )
748 {
749 RK[4] = RK[0] ^ RCON[i] ^
Paul Bakker5c2364c2012-10-01 14:41:15 +0000750 ( (uint32_t) FSb[ ( RK[3] >> 8 ) & 0xFF ] ) ^
751 ( (uint32_t) FSb[ ( RK[3] >> 16 ) & 0xFF ] << 8 ) ^
752 ( (uint32_t) FSb[ ( RK[3] >> 24 ) & 0xFF ] << 16 ) ^
753 ( (uint32_t) FSb[ ( RK[3] ) & 0xFF ] << 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000754
755 RK[5] = RK[1] ^ RK[4];
756 RK[6] = RK[2] ^ RK[5];
757 RK[7] = RK[3] ^ RK[6];
758 }
759 break;
Arto Kinnunen77b9cfc2019-08-30 11:43:21 +0300760#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000761 case 12:
762
763 for( i = 0; i < 8; i++, RK += 6 )
764 {
765 RK[6] = RK[0] ^ RCON[i] ^
Paul Bakker5c2364c2012-10-01 14:41:15 +0000766 ( (uint32_t) FSb[ ( RK[5] >> 8 ) & 0xFF ] ) ^
767 ( (uint32_t) FSb[ ( RK[5] >> 16 ) & 0xFF ] << 8 ) ^
768 ( (uint32_t) FSb[ ( RK[5] >> 24 ) & 0xFF ] << 16 ) ^
769 ( (uint32_t) FSb[ ( RK[5] ) & 0xFF ] << 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000770
771 RK[7] = RK[1] ^ RK[6];
772 RK[8] = RK[2] ^ RK[7];
773 RK[9] = RK[3] ^ RK[8];
774 RK[10] = RK[4] ^ RK[9];
775 RK[11] = RK[5] ^ RK[10];
776 }
777 break;
778
779 case 14:
780
781 for( i = 0; i < 7; i++, RK += 8 )
782 {
783 RK[8] = RK[0] ^ RCON[i] ^
Paul Bakker5c2364c2012-10-01 14:41:15 +0000784 ( (uint32_t) FSb[ ( RK[7] >> 8 ) & 0xFF ] ) ^
785 ( (uint32_t) FSb[ ( RK[7] >> 16 ) & 0xFF ] << 8 ) ^
786 ( (uint32_t) FSb[ ( RK[7] >> 24 ) & 0xFF ] << 16 ) ^
787 ( (uint32_t) FSb[ ( RK[7] ) & 0xFF ] << 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000788
789 RK[9] = RK[1] ^ RK[8];
790 RK[10] = RK[2] ^ RK[9];
791 RK[11] = RK[3] ^ RK[10];
792
793 RK[12] = RK[4] ^
Paul Bakker5c2364c2012-10-01 14:41:15 +0000794 ( (uint32_t) FSb[ ( RK[11] ) & 0xFF ] ) ^
795 ( (uint32_t) FSb[ ( RK[11] >> 8 ) & 0xFF ] << 8 ) ^
796 ( (uint32_t) FSb[ ( RK[11] >> 16 ) & 0xFF ] << 16 ) ^
797 ( (uint32_t) FSb[ ( RK[11] >> 24 ) & 0xFF ] << 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000798
799 RK[13] = RK[5] ^ RK[12];
800 RK[14] = RK[6] ^ RK[13];
801 RK[15] = RK[7] ^ RK[14];
802 }
803 break;
Arto Kinnunen77b9cfc2019-08-30 11:43:21 +0300804#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Paul Bakker5121ce52009-01-03 21:22:43 +0000805 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000806
Arto Kinnunen6ce49882019-12-03 13:56:06 +0200807 ret = 0;
808
809 /* Validate execution path */
Jarno Lamsa282db8e2020-01-08 14:53:17 +0200810 if( ( flow_ctrl == keybits >> 5 ) && ( ( ctx->nr == 10 && i == 10 )
Arto Kinnunen6ce49882019-12-03 13:56:06 +0200811#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
812 || ( ctx->nr == 12 && i == 8 )
813 || ( ctx->nr == 14 && i == 7 )
814#endif
815 ) )
816 {
Andrzej Kurekafec8852020-07-15 16:31:27 -0400817 return ret;
Arto Kinnunen6ce49882019-12-03 13:56:06 +0200818 }
819
Andrzej Kurekca609372020-07-08 03:19:02 -0400820 mbedtls_platform_memset( RK, 0, ( keybits >> 5 ) * 4 );
Arto Kinnunen6ce49882019-12-03 13:56:06 +0200821 return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000822}
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200823#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000824
825/*
826 * AES key schedule (decryption)
827 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200828#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200829int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key,
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200830 unsigned int keybits )
Paul Bakker5121ce52009-01-03 21:22:43 +0000831{
Arto Kinnunen14804442019-10-16 13:43:59 +0300832#if defined(MBEDTLS_AES_ONLY_ENCRYPT)
833 (void) ctx;
834 (void) key;
835 (void) keybits;
836
837 return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
838#else /* */
Arto Kinnunen6ce49882019-12-03 13:56:06 +0200839 volatile unsigned int i = 0, j = 0;
840 volatile int ret = MBEDTLS_ERR_PLATFORM_FAULT_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200841 mbedtls_aes_context cty;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000842 uint32_t *RK;
843 uint32_t *SK;
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200844
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100845 AES_VALIDATE_RET( ctx != NULL );
846 AES_VALIDATE_RET( key != NULL );
Simon Butcher5201e412018-12-06 17:40:14 +0000847
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200848 mbedtls_aes_init( &cty );
Paul Bakker5121ce52009-01-03 21:22:43 +0000849
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200850#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_PADLOCK_ALIGN16)
Paul Bakker048d04e2012-02-12 17:31:04 +0000851 if( aes_padlock_ace == -1 )
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100852 aes_padlock_ace = mbedtls_padlock_has_support( MBEDTLS_PADLOCK_ACE );
Paul Bakker048d04e2012-02-12 17:31:04 +0000853
854 if( aes_padlock_ace )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200855 ctx->rk = RK = MBEDTLS_PADLOCK_ALIGN16( ctx->buf );
Paul Bakker048d04e2012-02-12 17:31:04 +0000856 else
Paul Bakker5121ce52009-01-03 21:22:43 +0000857#endif
Paul Bakker048d04e2012-02-12 17:31:04 +0000858 ctx->rk = RK = ctx->buf;
Paul Bakker5121ce52009-01-03 21:22:43 +0000859
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200860 /* Also checks keybits */
861 if( ( ret = mbedtls_aes_setkey_enc( &cty, key, keybits ) ) != 0 )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200862 goto exit;
Paul Bakker2b222c82009-07-27 21:03:45 +0000863
Manuel Pégourié-Gonnardafd5a082014-05-28 21:52:59 +0200864 ctx->nr = cty.nr;
865
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200866#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100867 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) )
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100868 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200869 mbedtls_aesni_inverse_key( (unsigned char *) ctx->rk,
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100870 (const unsigned char *) cty.rk, ctx->nr );
Arto Kinnunen6ce49882019-12-03 13:56:06 +0200871 i = 0;
872 j = 4;
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200873 goto exit;
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100874 }
875#endif
876
Paul Bakker5121ce52009-01-03 21:22:43 +0000877 SK = cty.rk + cty.nr * 4;
878
879 *RK++ = *SK++;
880 *RK++ = *SK++;
881 *RK++ = *SK++;
882 *RK++ = *SK++;
883
884 for( i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8 )
885 {
886 for( j = 0; j < 4; j++, SK++ )
887 {
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200888 *RK++ = AES_RT0( FSb[ ( *SK ) & 0xFF ] ) ^
889 AES_RT1( FSb[ ( *SK >> 8 ) & 0xFF ] ) ^
890 AES_RT2( FSb[ ( *SK >> 16 ) & 0xFF ] ) ^
891 AES_RT3( FSb[ ( *SK >> 24 ) & 0xFF ] );
Paul Bakker5121ce52009-01-03 21:22:43 +0000892 }
893 }
894
895 *RK++ = *SK++;
896 *RK++ = *SK++;
897 *RK++ = *SK++;
898 *RK++ = *SK++;
899
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200900exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200901 mbedtls_aes_free( &cty );
Paul Bakker2b222c82009-07-27 21:03:45 +0000902
Arto Kinnunen6ce49882019-12-03 13:56:06 +0200903 if( ret != 0 )
904 {
905 return( ret );
906 }
907 else if( ( i == 0 ) && ( j == 4 ) )
908 {
909 return( ret );
910 }
911 else
912 {
913 return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
914 }
915
Arto Kinnunen14804442019-10-16 13:43:59 +0300916#endif /* MBEDTLS_AES_ONLY_ENCRYPT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000917}
Jaeden Amero9366feb2018-05-29 18:55:17 +0100918
919#if defined(MBEDTLS_CIPHER_MODE_XTS)
920static int mbedtls_aes_xts_decode_keys( const unsigned char *key,
921 unsigned int keybits,
922 const unsigned char **key1,
923 unsigned int *key1bits,
924 const unsigned char **key2,
925 unsigned int *key2bits )
926{
927 const unsigned int half_keybits = keybits / 2;
928 const unsigned int half_keybytes = half_keybits / 8;
929
930 switch( keybits )
931 {
932 case 256: break;
933 case 512: break;
934 default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH );
935 }
936
937 *key1bits = half_keybits;
938 *key2bits = half_keybits;
939 *key1 = &key[0];
940 *key2 = &key[half_keybytes];
941
942 return 0;
943}
944
945int mbedtls_aes_xts_setkey_enc( mbedtls_aes_xts_context *ctx,
946 const unsigned char *key,
947 unsigned int keybits)
948{
949 int ret;
950 const unsigned char *key1, *key2;
951 unsigned int key1bits, key2bits;
952
Manuel Pégourié-Gonnard68e3dff2018-12-12 12:48:04 +0100953 AES_VALIDATE_RET( ctx != NULL );
954 AES_VALIDATE_RET( key != NULL );
955
Jaeden Amero9366feb2018-05-29 18:55:17 +0100956 ret = mbedtls_aes_xts_decode_keys( key, keybits, &key1, &key1bits,
957 &key2, &key2bits );
958 if( ret != 0 )
959 return( ret );
960
961 /* Set the tweak key. Always set tweak key for the encryption mode. */
962 ret = mbedtls_aes_setkey_enc( &ctx->tweak, key2, key2bits );
963 if( ret != 0 )
964 return( ret );
965
966 /* Set crypt key for encryption. */
967 return mbedtls_aes_setkey_enc( &ctx->crypt, key1, key1bits );
968}
969
970int mbedtls_aes_xts_setkey_dec( mbedtls_aes_xts_context *ctx,
971 const unsigned char *key,
972 unsigned int keybits)
973{
974 int ret;
975 const unsigned char *key1, *key2;
976 unsigned int key1bits, key2bits;
977
Manuel Pégourié-Gonnard68e3dff2018-12-12 12:48:04 +0100978 AES_VALIDATE_RET( ctx != NULL );
979 AES_VALIDATE_RET( key != NULL );
980
Jaeden Amero9366feb2018-05-29 18:55:17 +0100981 ret = mbedtls_aes_xts_decode_keys( key, keybits, &key1, &key1bits,
982 &key2, &key2bits );
983 if( ret != 0 )
984 return( ret );
985
986 /* Set the tweak key. Always set tweak key for encryption. */
987 ret = mbedtls_aes_setkey_enc( &ctx->tweak, key2, key2bits );
988 if( ret != 0 )
989 return( ret );
990
991 /* Set crypt key for decryption. */
992 return mbedtls_aes_setkey_dec( &ctx->crypt, key1, key1bits );
993}
994#endif /* MBEDTLS_CIPHER_MODE_XTS */
995
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200996#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000997
Paul Bakker5121ce52009-01-03 21:22:43 +0000998/*
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200999 * AES-ECB block encryption
1000 */
1001#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Arto Kinnunenc3532c22019-11-29 15:07:11 +02001002
Arto Kinnunen311ab592020-01-16 17:20:51 +02001003#if defined(MBEDTLS_AES_SCA_COUNTERMEASURES)
Arto Kinnunenc3532c22019-11-29 15:07:11 +02001004static uint32_t *aes_fround( uint32_t *R,
1005 uint32_t *X0, uint32_t *X1, uint32_t *X2, uint32_t *X3,
1006 uint32_t Y0, uint32_t Y1, uint32_t Y2, uint32_t Y3 )
1007{
1008 *X0 = *R++ ^ AES_FT0( ( Y0 ) & 0xFF ) ^
1009 AES_FT1( ( Y1 >> 8 ) & 0xFF ) ^
1010 AES_FT2( ( Y2 >> 16 ) & 0xFF ) ^
1011 AES_FT3( ( Y3 >> 24 ) & 0xFF );
1012
1013 *X1 = *R++ ^ AES_FT0( ( Y1 ) & 0xFF ) ^
1014 AES_FT1( ( Y2 >> 8 ) & 0xFF ) ^
1015 AES_FT2( ( Y3 >> 16 ) & 0xFF ) ^
1016 AES_FT3( ( Y0 >> 24 ) & 0xFF );
1017
1018 *X2 = *R++ ^ AES_FT0( ( Y2 ) & 0xFF ) ^
1019 AES_FT1( ( Y3 >> 8 ) & 0xFF ) ^
1020 AES_FT2( ( Y0 >> 16 ) & 0xFF ) ^
1021 AES_FT3( ( Y1 >> 24 ) & 0xFF );
1022
1023 *X3 = *R++ ^ AES_FT0( ( Y3 ) & 0xFF ) ^
1024 AES_FT1( ( Y0 >> 8 ) & 0xFF ) ^
1025 AES_FT2( ( Y1 >> 16 ) & 0xFF ) ^
1026 AES_FT3( ( Y2 >> 24 ) & 0xFF );
1027
1028 return R;
1029}
1030
1031static void aes_fround_final( uint32_t *R,
1032 uint32_t *X0, uint32_t *X1, uint32_t *X2, uint32_t *X3,
1033 uint32_t Y0, uint32_t Y1, uint32_t Y2, uint32_t Y3 )
1034{
1035 *X0 = *R++ ^ ( (uint32_t) FSb[ ( (Y0) ) & 0xFF ] ) ^
1036 ( (uint32_t) FSb[ ( (Y1) >> 8 ) & 0xFF ] << 8 ) ^
1037 ( (uint32_t) FSb[ ( (Y2) >> 16 ) & 0xFF ] << 16 ) ^
1038 ( (uint32_t) FSb[ ( (Y3) >> 24 ) & 0xFF ] << 24 );
1039
1040 *X1 = *R++ ^ ( (uint32_t) FSb[ ( (Y1) ) & 0xFF ] ) ^
1041 ( (uint32_t) FSb[ ( (Y2) >> 8 ) & 0xFF ] << 8 ) ^
1042 ( (uint32_t) FSb[ ( (Y3) >> 16 ) & 0xFF ] << 16 ) ^
1043 ( (uint32_t) FSb[ ( (Y0) >> 24 ) & 0xFF ] << 24 );
1044
1045 *X2 = *R++ ^ ( (uint32_t) FSb[ ( (Y2) ) & 0xFF ] ) ^
1046 ( (uint32_t) FSb[ ( (Y3) >> 8 ) & 0xFF ] << 8 ) ^
1047 ( (uint32_t) FSb[ ( (Y0) >> 16 ) & 0xFF ] << 16 ) ^
1048 ( (uint32_t) FSb[ ( (Y1) >> 24 ) & 0xFF ] << 24 );
1049
1050 *X3 = *R++ ^ ( (uint32_t) FSb[ ( (Y3) ) & 0xFF ] ) ^
1051 ( (uint32_t) FSb[ ( (Y0) >> 8 ) & 0xFF ] << 8 ) ^
1052 ( (uint32_t) FSb[ ( (Y1) >> 16 ) & 0xFF ] << 16 ) ^
1053 ( (uint32_t) FSb[ ( (Y2) >> 24 ) & 0xFF ] << 24 );
1054}
1055
Andres AGf5bf7182017-03-03 14:09:56 +00001056int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx,
1057 const unsigned char input[16],
1058 unsigned char output[16] )
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001059{
Arto Kinnunen98c93af2020-01-14 13:31:03 +02001060 int i, tindex, offset, stop_mark, dummy_rounds;
Arto Kinnunen172836a2019-11-28 13:34:13 +02001061 aes_r_data_t aes_data_real; // real data
Arto Kinnunen172836a2019-11-28 13:34:13 +02001062 aes_r_data_t aes_data_fake; // fake data
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001063 aes_r_data_t *aes_data_ptr; // pointer to real or fake data
Arto Kinnunen172836a2019-11-28 13:34:13 +02001064 aes_r_data_t *aes_data_table[2]; // pointers to real and fake data
Arto Kinnunen311ab592020-01-16 17:20:51 +02001065 int round_ctrl_table_len = ctx->nr + 2 + AES_SCA_CM_ROUNDS;
Arto Kinnunen6ce49882019-12-03 13:56:06 +02001066 volatile int flow_control;
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001067 // control bytes for AES calculation rounds,
1068 // reserve based on max rounds + dummy rounds + 2 (for initial key addition)
1069 uint8_t round_ctrl_table[( 14 + AES_SCA_CM_ROUNDS + 2 )];
Arto Kinnunenf93d55e2019-10-11 11:15:57 +03001070
Arto Kinnunen172836a2019-11-28 13:34:13 +02001071 aes_data_real.rk_ptr = ctx->rk;
Arto Kinnunen172836a2019-11-28 13:34:13 +02001072 aes_data_fake.rk_ptr = ctx->rk;
Arto Kinnunen311ab592020-01-16 17:20:51 +02001073 aes_data_table[0] = &aes_data_real;
1074 aes_data_table[1] = &aes_data_fake;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001075
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001076 // Get AES calculation control bytes
Arto Kinnunen2b24f422020-01-16 15:04:11 +02001077 dummy_rounds = aes_sca_cm_data_randomize( round_ctrl_table,
1078 round_ctrl_table_len );
Arto Kinnunen98c93af2020-01-14 13:31:03 +02001079 flow_control = dummy_rounds;
Arto Kinnunen172836a2019-11-28 13:34:13 +02001080
Arto Kinnunen17540ab2020-01-20 11:46:34 +02001081 // SCA countermeasure, safely clear the aes_data_real.xy_values
Jarno Lamsa282db8e2020-01-08 14:53:17 +02001082 mbedtls_platform_memset( aes_data_real.xy_values, 0, 16 );
Jarno Lamsa282db8e2020-01-08 14:53:17 +02001083
Arto Kinnunen17540ab2020-01-20 11:46:34 +02001084 // SCA countermeasure, randomize secret data location by initializing it in
1085 // a random order and writing randomized fake data between the real data
1086 // writes.
1087 offset = mbedtls_platform_random_in_range( 4 );
Arto Kinnunen2b24f422020-01-16 15:04:11 +02001088 i = offset;
1089 do
Arto Kinnunen172836a2019-11-28 13:34:13 +02001090 {
1091 GET_UINT32_LE( aes_data_real.xy_values[i], input, ( i * 4 ) );
Arto Kinnunen311ab592020-01-16 17:20:51 +02001092 aes_data_fake.xy_values[i] = mbedtls_platform_random_in_range( 0xffffffff );
Arto Kinnunen2b24f422020-01-16 15:04:11 +02001093 flow_control++;
1094 } while( ( i = ( i + 1 ) % 4 ) != offset );
Jarno Lamsa282db8e2020-01-08 14:53:17 +02001095
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001096 tindex = 0;
1097 do
Jarno Lamsa282db8e2020-01-08 14:53:17 +02001098 {
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001099 // Get pointer to the real or fake data
1100 aes_data_ptr = aes_data_table[round_ctrl_table[tindex] >> 4];
1101 stop_mark = round_ctrl_table[tindex] & 0x03;
Arto Kinnunen172836a2019-11-28 13:34:13 +02001102
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001103 // initial round key addition
1104 for( i = 0; i < 4; i++ )
1105 {
1106 aes_data_ptr->xy_values[i] ^= *aes_data_ptr->rk_ptr++;
1107 }
1108 tindex++;
1109 flow_control++;
1110 } while( stop_mark == 0 );
1111
1112 // Calculate AES rounds (9, 11 or 13 rounds) + dummy rounds
1113 do
Arto Kinnunen172836a2019-11-28 13:34:13 +02001114 {
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001115 // Get pointer to the real or fake data
1116 aes_data_ptr = aes_data_table[round_ctrl_table[tindex] >> 4];
1117 offset = round_ctrl_table[tindex] & 0x04;
1118 stop_mark = round_ctrl_table[tindex] & 0x03;
Arto Kinnunen172836a2019-11-28 13:34:13 +02001119
Arto Kinnunenc3532c22019-11-29 15:07:11 +02001120 aes_data_ptr->rk_ptr = aes_fround( aes_data_ptr->rk_ptr,
1121 &aes_data_ptr->xy_values[0 + offset],
1122 &aes_data_ptr->xy_values[1 + offset],
1123 &aes_data_ptr->xy_values[2 + offset],
1124 &aes_data_ptr->xy_values[3 + offset],
Arto Kinnunen172836a2019-11-28 13:34:13 +02001125 aes_data_ptr->xy_values[4 - offset],
1126 aes_data_ptr->xy_values[5 - offset],
1127 aes_data_ptr->xy_values[6 - offset],
1128 aes_data_ptr->xy_values[7 - offset] );
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001129 tindex++;
Arto Kinnunen6ce49882019-12-03 13:56:06 +02001130 flow_control++;
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001131 } while( stop_mark == 0 );
Arto Kinnunen172836a2019-11-28 13:34:13 +02001132
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001133 // Calculate final AES round + dummy rounds
1134 do
Arto Kinnunen172836a2019-11-28 13:34:13 +02001135 {
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001136 aes_data_ptr = aes_data_table[round_ctrl_table[tindex] >> 4];
1137 stop_mark = round_ctrl_table[tindex] & 0x03;
Arto Kinnunenc3532c22019-11-29 15:07:11 +02001138 aes_fround_final( aes_data_ptr->rk_ptr,
1139 &aes_data_ptr->xy_values[0],
1140 &aes_data_ptr->xy_values[1],
1141 &aes_data_ptr->xy_values[2],
1142 &aes_data_ptr->xy_values[3],
Arto Kinnunen172836a2019-11-28 13:34:13 +02001143 aes_data_ptr->xy_values[4],
1144 aes_data_ptr->xy_values[5],
1145 aes_data_ptr->xy_values[6],
1146 aes_data_ptr->xy_values[7] );
Arto Kinnunen6ce49882019-12-03 13:56:06 +02001147 flow_control++;
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001148 tindex++;
1149 } while( stop_mark == 0 );
Arto Kinnunen172836a2019-11-28 13:34:13 +02001150
Arto Kinnunen17540ab2020-01-20 11:46:34 +02001151 // SCA countermeasure, safely clear the output
Jarno Lamsa282db8e2020-01-08 14:53:17 +02001152 mbedtls_platform_memset( output, 0, 16 );
Jarno Lamsa282db8e2020-01-08 14:53:17 +02001153
Arto Kinnunen17540ab2020-01-20 11:46:34 +02001154 // SCA countermeasure, randomize secret data location by writing to it in
1155 // a random order.
1156 offset = mbedtls_platform_random_in_range( 4 );
Arto Kinnunen2b24f422020-01-16 15:04:11 +02001157 i = offset;
1158 do
Jarno Lamsa282db8e2020-01-08 14:53:17 +02001159 {
1160 PUT_UINT32_LE( aes_data_real.xy_values[i], output, ( i * 4 ) );
1161 flow_control++;
Arto Kinnunen2b24f422020-01-16 15:04:11 +02001162 } while( ( i = ( i + 1 ) % 4 ) != offset );
Jarno Lamsa282db8e2020-01-08 14:53:17 +02001163
Arto Kinnunen2b24f422020-01-16 15:04:11 +02001164 if( flow_control == tindex + dummy_rounds + 8 )
Arto Kinnunen6ce49882019-12-03 13:56:06 +02001165 {
Andrzej Kurekafec8852020-07-15 16:31:27 -04001166 return 0;
Arto Kinnunen6ce49882019-12-03 13:56:06 +02001167 }
1168
Andrzej Kurekca609372020-07-08 03:19:02 -04001169 // Clear the output in case of a FI
1170 mbedtls_platform_memset( output, 0, 16 );
Arto Kinnunen6ce49882019-12-03 13:56:06 +02001171 return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001172}
Arto Kinnunen311ab592020-01-16 17:20:51 +02001173
1174#else /* MBEDTLS_AES_SCA_COUNTERMEASURES */
1175
1176#define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \
1177 do \
1178 { \
1179 (X0) = *RK++ ^ AES_FT0( ( (Y0) ) & 0xFF ) ^ \
1180 AES_FT1( ( (Y1) >> 8 ) & 0xFF ) ^ \
1181 AES_FT2( ( (Y2) >> 16 ) & 0xFF ) ^ \
1182 AES_FT3( ( (Y3) >> 24 ) & 0xFF ); \
1183 \
1184 (X1) = *RK++ ^ AES_FT0( ( (Y1) ) & 0xFF ) ^ \
1185 AES_FT1( ( (Y2) >> 8 ) & 0xFF ) ^ \
1186 AES_FT2( ( (Y3) >> 16 ) & 0xFF ) ^ \
1187 AES_FT3( ( (Y0) >> 24 ) & 0xFF ); \
1188 \
1189 (X2) = *RK++ ^ AES_FT0( ( (Y2) ) & 0xFF ) ^ \
1190 AES_FT1( ( (Y3) >> 8 ) & 0xFF ) ^ \
1191 AES_FT2( ( (Y0) >> 16 ) & 0xFF ) ^ \
1192 AES_FT3( ( (Y1) >> 24 ) & 0xFF ); \
1193 \
1194 (X3) = *RK++ ^ AES_FT0( ( (Y3) ) & 0xFF ) ^ \
1195 AES_FT1( ( (Y0) >> 8 ) & 0xFF ) ^ \
1196 AES_FT2( ( (Y1) >> 16 ) & 0xFF ) ^ \
1197 AES_FT3( ( (Y2) >> 24 ) & 0xFF ); \
1198 } while( 0 )
1199
1200int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx,
1201 const unsigned char input[16],
1202 unsigned char output[16] )
1203{
1204 int i;
1205 uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3;
1206
1207 RK = ctx->rk;
1208
1209 GET_UINT32_LE( X0, input, 0 ); X0 ^= *RK++;
1210 GET_UINT32_LE( X1, input, 4 ); X1 ^= *RK++;
1211 GET_UINT32_LE( X2, input, 8 ); X2 ^= *RK++;
1212 GET_UINT32_LE( X3, input, 12 ); X3 ^= *RK++;
1213
1214 for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- )
1215 {
1216 AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
1217 AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 );
1218 }
1219
1220 AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
1221
1222 X0 = *RK++ ^ \
1223 ( (uint32_t) FSb[ ( Y0 ) & 0xFF ] ) ^
1224 ( (uint32_t) FSb[ ( Y1 >> 8 ) & 0xFF ] << 8 ) ^
1225 ( (uint32_t) FSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^
1226 ( (uint32_t) FSb[ ( Y3 >> 24 ) & 0xFF ] << 24 );
1227
1228 X1 = *RK++ ^ \
1229 ( (uint32_t) FSb[ ( Y1 ) & 0xFF ] ) ^
1230 ( (uint32_t) FSb[ ( Y2 >> 8 ) & 0xFF ] << 8 ) ^
1231 ( (uint32_t) FSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^
1232 ( (uint32_t) FSb[ ( Y0 >> 24 ) & 0xFF ] << 24 );
1233
1234 X2 = *RK++ ^ \
1235 ( (uint32_t) FSb[ ( Y2 ) & 0xFF ] ) ^
1236 ( (uint32_t) FSb[ ( Y3 >> 8 ) & 0xFF ] << 8 ) ^
1237 ( (uint32_t) FSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^
1238 ( (uint32_t) FSb[ ( Y1 >> 24 ) & 0xFF ] << 24 );
1239
1240 X3 = *RK++ ^ \
1241 ( (uint32_t) FSb[ ( Y3 ) & 0xFF ] ) ^
1242 ( (uint32_t) FSb[ ( Y0 >> 8 ) & 0xFF ] << 8 ) ^
1243 ( (uint32_t) FSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^
1244 ( (uint32_t) FSb[ ( Y2 >> 24 ) & 0xFF ] << 24 );
1245
1246 PUT_UINT32_LE( X0, output, 0 );
1247 PUT_UINT32_LE( X1, output, 4 );
1248 PUT_UINT32_LE( X2, output, 8 );
1249 PUT_UINT32_LE( X3, output, 12 );
1250
Andrzej Kureka8405442019-11-12 03:34:03 -05001251 mbedtls_platform_zeroize( &X0, sizeof( X0 ) );
1252 mbedtls_platform_zeroize( &X1, sizeof( X1 ) );
1253 mbedtls_platform_zeroize( &X2, sizeof( X2 ) );
1254 mbedtls_platform_zeroize( &X3, sizeof( X3 ) );
1255
1256 mbedtls_platform_zeroize( &Y0, sizeof( Y0 ) );
1257 mbedtls_platform_zeroize( &Y1, sizeof( Y1 ) );
1258 mbedtls_platform_zeroize( &Y2, sizeof( Y2 ) );
1259 mbedtls_platform_zeroize( &Y3, sizeof( Y3 ) );
1260
1261 mbedtls_platform_zeroize( &RK, sizeof( RK ) );
1262
Arto Kinnunen311ab592020-01-16 17:20:51 +02001263 return( 0 );
1264}
1265#endif /* MBEDTLS_AES_SCA_COUNTERMEASURES */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001266#endif /* !MBEDTLS_AES_ENCRYPT_ALT */
1267
Gilles Peskine8db3efb2018-02-21 19:16:20 +01001268#if !defined(MBEDTLS_DEPRECATED_REMOVED)
Hanno Beckerbedc2052017-06-26 12:46:56 +01001269void mbedtls_aes_encrypt( mbedtls_aes_context *ctx,
1270 const unsigned char input[16],
1271 unsigned char output[16] )
1272{
1273 mbedtls_internal_aes_encrypt( ctx, input, output );
1274}
Gilles Peskine8db3efb2018-02-21 19:16:20 +01001275#endif /* !MBEDTLS_DEPRECATED_REMOVED */
Hanno Beckerbedc2052017-06-26 12:46:56 +01001276
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001277/*
1278 * AES-ECB block decryption
1279 */
Arto Kinnunen14804442019-10-16 13:43:59 +03001280
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001281#if !defined(MBEDTLS_AES_DECRYPT_ALT)
Arto Kinnunen14804442019-10-16 13:43:59 +03001282#if !defined(MBEDTLS_AES_ONLY_ENCRYPT)
Arto Kinnunenc3532c22019-11-29 15:07:11 +02001283
Arto Kinnunen311ab592020-01-16 17:20:51 +02001284#if defined(MBEDTLS_AES_SCA_COUNTERMEASURES)
Arto Kinnunenc3532c22019-11-29 15:07:11 +02001285static uint32_t *aes_rround( uint32_t *R,
1286 uint32_t *X0, uint32_t *X1, uint32_t *X2, uint32_t *X3,
1287 uint32_t Y0, uint32_t Y1, uint32_t Y2, uint32_t Y3 )
1288{
1289 *X0 = *R++ ^ AES_RT0( ( Y0 ) & 0xFF ) ^
1290 AES_RT1( ( Y3 >> 8 ) & 0xFF ) ^
1291 AES_RT2( ( Y2 >> 16 ) & 0xFF ) ^
1292 AES_RT3( ( Y1 >> 24 ) & 0xFF );
1293
1294 *X1 = *R++ ^ AES_RT0( ( Y1 ) & 0xFF ) ^
1295 AES_RT1( ( Y0 >> 8 ) & 0xFF ) ^
1296 AES_RT2( ( Y3 >> 16 ) & 0xFF ) ^
1297 AES_RT3( ( Y2 >> 24 ) & 0xFF );
1298
1299 *X2 = *R++ ^ AES_RT0( ( Y2 ) & 0xFF ) ^
1300 AES_RT1( ( Y1 >> 8 ) & 0xFF ) ^
1301 AES_RT2( ( Y0 >> 16 ) & 0xFF ) ^
1302 AES_RT3( ( Y3 >> 24 ) & 0xFF );
1303
1304 *X3 = *R++ ^ AES_RT0( ( Y3 ) & 0xFF ) ^
1305 AES_RT1( ( Y2 >> 8 ) & 0xFF ) ^
1306 AES_RT2( ( Y1 >> 16 ) & 0xFF ) ^
1307 AES_RT3( ( Y0 >> 24 ) & 0xFF );
1308 return R;
1309}
1310
1311static void aes_rround_final( uint32_t *R,
1312 uint32_t *X0, uint32_t *X1, uint32_t *X2, uint32_t *X3,
1313 uint32_t Y0, uint32_t Y1, uint32_t Y2, uint32_t Y3 )
1314{
1315 *X0 = *R++ ^ ( (uint32_t) RSb[ ( (Y0) ) & 0xFF ] ) ^
1316 ( (uint32_t) RSb[ ( (Y3) >> 8 ) & 0xFF ] << 8 ) ^
1317 ( (uint32_t) RSb[ ( (Y2) >> 16 ) & 0xFF ] << 16 ) ^
1318 ( (uint32_t) RSb[ ( (Y1) >> 24 ) & 0xFF ] << 24 );
1319
1320 *X1 = *R++ ^ ( (uint32_t) RSb[ ( (Y1) ) & 0xFF ] ) ^
1321 ( (uint32_t) RSb[ ( (Y0) >> 8 ) & 0xFF ] << 8 ) ^
1322 ( (uint32_t) RSb[ ( (Y3) >> 16 ) & 0xFF ] << 16 ) ^
1323 ( (uint32_t) RSb[ ( (Y2) >> 24 ) & 0xFF ] << 24 );
1324
1325 *X2 = *R++ ^ ( (uint32_t) RSb[ ( (Y2) ) & 0xFF ] ) ^
1326 ( (uint32_t) RSb[ ( (Y1) >> 8 ) & 0xFF ] << 8 ) ^
1327 ( (uint32_t) RSb[ ( (Y0) >> 16 ) & 0xFF ] << 16 ) ^
1328 ( (uint32_t) RSb[ ( (Y3) >> 24 ) & 0xFF ] << 24 );
1329
1330 *X3 = *R++ ^ ( (uint32_t) RSb[ ( (Y3) ) & 0xFF ] ) ^
1331 ( (uint32_t) RSb[ ( (Y2) >> 8 ) & 0xFF ] << 8 ) ^
1332 ( (uint32_t) RSb[ ( (Y1) >> 16 ) & 0xFF ] << 16 ) ^
1333 ( (uint32_t) RSb[ ( (Y0) >> 24 ) & 0xFF ] << 24 );
1334}
1335
Andres AGf5bf7182017-03-03 14:09:56 +00001336int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx,
1337 const unsigned char input[16],
1338 unsigned char output[16] )
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001339{
Arto Kinnunen98c93af2020-01-14 13:31:03 +02001340 int i, tindex, offset, stop_mark, dummy_rounds;
Arto Kinnunen172836a2019-11-28 13:34:13 +02001341 aes_r_data_t aes_data_real; // real data
Arto Kinnunen172836a2019-11-28 13:34:13 +02001342 aes_r_data_t aes_data_fake; // fake data
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001343 aes_r_data_t *aes_data_ptr; // pointer to real or fake data
Arto Kinnunen172836a2019-11-28 13:34:13 +02001344 aes_r_data_t *aes_data_table[2]; // pointers to real and fake data
Arto Kinnunen311ab592020-01-16 17:20:51 +02001345 int round_ctrl_table_len = ctx->nr + 2 + AES_SCA_CM_ROUNDS;
Arto Kinnunen6ce49882019-12-03 13:56:06 +02001346 volatile int flow_control;
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001347 // control bytes for AES calculation rounds,
1348 // reserve based on max rounds + dummy rounds + 2 (for initial key addition)
1349 uint8_t round_ctrl_table[( 14 + AES_SCA_CM_ROUNDS + 2 )];
Arto Kinnunenf93d55e2019-10-11 11:15:57 +03001350
Arto Kinnunen172836a2019-11-28 13:34:13 +02001351 aes_data_real.rk_ptr = ctx->rk;
Arto Kinnunen172836a2019-11-28 13:34:13 +02001352 aes_data_fake.rk_ptr = ctx->rk;
Arto Kinnunen311ab592020-01-16 17:20:51 +02001353 aes_data_table[0] = &aes_data_real;
1354 aes_data_table[1] = &aes_data_fake;
Arto Kinnunenf93d55e2019-10-11 11:15:57 +03001355
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001356 // Get AES calculation control bytes
Arto Kinnunen98c93af2020-01-14 13:31:03 +02001357 dummy_rounds = aes_sca_cm_data_randomize( round_ctrl_table,
Arto Kinnunen2b24f422020-01-16 15:04:11 +02001358 round_ctrl_table_len );
Arto Kinnunen98c93af2020-01-14 13:31:03 +02001359 flow_control = dummy_rounds;
1360
Arto Kinnunen17540ab2020-01-20 11:46:34 +02001361 // SCA countermeasure, safely clear the aes_data_real.xy_values
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001362 mbedtls_platform_memset( aes_data_real.xy_values, 0, 16 );
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001363
Arto Kinnunen17540ab2020-01-20 11:46:34 +02001364 // SCA countermeasure, randomize secret data location by initializing it in
1365 // a random order and writing randomized fake data between the real data
1366 // writes.
1367 offset = mbedtls_platform_random_in_range( 4 );
Arto Kinnunen2b24f422020-01-16 15:04:11 +02001368 i = offset;
1369 do
Arto Kinnunenf93d55e2019-10-11 11:15:57 +03001370 {
Arto Kinnunen172836a2019-11-28 13:34:13 +02001371 GET_UINT32_LE( aes_data_real.xy_values[i], input, ( i * 4 ) );
Arto Kinnunen311ab592020-01-16 17:20:51 +02001372 aes_data_fake.xy_values[i] = mbedtls_platform_random_in_range( 0xffffffff );
Arto Kinnunen2b24f422020-01-16 15:04:11 +02001373 flow_control++;
1374 } while( ( i = ( i + 1 ) % 4 ) != offset );
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001375
1376 tindex = 0;
1377 do
1378 {
1379 // Get pointer to the real or fake data
1380 aes_data_ptr = aes_data_table[round_ctrl_table[tindex] >> 4];
1381 stop_mark = round_ctrl_table[tindex] & 0x03;
1382
1383 // initial round key addition
1384 for( i = 0; i < 4; i++ )
1385 {
1386 aes_data_ptr->xy_values[i] ^= *aes_data_ptr->rk_ptr++;
1387 }
1388 tindex++;
1389 flow_control++;
1390 } while( stop_mark == 0 );
1391
1392 // Calculate AES rounds (9, 11 or 13 rounds) + dummy rounds
1393 do
1394 {
1395 // Get pointer to the real or fake data
1396 aes_data_ptr = aes_data_table[round_ctrl_table[tindex] >> 4];
1397 offset = round_ctrl_table[tindex] & 0x04;
1398 stop_mark = round_ctrl_table[tindex] & 0x03;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001399
Arto Kinnunenc3532c22019-11-29 15:07:11 +02001400 aes_data_ptr->rk_ptr = aes_rround( aes_data_ptr->rk_ptr,
1401 &aes_data_ptr->xy_values[0 + offset],
1402 &aes_data_ptr->xy_values[1 + offset],
1403 &aes_data_ptr->xy_values[2 + offset],
1404 &aes_data_ptr->xy_values[3 + offset],
Arto Kinnunen172836a2019-11-28 13:34:13 +02001405 aes_data_ptr->xy_values[4 - offset],
1406 aes_data_ptr->xy_values[5 - offset],
1407 aes_data_ptr->xy_values[6 - offset],
1408 aes_data_ptr->xy_values[7 - offset] );
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001409 tindex++;
Arto Kinnunen6ce49882019-12-03 13:56:06 +02001410 flow_control++;
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001411 } while( stop_mark == 0 );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001412
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001413 // Calculate final AES round + dummy rounds
1414 do
Arto Kinnunen172836a2019-11-28 13:34:13 +02001415 {
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001416 aes_data_ptr = aes_data_table[round_ctrl_table[tindex] >> 4];
1417 stop_mark = round_ctrl_table[tindex] & 0x03;
Arto Kinnunenc3532c22019-11-29 15:07:11 +02001418 aes_rround_final( aes_data_ptr->rk_ptr,
1419 &aes_data_ptr->xy_values[0],
1420 &aes_data_ptr->xy_values[1],
1421 &aes_data_ptr->xy_values[2],
1422 &aes_data_ptr->xy_values[3],
Arto Kinnunen172836a2019-11-28 13:34:13 +02001423 aes_data_ptr->xy_values[4],
1424 aes_data_ptr->xy_values[5],
1425 aes_data_ptr->xy_values[6],
1426 aes_data_ptr->xy_values[7] );
Arto Kinnunen6ce49882019-12-03 13:56:06 +02001427 flow_control++;
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001428 tindex++;
1429 } while( stop_mark == 0 );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001430
Arto Kinnunen17540ab2020-01-20 11:46:34 +02001431 // SCA countermeasure, safely clear the output
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001432 mbedtls_platform_memset( output, 0, 16 );
Arto Kinnunen2eb678f2020-01-13 16:44:13 +02001433
Arto Kinnunen17540ab2020-01-20 11:46:34 +02001434 // SCA countermeasure, randomize secret data location by writing to it in
1435 // a random order.
1436 offset = mbedtls_platform_random_in_range( 4 );
Arto Kinnunen2b24f422020-01-16 15:04:11 +02001437 i = offset;
1438 do
Arto Kinnunen172836a2019-11-28 13:34:13 +02001439 {
1440 PUT_UINT32_LE( aes_data_real.xy_values[i], output, ( i * 4 ) );
Arto Kinnunen6ce49882019-12-03 13:56:06 +02001441 flow_control++;
Arto Kinnunen2b24f422020-01-16 15:04:11 +02001442 } while( ( i = ( i + 1 ) % 4 ) != offset );
Andres AGf5bf7182017-03-03 14:09:56 +00001443
Arto Kinnunen2b24f422020-01-16 15:04:11 +02001444 if( flow_control == tindex + dummy_rounds + 8 )
Arto Kinnunen6ce49882019-12-03 13:56:06 +02001445 {
Andrzej Kurekafec8852020-07-15 16:31:27 -04001446 return 0;
Arto Kinnunen6ce49882019-12-03 13:56:06 +02001447 }
1448
Andrzej Kurekca609372020-07-08 03:19:02 -04001449 // Clear the output in case of a FI
1450 mbedtls_platform_memset( output, 0, 16 );
Arto Kinnunen6ce49882019-12-03 13:56:06 +02001451 return( MBEDTLS_ERR_PLATFORM_FAULT_DETECTED );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001452}
Arto Kinnunen311ab592020-01-16 17:20:51 +02001453
1454#else /* MBEDTLS_AES_SCA_COUNTERMEASURES */
1455
1456#define AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \
1457 do \
1458 { \
1459 (X0) = *RK++ ^ AES_RT0( ( (Y0) ) & 0xFF ) ^ \
1460 AES_RT1( ( (Y3) >> 8 ) & 0xFF ) ^ \
1461 AES_RT2( ( (Y2) >> 16 ) & 0xFF ) ^ \
1462 AES_RT3( ( (Y1) >> 24 ) & 0xFF ); \
1463 \
1464 (X1) = *RK++ ^ AES_RT0( ( (Y1) ) & 0xFF ) ^ \
1465 AES_RT1( ( (Y0) >> 8 ) & 0xFF ) ^ \
1466 AES_RT2( ( (Y3) >> 16 ) & 0xFF ) ^ \
1467 AES_RT3( ( (Y2) >> 24 ) & 0xFF ); \
1468 \
1469 (X2) = *RK++ ^ AES_RT0( ( (Y2) ) & 0xFF ) ^ \
1470 AES_RT1( ( (Y1) >> 8 ) & 0xFF ) ^ \
1471 AES_RT2( ( (Y0) >> 16 ) & 0xFF ) ^ \
1472 AES_RT3( ( (Y3) >> 24 ) & 0xFF ); \
1473 \
1474 (X3) = *RK++ ^ AES_RT0( ( (Y3) ) & 0xFF ) ^ \
1475 AES_RT1( ( (Y2) >> 8 ) & 0xFF ) ^ \
1476 AES_RT2( ( (Y1) >> 16 ) & 0xFF ) ^ \
1477 AES_RT3( ( (Y0) >> 24 ) & 0xFF ); \
1478 } while( 0 )
1479
1480int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx,
1481 const unsigned char input[16],
1482 unsigned char output[16] )
1483{
1484 int i;
1485 uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3;
1486
1487 RK = ctx->rk;
1488
1489 GET_UINT32_LE( X0, input, 0 ); X0 ^= *RK++;
1490 GET_UINT32_LE( X1, input, 4 ); X1 ^= *RK++;
1491 GET_UINT32_LE( X2, input, 8 ); X2 ^= *RK++;
1492 GET_UINT32_LE( X3, input, 12 ); X3 ^= *RK++;
1493
1494 for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- )
1495 {
1496 AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
1497 AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 );
1498 }
1499
1500 AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
1501
1502 X0 = *RK++ ^ \
1503 ( (uint32_t) RSb[ ( Y0 ) & 0xFF ] ) ^
1504 ( (uint32_t) RSb[ ( Y3 >> 8 ) & 0xFF ] << 8 ) ^
1505 ( (uint32_t) RSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^
1506 ( (uint32_t) RSb[ ( Y1 >> 24 ) & 0xFF ] << 24 );
1507
1508 X1 = *RK++ ^ \
1509 ( (uint32_t) RSb[ ( Y1 ) & 0xFF ] ) ^
1510 ( (uint32_t) RSb[ ( Y0 >> 8 ) & 0xFF ] << 8 ) ^
1511 ( (uint32_t) RSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^
1512 ( (uint32_t) RSb[ ( Y2 >> 24 ) & 0xFF ] << 24 );
1513
1514 X2 = *RK++ ^ \
1515 ( (uint32_t) RSb[ ( Y2 ) & 0xFF ] ) ^
1516 ( (uint32_t) RSb[ ( Y1 >> 8 ) & 0xFF ] << 8 ) ^
1517 ( (uint32_t) RSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^
1518 ( (uint32_t) RSb[ ( Y3 >> 24 ) & 0xFF ] << 24 );
1519
1520 X3 = *RK++ ^ \
1521 ( (uint32_t) RSb[ ( Y3 ) & 0xFF ] ) ^
1522 ( (uint32_t) RSb[ ( Y2 >> 8 ) & 0xFF ] << 8 ) ^
1523 ( (uint32_t) RSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^
1524 ( (uint32_t) RSb[ ( Y0 >> 24 ) & 0xFF ] << 24 );
1525
1526 PUT_UINT32_LE( X0, output, 0 );
1527 PUT_UINT32_LE( X1, output, 4 );
1528 PUT_UINT32_LE( X2, output, 8 );
1529 PUT_UINT32_LE( X3, output, 12 );
1530
Andrzej Kureka8405442019-11-12 03:34:03 -05001531 mbedtls_platform_zeroize( &X0, sizeof( X0 ) );
1532 mbedtls_platform_zeroize( &X1, sizeof( X1 ) );
1533 mbedtls_platform_zeroize( &X2, sizeof( X2 ) );
1534 mbedtls_platform_zeroize( &X3, sizeof( X3 ) );
1535
1536 mbedtls_platform_zeroize( &Y0, sizeof( Y0 ) );
1537 mbedtls_platform_zeroize( &Y1, sizeof( Y1 ) );
1538 mbedtls_platform_zeroize( &Y2, sizeof( Y2 ) );
1539 mbedtls_platform_zeroize( &Y3, sizeof( Y3 ) );
1540
1541 mbedtls_platform_zeroize( &RK, sizeof( RK ) );
1542
Arto Kinnunen311ab592020-01-16 17:20:51 +02001543 return( 0 );
1544}
1545#endif /* MBEDTLS_AES_SCA_COUNTERMEASURES */
1546
Arto Kinnunen14804442019-10-16 13:43:59 +03001547#endif /* !MBEDTLS_AES_ONLY_ENCRYPT */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001548#endif /* !MBEDTLS_AES_DECRYPT_ALT */
1549
Gilles Peskine8db3efb2018-02-21 19:16:20 +01001550#if !defined(MBEDTLS_DEPRECATED_REMOVED)
Hanno Beckerbedc2052017-06-26 12:46:56 +01001551void mbedtls_aes_decrypt( mbedtls_aes_context *ctx,
1552 const unsigned char input[16],
1553 unsigned char output[16] )
1554{
Arto Kinnunen14804442019-10-16 13:43:59 +03001555#if defined(MBEDTLS_AES_ONLY_ENCRYPT)
1556 (void) ctx;
1557 (void) input;
1558 (void) output;
1559#else /* MBEDTLS_AES_ONLY_ENCRYPT */
Hanno Beckerbedc2052017-06-26 12:46:56 +01001560 mbedtls_internal_aes_decrypt( ctx, input, output );
Arto Kinnunen14804442019-10-16 13:43:59 +03001561#endif /* MBEDTLS_AES_ONLY_ENCRYPT */
Hanno Beckerbedc2052017-06-26 12:46:56 +01001562}
Gilles Peskine8db3efb2018-02-21 19:16:20 +01001563#endif /* !MBEDTLS_DEPRECATED_REMOVED */
Hanno Beckerbedc2052017-06-26 12:46:56 +01001564
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001565/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001566 * AES-ECB block encryption/decryption
1567 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001568int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx,
Manuel Pégourié-Gonnardeb6d3962018-12-18 09:59:35 +01001569 int mode,
1570 const unsigned char input[16],
1571 unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +00001572{
Manuel Pégourié-Gonnard1aca2602018-12-12 12:56:55 +01001573 AES_VALIDATE_RET( ctx != NULL );
1574 AES_VALIDATE_RET( input != NULL );
1575 AES_VALIDATE_RET( output != NULL );
1576 AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
1577 mode == MBEDTLS_AES_DECRYPT );
Arto Kinnunen14804442019-10-16 13:43:59 +03001578 (void) mode;
Manuel Pégourié-Gonnard1aca2602018-12-12 12:56:55 +01001579
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001580#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +01001581 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001582 return( mbedtls_aesni_crypt_ecb( ctx, mode, input, output ) );
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +01001583#endif
1584
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001585#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Paul Bakker048d04e2012-02-12 17:31:04 +00001586 if( aes_padlock_ace )
Paul Bakker5121ce52009-01-03 21:22:43 +00001587 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001588 if( mbedtls_padlock_xcryptecb( ctx, mode, input, output ) == 0 )
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001589 return( 0 );
1590
1591 // If padlock data misaligned, we just fall back to
1592 // unaccelerated mode
1593 //
Paul Bakker5121ce52009-01-03 21:22:43 +00001594 }
1595#endif
Arto Kinnunen6ce49882019-12-03 13:56:06 +02001596
Arto Kinnunen14804442019-10-16 13:43:59 +03001597#if defined(MBEDTLS_AES_ONLY_ENCRYPT)
1598 return( mbedtls_internal_aes_encrypt( ctx, input, output ) );
1599#else /* MBEDTLS_AES_ONLY_ENCRYPT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001600
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001601 if( mode == MBEDTLS_AES_ENCRYPT )
Andres AGf5bf7182017-03-03 14:09:56 +00001602 return( mbedtls_internal_aes_encrypt( ctx, input, output ) );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001603 else
Andres AGf5bf7182017-03-03 14:09:56 +00001604 return( mbedtls_internal_aes_decrypt( ctx, input, output ) );
Arto Kinnunen14804442019-10-16 13:43:59 +03001605#endif /* MBEDTLS_AES_ONLY_ENCRYPT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001606}
1607
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001608#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001609/*
1610 * AES-CBC buffer encryption/decryption
1611 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001612int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx,
Paul Bakker5121ce52009-01-03 21:22:43 +00001613 int mode,
Paul Bakker23986e52011-04-24 08:57:21 +00001614 size_t length,
Paul Bakker5121ce52009-01-03 21:22:43 +00001615 unsigned char iv[16],
Paul Bakkerff60ee62010-03-16 21:09:09 +00001616 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +00001617 unsigned char *output )
1618{
1619 int i;
1620 unsigned char temp[16];
1621
Manuel Pégourié-Gonnard3178d1a2018-12-12 13:05:00 +01001622 AES_VALIDATE_RET( ctx != NULL );
1623 AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
1624 mode == MBEDTLS_AES_DECRYPT );
1625 AES_VALIDATE_RET( iv != NULL );
1626 AES_VALIDATE_RET( input != NULL );
1627 AES_VALIDATE_RET( output != NULL );
1628
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001629 if( length % 16 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001630 return( MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH );
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001631
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001632#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Paul Bakker048d04e2012-02-12 17:31:04 +00001633 if( aes_padlock_ace )
Paul Bakker5121ce52009-01-03 21:22:43 +00001634 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001635 if( mbedtls_padlock_xcryptcbc( ctx, mode, length, iv, input, output ) == 0 )
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001636 return( 0 );
Paul Bakker9af723c2014-05-01 13:03:14 +02001637
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001638 // If padlock data misaligned, we just fall back to
1639 // unaccelerated mode
1640 //
Paul Bakker5121ce52009-01-03 21:22:43 +00001641 }
1642#endif
1643
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001644 if( mode == MBEDTLS_AES_DECRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +00001645 {
1646 while( length > 0 )
1647 {
Teppo Järvelin91d79382019-10-02 09:09:31 +03001648 mbedtls_platform_memcpy( temp, input, 16 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001649 mbedtls_aes_crypt_ecb( ctx, mode, input, output );
Paul Bakker5121ce52009-01-03 21:22:43 +00001650
1651 for( i = 0; i < 16; i++ )
1652 output[i] = (unsigned char)( output[i] ^ iv[i] );
1653
Teppo Järvelin91d79382019-10-02 09:09:31 +03001654 mbedtls_platform_memcpy( iv, temp, 16 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001655
1656 input += 16;
1657 output += 16;
1658 length -= 16;
1659 }
1660 }
1661 else
1662 {
1663 while( length > 0 )
1664 {
1665 for( i = 0; i < 16; i++ )
1666 output[i] = (unsigned char)( input[i] ^ iv[i] );
1667
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001668 mbedtls_aes_crypt_ecb( ctx, mode, output, output );
Teppo Järvelin91d79382019-10-02 09:09:31 +03001669 mbedtls_platform_memcpy( iv, output, 16 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001670
1671 input += 16;
1672 output += 16;
1673 length -= 16;
1674 }
1675 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001676
1677 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001678}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001679#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001680
Aorimn5f778012016-06-09 23:22:58 +02001681#if defined(MBEDTLS_CIPHER_MODE_XTS)
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001682
1683/* Endianess with 64 bits values */
1684#ifndef GET_UINT64_LE
1685#define GET_UINT64_LE(n,b,i) \
1686{ \
1687 (n) = ( (uint64_t) (b)[(i) + 7] << 56 ) \
1688 | ( (uint64_t) (b)[(i) + 6] << 48 ) \
1689 | ( (uint64_t) (b)[(i) + 5] << 40 ) \
1690 | ( (uint64_t) (b)[(i) + 4] << 32 ) \
1691 | ( (uint64_t) (b)[(i) + 3] << 24 ) \
1692 | ( (uint64_t) (b)[(i) + 2] << 16 ) \
1693 | ( (uint64_t) (b)[(i) + 1] << 8 ) \
1694 | ( (uint64_t) (b)[(i) ] ); \
1695}
1696#endif
1697
1698#ifndef PUT_UINT64_LE
1699#define PUT_UINT64_LE(n,b,i) \
1700{ \
1701 (b)[(i) + 7] = (unsigned char) ( (n) >> 56 ); \
1702 (b)[(i) + 6] = (unsigned char) ( (n) >> 48 ); \
1703 (b)[(i) + 5] = (unsigned char) ( (n) >> 40 ); \
1704 (b)[(i) + 4] = (unsigned char) ( (n) >> 32 ); \
1705 (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \
1706 (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \
1707 (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \
1708 (b)[(i) ] = (unsigned char) ( (n) ); \
1709}
1710#endif
1711
1712typedef unsigned char mbedtls_be128[16];
1713
1714/*
1715 * GF(2^128) multiplication function
1716 *
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001717 * This function multiplies a field element by x in the polynomial field
1718 * representation. It uses 64-bit word operations to gain speed but compensates
1719 * for machine endianess and hence works correctly on both big and little
1720 * endian machines.
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001721 */
1722static void mbedtls_gf128mul_x_ble( unsigned char r[16],
Jaeden Amero8cfc75f2018-05-31 16:53:08 +01001723 const unsigned char x[16] )
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001724{
1725 uint64_t a, b, ra, rb;
1726
Jaeden Amero8cfc75f2018-05-31 16:53:08 +01001727 GET_UINT64_LE( a, x, 0 );
1728 GET_UINT64_LE( b, x, 8 );
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001729
Jaeden Amero8cfc75f2018-05-31 16:53:08 +01001730 ra = ( a << 1 ) ^ 0x0087 >> ( 8 - ( ( b >> 63 ) << 3 ) );
1731 rb = ( a >> 63 ) | ( b << 1 );
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001732
Jaeden Amero8cfc75f2018-05-31 16:53:08 +01001733 PUT_UINT64_LE( ra, r, 0 );
1734 PUT_UINT64_LE( rb, r, 8 );
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001735}
1736
Aorimn5f778012016-06-09 23:22:58 +02001737/*
1738 * AES-XTS buffer encryption/decryption
1739 */
Jaeden Amero9366feb2018-05-29 18:55:17 +01001740int mbedtls_aes_crypt_xts( mbedtls_aes_xts_context *ctx,
1741 int mode,
Jaeden Amero5162b932018-05-29 12:55:24 +01001742 size_t length,
Jaeden Amerocd9fc5e2018-05-30 15:23:24 +01001743 const unsigned char data_unit[16],
Jaeden Amero9366feb2018-05-29 18:55:17 +01001744 const unsigned char *input,
1745 unsigned char *output )
Aorimn5f778012016-06-09 23:22:58 +02001746{
Jaeden Amerod82cd862018-04-28 15:02:45 +01001747 int ret;
1748 size_t blocks = length / 16;
1749 size_t leftover = length % 16;
1750 unsigned char tweak[16];
1751 unsigned char prev_tweak[16];
1752 unsigned char tmp[16];
Aorimn5f778012016-06-09 23:22:58 +02001753
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01001754 AES_VALIDATE_RET( ctx != NULL );
1755 AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
1756 mode == MBEDTLS_AES_DECRYPT );
Manuel Pégourié-Gonnard998a3582018-12-18 10:03:13 +01001757 AES_VALIDATE_RET( data_unit != NULL );
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01001758 AES_VALIDATE_RET( input != NULL );
1759 AES_VALIDATE_RET( output != NULL );
1760
Jaeden Amero8381fcb2018-10-11 12:06:15 +01001761 /* Data units must be at least 16 bytes long. */
Aorimn5f778012016-06-09 23:22:58 +02001762 if( length < 16 )
Jaeden Amerod82cd862018-04-28 15:02:45 +01001763 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Aorimn5f778012016-06-09 23:22:58 +02001764
Jaeden Ameroa74faba2018-10-11 12:07:43 +01001765 /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */
Jaeden Amero0a8b0202018-05-30 15:36:06 +01001766 if( length > ( 1 << 20 ) * 16 )
1767 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Aorimn5f778012016-06-09 23:22:58 +02001768
Jaeden Amerod82cd862018-04-28 15:02:45 +01001769 /* Compute the tweak. */
Jaeden Amerocd9fc5e2018-05-30 15:23:24 +01001770 ret = mbedtls_aes_crypt_ecb( &ctx->tweak, MBEDTLS_AES_ENCRYPT,
1771 data_unit, tweak );
Jaeden Amerod82cd862018-04-28 15:02:45 +01001772 if( ret != 0 )
1773 return( ret );
Aorimn5f778012016-06-09 23:22:58 +02001774
Jaeden Amerod82cd862018-04-28 15:02:45 +01001775 while( blocks-- )
Aorimn5f778012016-06-09 23:22:58 +02001776 {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001777 size_t i;
1778
1779 if( leftover && ( mode == MBEDTLS_AES_DECRYPT ) && blocks == 0 )
1780 {
1781 /* We are on the last block in a decrypt operation that has
1782 * leftover bytes, so we need to use the next tweak for this block,
1783 * and this tweak for the lefover bytes. Save the current tweak for
1784 * the leftovers and then update the current tweak for use on this,
1785 * the last full block. */
Teppo Järvelin91d79382019-10-02 09:09:31 +03001786 mbedtls_platform_memcpy( prev_tweak, tweak, sizeof( tweak ) );
Jaeden Amerod82cd862018-04-28 15:02:45 +01001787 mbedtls_gf128mul_x_ble( tweak, tweak );
1788 }
1789
1790 for( i = 0; i < 16; i++ )
1791 tmp[i] = input[i] ^ tweak[i];
1792
1793 ret = mbedtls_aes_crypt_ecb( &ctx->crypt, mode, tmp, tmp );
1794 if( ret != 0 )
1795 return( ret );
1796
1797 for( i = 0; i < 16; i++ )
1798 output[i] = tmp[i] ^ tweak[i];
1799
1800 /* Update the tweak for the next block. */
1801 mbedtls_gf128mul_x_ble( tweak, tweak );
1802
1803 output += 16;
1804 input += 16;
Aorimn5f778012016-06-09 23:22:58 +02001805 }
1806
Jaeden Amerod82cd862018-04-28 15:02:45 +01001807 if( leftover )
Aorimn5f778012016-06-09 23:22:58 +02001808 {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001809 /* If we are on the leftover bytes in a decrypt operation, we need to
1810 * use the previous tweak for these bytes (as saved in prev_tweak). */
1811 unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
Aorimn5f778012016-06-09 23:22:58 +02001812
Jaeden Amerod82cd862018-04-28 15:02:45 +01001813 /* We are now on the final part of the data unit, which doesn't divide
1814 * evenly by 16. It's time for ciphertext stealing. */
1815 size_t i;
1816 unsigned char *prev_output = output - 16;
Aorimn5f778012016-06-09 23:22:58 +02001817
Jaeden Amerod82cd862018-04-28 15:02:45 +01001818 /* Copy ciphertext bytes from the previous block to our output for each
1819 * byte of cyphertext we won't steal. At the same time, copy the
1820 * remainder of the input for this final round (since the loop bounds
1821 * are the same). */
1822 for( i = 0; i < leftover; i++ )
Aorimn5f778012016-06-09 23:22:58 +02001823 {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001824 output[i] = prev_output[i];
1825 tmp[i] = input[i] ^ t[i];
Aorimn5f778012016-06-09 23:22:58 +02001826 }
Aorimn5f778012016-06-09 23:22:58 +02001827
Jaeden Amerod82cd862018-04-28 15:02:45 +01001828 /* Copy ciphertext bytes from the previous block for input in this
1829 * round. */
1830 for( ; i < 16; i++ )
1831 tmp[i] = prev_output[i] ^ t[i];
Aorimn5f778012016-06-09 23:22:58 +02001832
Jaeden Amerod82cd862018-04-28 15:02:45 +01001833 ret = mbedtls_aes_crypt_ecb( &ctx->crypt, mode, tmp, tmp );
1834 if( ret != 0 )
1835 return ret;
Aorimn5f778012016-06-09 23:22:58 +02001836
Jaeden Amerod82cd862018-04-28 15:02:45 +01001837 /* Write the result back to the previous block, overriding the previous
1838 * output we copied. */
1839 for( i = 0; i < 16; i++ )
1840 prev_output[i] = tmp[i] ^ t[i];
Aorimn5f778012016-06-09 23:22:58 +02001841 }
1842
1843 return( 0 );
1844}
1845#endif /* MBEDTLS_CIPHER_MODE_XTS */
1846
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001847#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001848/*
1849 * AES-CFB128 buffer encryption/decryption
1850 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001851int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx,
Paul Bakker5121ce52009-01-03 21:22:43 +00001852 int mode,
Paul Bakker23986e52011-04-24 08:57:21 +00001853 size_t length,
Paul Bakker27fdf462011-06-09 13:55:13 +00001854 size_t *iv_off,
Paul Bakker5121ce52009-01-03 21:22:43 +00001855 unsigned char iv[16],
Paul Bakkerff60ee62010-03-16 21:09:09 +00001856 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +00001857 unsigned char *output )
1858{
Paul Bakker27fdf462011-06-09 13:55:13 +00001859 int c;
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001860 size_t n;
1861
1862 AES_VALIDATE_RET( ctx != NULL );
1863 AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
1864 mode == MBEDTLS_AES_DECRYPT );
1865 AES_VALIDATE_RET( iv_off != NULL );
1866 AES_VALIDATE_RET( iv != NULL );
1867 AES_VALIDATE_RET( input != NULL );
1868 AES_VALIDATE_RET( output != NULL );
1869
1870 n = *iv_off;
Paul Bakker5121ce52009-01-03 21:22:43 +00001871
Manuel Pégourié-Gonnarde55e1032018-12-18 12:09:02 +01001872 if( n > 15 )
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001873 return( MBEDTLS_ERR_AES_BAD_INPUT_DATA );
1874
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001875 if( mode == MBEDTLS_AES_DECRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +00001876 {
1877 while( length-- )
1878 {
1879 if( n == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001880 mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
Paul Bakker5121ce52009-01-03 21:22:43 +00001881
1882 c = *input++;
1883 *output++ = (unsigned char)( c ^ iv[n] );
1884 iv[n] = (unsigned char) c;
1885
Paul Bakker66d5d072014-06-17 16:39:18 +02001886 n = ( n + 1 ) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001887 }
1888 }
1889 else
1890 {
1891 while( length-- )
1892 {
1893 if( n == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001894 mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
Paul Bakker5121ce52009-01-03 21:22:43 +00001895
1896 iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ );
1897
Paul Bakker66d5d072014-06-17 16:39:18 +02001898 n = ( n + 1 ) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001899 }
1900 }
1901
1902 *iv_off = n;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001903
1904 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001905}
Paul Bakker556efba2014-01-24 15:38:12 +01001906
1907/*
1908 * AES-CFB8 buffer encryption/decryption
1909 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001910int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx,
Manuel Pégourié-Gonnardeb6d3962018-12-18 09:59:35 +01001911 int mode,
1912 size_t length,
1913 unsigned char iv[16],
1914 const unsigned char *input,
1915 unsigned char *output )
Paul Bakker556efba2014-01-24 15:38:12 +01001916{
1917 unsigned char c;
1918 unsigned char ov[17];
1919
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001920 AES_VALIDATE_RET( ctx != NULL );
1921 AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
1922 mode == MBEDTLS_AES_DECRYPT );
1923 AES_VALIDATE_RET( iv != NULL );
1924 AES_VALIDATE_RET( input != NULL );
1925 AES_VALIDATE_RET( output != NULL );
Paul Bakker556efba2014-01-24 15:38:12 +01001926 while( length-- )
1927 {
Teppo Järvelin91d79382019-10-02 09:09:31 +03001928 mbedtls_platform_memcpy( ov, iv, 16 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001929 mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
Paul Bakker556efba2014-01-24 15:38:12 +01001930
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001931 if( mode == MBEDTLS_AES_DECRYPT )
Paul Bakker556efba2014-01-24 15:38:12 +01001932 ov[16] = *input;
1933
1934 c = *output++ = (unsigned char)( iv[0] ^ *input++ );
1935
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001936 if( mode == MBEDTLS_AES_ENCRYPT )
Paul Bakker556efba2014-01-24 15:38:12 +01001937 ov[16] = c;
1938
Teppo Järvelin91d79382019-10-02 09:09:31 +03001939 mbedtls_platform_memcpy( iv, ov + 1, 16 );
Paul Bakker556efba2014-01-24 15:38:12 +01001940 }
1941
1942 return( 0 );
1943}
Simon Butcher76a5b222018-04-22 22:57:27 +01001944#endif /* MBEDTLS_CIPHER_MODE_CFB */
1945
1946#if defined(MBEDTLS_CIPHER_MODE_OFB)
1947/*
1948 * AES-OFB (Output Feedback Mode) buffer encryption/decryption
1949 */
1950int mbedtls_aes_crypt_ofb( mbedtls_aes_context *ctx,
Simon Butcher00131442018-05-22 22:40:36 +01001951 size_t length,
1952 size_t *iv_off,
1953 unsigned char iv[16],
1954 const unsigned char *input,
1955 unsigned char *output )
Simon Butcher76a5b222018-04-22 22:57:27 +01001956{
Simon Butcherad4e4932018-04-29 00:43:47 +01001957 int ret = 0;
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001958 size_t n;
1959
1960 AES_VALIDATE_RET( ctx != NULL );
1961 AES_VALIDATE_RET( iv_off != NULL );
1962 AES_VALIDATE_RET( iv != NULL );
1963 AES_VALIDATE_RET( input != NULL );
1964 AES_VALIDATE_RET( output != NULL );
1965
1966 n = *iv_off;
Simon Butcher76a5b222018-04-22 22:57:27 +01001967
Manuel Pégourié-Gonnarde55e1032018-12-18 12:09:02 +01001968 if( n > 15 )
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001969 return( MBEDTLS_ERR_AES_BAD_INPUT_DATA );
1970
Simon Butcher76a5b222018-04-22 22:57:27 +01001971 while( length-- )
1972 {
1973 if( n == 0 )
Simon Butcherad4e4932018-04-29 00:43:47 +01001974 {
1975 ret = mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
1976 if( ret != 0 )
1977 goto exit;
1978 }
Simon Butcher76a5b222018-04-22 22:57:27 +01001979 *output++ = *input++ ^ iv[n];
1980
1981 n = ( n + 1 ) & 0x0F;
1982 }
1983
1984 *iv_off = n;
1985
Simon Butcherad4e4932018-04-29 00:43:47 +01001986exit:
1987 return( ret );
Simon Butcher76a5b222018-04-22 22:57:27 +01001988}
1989#endif /* MBEDTLS_CIPHER_MODE_OFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001990
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001991#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001992/*
1993 * AES-CTR buffer encryption/decryption
1994 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001995int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx,
Paul Bakker27fdf462011-06-09 13:55:13 +00001996 size_t length,
1997 size_t *nc_off,
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001998 unsigned char nonce_counter[16],
1999 unsigned char stream_block[16],
2000 const unsigned char *input,
2001 unsigned char *output )
2002{
Paul Bakker369e14b2012-04-18 14:16:09 +00002003 int c, i;
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01002004 size_t n;
2005
2006 AES_VALIDATE_RET( ctx != NULL );
2007 AES_VALIDATE_RET( nc_off != NULL );
2008 AES_VALIDATE_RET( nonce_counter != NULL );
2009 AES_VALIDATE_RET( stream_block != NULL );
2010 AES_VALIDATE_RET( input != NULL );
2011 AES_VALIDATE_RET( output != NULL );
2012
2013 n = *nc_off;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002014
Arto Kinnunen75439012019-12-03 14:12:10 +02002015 if( n > 0x0F )
Mohammad Azim Khan3f7f8172017-11-23 17:49:05 +00002016 return( MBEDTLS_ERR_AES_BAD_INPUT_DATA );
2017
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002018 while( length-- )
2019 {
2020 if( n == 0 ) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002021 mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block );
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002022
Paul Bakker369e14b2012-04-18 14:16:09 +00002023 for( i = 16; i > 0; i-- )
2024 if( ++nonce_counter[i - 1] != 0 )
2025 break;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002026 }
2027 c = *input++;
2028 *output++ = (unsigned char)( c ^ stream_block[n] );
2029
Paul Bakker66d5d072014-06-17 16:39:18 +02002030 n = ( n + 1 ) & 0x0F;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002031 }
2032
2033 *nc_off = n;
2034
2035 return( 0 );
2036}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002037#endif /* MBEDTLS_CIPHER_MODE_CTR */
Manuel Pégourié-Gonnard1ec220b2014-03-10 11:20:17 +01002038
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002039#endif /* !MBEDTLS_AES_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +00002040
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002041#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00002042/*
2043 * AES test vectors from:
2044 *
2045 * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
2046 */
2047static const unsigned char aes_test_ecb_dec[3][16] =
2048{
2049 { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
2050 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
2051 { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
2052 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
2053 { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
2054 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
2055};
2056
2057static const unsigned char aes_test_ecb_enc[3][16] =
2058{
2059 { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
2060 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
2061 { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
2062 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
2063 { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
2064 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
2065};
2066
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002067#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00002068static const unsigned char aes_test_cbc_dec[3][16] =
2069{
2070 { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
2071 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
2072 { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
2073 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
2074 { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
2075 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
2076};
2077
2078static const unsigned char aes_test_cbc_enc[3][16] =
2079{
2080 { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
2081 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
2082 { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
2083 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
2084 { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
2085 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
2086};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002087#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00002088
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002089#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00002090/*
2091 * AES-CFB128 test vectors from:
2092 *
2093 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
2094 */
2095static const unsigned char aes_test_cfb128_key[3][32] =
2096{
2097 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
2098 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
2099 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
2100 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
2101 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
2102 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
2103 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
2104 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
2105 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
2106};
2107
2108static const unsigned char aes_test_cfb128_iv[16] =
2109{
2110 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
2111 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
2112};
2113
2114static const unsigned char aes_test_cfb128_pt[64] =
2115{
2116 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
2117 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
2118 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
2119 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
2120 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
2121 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
2122 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
2123 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
2124};
2125
2126static const unsigned char aes_test_cfb128_ct[3][64] =
2127{
2128 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
2129 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
2130 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F,
2131 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B,
2132 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40,
2133 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF,
2134 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E,
2135 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 },
2136 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
2137 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
2138 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21,
2139 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A,
2140 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1,
2141 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9,
2142 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0,
2143 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF },
2144 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
2145 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
2146 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8,
2147 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B,
2148 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92,
2149 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9,
2150 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8,
2151 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 }
2152};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002153#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002154
Simon Butcherad4e4932018-04-29 00:43:47 +01002155#if defined(MBEDTLS_CIPHER_MODE_OFB)
2156/*
2157 * AES-OFB test vectors from:
2158 *
Simon Butcher5db13622018-06-04 22:11:25 +01002159 * https://csrc.nist.gov/publications/detail/sp/800-38a/final
Simon Butcherad4e4932018-04-29 00:43:47 +01002160 */
2161static const unsigned char aes_test_ofb_key[3][32] =
2162{
2163 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
2164 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
2165 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
2166 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
2167 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
2168 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
2169 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
2170 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
2171 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
2172};
2173
2174static const unsigned char aes_test_ofb_iv[16] =
2175{
2176 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
2177 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
2178};
2179
2180static const unsigned char aes_test_ofb_pt[64] =
2181{
2182 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
2183 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
2184 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
2185 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
2186 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
2187 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
2188 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
2189 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
2190};
2191
2192static const unsigned char aes_test_ofb_ct[3][64] =
2193{
2194 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
2195 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
2196 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
2197 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
2198 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
2199 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
2200 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
2201 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e },
2202 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
2203 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
2204 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
2205 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
2206 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f,
2207 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
2208 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e,
2209 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a },
2210 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
2211 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
2212 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
2213 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
2214 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed,
2215 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
2216 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8,
2217 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 }
2218};
2219#endif /* MBEDTLS_CIPHER_MODE_OFB */
2220
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002221#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002222/*
2223 * AES-CTR test vectors from:
2224 *
2225 * http://www.faqs.org/rfcs/rfc3686.html
2226 */
2227
2228static const unsigned char aes_test_ctr_key[3][16] =
2229{
2230 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
2231 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
2232 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
2233 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
2234 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
2235 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
2236};
2237
2238static const unsigned char aes_test_ctr_nonce_counter[3][16] =
2239{
2240 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
2241 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
2242 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
2243 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
2244 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
2245 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
2246};
2247
2248static const unsigned char aes_test_ctr_pt[3][48] =
2249{
2250 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
2251 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
2252
2253 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
2254 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
2255 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
2256 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
2257
2258 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
2259 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
2260 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
2261 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
2262 0x20, 0x21, 0x22, 0x23 }
2263};
2264
2265static const unsigned char aes_test_ctr_ct[3][48] =
2266{
2267 { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79,
2268 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 },
2269 { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9,
2270 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88,
2271 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8,
2272 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 },
2273 { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
2274 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
2275 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
2276 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
2277 0x25, 0xB2, 0x07, 0x2F }
2278};
2279
2280static const int aes_test_ctr_len[3] =
2281 { 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002282#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00002283
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002284#if defined(MBEDTLS_CIPHER_MODE_XTS)
2285/*
2286 * AES-XTS test vectors from:
2287 *
2288 * IEEE P1619/D16 Annex B
2289 * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf
2290 * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf)
2291 */
2292static const unsigned char aes_test_xts_key[][32] =
2293{
2294 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2295 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2296 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2297 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
2298 { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
2299 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
2300 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
2301 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
2302 { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
2303 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
2304 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
2305 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
2306};
2307
2308static const unsigned char aes_test_xts_pt32[][32] =
2309{
2310 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2311 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2312 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2313 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
2314 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2315 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2316 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2317 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
2318 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2319 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2320 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
2321 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
2322};
2323
2324static const unsigned char aes_test_xts_ct32[][32] =
2325{
2326 { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec,
2327 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92,
2328 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85,
2329 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e },
2330 { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e,
2331 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b,
2332 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4,
2333 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 },
2334 { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a,
2335 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2,
2336 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53,
2337 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 },
2338};
2339
2340static const unsigned char aes_test_xts_data_unit[][16] =
2341{
2342 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2343 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
2344 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
2345 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
2346 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
2347 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
2348};
2349
2350#endif /* MBEDTLS_CIPHER_MODE_XTS */
2351
Paul Bakker5121ce52009-01-03 21:22:43 +00002352/*
2353 * Checkup routine
2354 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002355int mbedtls_aes_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +00002356{
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002357 int ret = 0, i, j, u, mode;
2358 unsigned int keybits;
Paul Bakker5121ce52009-01-03 21:22:43 +00002359 unsigned char key[32];
2360 unsigned char buf[64];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002361 const unsigned char *aes_tests;
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03002362#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00002363 unsigned char iv[16];
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03002364#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002365#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +02002366 unsigned char prv[16];
2367#endif
Simon Butcher2ff0e522018-06-14 09:57:07 +01002368#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
2369 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker27fdf462011-06-09 13:55:13 +00002370 size_t offset;
Paul Bakkere91d01e2011-04-19 15:55:50 +00002371#endif
Simon Butcher66a89032018-06-15 18:20:29 +01002372#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS)
Paul Bakkere91d01e2011-04-19 15:55:50 +00002373 int len;
Simon Butcher66a89032018-06-15 18:20:29 +01002374#endif
2375#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002376 unsigned char nonce_counter[16];
2377 unsigned char stream_block[16];
2378#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002379 mbedtls_aes_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00002380
Teppo Järvelind49d2b62019-10-30 13:48:12 +02002381 memset( key, 0, 32 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002382 mbedtls_aes_init( &ctx );
Paul Bakker5121ce52009-01-03 21:22:43 +00002383
2384 /*
2385 * ECB mode
2386 */
2387 for( i = 0; i < 6; i++ )
2388 {
2389 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002390 keybits = 128 + u * 64;
2391 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00002392
2393 if( verbose != 0 )
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002394 mbedtls_printf( " AES-ECB-%3d (%s): ", keybits,
2395 ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002396
Arto Kinnunen77b9cfc2019-08-30 11:43:21 +03002397#if defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
2398 if( keybits > 128 )
2399 {
2400 mbedtls_printf( "skipped\n" );
2401 continue;
2402 }
Arto Kinnunenc0a8bd42019-10-16 14:23:14 +03002403#endif /* MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
2404
2405#if defined(MBEDTLS_AES_ONLY_ENCRYPT)
2406 if( mode == MBEDTLS_AES_DECRYPT )
2407 {
2408 mbedtls_printf( "skipped\n" );
2409 continue;
2410 }
2411#endif /* MBEDTLS_AES_ONLY_ENCRYPT */
Arto Kinnunen77b9cfc2019-08-30 11:43:21 +03002412
Teppo Järvelind49d2b62019-10-30 13:48:12 +02002413 memset( buf, 0, 16 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002414
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002415 if( mode == MBEDTLS_AES_DECRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +00002416 {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002417 ret = mbedtls_aes_setkey_dec( &ctx, key, keybits );
2418 aes_tests = aes_test_ecb_dec[u];
Paul Bakker5121ce52009-01-03 21:22:43 +00002419 }
2420 else
2421 {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002422 ret = mbedtls_aes_setkey_enc( &ctx, key, keybits );
2423 aes_tests = aes_test_ecb_enc[u];
2424 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002425
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01002426 /*
2427 * AES-192 is an optional feature that may be unavailable when
2428 * there is an alternative underlying implementation i.e. when
2429 * MBEDTLS_AES_ALT is defined.
2430 */
Ron Eldor9924bdc2018-10-04 10:59:13 +03002431 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 )
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002432 {
2433 mbedtls_printf( "skipped\n" );
2434 continue;
2435 }
2436 else if( ret != 0 )
2437 {
2438 goto exit;
2439 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002440
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002441 for( j = 0; j < 10000; j++ )
2442 {
2443 ret = mbedtls_aes_crypt_ecb( &ctx, mode, buf, buf );
2444 if( ret != 0 )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002445 goto exit;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002446 }
2447
2448 if( memcmp( buf, aes_tests, 16 ) != 0 )
2449 {
2450 ret = 1;
2451 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00002452 }
2453
2454 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002455 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002456 }
2457
2458 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002459 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002460
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002461#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00002462 /*
2463 * CBC mode
2464 */
2465 for( i = 0; i < 6; i++ )
2466 {
2467 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002468 keybits = 128 + u * 64;
2469 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00002470
2471 if( verbose != 0 )
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002472 mbedtls_printf( " AES-CBC-%3d (%s): ", keybits,
2473 ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002474
Arto Kinnunen77b9cfc2019-08-30 11:43:21 +03002475#if defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
2476 if( keybits > 128 )
2477 {
2478 mbedtls_printf( "skipped\n" );
2479 continue;
2480 }
2481#endif
2482
Arto Kinnunenc0a8bd42019-10-16 14:23:14 +03002483#if defined(MBEDTLS_AES_ONLY_ENCRYPT)
2484 if( mode == MBEDTLS_AES_DECRYPT )
2485 {
2486 mbedtls_printf( "skipped\n" );
2487 continue;
2488 }
2489#endif /* MBEDTLS_AES_ONLY_ENCRYPT */
2490
Teppo Järvelind49d2b62019-10-30 13:48:12 +02002491 memset( iv , 0, 16 );
2492 memset( prv, 0, 16 );
2493 memset( buf, 0, 16 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002494
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002495 if( mode == MBEDTLS_AES_DECRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +00002496 {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002497 ret = mbedtls_aes_setkey_dec( &ctx, key, keybits );
2498 aes_tests = aes_test_cbc_dec[u];
Paul Bakker5121ce52009-01-03 21:22:43 +00002499 }
2500 else
2501 {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002502 ret = mbedtls_aes_setkey_enc( &ctx, key, keybits );
2503 aes_tests = aes_test_cbc_enc[u];
2504 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002505
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01002506 /*
2507 * AES-192 is an optional feature that may be unavailable when
2508 * there is an alternative underlying implementation i.e. when
2509 * MBEDTLS_AES_ALT is defined.
2510 */
Ron Eldor9924bdc2018-10-04 10:59:13 +03002511 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 )
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002512 {
2513 mbedtls_printf( "skipped\n" );
2514 continue;
2515 }
2516 else if( ret != 0 )
2517 {
2518 goto exit;
2519 }
2520
2521 for( j = 0; j < 10000; j++ )
2522 {
2523 if( mode == MBEDTLS_AES_ENCRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +00002524 {
2525 unsigned char tmp[16];
2526
Teppo Järvelinb5c46712019-10-04 13:35:55 +03002527 memcpy( tmp, prv, 16 );
2528 memcpy( prv, buf, 16 );
2529 memcpy( buf, tmp, 16 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002530 }
2531
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002532 ret = mbedtls_aes_crypt_cbc( &ctx, mode, 16, iv, buf, buf );
2533 if( ret != 0 )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002534 goto exit;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002535
2536 }
2537
2538 if( memcmp( buf, aes_tests, 16 ) != 0 )
2539 {
2540 ret = 1;
2541 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00002542 }
2543
2544 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002545 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002546 }
2547
2548 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002549 mbedtls_printf( "\n" );
2550#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00002551
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002552#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00002553 /*
2554 * CFB128 mode
2555 */
2556 for( i = 0; i < 6; i++ )
2557 {
2558 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002559 keybits = 128 + u * 64;
2560 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00002561
2562 if( verbose != 0 )
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002563 mbedtls_printf( " AES-CFB128-%3d (%s): ", keybits,
2564 ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002565
Arto Kinnunen77b9cfc2019-08-30 11:43:21 +03002566#if defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
2567 if( keybits > 128 )
2568 {
2569 mbedtls_printf( "skipped\n" );
2570 continue;
2571 }
2572#endif
2573
Arto Kinnunenc0a8bd42019-10-16 14:23:14 +03002574#if defined(MBEDTLS_AES_ONLY_ENCRYPT)
2575 if( mode == MBEDTLS_AES_DECRYPT )
2576 {
2577 mbedtls_printf( "skipped\n" );
2578 continue;
2579 }
2580#endif /* MBEDTLS_AES_ONLY_ENCRYPT */
2581
Paul Bakker5121ce52009-01-03 21:22:43 +00002582 memcpy( iv, aes_test_cfb128_iv, 16 );
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002583 memcpy( key, aes_test_cfb128_key[u], keybits / 8 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002584
2585 offset = 0;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002586 ret = mbedtls_aes_setkey_enc( &ctx, key, keybits );
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01002587 /*
2588 * AES-192 is an optional feature that may be unavailable when
2589 * there is an alternative underlying implementation i.e. when
2590 * MBEDTLS_AES_ALT is defined.
2591 */
Ron Eldor9924bdc2018-10-04 10:59:13 +03002592 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 )
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002593 {
2594 mbedtls_printf( "skipped\n" );
2595 continue;
2596 }
2597 else if( ret != 0 )
2598 {
2599 goto exit;
2600 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002601
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002602 if( mode == MBEDTLS_AES_DECRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +00002603 {
Teppo Järvelinb5c46712019-10-04 13:35:55 +03002604 memcpy( buf, aes_test_cfb128_ct[u], 64 );
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002605 aes_tests = aes_test_cfb128_pt;
Paul Bakker5121ce52009-01-03 21:22:43 +00002606 }
2607 else
2608 {
Teppo Järvelinb5c46712019-10-04 13:35:55 +03002609 memcpy( buf, aes_test_cfb128_pt, 64 );
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002610 aes_tests = aes_test_cfb128_ct[u];
2611 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002612
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002613 ret = mbedtls_aes_crypt_cfb128( &ctx, mode, 64, &offset, iv, buf, buf );
2614 if( ret != 0 )
2615 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00002616
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002617 if( memcmp( buf, aes_tests, 64 ) != 0 )
2618 {
2619 ret = 1;
2620 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00002621 }
2622
2623 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002624 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002625 }
2626
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002627 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002628 mbedtls_printf( "\n" );
2629#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002630
Simon Butcherad4e4932018-04-29 00:43:47 +01002631#if defined(MBEDTLS_CIPHER_MODE_OFB)
2632 /*
2633 * OFB mode
2634 */
2635 for( i = 0; i < 6; i++ )
2636 {
2637 u = i >> 1;
2638 keybits = 128 + u * 64;
2639 mode = i & 1;
2640
2641 if( verbose != 0 )
2642 mbedtls_printf( " AES-OFB-%3d (%s): ", keybits,
2643 ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
2644
Arto Kinnunen77b9cfc2019-08-30 11:43:21 +03002645#if defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
2646 if( keybits > 128 )
2647 {
2648 mbedtls_printf( "skipped\n" );
2649 continue;
2650 }
2651#endif
Arto Kinnunenc0a8bd42019-10-16 14:23:14 +03002652
2653#if defined(MBEDTLS_AES_ONLY_ENCRYPT)
2654 if( mode == MBEDTLS_AES_DECRYPT )
2655 {
2656 mbedtls_printf( "skipped\n" );
2657 continue;
2658 }
2659#endif /* MBEDTLS_AES_ONLY_ENCRYPT */
2660
Simon Butcherad4e4932018-04-29 00:43:47 +01002661 memcpy( iv, aes_test_ofb_iv, 16 );
2662 memcpy( key, aes_test_ofb_key[u], keybits / 8 );
2663
2664 offset = 0;
2665 ret = mbedtls_aes_setkey_enc( &ctx, key, keybits );
2666 /*
2667 * AES-192 is an optional feature that may be unavailable when
2668 * there is an alternative underlying implementation i.e. when
2669 * MBEDTLS_AES_ALT is defined.
2670 */
Ron Eldor9924bdc2018-10-04 10:59:13 +03002671 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 )
Simon Butcherad4e4932018-04-29 00:43:47 +01002672 {
2673 mbedtls_printf( "skipped\n" );
2674 continue;
2675 }
2676 else if( ret != 0 )
2677 {
2678 goto exit;
2679 }
2680
2681 if( mode == MBEDTLS_AES_DECRYPT )
2682 {
Teppo Järvelinb5c46712019-10-04 13:35:55 +03002683 memcpy( buf, aes_test_ofb_ct[u], 64 );
Simon Butcherad4e4932018-04-29 00:43:47 +01002684 aes_tests = aes_test_ofb_pt;
2685 }
2686 else
2687 {
Teppo Järvelinb5c46712019-10-04 13:35:55 +03002688 memcpy( buf, aes_test_ofb_pt, 64 );
Simon Butcherad4e4932018-04-29 00:43:47 +01002689 aes_tests = aes_test_ofb_ct[u];
2690 }
2691
2692 ret = mbedtls_aes_crypt_ofb( &ctx, 64, &offset, iv, buf, buf );
2693 if( ret != 0 )
2694 goto exit;
2695
2696 if( memcmp( buf, aes_tests, 64 ) != 0 )
2697 {
2698 ret = 1;
2699 goto exit;
2700 }
2701
2702 if( verbose != 0 )
2703 mbedtls_printf( "passed\n" );
2704 }
2705
2706 if( verbose != 0 )
2707 mbedtls_printf( "\n" );
2708#endif /* MBEDTLS_CIPHER_MODE_OFB */
2709
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002710#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002711 /*
2712 * CTR mode
2713 */
2714 for( i = 0; i < 6; i++ )
2715 {
2716 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002717 mode = i & 1;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002718
2719 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002720 mbedtls_printf( " AES-CTR-128 (%s): ",
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002721 ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002722
Arto Kinnunen77b9cfc2019-08-30 11:43:21 +03002723#if defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
2724 if( keybits > 128 )
2725 {
2726 mbedtls_printf( "skipped\n" );
2727 continue;
2728 }
2729#endif
2730
Arto Kinnunenc0a8bd42019-10-16 14:23:14 +03002731#if defined(MBEDTLS_AES_ONLY_ENCRYPT)
2732 if( mode == MBEDTLS_AES_DECRYPT )
2733 {
2734 mbedtls_printf( "skipped\n" );
2735 continue;
2736 }
2737#endif /* MBEDTLS_AES_ONLY_ENCRYPT */
2738
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002739 memcpy( nonce_counter, aes_test_ctr_nonce_counter[u], 16 );
2740 memcpy( key, aes_test_ctr_key[u], 16 );
2741
2742 offset = 0;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002743 if( ( ret = mbedtls_aes_setkey_enc( &ctx, key, 128 ) ) != 0 )
2744 goto exit;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002745
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002746 len = aes_test_ctr_len[u];
2747
2748 if( mode == MBEDTLS_AES_DECRYPT )
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002749 {
Teppo Järvelinb5c46712019-10-04 13:35:55 +03002750 memcpy( buf, aes_test_ctr_ct[u], len );
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002751 aes_tests = aes_test_ctr_pt[u];
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002752 }
2753 else
2754 {
Teppo Järvelinb5c46712019-10-04 13:35:55 +03002755 memcpy( buf, aes_test_ctr_pt[u], len );
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002756 aes_tests = aes_test_ctr_ct[u];
2757 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002758
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002759 ret = mbedtls_aes_crypt_ctr( &ctx, len, &offset, nonce_counter,
2760 stream_block, buf, buf );
2761 if( ret != 0 )
2762 goto exit;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002763
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002764 if( memcmp( buf, aes_tests, len ) != 0 )
2765 {
2766 ret = 1;
2767 goto exit;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002768 }
2769
2770 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002771 mbedtls_printf( "passed\n" );
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002772 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002773
2774 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002775 mbedtls_printf( "\n" );
2776#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00002777
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002778#if defined(MBEDTLS_CIPHER_MODE_XTS)
2779 {
2780 static const int num_tests =
2781 sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key);
2782 mbedtls_aes_xts_context ctx_xts;
2783
2784 /*
2785 * XTS mode
2786 */
2787 mbedtls_aes_xts_init( &ctx_xts );
2788
2789 for( i = 0; i < num_tests << 1; i++ )
2790 {
2791 const unsigned char *data_unit;
2792 u = i >> 1;
2793 mode = i & 1;
2794
2795 if( verbose != 0 )
2796 mbedtls_printf( " AES-XTS-128 (%s): ",
2797 ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
2798
Arto Kinnunenc0a8bd42019-10-16 14:23:14 +03002799#if defined(MBEDTLS_AES_ONLY_ENCRYPT)
2800 if( mode == MBEDTLS_AES_DECRYPT )
2801 {
2802 mbedtls_printf( "skipped\n" );
2803 continue;
2804 }
2805#endif /* MBEDTLS_AES_ONLY_ENCRYPT */
2806
Teppo Järvelind49d2b62019-10-30 13:48:12 +02002807 memset( key, 0, sizeof( key ) );
2808 memcpy( key, aes_test_xts_key[u], 32 );
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002809 data_unit = aes_test_xts_data_unit[u];
2810
2811 len = sizeof( *aes_test_xts_ct32 );
2812
2813 if( mode == MBEDTLS_AES_DECRYPT )
2814 {
2815 ret = mbedtls_aes_xts_setkey_dec( &ctx_xts, key, 256 );
2816 if( ret != 0)
2817 goto exit;
Teppo Järvelinb5c46712019-10-04 13:35:55 +03002818 memcpy( buf, aes_test_xts_ct32[u], len );
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002819 aes_tests = aes_test_xts_pt32[u];
2820 }
2821 else
2822 {
2823 ret = mbedtls_aes_xts_setkey_enc( &ctx_xts, key, 256 );
2824 if( ret != 0)
2825 goto exit;
Teppo Järvelinb5c46712019-10-04 13:35:55 +03002826 memcpy( buf, aes_test_xts_pt32[u], len );
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002827 aes_tests = aes_test_xts_ct32[u];
2828 }
2829
2830
2831 ret = mbedtls_aes_crypt_xts( &ctx_xts, mode, len, data_unit,
2832 buf, buf );
2833 if( ret != 0 )
2834 goto exit;
2835
2836 if( memcmp( buf, aes_tests, len ) != 0 )
2837 {
2838 ret = 1;
2839 goto exit;
2840 }
2841
2842 if( verbose != 0 )
2843 mbedtls_printf( "passed\n" );
2844 }
2845
2846 if( verbose != 0 )
2847 mbedtls_printf( "\n" );
2848
2849 mbedtls_aes_xts_free( &ctx_xts );
2850 }
2851#endif /* MBEDTLS_CIPHER_MODE_XTS */
2852
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002853 ret = 0;
2854
2855exit:
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002856 if( ret != 0 && verbose != 0 )
2857 mbedtls_printf( "failed\n" );
2858
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002859 mbedtls_aes_free( &ctx );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002860
2861 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002862}
2863
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002864#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002865
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002866#endif /* MBEDTLS_AES_C */