blob: 31824e75cf540489345fea11cddbe081742bd2a0 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * FIPS-197 compliant AES implementation
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Paul Bakker5121ce52009-01-03 21:22:43 +000018 */
19/*
20 * The AES block cipher was designed by Vincent Rijmen and Joan Daemen.
21 *
22 * http://csrc.nist.gov/encryption/aes/rijndael/Rijndael.pdf
23 * http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
24 */
25
Gilles Peskinedb09ef62020-06-03 01:43:33 +020026#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000027
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020028#if defined(MBEDTLS_AES_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000029
Rich Evans00ab4702015-02-06 13:43:58 +000030#include <string.h>
31
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000032#include "mbedtls/aes.h"
Ron Eldor9924bdc2018-10-04 10:59:13 +030033#include "mbedtls/platform.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050034#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000035#include "mbedtls/error.h"
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020036#if defined(MBEDTLS_PADLOCK_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000037#include "mbedtls/padlock.h"
Paul Bakker67820bd2012-06-04 12:47:23 +000038#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020039#if defined(MBEDTLS_AESNI_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000040#include "mbedtls/aesni.h"
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +010041#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000042
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020043#if defined(MBEDTLS_SELF_TEST)
44#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000045#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010046#else
Rich Evans00ab4702015-02-06 13:43:58 +000047#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020048#define mbedtls_printf printf
49#endif /* MBEDTLS_PLATFORM_C */
50#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010051
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020052#if !defined(MBEDTLS_AES_ALT)
Paul Bakker90995b52013-06-24 19:20:35 +020053
Manuel Pégourié-Gonnard0e9cddb2018-12-10 16:37:51 +010054/* Parameter validation macros based on platform_util.h */
55#define AES_VALIDATE_RET( cond ) \
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +010056 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_AES_BAD_INPUT_DATA )
Manuel Pégourié-Gonnard0e9cddb2018-12-10 16:37:51 +010057#define AES_VALIDATE( cond ) \
58 MBEDTLS_INTERNAL_VALIDATE( cond )
59
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020060#if defined(MBEDTLS_PADLOCK_C) && \
61 ( defined(MBEDTLS_HAVE_X86) || defined(MBEDTLS_PADLOCK_ALIGN16) )
Paul Bakker048d04e2012-02-12 17:31:04 +000062static int aes_padlock_ace = -1;
63#endif
64
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020065#if defined(MBEDTLS_AES_ROM_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +000066/*
67 * Forward S-box
68 */
69static const unsigned char FSb[256] =
70{
71 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
72 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
73 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
74 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
75 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
76 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
77 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
78 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
79 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
80 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
81 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
82 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
83 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
84 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
85 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
86 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
87 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
88 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
89 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
90 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
91 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
92 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
93 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
94 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
95 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
96 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
97 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
98 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
99 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
100 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
101 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
102 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
103};
104
105/*
106 * Forward tables
107 */
108#define FT \
109\
110 V(A5,63,63,C6), V(84,7C,7C,F8), V(99,77,77,EE), V(8D,7B,7B,F6), \
111 V(0D,F2,F2,FF), V(BD,6B,6B,D6), V(B1,6F,6F,DE), V(54,C5,C5,91), \
112 V(50,30,30,60), V(03,01,01,02), V(A9,67,67,CE), V(7D,2B,2B,56), \
113 V(19,FE,FE,E7), V(62,D7,D7,B5), V(E6,AB,AB,4D), V(9A,76,76,EC), \
114 V(45,CA,CA,8F), V(9D,82,82,1F), V(40,C9,C9,89), V(87,7D,7D,FA), \
115 V(15,FA,FA,EF), V(EB,59,59,B2), V(C9,47,47,8E), V(0B,F0,F0,FB), \
116 V(EC,AD,AD,41), V(67,D4,D4,B3), V(FD,A2,A2,5F), V(EA,AF,AF,45), \
117 V(BF,9C,9C,23), V(F7,A4,A4,53), V(96,72,72,E4), V(5B,C0,C0,9B), \
118 V(C2,B7,B7,75), V(1C,FD,FD,E1), V(AE,93,93,3D), V(6A,26,26,4C), \
119 V(5A,36,36,6C), V(41,3F,3F,7E), V(02,F7,F7,F5), V(4F,CC,CC,83), \
120 V(5C,34,34,68), V(F4,A5,A5,51), V(34,E5,E5,D1), V(08,F1,F1,F9), \
121 V(93,71,71,E2), V(73,D8,D8,AB), V(53,31,31,62), V(3F,15,15,2A), \
122 V(0C,04,04,08), V(52,C7,C7,95), V(65,23,23,46), V(5E,C3,C3,9D), \
123 V(28,18,18,30), V(A1,96,96,37), V(0F,05,05,0A), V(B5,9A,9A,2F), \
124 V(09,07,07,0E), V(36,12,12,24), V(9B,80,80,1B), V(3D,E2,E2,DF), \
125 V(26,EB,EB,CD), V(69,27,27,4E), V(CD,B2,B2,7F), V(9F,75,75,EA), \
126 V(1B,09,09,12), V(9E,83,83,1D), V(74,2C,2C,58), V(2E,1A,1A,34), \
127 V(2D,1B,1B,36), V(B2,6E,6E,DC), V(EE,5A,5A,B4), V(FB,A0,A0,5B), \
128 V(F6,52,52,A4), V(4D,3B,3B,76), V(61,D6,D6,B7), V(CE,B3,B3,7D), \
129 V(7B,29,29,52), V(3E,E3,E3,DD), V(71,2F,2F,5E), V(97,84,84,13), \
130 V(F5,53,53,A6), V(68,D1,D1,B9), V(00,00,00,00), V(2C,ED,ED,C1), \
131 V(60,20,20,40), V(1F,FC,FC,E3), V(C8,B1,B1,79), V(ED,5B,5B,B6), \
132 V(BE,6A,6A,D4), V(46,CB,CB,8D), V(D9,BE,BE,67), V(4B,39,39,72), \
133 V(DE,4A,4A,94), V(D4,4C,4C,98), V(E8,58,58,B0), V(4A,CF,CF,85), \
134 V(6B,D0,D0,BB), V(2A,EF,EF,C5), V(E5,AA,AA,4F), V(16,FB,FB,ED), \
135 V(C5,43,43,86), V(D7,4D,4D,9A), V(55,33,33,66), V(94,85,85,11), \
136 V(CF,45,45,8A), V(10,F9,F9,E9), V(06,02,02,04), V(81,7F,7F,FE), \
137 V(F0,50,50,A0), V(44,3C,3C,78), V(BA,9F,9F,25), V(E3,A8,A8,4B), \
138 V(F3,51,51,A2), V(FE,A3,A3,5D), V(C0,40,40,80), V(8A,8F,8F,05), \
139 V(AD,92,92,3F), V(BC,9D,9D,21), V(48,38,38,70), V(04,F5,F5,F1), \
140 V(DF,BC,BC,63), V(C1,B6,B6,77), V(75,DA,DA,AF), V(63,21,21,42), \
141 V(30,10,10,20), V(1A,FF,FF,E5), V(0E,F3,F3,FD), V(6D,D2,D2,BF), \
142 V(4C,CD,CD,81), V(14,0C,0C,18), V(35,13,13,26), V(2F,EC,EC,C3), \
143 V(E1,5F,5F,BE), V(A2,97,97,35), V(CC,44,44,88), V(39,17,17,2E), \
144 V(57,C4,C4,93), V(F2,A7,A7,55), V(82,7E,7E,FC), V(47,3D,3D,7A), \
145 V(AC,64,64,C8), V(E7,5D,5D,BA), V(2B,19,19,32), V(95,73,73,E6), \
146 V(A0,60,60,C0), V(98,81,81,19), V(D1,4F,4F,9E), V(7F,DC,DC,A3), \
147 V(66,22,22,44), V(7E,2A,2A,54), V(AB,90,90,3B), V(83,88,88,0B), \
148 V(CA,46,46,8C), V(29,EE,EE,C7), V(D3,B8,B8,6B), V(3C,14,14,28), \
149 V(79,DE,DE,A7), V(E2,5E,5E,BC), V(1D,0B,0B,16), V(76,DB,DB,AD), \
150 V(3B,E0,E0,DB), V(56,32,32,64), V(4E,3A,3A,74), V(1E,0A,0A,14), \
151 V(DB,49,49,92), V(0A,06,06,0C), V(6C,24,24,48), V(E4,5C,5C,B8), \
152 V(5D,C2,C2,9F), V(6E,D3,D3,BD), V(EF,AC,AC,43), V(A6,62,62,C4), \
153 V(A8,91,91,39), V(A4,95,95,31), V(37,E4,E4,D3), V(8B,79,79,F2), \
154 V(32,E7,E7,D5), V(43,C8,C8,8B), V(59,37,37,6E), V(B7,6D,6D,DA), \
155 V(8C,8D,8D,01), V(64,D5,D5,B1), V(D2,4E,4E,9C), V(E0,A9,A9,49), \
156 V(B4,6C,6C,D8), V(FA,56,56,AC), V(07,F4,F4,F3), V(25,EA,EA,CF), \
157 V(AF,65,65,CA), V(8E,7A,7A,F4), V(E9,AE,AE,47), V(18,08,08,10), \
158 V(D5,BA,BA,6F), V(88,78,78,F0), V(6F,25,25,4A), V(72,2E,2E,5C), \
159 V(24,1C,1C,38), V(F1,A6,A6,57), V(C7,B4,B4,73), V(51,C6,C6,97), \
160 V(23,E8,E8,CB), V(7C,DD,DD,A1), V(9C,74,74,E8), V(21,1F,1F,3E), \
161 V(DD,4B,4B,96), V(DC,BD,BD,61), V(86,8B,8B,0D), V(85,8A,8A,0F), \
162 V(90,70,70,E0), V(42,3E,3E,7C), V(C4,B5,B5,71), V(AA,66,66,CC), \
163 V(D8,48,48,90), V(05,03,03,06), V(01,F6,F6,F7), V(12,0E,0E,1C), \
164 V(A3,61,61,C2), V(5F,35,35,6A), V(F9,57,57,AE), V(D0,B9,B9,69), \
165 V(91,86,86,17), V(58,C1,C1,99), V(27,1D,1D,3A), V(B9,9E,9E,27), \
166 V(38,E1,E1,D9), V(13,F8,F8,EB), V(B3,98,98,2B), V(33,11,11,22), \
167 V(BB,69,69,D2), V(70,D9,D9,A9), V(89,8E,8E,07), V(A7,94,94,33), \
168 V(B6,9B,9B,2D), V(22,1E,1E,3C), V(92,87,87,15), V(20,E9,E9,C9), \
169 V(49,CE,CE,87), V(FF,55,55,AA), V(78,28,28,50), V(7A,DF,DF,A5), \
170 V(8F,8C,8C,03), V(F8,A1,A1,59), V(80,89,89,09), V(17,0D,0D,1A), \
171 V(DA,BF,BF,65), V(31,E6,E6,D7), V(C6,42,42,84), V(B8,68,68,D0), \
172 V(C3,41,41,82), V(B0,99,99,29), V(77,2D,2D,5A), V(11,0F,0F,1E), \
173 V(CB,B0,B0,7B), V(FC,54,54,A8), V(D6,BB,BB,6D), V(3A,16,16,2C)
174
175#define V(a,b,c,d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000176static const uint32_t FT0[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000177#undef V
178
Hanno Beckerad049a92017-06-19 16:31:54 +0100179#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200180
Paul Bakker5121ce52009-01-03 21:22:43 +0000181#define V(a,b,c,d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000182static const uint32_t FT1[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000183#undef V
184
185#define V(a,b,c,d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000186static const uint32_t FT2[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000187#undef V
188
189#define V(a,b,c,d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000190static const uint32_t FT3[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000191#undef V
192
Hanno Becker177d3cf2017-06-07 15:52:48 +0100193#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200194
Paul Bakker5121ce52009-01-03 21:22:43 +0000195#undef FT
196
197/*
198 * Reverse S-box
199 */
200static const unsigned char RSb[256] =
201{
202 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
203 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
204 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
205 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
206 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
207 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
208 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
209 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
210 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
211 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
212 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
213 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
214 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
215 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
216 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
217 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
218 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
219 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
220 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
221 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
222 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
223 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
224 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
225 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
226 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
227 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
228 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
229 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
230 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
231 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
232 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
233 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
234};
235
236/*
237 * Reverse tables
238 */
239#define RT \
240\
241 V(50,A7,F4,51), V(53,65,41,7E), V(C3,A4,17,1A), V(96,5E,27,3A), \
242 V(CB,6B,AB,3B), V(F1,45,9D,1F), V(AB,58,FA,AC), V(93,03,E3,4B), \
243 V(55,FA,30,20), V(F6,6D,76,AD), V(91,76,CC,88), V(25,4C,02,F5), \
244 V(FC,D7,E5,4F), V(D7,CB,2A,C5), V(80,44,35,26), V(8F,A3,62,B5), \
245 V(49,5A,B1,DE), V(67,1B,BA,25), V(98,0E,EA,45), V(E1,C0,FE,5D), \
246 V(02,75,2F,C3), V(12,F0,4C,81), V(A3,97,46,8D), V(C6,F9,D3,6B), \
247 V(E7,5F,8F,03), V(95,9C,92,15), V(EB,7A,6D,BF), V(DA,59,52,95), \
248 V(2D,83,BE,D4), V(D3,21,74,58), V(29,69,E0,49), V(44,C8,C9,8E), \
249 V(6A,89,C2,75), V(78,79,8E,F4), V(6B,3E,58,99), V(DD,71,B9,27), \
250 V(B6,4F,E1,BE), V(17,AD,88,F0), V(66,AC,20,C9), V(B4,3A,CE,7D), \
251 V(18,4A,DF,63), V(82,31,1A,E5), V(60,33,51,97), V(45,7F,53,62), \
252 V(E0,77,64,B1), V(84,AE,6B,BB), V(1C,A0,81,FE), V(94,2B,08,F9), \
253 V(58,68,48,70), V(19,FD,45,8F), V(87,6C,DE,94), V(B7,F8,7B,52), \
254 V(23,D3,73,AB), V(E2,02,4B,72), V(57,8F,1F,E3), V(2A,AB,55,66), \
255 V(07,28,EB,B2), V(03,C2,B5,2F), V(9A,7B,C5,86), V(A5,08,37,D3), \
256 V(F2,87,28,30), V(B2,A5,BF,23), V(BA,6A,03,02), V(5C,82,16,ED), \
257 V(2B,1C,CF,8A), V(92,B4,79,A7), V(F0,F2,07,F3), V(A1,E2,69,4E), \
258 V(CD,F4,DA,65), V(D5,BE,05,06), V(1F,62,34,D1), V(8A,FE,A6,C4), \
259 V(9D,53,2E,34), V(A0,55,F3,A2), V(32,E1,8A,05), V(75,EB,F6,A4), \
260 V(39,EC,83,0B), V(AA,EF,60,40), V(06,9F,71,5E), V(51,10,6E,BD), \
261 V(F9,8A,21,3E), V(3D,06,DD,96), V(AE,05,3E,DD), V(46,BD,E6,4D), \
262 V(B5,8D,54,91), V(05,5D,C4,71), V(6F,D4,06,04), V(FF,15,50,60), \
263 V(24,FB,98,19), V(97,E9,BD,D6), V(CC,43,40,89), V(77,9E,D9,67), \
264 V(BD,42,E8,B0), V(88,8B,89,07), V(38,5B,19,E7), V(DB,EE,C8,79), \
265 V(47,0A,7C,A1), V(E9,0F,42,7C), V(C9,1E,84,F8), V(00,00,00,00), \
266 V(83,86,80,09), V(48,ED,2B,32), V(AC,70,11,1E), V(4E,72,5A,6C), \
267 V(FB,FF,0E,FD), V(56,38,85,0F), V(1E,D5,AE,3D), V(27,39,2D,36), \
268 V(64,D9,0F,0A), V(21,A6,5C,68), V(D1,54,5B,9B), V(3A,2E,36,24), \
269 V(B1,67,0A,0C), V(0F,E7,57,93), V(D2,96,EE,B4), V(9E,91,9B,1B), \
270 V(4F,C5,C0,80), V(A2,20,DC,61), V(69,4B,77,5A), V(16,1A,12,1C), \
271 V(0A,BA,93,E2), V(E5,2A,A0,C0), V(43,E0,22,3C), V(1D,17,1B,12), \
272 V(0B,0D,09,0E), V(AD,C7,8B,F2), V(B9,A8,B6,2D), V(C8,A9,1E,14), \
273 V(85,19,F1,57), V(4C,07,75,AF), V(BB,DD,99,EE), V(FD,60,7F,A3), \
274 V(9F,26,01,F7), V(BC,F5,72,5C), V(C5,3B,66,44), V(34,7E,FB,5B), \
275 V(76,29,43,8B), V(DC,C6,23,CB), V(68,FC,ED,B6), V(63,F1,E4,B8), \
276 V(CA,DC,31,D7), V(10,85,63,42), V(40,22,97,13), V(20,11,C6,84), \
277 V(7D,24,4A,85), V(F8,3D,BB,D2), V(11,32,F9,AE), V(6D,A1,29,C7), \
278 V(4B,2F,9E,1D), V(F3,30,B2,DC), V(EC,52,86,0D), V(D0,E3,C1,77), \
279 V(6C,16,B3,2B), V(99,B9,70,A9), V(FA,48,94,11), V(22,64,E9,47), \
280 V(C4,8C,FC,A8), V(1A,3F,F0,A0), V(D8,2C,7D,56), V(EF,90,33,22), \
281 V(C7,4E,49,87), V(C1,D1,38,D9), V(FE,A2,CA,8C), V(36,0B,D4,98), \
282 V(CF,81,F5,A6), V(28,DE,7A,A5), V(26,8E,B7,DA), V(A4,BF,AD,3F), \
283 V(E4,9D,3A,2C), V(0D,92,78,50), V(9B,CC,5F,6A), V(62,46,7E,54), \
284 V(C2,13,8D,F6), V(E8,B8,D8,90), V(5E,F7,39,2E), V(F5,AF,C3,82), \
285 V(BE,80,5D,9F), V(7C,93,D0,69), V(A9,2D,D5,6F), V(B3,12,25,CF), \
286 V(3B,99,AC,C8), V(A7,7D,18,10), V(6E,63,9C,E8), V(7B,BB,3B,DB), \
287 V(09,78,26,CD), V(F4,18,59,6E), V(01,B7,9A,EC), V(A8,9A,4F,83), \
288 V(65,6E,95,E6), V(7E,E6,FF,AA), V(08,CF,BC,21), V(E6,E8,15,EF), \
289 V(D9,9B,E7,BA), V(CE,36,6F,4A), V(D4,09,9F,EA), V(D6,7C,B0,29), \
290 V(AF,B2,A4,31), V(31,23,3F,2A), V(30,94,A5,C6), V(C0,66,A2,35), \
291 V(37,BC,4E,74), V(A6,CA,82,FC), V(B0,D0,90,E0), V(15,D8,A7,33), \
292 V(4A,98,04,F1), V(F7,DA,EC,41), V(0E,50,CD,7F), V(2F,F6,91,17), \
293 V(8D,D6,4D,76), V(4D,B0,EF,43), V(54,4D,AA,CC), V(DF,04,96,E4), \
294 V(E3,B5,D1,9E), V(1B,88,6A,4C), V(B8,1F,2C,C1), V(7F,51,65,46), \
295 V(04,EA,5E,9D), V(5D,35,8C,01), V(73,74,87,FA), V(2E,41,0B,FB), \
296 V(5A,1D,67,B3), V(52,D2,DB,92), V(33,56,10,E9), V(13,47,D6,6D), \
297 V(8C,61,D7,9A), V(7A,0C,A1,37), V(8E,14,F8,59), V(89,3C,13,EB), \
298 V(EE,27,A9,CE), V(35,C9,61,B7), V(ED,E5,1C,E1), V(3C,B1,47,7A), \
299 V(59,DF,D2,9C), V(3F,73,F2,55), V(79,CE,14,18), V(BF,37,C7,73), \
300 V(EA,CD,F7,53), V(5B,AA,FD,5F), V(14,6F,3D,DF), V(86,DB,44,78), \
301 V(81,F3,AF,CA), V(3E,C4,68,B9), V(2C,34,24,38), V(5F,40,A3,C2), \
302 V(72,C3,1D,16), V(0C,25,E2,BC), V(8B,49,3C,28), V(41,95,0D,FF), \
303 V(71,01,A8,39), V(DE,B3,0C,08), V(9C,E4,B4,D8), V(90,C1,56,64), \
304 V(61,84,CB,7B), V(70,B6,32,D5), V(74,5C,6C,48), V(42,57,B8,D0)
305
306#define V(a,b,c,d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000307static const uint32_t RT0[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000308#undef V
309
Hanno Beckerad049a92017-06-19 16:31:54 +0100310#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200311
Paul Bakker5121ce52009-01-03 21:22:43 +0000312#define V(a,b,c,d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000313static const uint32_t RT1[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000314#undef V
315
316#define V(a,b,c,d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000317static const uint32_t RT2[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000318#undef V
319
320#define V(a,b,c,d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000321static const uint32_t RT3[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000322#undef V
323
Hanno Becker177d3cf2017-06-07 15:52:48 +0100324#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200325
Paul Bakker5121ce52009-01-03 21:22:43 +0000326#undef RT
327
328/*
329 * Round constants
330 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000331static const uint32_t RCON[10] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000332{
333 0x00000001, 0x00000002, 0x00000004, 0x00000008,
334 0x00000010, 0x00000020, 0x00000040, 0x00000080,
335 0x0000001B, 0x00000036
336};
337
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200338#else /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000339
340/*
341 * Forward S-box & tables
342 */
343static unsigned char FSb[256];
Paul Bakker9af723c2014-05-01 13:03:14 +0200344static uint32_t FT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100345#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker9af723c2014-05-01 13:03:14 +0200346static uint32_t FT1[256];
347static uint32_t FT2[256];
348static uint32_t FT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100349#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000350
351/*
352 * Reverse S-box & tables
353 */
354static unsigned char RSb[256];
Paul Bakker5c2364c2012-10-01 14:41:15 +0000355static uint32_t RT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100356#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker5c2364c2012-10-01 14:41:15 +0000357static uint32_t RT1[256];
358static uint32_t RT2[256];
359static uint32_t RT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100360#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000361
362/*
363 * Round constants
364 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000365static uint32_t RCON[10];
Paul Bakker5121ce52009-01-03 21:22:43 +0000366
367/*
368 * Tables generation code
369 */
Hanno Becker1eeca412018-10-15 12:01:35 +0100370#define ROTL8(x) ( ( (x) << 8 ) & 0xFFFFFFFF ) | ( (x) >> 24 )
371#define XTIME(x) ( ( (x) << 1 ) ^ ( ( (x) & 0x80 ) ? 0x1B : 0x00 ) )
Hanno Becker818bac52018-10-26 09:13:26 +0100372#define MUL(x,y) ( ( (x) && (y) ) ? pow[(log[(x)]+log[(y)]) % 255] : 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000373
374static int aes_init_done = 0;
375
376static void aes_gen_tables( void )
377{
378 int i, x, y, z;
379 int pow[256];
380 int log[256];
381
382 /*
383 * compute pow and log tables over GF(2^8)
384 */
385 for( i = 0, x = 1; i < 256; i++ )
386 {
387 pow[i] = x;
388 log[x] = i;
Joe Subbiani6b897c92021-07-08 14:59:52 +0100389 x = MBEDTLS_BYTE_0( x ^ XTIME( x ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000390 }
391
392 /*
393 * calculate the round constants
394 */
395 for( i = 0, x = 1; i < 10; i++ )
396 {
Paul Bakker5c2364c2012-10-01 14:41:15 +0000397 RCON[i] = (uint32_t) x;
Joe Subbiani6b897c92021-07-08 14:59:52 +0100398 x = MBEDTLS_BYTE_0( XTIME( x ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000399 }
400
401 /*
402 * generate the forward and reverse S-boxes
403 */
404 FSb[0x00] = 0x63;
405 RSb[0x63] = 0x00;
406
407 for( i = 1; i < 256; i++ )
408 {
409 x = pow[255 - log[i]];
410
Joe Subbiani6b897c92021-07-08 14:59:52 +0100411 y = x; y = MBEDTLS_BYTE_0( ( y << 1 ) | ( y >> 7 ) );
412 x ^= y; y = MBEDTLS_BYTE_0( ( y << 1 ) | ( y >> 7 ) );
413 x ^= y; y = MBEDTLS_BYTE_0( ( y << 1 ) | ( y >> 7 ) );
414 x ^= y; y = MBEDTLS_BYTE_0( ( y << 1 ) | ( y >> 7 ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000415 x ^= y ^ 0x63;
416
417 FSb[i] = (unsigned char) x;
418 RSb[x] = (unsigned char) i;
419 }
420
421 /*
422 * generate the forward and reverse tables
423 */
424 for( i = 0; i < 256; i++ )
425 {
426 x = FSb[i];
Joe Subbiani6b897c92021-07-08 14:59:52 +0100427 y = MBEDTLS_BYTE_0( XTIME( x ) );
428 z = MBEDTLS_BYTE_0( y ^ x );
Paul Bakker5121ce52009-01-03 21:22:43 +0000429
Paul Bakker5c2364c2012-10-01 14:41:15 +0000430 FT0[i] = ( (uint32_t) y ) ^
431 ( (uint32_t) x << 8 ) ^
432 ( (uint32_t) x << 16 ) ^
433 ( (uint32_t) z << 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000434
Hanno Beckerad049a92017-06-19 16:31:54 +0100435#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +0000436 FT1[i] = ROTL8( FT0[i] );
437 FT2[i] = ROTL8( FT1[i] );
438 FT3[i] = ROTL8( FT2[i] );
Hanno Becker177d3cf2017-06-07 15:52:48 +0100439#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000440
441 x = RSb[i];
442
Paul Bakker5c2364c2012-10-01 14:41:15 +0000443 RT0[i] = ( (uint32_t) MUL( 0x0E, x ) ) ^
444 ( (uint32_t) MUL( 0x09, x ) << 8 ) ^
445 ( (uint32_t) MUL( 0x0D, x ) << 16 ) ^
446 ( (uint32_t) MUL( 0x0B, x ) << 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000447
Hanno Beckerad049a92017-06-19 16:31:54 +0100448#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +0000449 RT1[i] = ROTL8( RT0[i] );
450 RT2[i] = ROTL8( RT1[i] );
451 RT3[i] = ROTL8( RT2[i] );
Hanno Becker177d3cf2017-06-07 15:52:48 +0100452#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000453 }
454}
455
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200456#undef ROTL8
457
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200458#endif /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000459
Hanno Beckerad049a92017-06-19 16:31:54 +0100460#if defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200461
462#define ROTL8(x) ( (uint32_t)( ( x ) << 8 ) + (uint32_t)( ( x ) >> 24 ) )
463#define ROTL16(x) ( (uint32_t)( ( x ) << 16 ) + (uint32_t)( ( x ) >> 16 ) )
464#define ROTL24(x) ( (uint32_t)( ( x ) << 24 ) + (uint32_t)( ( x ) >> 8 ) )
465
466#define AES_RT0(idx) RT0[idx]
467#define AES_RT1(idx) ROTL8( RT0[idx] )
468#define AES_RT2(idx) ROTL16( RT0[idx] )
469#define AES_RT3(idx) ROTL24( RT0[idx] )
470
471#define AES_FT0(idx) FT0[idx]
472#define AES_FT1(idx) ROTL8( FT0[idx] )
473#define AES_FT2(idx) ROTL16( FT0[idx] )
474#define AES_FT3(idx) ROTL24( FT0[idx] )
475
Hanno Becker177d3cf2017-06-07 15:52:48 +0100476#else /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200477
478#define AES_RT0(idx) RT0[idx]
479#define AES_RT1(idx) RT1[idx]
480#define AES_RT2(idx) RT2[idx]
481#define AES_RT3(idx) RT3[idx]
482
483#define AES_FT0(idx) FT0[idx]
484#define AES_FT1(idx) FT1[idx]
485#define AES_FT2(idx) FT2[idx]
486#define AES_FT3(idx) FT3[idx]
487
Hanno Becker177d3cf2017-06-07 15:52:48 +0100488#endif /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200489
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200490void mbedtls_aes_init( mbedtls_aes_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200491{
Manuel Pégourié-Gonnard0e9cddb2018-12-10 16:37:51 +0100492 AES_VALIDATE( ctx != NULL );
Simon Butcher5201e412018-12-06 17:40:14 +0000493
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200494 memset( ctx, 0, sizeof( mbedtls_aes_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200495}
496
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200497void mbedtls_aes_free( mbedtls_aes_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200498{
499 if( ctx == NULL )
500 return;
501
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500502 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_aes_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200503}
504
Jaeden Amero9366feb2018-05-29 18:55:17 +0100505#if defined(MBEDTLS_CIPHER_MODE_XTS)
506void mbedtls_aes_xts_init( mbedtls_aes_xts_context *ctx )
507{
Manuel Pégourié-Gonnard0e9cddb2018-12-10 16:37:51 +0100508 AES_VALIDATE( ctx != NULL );
Simon Butcher5201e412018-12-06 17:40:14 +0000509
Jaeden Amero9366feb2018-05-29 18:55:17 +0100510 mbedtls_aes_init( &ctx->crypt );
511 mbedtls_aes_init( &ctx->tweak );
512}
513
514void mbedtls_aes_xts_free( mbedtls_aes_xts_context *ctx )
515{
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100516 if( ctx == NULL )
517 return;
Simon Butcher5201e412018-12-06 17:40:14 +0000518
Jaeden Amero9366feb2018-05-29 18:55:17 +0100519 mbedtls_aes_free( &ctx->crypt );
520 mbedtls_aes_free( &ctx->tweak );
521}
522#endif /* MBEDTLS_CIPHER_MODE_XTS */
523
Paul Bakker5121ce52009-01-03 21:22:43 +0000524/*
525 * AES key schedule (encryption)
526 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200527#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200528int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key,
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200529 unsigned int keybits )
Paul Bakker5121ce52009-01-03 21:22:43 +0000530{
Paul Bakker23986e52011-04-24 08:57:21 +0000531 unsigned int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000532 uint32_t *RK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000533
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100534 AES_VALIDATE_RET( ctx != NULL );
535 AES_VALIDATE_RET( key != NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000536
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200537 switch( keybits )
Paul Bakker5121ce52009-01-03 21:22:43 +0000538 {
539 case 128: ctx->nr = 10; break;
540 case 192: ctx->nr = 12; break;
541 case 256: ctx->nr = 14; break;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200542 default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000543 }
544
Simon Butcher5201e412018-12-06 17:40:14 +0000545#if !defined(MBEDTLS_AES_ROM_TABLES)
546 if( aes_init_done == 0 )
547 {
548 aes_gen_tables();
549 aes_init_done = 1;
Simon Butcher5201e412018-12-06 17:40:14 +0000550 }
551#endif
552
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200553#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_PADLOCK_ALIGN16)
Paul Bakker048d04e2012-02-12 17:31:04 +0000554 if( aes_padlock_ace == -1 )
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100555 aes_padlock_ace = mbedtls_padlock_has_support( MBEDTLS_PADLOCK_ACE );
Paul Bakker048d04e2012-02-12 17:31:04 +0000556
557 if( aes_padlock_ace )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200558 ctx->rk = RK = MBEDTLS_PADLOCK_ALIGN16( ctx->buf );
Paul Bakker048d04e2012-02-12 17:31:04 +0000559 else
Paul Bakker5121ce52009-01-03 21:22:43 +0000560#endif
Paul Bakker048d04e2012-02-12 17:31:04 +0000561 ctx->rk = RK = ctx->buf;
Paul Bakker5121ce52009-01-03 21:22:43 +0000562
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200563#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100564 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) )
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200565 return( mbedtls_aesni_setkey_enc( (unsigned char *) ctx->rk, key, keybits ) );
Manuel Pégourié-Gonnard47a35362013-12-28 20:45:04 +0100566#endif
567
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200568 for( i = 0; i < ( keybits >> 5 ); i++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000569 {
Joe Subbiani9231d5f2021-07-07 16:56:29 +0100570 RK[i] = MBEDTLS_GET_UINT32_LE( key, i << 2 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000571 }
572
573 switch( ctx->nr )
574 {
575 case 10:
576
577 for( i = 0; i < 10; i++, RK += 4 )
578 {
579 RK[4] = RK[0] ^ RCON[i] ^
Joe Subbiani6b897c92021-07-08 14:59:52 +0100580 ( (uint32_t) FSb[ MBEDTLS_BYTE_1( RK[3] ) ] ) ^
581 ( (uint32_t) FSb[ MBEDTLS_BYTE_2( RK[3] ) ] << 8 ) ^
582 ( (uint32_t) FSb[ MBEDTLS_BYTE_3( RK[3] ) ] << 16 ) ^
583 ( (uint32_t) FSb[ MBEDTLS_BYTE_0( RK[3] ) ] << 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000584
585 RK[5] = RK[1] ^ RK[4];
586 RK[6] = RK[2] ^ RK[5];
587 RK[7] = RK[3] ^ RK[6];
588 }
589 break;
590
591 case 12:
592
593 for( i = 0; i < 8; i++, RK += 6 )
594 {
595 RK[6] = RK[0] ^ RCON[i] ^
Joe Subbiani6b897c92021-07-08 14:59:52 +0100596 ( (uint32_t) FSb[ MBEDTLS_BYTE_1( RK[5] ) ] ) ^
597 ( (uint32_t) FSb[ MBEDTLS_BYTE_2( RK[5] ) ] << 8 ) ^
598 ( (uint32_t) FSb[ MBEDTLS_BYTE_3( RK[5] ) ] << 16 ) ^
599 ( (uint32_t) FSb[ MBEDTLS_BYTE_0( RK[5] ) ] << 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000600
601 RK[7] = RK[1] ^ RK[6];
602 RK[8] = RK[2] ^ RK[7];
603 RK[9] = RK[3] ^ RK[8];
604 RK[10] = RK[4] ^ RK[9];
605 RK[11] = RK[5] ^ RK[10];
606 }
607 break;
608
609 case 14:
610
611 for( i = 0; i < 7; i++, RK += 8 )
612 {
613 RK[8] = RK[0] ^ RCON[i] ^
Joe Subbiani6b897c92021-07-08 14:59:52 +0100614 ( (uint32_t) FSb[ MBEDTLS_BYTE_1( RK[7] ) ] ) ^
615 ( (uint32_t) FSb[ MBEDTLS_BYTE_2( RK[7] ) ] << 8 ) ^
616 ( (uint32_t) FSb[ MBEDTLS_BYTE_3( RK[7] ) ] << 16 ) ^
617 ( (uint32_t) FSb[ MBEDTLS_BYTE_0( RK[7] ) ] << 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000618
619 RK[9] = RK[1] ^ RK[8];
620 RK[10] = RK[2] ^ RK[9];
621 RK[11] = RK[3] ^ RK[10];
622
623 RK[12] = RK[4] ^
Joe Subbiani6b897c92021-07-08 14:59:52 +0100624 ( (uint32_t) FSb[ MBEDTLS_BYTE_0( RK[11] ) ] ) ^
625 ( (uint32_t) FSb[ MBEDTLS_BYTE_1( RK[11] ) ] << 8 ) ^
626 ( (uint32_t) FSb[ MBEDTLS_BYTE_2( RK[11] ) ] << 16 ) ^
627 ( (uint32_t) FSb[ MBEDTLS_BYTE_3( RK[11] ) ] << 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000628
629 RK[13] = RK[5] ^ RK[12];
630 RK[14] = RK[6] ^ RK[13];
631 RK[15] = RK[7] ^ RK[14];
632 }
633 break;
Paul Bakker5121ce52009-01-03 21:22:43 +0000634 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000635
636 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000637}
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200638#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000639
640/*
641 * AES key schedule (decryption)
642 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200643#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200644int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key,
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200645 unsigned int keybits )
Paul Bakker5121ce52009-01-03 21:22:43 +0000646{
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200647 int i, j, ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200648 mbedtls_aes_context cty;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000649 uint32_t *RK;
650 uint32_t *SK;
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200651
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100652 AES_VALIDATE_RET( ctx != NULL );
653 AES_VALIDATE_RET( key != NULL );
Simon Butcher5201e412018-12-06 17:40:14 +0000654
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200655 mbedtls_aes_init( &cty );
Paul Bakker5121ce52009-01-03 21:22:43 +0000656
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200657#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_PADLOCK_ALIGN16)
Paul Bakker048d04e2012-02-12 17:31:04 +0000658 if( aes_padlock_ace == -1 )
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100659 aes_padlock_ace = mbedtls_padlock_has_support( MBEDTLS_PADLOCK_ACE );
Paul Bakker048d04e2012-02-12 17:31:04 +0000660
661 if( aes_padlock_ace )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200662 ctx->rk = RK = MBEDTLS_PADLOCK_ALIGN16( ctx->buf );
Paul Bakker048d04e2012-02-12 17:31:04 +0000663 else
Paul Bakker5121ce52009-01-03 21:22:43 +0000664#endif
Paul Bakker048d04e2012-02-12 17:31:04 +0000665 ctx->rk = RK = ctx->buf;
Paul Bakker5121ce52009-01-03 21:22:43 +0000666
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200667 /* Also checks keybits */
668 if( ( ret = mbedtls_aes_setkey_enc( &cty, key, keybits ) ) != 0 )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200669 goto exit;
Paul Bakker2b222c82009-07-27 21:03:45 +0000670
Manuel Pégourié-Gonnardafd5a082014-05-28 21:52:59 +0200671 ctx->nr = cty.nr;
672
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200673#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100674 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) )
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100675 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200676 mbedtls_aesni_inverse_key( (unsigned char *) ctx->rk,
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100677 (const unsigned char *) cty.rk, ctx->nr );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200678 goto exit;
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100679 }
680#endif
681
Paul Bakker5121ce52009-01-03 21:22:43 +0000682 SK = cty.rk + cty.nr * 4;
683
684 *RK++ = *SK++;
685 *RK++ = *SK++;
686 *RK++ = *SK++;
687 *RK++ = *SK++;
688
689 for( i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8 )
690 {
691 for( j = 0; j < 4; j++, SK++ )
692 {
Joe Subbiani6b897c92021-07-08 14:59:52 +0100693 *RK++ = AES_RT0( FSb[ MBEDTLS_BYTE_0( *SK ) ] ) ^
694 AES_RT1( FSb[ MBEDTLS_BYTE_1( *SK ) ] ) ^
695 AES_RT2( FSb[ MBEDTLS_BYTE_2( *SK ) ] ) ^
696 AES_RT3( FSb[ MBEDTLS_BYTE_3( *SK ) ] );
Paul Bakker5121ce52009-01-03 21:22:43 +0000697 }
698 }
699
700 *RK++ = *SK++;
701 *RK++ = *SK++;
702 *RK++ = *SK++;
703 *RK++ = *SK++;
704
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200705exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200706 mbedtls_aes_free( &cty );
Paul Bakker2b222c82009-07-27 21:03:45 +0000707
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200708 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000709}
gabor-mezei-arm95db3012020-10-26 11:35:23 +0100710#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */
Jaeden Amero9366feb2018-05-29 18:55:17 +0100711
712#if defined(MBEDTLS_CIPHER_MODE_XTS)
713static int mbedtls_aes_xts_decode_keys( const unsigned char *key,
714 unsigned int keybits,
715 const unsigned char **key1,
716 unsigned int *key1bits,
717 const unsigned char **key2,
718 unsigned int *key2bits )
719{
720 const unsigned int half_keybits = keybits / 2;
721 const unsigned int half_keybytes = half_keybits / 8;
722
723 switch( keybits )
724 {
725 case 256: break;
726 case 512: break;
727 default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH );
728 }
729
730 *key1bits = half_keybits;
731 *key2bits = half_keybits;
732 *key1 = &key[0];
733 *key2 = &key[half_keybytes];
734
735 return 0;
736}
737
738int mbedtls_aes_xts_setkey_enc( mbedtls_aes_xts_context *ctx,
739 const unsigned char *key,
740 unsigned int keybits)
741{
Janos Follath24eed8d2019-11-22 13:21:35 +0000742 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100743 const unsigned char *key1, *key2;
744 unsigned int key1bits, key2bits;
745
Manuel Pégourié-Gonnard68e3dff2018-12-12 12:48:04 +0100746 AES_VALIDATE_RET( ctx != NULL );
747 AES_VALIDATE_RET( key != NULL );
748
Jaeden Amero9366feb2018-05-29 18:55:17 +0100749 ret = mbedtls_aes_xts_decode_keys( key, keybits, &key1, &key1bits,
750 &key2, &key2bits );
751 if( ret != 0 )
752 return( ret );
753
754 /* Set the tweak key. Always set tweak key for the encryption mode. */
755 ret = mbedtls_aes_setkey_enc( &ctx->tweak, key2, key2bits );
756 if( ret != 0 )
757 return( ret );
758
759 /* Set crypt key for encryption. */
760 return mbedtls_aes_setkey_enc( &ctx->crypt, key1, key1bits );
761}
762
763int mbedtls_aes_xts_setkey_dec( mbedtls_aes_xts_context *ctx,
764 const unsigned char *key,
765 unsigned int keybits)
766{
Janos Follath24eed8d2019-11-22 13:21:35 +0000767 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100768 const unsigned char *key1, *key2;
769 unsigned int key1bits, key2bits;
770
Manuel Pégourié-Gonnard68e3dff2018-12-12 12:48:04 +0100771 AES_VALIDATE_RET( ctx != NULL );
772 AES_VALIDATE_RET( key != NULL );
773
Jaeden Amero9366feb2018-05-29 18:55:17 +0100774 ret = mbedtls_aes_xts_decode_keys( key, keybits, &key1, &key1bits,
775 &key2, &key2bits );
776 if( ret != 0 )
777 return( ret );
778
779 /* Set the tweak key. Always set tweak key for encryption. */
780 ret = mbedtls_aes_setkey_enc( &ctx->tweak, key2, key2bits );
781 if( ret != 0 )
782 return( ret );
783
784 /* Set crypt key for decryption. */
785 return mbedtls_aes_setkey_dec( &ctx->crypt, key1, key1bits );
786}
787#endif /* MBEDTLS_CIPHER_MODE_XTS */
788
Joe Subbiani6b897c92021-07-08 14:59:52 +0100789#define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \
790 do \
791 { \
792 (X0) = *RK++ ^ AES_FT0( MBEDTLS_BYTE_0( Y0 ) ) ^ \
793 AES_FT1( MBEDTLS_BYTE_1( Y1 ) ) ^ \
794 AES_FT2( MBEDTLS_BYTE_2( Y2 ) ) ^ \
795 AES_FT3( MBEDTLS_BYTE_3( Y3 ) ); \
796 \
797 (X1) = *RK++ ^ AES_FT0( MBEDTLS_BYTE_0( Y1 ) ) ^ \
798 AES_FT1( MBEDTLS_BYTE_1( Y2 ) ) ^ \
799 AES_FT2( MBEDTLS_BYTE_2( Y3 ) ) ^ \
800 AES_FT3( MBEDTLS_BYTE_3( Y0 ) ); \
801 \
802 (X2) = *RK++ ^ AES_FT0( MBEDTLS_BYTE_0( Y2 ) ) ^ \
803 AES_FT1( MBEDTLS_BYTE_1( Y3 ) ) ^ \
804 AES_FT2( MBEDTLS_BYTE_2( Y0 ) ) ^ \
805 AES_FT3( MBEDTLS_BYTE_3( Y1 ) ); \
806 \
807 (X3) = *RK++ ^ AES_FT0( MBEDTLS_BYTE_0( Y3 ) ) ^ \
808 AES_FT1( MBEDTLS_BYTE_1( Y0 ) ) ^ \
809 AES_FT2( MBEDTLS_BYTE_2( Y1 ) ) ^ \
810 AES_FT3( MBEDTLS_BYTE_3( Y2 ) ); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100811 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000812
Hanno Becker1eeca412018-10-15 12:01:35 +0100813#define AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \
814 do \
815 { \
Joe Subbiani6b897c92021-07-08 14:59:52 +0100816 (X0) = *RK++ ^ AES_RT0( MBEDTLS_BYTE_0( Y0 ) ) ^ \
817 AES_RT1( MBEDTLS_BYTE_1( Y3 ) ) ^ \
818 AES_RT2( MBEDTLS_BYTE_2( Y2 ) ) ^ \
819 AES_RT3( MBEDTLS_BYTE_3( Y1 ) ); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100820 \
Joe Subbiani6b897c92021-07-08 14:59:52 +0100821 (X1) = *RK++ ^ AES_RT0( MBEDTLS_BYTE_0( Y1 ) ) ^ \
822 AES_RT1( MBEDTLS_BYTE_1( Y0 ) ) ^ \
823 AES_RT2( MBEDTLS_BYTE_2( Y3 ) ) ^ \
824 AES_RT3( MBEDTLS_BYTE_3( Y2 ) ); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100825 \
Joe Subbiani6b897c92021-07-08 14:59:52 +0100826 (X2) = *RK++ ^ AES_RT0( MBEDTLS_BYTE_0( Y2 ) ) ^ \
827 AES_RT1( MBEDTLS_BYTE_1( Y1 ) ) ^ \
828 AES_RT2( MBEDTLS_BYTE_2( Y0 ) ) ^ \
829 AES_RT3( MBEDTLS_BYTE_3( Y3 ) ); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100830 \
Joe Subbiani6b897c92021-07-08 14:59:52 +0100831 (X3) = *RK++ ^ AES_RT0( MBEDTLS_BYTE_0( Y3 ) ) ^ \
832 AES_RT1( MBEDTLS_BYTE_1( Y2 ) ) ^ \
833 AES_RT2( MBEDTLS_BYTE_2( Y1 ) ) ^ \
834 AES_RT3( MBEDTLS_BYTE_3( Y0 ) ); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100835 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000836
837/*
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200838 * AES-ECB block encryption
839 */
840#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Andres AGf5bf7182017-03-03 14:09:56 +0000841int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx,
842 const unsigned char input[16],
843 unsigned char output[16] )
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200844{
845 int i;
Gilles Peskine5197c662020-08-26 17:03:24 +0200846 uint32_t *RK = ctx->rk;
847 struct
848 {
849 uint32_t X[4];
850 uint32_t Y[4];
851 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200852
Joe Subbiani9231d5f2021-07-07 16:56:29 +0100853 t.X[0] = MBEDTLS_GET_UINT32_LE( input, 0 ); t.X[0] ^= *RK++;
854 t.X[1] = MBEDTLS_GET_UINT32_LE( input, 4 ); t.X[1] ^= *RK++;
855 t.X[2] = MBEDTLS_GET_UINT32_LE( input, 8 ); t.X[2] ^= *RK++;
856 t.X[3] = MBEDTLS_GET_UINT32_LE( input, 12 ); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200857
858 for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- )
859 {
Gilles Peskine5197c662020-08-26 17:03:24 +0200860 AES_FROUND( t.Y[0], t.Y[1], t.Y[2], t.Y[3], t.X[0], t.X[1], t.X[2], t.X[3] );
861 AES_FROUND( t.X[0], t.X[1], t.X[2], t.X[3], t.Y[0], t.Y[1], t.Y[2], t.Y[3] );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200862 }
863
Gilles Peskine5197c662020-08-26 17:03:24 +0200864 AES_FROUND( t.Y[0], t.Y[1], t.Y[2], t.Y[3], t.X[0], t.X[1], t.X[2], t.X[3] );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200865
Gilles Peskine5197c662020-08-26 17:03:24 +0200866 t.X[0] = *RK++ ^ \
Joe Subbiani6b897c92021-07-08 14:59:52 +0100867 ( (uint32_t) FSb[ MBEDTLS_BYTE_0( t.Y[0] ) ] ) ^
868 ( (uint32_t) FSb[ MBEDTLS_BYTE_1( t.Y[1] ) ] << 8 ) ^
869 ( (uint32_t) FSb[ MBEDTLS_BYTE_2( t.Y[2] ) ] << 16 ) ^
870 ( (uint32_t) FSb[ MBEDTLS_BYTE_3( t.Y[3] ) ] << 24 );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200871
Gilles Peskine5197c662020-08-26 17:03:24 +0200872 t.X[1] = *RK++ ^ \
Joe Subbiani6b897c92021-07-08 14:59:52 +0100873 ( (uint32_t) FSb[ MBEDTLS_BYTE_0( t.Y[1] ) ] ) ^
874 ( (uint32_t) FSb[ MBEDTLS_BYTE_1( t.Y[2] ) ] << 8 ) ^
875 ( (uint32_t) FSb[ MBEDTLS_BYTE_2( t.Y[3] ) ] << 16 ) ^
876 ( (uint32_t) FSb[ MBEDTLS_BYTE_3( t.Y[0] ) ] << 24 );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200877
Gilles Peskine5197c662020-08-26 17:03:24 +0200878 t.X[2] = *RK++ ^ \
Joe Subbiani6b897c92021-07-08 14:59:52 +0100879 ( (uint32_t) FSb[ MBEDTLS_BYTE_0( t.Y[2] ) ] ) ^
880 ( (uint32_t) FSb[ MBEDTLS_BYTE_1( t.Y[3] ) ] << 8 ) ^
881 ( (uint32_t) FSb[ MBEDTLS_BYTE_2( t.Y[0] ) ] << 16 ) ^
882 ( (uint32_t) FSb[ MBEDTLS_BYTE_3( t.Y[1] ) ] << 24 );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200883
Gilles Peskine5197c662020-08-26 17:03:24 +0200884 t.X[3] = *RK++ ^ \
Joe Subbiani6b897c92021-07-08 14:59:52 +0100885 ( (uint32_t) FSb[ MBEDTLS_BYTE_0( t.Y[3] ) ] ) ^
886 ( (uint32_t) FSb[ MBEDTLS_BYTE_1( t.Y[0] ) ] << 8 ) ^
887 ( (uint32_t) FSb[ MBEDTLS_BYTE_2( t.Y[1] ) ] << 16 ) ^
888 ( (uint32_t) FSb[ MBEDTLS_BYTE_3( t.Y[2] ) ] << 24 );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200889
Joe Subbiani2bbafda2021-06-24 13:00:03 +0100890 MBEDTLS_PUT_UINT32_LE( t.X[0], output, 0 );
891 MBEDTLS_PUT_UINT32_LE( t.X[1], output, 4 );
892 MBEDTLS_PUT_UINT32_LE( t.X[2], output, 8 );
893 MBEDTLS_PUT_UINT32_LE( t.X[3], output, 12 );
Andres AGf5bf7182017-03-03 14:09:56 +0000894
Gilles Peskine5197c662020-08-26 17:03:24 +0200895 mbedtls_platform_zeroize( &t, sizeof( t ) );
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500896
Andres AGf5bf7182017-03-03 14:09:56 +0000897 return( 0 );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200898}
899#endif /* !MBEDTLS_AES_ENCRYPT_ALT */
900
Gilles Peskine8db3efb2018-02-21 19:16:20 +0100901#if !defined(MBEDTLS_DEPRECATED_REMOVED)
Hanno Beckerbedc2052017-06-26 12:46:56 +0100902void mbedtls_aes_encrypt( mbedtls_aes_context *ctx,
903 const unsigned char input[16],
904 unsigned char output[16] )
905{
Mateusz Starzyk15a74202021-08-05 13:56:48 +0200906 MBEDTLS_IGNORE_RETURN( mbedtls_internal_aes_encrypt( ctx, input, output ) );
Hanno Beckerbedc2052017-06-26 12:46:56 +0100907}
Gilles Peskine8db3efb2018-02-21 19:16:20 +0100908#endif /* !MBEDTLS_DEPRECATED_REMOVED */
Hanno Beckerbedc2052017-06-26 12:46:56 +0100909
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200910/*
911 * AES-ECB block decryption
912 */
913#if !defined(MBEDTLS_AES_DECRYPT_ALT)
Andres AGf5bf7182017-03-03 14:09:56 +0000914int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx,
915 const unsigned char input[16],
916 unsigned char output[16] )
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200917{
918 int i;
Gilles Peskine5197c662020-08-26 17:03:24 +0200919 uint32_t *RK = ctx->rk;
920 struct
921 {
922 uint32_t X[4];
923 uint32_t Y[4];
924 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200925
Joe Subbiani9231d5f2021-07-07 16:56:29 +0100926 t.X[0] = MBEDTLS_GET_UINT32_LE( input, 0 ); t.X[0] ^= *RK++;
927 t.X[1] = MBEDTLS_GET_UINT32_LE( input, 4 ); t.X[1] ^= *RK++;
928 t.X[2] = MBEDTLS_GET_UINT32_LE( input, 8 ); t.X[2] ^= *RK++;
929 t.X[3] = MBEDTLS_GET_UINT32_LE( input, 12 ); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200930
931 for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- )
932 {
Gilles Peskine5197c662020-08-26 17:03:24 +0200933 AES_RROUND( t.Y[0], t.Y[1], t.Y[2], t.Y[3], t.X[0], t.X[1], t.X[2], t.X[3] );
934 AES_RROUND( t.X[0], t.X[1], t.X[2], t.X[3], t.Y[0], t.Y[1], t.Y[2], t.Y[3] );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200935 }
936
Gilles Peskine5197c662020-08-26 17:03:24 +0200937 AES_RROUND( t.Y[0], t.Y[1], t.Y[2], t.Y[3], t.X[0], t.X[1], t.X[2], t.X[3] );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200938
Gilles Peskine5197c662020-08-26 17:03:24 +0200939 t.X[0] = *RK++ ^ \
Joe Subbiani6b897c92021-07-08 14:59:52 +0100940 ( (uint32_t) RSb[ MBEDTLS_BYTE_0( t.Y[0] ) ] ) ^
941 ( (uint32_t) RSb[ MBEDTLS_BYTE_1( t.Y[3] ) ] << 8 ) ^
942 ( (uint32_t) RSb[ MBEDTLS_BYTE_2( t.Y[2] ) ] << 16 ) ^
943 ( (uint32_t) RSb[ MBEDTLS_BYTE_3( t.Y[1] ) ] << 24 );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200944
Gilles Peskine5197c662020-08-26 17:03:24 +0200945 t.X[1] = *RK++ ^ \
Joe Subbiani6b897c92021-07-08 14:59:52 +0100946 ( (uint32_t) RSb[ MBEDTLS_BYTE_0( t.Y[1] ) ] ) ^
947 ( (uint32_t) RSb[ MBEDTLS_BYTE_1( t.Y[0] ) ] << 8 ) ^
948 ( (uint32_t) RSb[ MBEDTLS_BYTE_2( t.Y[3] ) ] << 16 ) ^
949 ( (uint32_t) RSb[ MBEDTLS_BYTE_3( t.Y[2] ) ] << 24 );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200950
Gilles Peskine5197c662020-08-26 17:03:24 +0200951 t.X[2] = *RK++ ^ \
Joe Subbiani6b897c92021-07-08 14:59:52 +0100952 ( (uint32_t) RSb[ MBEDTLS_BYTE_0( t.Y[2] ) ] ) ^
953 ( (uint32_t) RSb[ MBEDTLS_BYTE_1( t.Y[1] ) ] << 8 ) ^
954 ( (uint32_t) RSb[ MBEDTLS_BYTE_2( t.Y[0] ) ] << 16 ) ^
955 ( (uint32_t) RSb[ MBEDTLS_BYTE_3( t.Y[3] ) ] << 24 );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200956
Gilles Peskine5197c662020-08-26 17:03:24 +0200957 t.X[3] = *RK++ ^ \
Joe Subbiani6b897c92021-07-08 14:59:52 +0100958 ( (uint32_t) RSb[ MBEDTLS_BYTE_0( t.Y[3] ) ] ) ^
959 ( (uint32_t) RSb[ MBEDTLS_BYTE_1( t.Y[2] ) ] << 8 ) ^
960 ( (uint32_t) RSb[ MBEDTLS_BYTE_2( t.Y[1] ) ] << 16 ) ^
961 ( (uint32_t) RSb[ MBEDTLS_BYTE_3( t.Y[0] ) ] << 24 );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200962
Joe Subbiani2bbafda2021-06-24 13:00:03 +0100963 MBEDTLS_PUT_UINT32_LE( t.X[0], output, 0 );
964 MBEDTLS_PUT_UINT32_LE( t.X[1], output, 4 );
965 MBEDTLS_PUT_UINT32_LE( t.X[2], output, 8 );
966 MBEDTLS_PUT_UINT32_LE( t.X[3], output, 12 );
Andres AGf5bf7182017-03-03 14:09:56 +0000967
Gilles Peskine5197c662020-08-26 17:03:24 +0200968 mbedtls_platform_zeroize( &t, sizeof( t ) );
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500969
Andres AGf5bf7182017-03-03 14:09:56 +0000970 return( 0 );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200971}
972#endif /* !MBEDTLS_AES_DECRYPT_ALT */
973
Gilles Peskine8db3efb2018-02-21 19:16:20 +0100974#if !defined(MBEDTLS_DEPRECATED_REMOVED)
Hanno Beckerbedc2052017-06-26 12:46:56 +0100975void mbedtls_aes_decrypt( mbedtls_aes_context *ctx,
976 const unsigned char input[16],
977 unsigned char output[16] )
978{
Mateusz Starzyk15a74202021-08-05 13:56:48 +0200979 MBEDTLS_IGNORE_RETURN( mbedtls_internal_aes_decrypt( ctx, input, output ) );
Hanno Beckerbedc2052017-06-26 12:46:56 +0100980}
Gilles Peskine8db3efb2018-02-21 19:16:20 +0100981#endif /* !MBEDTLS_DEPRECATED_REMOVED */
Hanno Beckerbedc2052017-06-26 12:46:56 +0100982
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200983/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000984 * AES-ECB block encryption/decryption
985 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200986int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx,
Manuel Pégourié-Gonnardeb6d3962018-12-18 09:59:35 +0100987 int mode,
988 const unsigned char input[16],
989 unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000990{
Manuel Pégourié-Gonnard1aca2602018-12-12 12:56:55 +0100991 AES_VALIDATE_RET( ctx != NULL );
992 AES_VALIDATE_RET( input != NULL );
993 AES_VALIDATE_RET( output != NULL );
994 AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
995 mode == MBEDTLS_AES_DECRYPT );
996
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200997#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100998 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200999 return( mbedtls_aesni_crypt_ecb( ctx, mode, input, output ) );
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +01001000#endif
1001
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001002#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Paul Bakker048d04e2012-02-12 17:31:04 +00001003 if( aes_padlock_ace )
Paul Bakker5121ce52009-01-03 21:22:43 +00001004 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001005 if( mbedtls_padlock_xcryptecb( ctx, mode, input, output ) == 0 )
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001006 return( 0 );
1007
1008 // If padlock data misaligned, we just fall back to
1009 // unaccelerated mode
1010 //
Paul Bakker5121ce52009-01-03 21:22:43 +00001011 }
1012#endif
1013
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001014 if( mode == MBEDTLS_AES_ENCRYPT )
Andres AGf5bf7182017-03-03 14:09:56 +00001015 return( mbedtls_internal_aes_encrypt( ctx, input, output ) );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001016 else
Andres AGf5bf7182017-03-03 14:09:56 +00001017 return( mbedtls_internal_aes_decrypt( ctx, input, output ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001018}
1019
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001020#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001021/*
1022 * AES-CBC buffer encryption/decryption
1023 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001024int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx,
Paul Bakker5121ce52009-01-03 21:22:43 +00001025 int mode,
Paul Bakker23986e52011-04-24 08:57:21 +00001026 size_t length,
Paul Bakker5121ce52009-01-03 21:22:43 +00001027 unsigned char iv[16],
Paul Bakkerff60ee62010-03-16 21:09:09 +00001028 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +00001029 unsigned char *output )
1030{
1031 int i;
Gilles Peskine377a3102021-07-07 21:08:28 +02001032 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +00001033 unsigned char temp[16];
1034
Manuel Pégourié-Gonnard3178d1a2018-12-12 13:05:00 +01001035 AES_VALIDATE_RET( ctx != NULL );
1036 AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
1037 mode == MBEDTLS_AES_DECRYPT );
1038 AES_VALIDATE_RET( iv != NULL );
1039 AES_VALIDATE_RET( input != NULL );
1040 AES_VALIDATE_RET( output != NULL );
1041
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001042 if( length % 16 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001043 return( MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH );
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001044
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001045#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Paul Bakker048d04e2012-02-12 17:31:04 +00001046 if( aes_padlock_ace )
Paul Bakker5121ce52009-01-03 21:22:43 +00001047 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001048 if( mbedtls_padlock_xcryptcbc( ctx, mode, length, iv, input, output ) == 0 )
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001049 return( 0 );
Paul Bakker9af723c2014-05-01 13:03:14 +02001050
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001051 // If padlock data misaligned, we just fall back to
1052 // unaccelerated mode
1053 //
Paul Bakker5121ce52009-01-03 21:22:43 +00001054 }
1055#endif
1056
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001057 if( mode == MBEDTLS_AES_DECRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +00001058 {
1059 while( length > 0 )
1060 {
1061 memcpy( temp, input, 16 );
Gilles Peskine377a3102021-07-07 21:08:28 +02001062 ret = mbedtls_aes_crypt_ecb( ctx, mode, input, output );
1063 if( ret != 0 )
1064 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001065
1066 for( i = 0; i < 16; i++ )
1067 output[i] = (unsigned char)( output[i] ^ iv[i] );
1068
1069 memcpy( iv, temp, 16 );
1070
1071 input += 16;
1072 output += 16;
1073 length -= 16;
1074 }
1075 }
1076 else
1077 {
1078 while( length > 0 )
1079 {
1080 for( i = 0; i < 16; i++ )
1081 output[i] = (unsigned char)( input[i] ^ iv[i] );
1082
Gilles Peskine377a3102021-07-07 21:08:28 +02001083 ret = mbedtls_aes_crypt_ecb( ctx, mode, output, output );
1084 if( ret != 0 )
1085 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001086 memcpy( iv, output, 16 );
1087
1088 input += 16;
1089 output += 16;
1090 length -= 16;
1091 }
1092 }
Gilles Peskine377a3102021-07-07 21:08:28 +02001093 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001094
Gilles Peskine377a3102021-07-07 21:08:28 +02001095exit:
1096 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001097}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001098#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001099
Aorimn5f778012016-06-09 23:22:58 +02001100#if defined(MBEDTLS_CIPHER_MODE_XTS)
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001101
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001102typedef unsigned char mbedtls_be128[16];
1103
1104/*
1105 * GF(2^128) multiplication function
1106 *
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001107 * This function multiplies a field element by x in the polynomial field
1108 * representation. It uses 64-bit word operations to gain speed but compensates
1109 * for machine endianess and hence works correctly on both big and little
1110 * endian machines.
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001111 */
1112static void mbedtls_gf128mul_x_ble( unsigned char r[16],
Jaeden Amero8cfc75f2018-05-31 16:53:08 +01001113 const unsigned char x[16] )
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001114{
1115 uint64_t a, b, ra, rb;
1116
Joe Subbiani1bd5d7d2021-07-16 12:29:49 +01001117 a = MBEDTLS_GET_UINT64_LE( x, 0 );
1118 b = MBEDTLS_GET_UINT64_LE( x, 8 );
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001119
Jaeden Amero8cfc75f2018-05-31 16:53:08 +01001120 ra = ( a << 1 ) ^ 0x0087 >> ( 8 - ( ( b >> 63 ) << 3 ) );
1121 rb = ( a >> 63 ) | ( b << 1 );
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001122
Joe Subbiani1bd5d7d2021-07-16 12:29:49 +01001123 MBEDTLS_PUT_UINT64_LE( ra, r, 0 );
1124 MBEDTLS_PUT_UINT64_LE( rb, r, 8 );
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001125}
1126
Aorimn5f778012016-06-09 23:22:58 +02001127/*
1128 * AES-XTS buffer encryption/decryption
1129 */
Jaeden Amero9366feb2018-05-29 18:55:17 +01001130int mbedtls_aes_crypt_xts( mbedtls_aes_xts_context *ctx,
1131 int mode,
Jaeden Amero5162b932018-05-29 12:55:24 +01001132 size_t length,
Jaeden Amerocd9fc5e2018-05-30 15:23:24 +01001133 const unsigned char data_unit[16],
Jaeden Amero9366feb2018-05-29 18:55:17 +01001134 const unsigned char *input,
1135 unsigned char *output )
Aorimn5f778012016-06-09 23:22:58 +02001136{
Janos Follath24eed8d2019-11-22 13:21:35 +00001137 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amerod82cd862018-04-28 15:02:45 +01001138 size_t blocks = length / 16;
1139 size_t leftover = length % 16;
1140 unsigned char tweak[16];
1141 unsigned char prev_tweak[16];
1142 unsigned char tmp[16];
Aorimn5f778012016-06-09 23:22:58 +02001143
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01001144 AES_VALIDATE_RET( ctx != NULL );
1145 AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
1146 mode == MBEDTLS_AES_DECRYPT );
Manuel Pégourié-Gonnard998a3582018-12-18 10:03:13 +01001147 AES_VALIDATE_RET( data_unit != NULL );
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01001148 AES_VALIDATE_RET( input != NULL );
1149 AES_VALIDATE_RET( output != NULL );
1150
Jaeden Amero8381fcb2018-10-11 12:06:15 +01001151 /* Data units must be at least 16 bytes long. */
Aorimn5f778012016-06-09 23:22:58 +02001152 if( length < 16 )
Jaeden Amerod82cd862018-04-28 15:02:45 +01001153 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Aorimn5f778012016-06-09 23:22:58 +02001154
Jaeden Ameroa74faba2018-10-11 12:07:43 +01001155 /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */
Jaeden Amero0a8b0202018-05-30 15:36:06 +01001156 if( length > ( 1 << 20 ) * 16 )
1157 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Aorimn5f778012016-06-09 23:22:58 +02001158
Jaeden Amerod82cd862018-04-28 15:02:45 +01001159 /* Compute the tweak. */
Jaeden Amerocd9fc5e2018-05-30 15:23:24 +01001160 ret = mbedtls_aes_crypt_ecb( &ctx->tweak, MBEDTLS_AES_ENCRYPT,
1161 data_unit, tweak );
Jaeden Amerod82cd862018-04-28 15:02:45 +01001162 if( ret != 0 )
1163 return( ret );
Aorimn5f778012016-06-09 23:22:58 +02001164
Jaeden Amerod82cd862018-04-28 15:02:45 +01001165 while( blocks-- )
Aorimn5f778012016-06-09 23:22:58 +02001166 {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001167 size_t i;
1168
1169 if( leftover && ( mode == MBEDTLS_AES_DECRYPT ) && blocks == 0 )
1170 {
1171 /* We are on the last block in a decrypt operation that has
1172 * leftover bytes, so we need to use the next tweak for this block,
1173 * and this tweak for the lefover bytes. Save the current tweak for
1174 * the leftovers and then update the current tweak for use on this,
1175 * the last full block. */
1176 memcpy( prev_tweak, tweak, sizeof( tweak ) );
1177 mbedtls_gf128mul_x_ble( tweak, tweak );
1178 }
1179
1180 for( i = 0; i < 16; i++ )
1181 tmp[i] = input[i] ^ tweak[i];
1182
1183 ret = mbedtls_aes_crypt_ecb( &ctx->crypt, mode, tmp, tmp );
1184 if( ret != 0 )
1185 return( ret );
1186
1187 for( i = 0; i < 16; i++ )
1188 output[i] = tmp[i] ^ tweak[i];
1189
1190 /* Update the tweak for the next block. */
1191 mbedtls_gf128mul_x_ble( tweak, tweak );
1192
1193 output += 16;
1194 input += 16;
Aorimn5f778012016-06-09 23:22:58 +02001195 }
1196
Jaeden Amerod82cd862018-04-28 15:02:45 +01001197 if( leftover )
Aorimn5f778012016-06-09 23:22:58 +02001198 {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001199 /* If we are on the leftover bytes in a decrypt operation, we need to
1200 * use the previous tweak for these bytes (as saved in prev_tweak). */
1201 unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
Aorimn5f778012016-06-09 23:22:58 +02001202
Jaeden Amerod82cd862018-04-28 15:02:45 +01001203 /* We are now on the final part of the data unit, which doesn't divide
1204 * evenly by 16. It's time for ciphertext stealing. */
1205 size_t i;
1206 unsigned char *prev_output = output - 16;
Aorimn5f778012016-06-09 23:22:58 +02001207
Jaeden Amerod82cd862018-04-28 15:02:45 +01001208 /* Copy ciphertext bytes from the previous block to our output for each
1209 * byte of cyphertext we won't steal. At the same time, copy the
1210 * remainder of the input for this final round (since the loop bounds
1211 * are the same). */
1212 for( i = 0; i < leftover; i++ )
Aorimn5f778012016-06-09 23:22:58 +02001213 {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001214 output[i] = prev_output[i];
1215 tmp[i] = input[i] ^ t[i];
Aorimn5f778012016-06-09 23:22:58 +02001216 }
Aorimn5f778012016-06-09 23:22:58 +02001217
Jaeden Amerod82cd862018-04-28 15:02:45 +01001218 /* Copy ciphertext bytes from the previous block for input in this
1219 * round. */
1220 for( ; i < 16; i++ )
1221 tmp[i] = prev_output[i] ^ t[i];
Aorimn5f778012016-06-09 23:22:58 +02001222
Jaeden Amerod82cd862018-04-28 15:02:45 +01001223 ret = mbedtls_aes_crypt_ecb( &ctx->crypt, mode, tmp, tmp );
1224 if( ret != 0 )
1225 return ret;
Aorimn5f778012016-06-09 23:22:58 +02001226
Jaeden Amerod82cd862018-04-28 15:02:45 +01001227 /* Write the result back to the previous block, overriding the previous
1228 * output we copied. */
1229 for( i = 0; i < 16; i++ )
1230 prev_output[i] = tmp[i] ^ t[i];
Aorimn5f778012016-06-09 23:22:58 +02001231 }
1232
1233 return( 0 );
1234}
1235#endif /* MBEDTLS_CIPHER_MODE_XTS */
1236
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001237#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001238/*
1239 * AES-CFB128 buffer encryption/decryption
1240 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001241int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx,
Paul Bakker5121ce52009-01-03 21:22:43 +00001242 int mode,
Paul Bakker23986e52011-04-24 08:57:21 +00001243 size_t length,
Paul Bakker27fdf462011-06-09 13:55:13 +00001244 size_t *iv_off,
Paul Bakker5121ce52009-01-03 21:22:43 +00001245 unsigned char iv[16],
Paul Bakkerff60ee62010-03-16 21:09:09 +00001246 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +00001247 unsigned char *output )
1248{
Paul Bakker27fdf462011-06-09 13:55:13 +00001249 int c;
Gilles Peskine377a3102021-07-07 21:08:28 +02001250 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001251 size_t n;
1252
1253 AES_VALIDATE_RET( ctx != NULL );
1254 AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
1255 mode == MBEDTLS_AES_DECRYPT );
1256 AES_VALIDATE_RET( iv_off != NULL );
1257 AES_VALIDATE_RET( iv != NULL );
1258 AES_VALIDATE_RET( input != NULL );
1259 AES_VALIDATE_RET( output != NULL );
1260
1261 n = *iv_off;
Paul Bakker5121ce52009-01-03 21:22:43 +00001262
Manuel Pégourié-Gonnarde55e1032018-12-18 12:09:02 +01001263 if( n > 15 )
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001264 return( MBEDTLS_ERR_AES_BAD_INPUT_DATA );
1265
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001266 if( mode == MBEDTLS_AES_DECRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +00001267 {
1268 while( length-- )
1269 {
1270 if( n == 0 )
Gilles Peskine377a3102021-07-07 21:08:28 +02001271 {
1272 ret = mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
1273 if( ret != 0 )
1274 goto exit;
1275 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001276
1277 c = *input++;
1278 *output++ = (unsigned char)( c ^ iv[n] );
1279 iv[n] = (unsigned char) c;
1280
Paul Bakker66d5d072014-06-17 16:39:18 +02001281 n = ( n + 1 ) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001282 }
1283 }
1284 else
1285 {
1286 while( length-- )
1287 {
1288 if( n == 0 )
Gilles Peskine377a3102021-07-07 21:08:28 +02001289 {
1290 ret = mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
1291 if( ret != 0 )
1292 goto exit;
1293 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001294
1295 iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ );
1296
Paul Bakker66d5d072014-06-17 16:39:18 +02001297 n = ( n + 1 ) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001298 }
1299 }
1300
1301 *iv_off = n;
Gilles Peskine377a3102021-07-07 21:08:28 +02001302 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001303
Gilles Peskine377a3102021-07-07 21:08:28 +02001304exit:
1305 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001306}
Paul Bakker556efba2014-01-24 15:38:12 +01001307
1308/*
1309 * AES-CFB8 buffer encryption/decryption
1310 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001311int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx,
Manuel Pégourié-Gonnardeb6d3962018-12-18 09:59:35 +01001312 int mode,
1313 size_t length,
1314 unsigned char iv[16],
1315 const unsigned char *input,
1316 unsigned char *output )
Paul Bakker556efba2014-01-24 15:38:12 +01001317{
Gilles Peskine377a3102021-07-07 21:08:28 +02001318 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker556efba2014-01-24 15:38:12 +01001319 unsigned char c;
1320 unsigned char ov[17];
1321
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001322 AES_VALIDATE_RET( ctx != NULL );
1323 AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
1324 mode == MBEDTLS_AES_DECRYPT );
1325 AES_VALIDATE_RET( iv != NULL );
1326 AES_VALIDATE_RET( input != NULL );
1327 AES_VALIDATE_RET( output != NULL );
Paul Bakker556efba2014-01-24 15:38:12 +01001328 while( length-- )
1329 {
Paul Bakker66d5d072014-06-17 16:39:18 +02001330 memcpy( ov, iv, 16 );
Gilles Peskine377a3102021-07-07 21:08:28 +02001331 ret = mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
1332 if( ret != 0 )
1333 goto exit;
Paul Bakker556efba2014-01-24 15:38:12 +01001334
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001335 if( mode == MBEDTLS_AES_DECRYPT )
Paul Bakker556efba2014-01-24 15:38:12 +01001336 ov[16] = *input;
1337
1338 c = *output++ = (unsigned char)( iv[0] ^ *input++ );
1339
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001340 if( mode == MBEDTLS_AES_ENCRYPT )
Paul Bakker556efba2014-01-24 15:38:12 +01001341 ov[16] = c;
1342
Paul Bakker66d5d072014-06-17 16:39:18 +02001343 memcpy( iv, ov + 1, 16 );
Paul Bakker556efba2014-01-24 15:38:12 +01001344 }
Gilles Peskine377a3102021-07-07 21:08:28 +02001345 ret = 0;
Paul Bakker556efba2014-01-24 15:38:12 +01001346
Gilles Peskine377a3102021-07-07 21:08:28 +02001347exit:
1348 return( ret );
Paul Bakker556efba2014-01-24 15:38:12 +01001349}
Simon Butcher76a5b222018-04-22 22:57:27 +01001350#endif /* MBEDTLS_CIPHER_MODE_CFB */
1351
1352#if defined(MBEDTLS_CIPHER_MODE_OFB)
1353/*
1354 * AES-OFB (Output Feedback Mode) buffer encryption/decryption
1355 */
1356int mbedtls_aes_crypt_ofb( mbedtls_aes_context *ctx,
Simon Butcher00131442018-05-22 22:40:36 +01001357 size_t length,
1358 size_t *iv_off,
1359 unsigned char iv[16],
1360 const unsigned char *input,
1361 unsigned char *output )
Simon Butcher76a5b222018-04-22 22:57:27 +01001362{
Simon Butcherad4e4932018-04-29 00:43:47 +01001363 int ret = 0;
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001364 size_t n;
1365
1366 AES_VALIDATE_RET( ctx != NULL );
1367 AES_VALIDATE_RET( iv_off != NULL );
1368 AES_VALIDATE_RET( iv != NULL );
1369 AES_VALIDATE_RET( input != NULL );
1370 AES_VALIDATE_RET( output != NULL );
1371
1372 n = *iv_off;
Simon Butcher76a5b222018-04-22 22:57:27 +01001373
Manuel Pégourié-Gonnarde55e1032018-12-18 12:09:02 +01001374 if( n > 15 )
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001375 return( MBEDTLS_ERR_AES_BAD_INPUT_DATA );
1376
Simon Butcher76a5b222018-04-22 22:57:27 +01001377 while( length-- )
1378 {
1379 if( n == 0 )
Simon Butcherad4e4932018-04-29 00:43:47 +01001380 {
1381 ret = mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
1382 if( ret != 0 )
1383 goto exit;
1384 }
Simon Butcher76a5b222018-04-22 22:57:27 +01001385 *output++ = *input++ ^ iv[n];
1386
1387 n = ( n + 1 ) & 0x0F;
1388 }
1389
1390 *iv_off = n;
1391
Simon Butcherad4e4932018-04-29 00:43:47 +01001392exit:
1393 return( ret );
Simon Butcher76a5b222018-04-22 22:57:27 +01001394}
1395#endif /* MBEDTLS_CIPHER_MODE_OFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001396
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001397#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001398/*
1399 * AES-CTR buffer encryption/decryption
1400 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001401int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx,
Paul Bakker27fdf462011-06-09 13:55:13 +00001402 size_t length,
1403 size_t *nc_off,
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001404 unsigned char nonce_counter[16],
1405 unsigned char stream_block[16],
1406 const unsigned char *input,
1407 unsigned char *output )
1408{
Paul Bakker369e14b2012-04-18 14:16:09 +00001409 int c, i;
Gilles Peskine377a3102021-07-07 21:08:28 +02001410 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001411 size_t n;
1412
1413 AES_VALIDATE_RET( ctx != NULL );
1414 AES_VALIDATE_RET( nc_off != NULL );
1415 AES_VALIDATE_RET( nonce_counter != NULL );
1416 AES_VALIDATE_RET( stream_block != NULL );
1417 AES_VALIDATE_RET( input != NULL );
1418 AES_VALIDATE_RET( output != NULL );
1419
1420 n = *nc_off;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001421
Mohammad Azim Khan3f7f8172017-11-23 17:49:05 +00001422 if ( n > 0x0F )
1423 return( MBEDTLS_ERR_AES_BAD_INPUT_DATA );
1424
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001425 while( length-- )
1426 {
1427 if( n == 0 ) {
Gilles Peskine377a3102021-07-07 21:08:28 +02001428 ret = mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block );
1429 if( ret != 0 )
1430 goto exit;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001431
Paul Bakker369e14b2012-04-18 14:16:09 +00001432 for( i = 16; i > 0; i-- )
1433 if( ++nonce_counter[i - 1] != 0 )
1434 break;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001435 }
1436 c = *input++;
1437 *output++ = (unsigned char)( c ^ stream_block[n] );
1438
Paul Bakker66d5d072014-06-17 16:39:18 +02001439 n = ( n + 1 ) & 0x0F;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001440 }
1441
1442 *nc_off = n;
Gilles Peskine377a3102021-07-07 21:08:28 +02001443 ret = 0;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001444
Gilles Peskine377a3102021-07-07 21:08:28 +02001445exit:
1446 return( ret );
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001447}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001448#endif /* MBEDTLS_CIPHER_MODE_CTR */
Manuel Pégourié-Gonnard1ec220b2014-03-10 11:20:17 +01001449
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001450#endif /* !MBEDTLS_AES_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001451
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001452#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001453/*
1454 * AES test vectors from:
1455 *
1456 * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
1457 */
1458static const unsigned char aes_test_ecb_dec[3][16] =
1459{
1460 { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
1461 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
1462 { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
1463 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
1464 { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
1465 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
1466};
1467
1468static const unsigned char aes_test_ecb_enc[3][16] =
1469{
1470 { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
1471 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
1472 { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
1473 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
1474 { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
1475 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
1476};
1477
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001478#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001479static const unsigned char aes_test_cbc_dec[3][16] =
1480{
1481 { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
1482 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
1483 { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
1484 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
1485 { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
1486 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
1487};
1488
1489static const unsigned char aes_test_cbc_enc[3][16] =
1490{
1491 { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
1492 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
1493 { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
1494 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
1495 { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
1496 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
1497};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001498#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001499
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001500#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001501/*
1502 * AES-CFB128 test vectors from:
1503 *
1504 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
1505 */
1506static const unsigned char aes_test_cfb128_key[3][32] =
1507{
1508 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1509 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
1510 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1511 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1512 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1513 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1514 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1515 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1516 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
1517};
1518
1519static const unsigned char aes_test_cfb128_iv[16] =
1520{
1521 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1522 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1523};
1524
1525static const unsigned char aes_test_cfb128_pt[64] =
1526{
1527 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1528 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1529 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1530 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1531 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1532 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1533 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1534 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1535};
1536
1537static const unsigned char aes_test_cfb128_ct[3][64] =
1538{
1539 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1540 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1541 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F,
1542 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B,
1543 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40,
1544 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF,
1545 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E,
1546 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 },
1547 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1548 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1549 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21,
1550 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A,
1551 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1,
1552 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9,
1553 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0,
1554 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF },
1555 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1556 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1557 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8,
1558 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B,
1559 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92,
1560 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9,
1561 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8,
1562 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 }
1563};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001564#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001565
Simon Butcherad4e4932018-04-29 00:43:47 +01001566#if defined(MBEDTLS_CIPHER_MODE_OFB)
1567/*
1568 * AES-OFB test vectors from:
1569 *
Simon Butcher5db13622018-06-04 22:11:25 +01001570 * https://csrc.nist.gov/publications/detail/sp/800-38a/final
Simon Butcherad4e4932018-04-29 00:43:47 +01001571 */
1572static const unsigned char aes_test_ofb_key[3][32] =
1573{
1574 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1575 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
1576 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1577 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1578 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1579 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1580 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1581 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1582 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
1583};
1584
1585static const unsigned char aes_test_ofb_iv[16] =
1586{
1587 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1588 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1589};
1590
1591static const unsigned char aes_test_ofb_pt[64] =
1592{
1593 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1594 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1595 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1596 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1597 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1598 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1599 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1600 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1601};
1602
1603static const unsigned char aes_test_ofb_ct[3][64] =
1604{
1605 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1606 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1607 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
1608 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
1609 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
1610 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
1611 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
1612 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e },
1613 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1614 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1615 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
1616 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
1617 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f,
1618 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
1619 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e,
1620 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a },
1621 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1622 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1623 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
1624 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
1625 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed,
1626 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
1627 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8,
1628 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 }
1629};
1630#endif /* MBEDTLS_CIPHER_MODE_OFB */
1631
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001632#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001633/*
1634 * AES-CTR test vectors from:
1635 *
1636 * http://www.faqs.org/rfcs/rfc3686.html
1637 */
1638
1639static const unsigned char aes_test_ctr_key[3][16] =
1640{
1641 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
1642 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
1643 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
1644 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
1645 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
1646 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
1647};
1648
1649static const unsigned char aes_test_ctr_nonce_counter[3][16] =
1650{
1651 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
1652 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
1653 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
1654 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
1655 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
1656 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
1657};
1658
1659static const unsigned char aes_test_ctr_pt[3][48] =
1660{
1661 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
1662 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
1663
1664 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1665 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1666 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1667 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
1668
1669 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1670 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1671 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1672 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
1673 0x20, 0x21, 0x22, 0x23 }
1674};
1675
1676static const unsigned char aes_test_ctr_ct[3][48] =
1677{
1678 { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79,
1679 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 },
1680 { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9,
1681 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88,
1682 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8,
1683 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 },
1684 { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
1685 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
1686 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
1687 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
1688 0x25, 0xB2, 0x07, 0x2F }
1689};
1690
1691static const int aes_test_ctr_len[3] =
1692 { 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001693#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00001694
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001695#if defined(MBEDTLS_CIPHER_MODE_XTS)
1696/*
1697 * AES-XTS test vectors from:
1698 *
1699 * IEEE P1619/D16 Annex B
1700 * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf
1701 * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf)
1702 */
1703static const unsigned char aes_test_xts_key[][32] =
1704{
1705 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1706 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1707 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1708 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1709 { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1710 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1711 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1712 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1713 { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
1714 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
1715 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1716 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1717};
1718
1719static const unsigned char aes_test_xts_pt32[][32] =
1720{
1721 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1722 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1723 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1724 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1725 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1726 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1727 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1728 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1729 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1730 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1731 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1732 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1733};
1734
1735static const unsigned char aes_test_xts_ct32[][32] =
1736{
1737 { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec,
1738 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92,
1739 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85,
1740 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e },
1741 { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e,
1742 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b,
1743 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4,
1744 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 },
1745 { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a,
1746 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2,
1747 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53,
1748 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 },
1749};
1750
1751static const unsigned char aes_test_xts_data_unit[][16] =
1752{
1753 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1754 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1755 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1756 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1757 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1758 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1759};
1760
1761#endif /* MBEDTLS_CIPHER_MODE_XTS */
1762
Paul Bakker5121ce52009-01-03 21:22:43 +00001763/*
1764 * Checkup routine
1765 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001766int mbedtls_aes_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +00001767{
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001768 int ret = 0, i, j, u, mode;
1769 unsigned int keybits;
Paul Bakker5121ce52009-01-03 21:22:43 +00001770 unsigned char key[32];
1771 unsigned char buf[64];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001772 const unsigned char *aes_tests;
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03001773#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001774 unsigned char iv[16];
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03001775#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001776#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +02001777 unsigned char prv[16];
1778#endif
Simon Butcher2ff0e522018-06-14 09:57:07 +01001779#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1780 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker27fdf462011-06-09 13:55:13 +00001781 size_t offset;
Paul Bakkere91d01e2011-04-19 15:55:50 +00001782#endif
Simon Butcher66a89032018-06-15 18:20:29 +01001783#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS)
Paul Bakkere91d01e2011-04-19 15:55:50 +00001784 int len;
Simon Butcher66a89032018-06-15 18:20:29 +01001785#endif
1786#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001787 unsigned char nonce_counter[16];
1788 unsigned char stream_block[16];
1789#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001790 mbedtls_aes_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001791
1792 memset( key, 0, 32 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001793 mbedtls_aes_init( &ctx );
Paul Bakker5121ce52009-01-03 21:22:43 +00001794
1795 /*
1796 * ECB mode
1797 */
1798 for( i = 0; i < 6; i++ )
1799 {
1800 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001801 keybits = 128 + u * 64;
1802 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001803
1804 if( verbose != 0 )
Kenneth Soerensen518d4352020-04-01 17:22:45 +02001805 mbedtls_printf( " AES-ECB-%3u (%s): ", keybits,
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001806 ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001807
1808 memset( buf, 0, 16 );
1809
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001810 if( mode == MBEDTLS_AES_DECRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +00001811 {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001812 ret = mbedtls_aes_setkey_dec( &ctx, key, keybits );
1813 aes_tests = aes_test_ecb_dec[u];
Paul Bakker5121ce52009-01-03 21:22:43 +00001814 }
1815 else
1816 {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001817 ret = mbedtls_aes_setkey_enc( &ctx, key, keybits );
1818 aes_tests = aes_test_ecb_enc[u];
1819 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001820
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01001821 /*
1822 * AES-192 is an optional feature that may be unavailable when
1823 * there is an alternative underlying implementation i.e. when
1824 * MBEDTLS_AES_ALT is defined.
1825 */
Ron Eldor9924bdc2018-10-04 10:59:13 +03001826 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 )
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001827 {
1828 mbedtls_printf( "skipped\n" );
1829 continue;
1830 }
1831 else if( ret != 0 )
1832 {
1833 goto exit;
1834 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001835
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001836 for( j = 0; j < 10000; j++ )
1837 {
1838 ret = mbedtls_aes_crypt_ecb( &ctx, mode, buf, buf );
1839 if( ret != 0 )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001840 goto exit;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001841 }
1842
1843 if( memcmp( buf, aes_tests, 16 ) != 0 )
1844 {
1845 ret = 1;
1846 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001847 }
1848
1849 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001850 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001851 }
1852
1853 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001854 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001855
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001856#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001857 /*
1858 * CBC mode
1859 */
1860 for( i = 0; i < 6; i++ )
1861 {
1862 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001863 keybits = 128 + u * 64;
1864 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001865
1866 if( verbose != 0 )
Kenneth Soerensen518d4352020-04-01 17:22:45 +02001867 mbedtls_printf( " AES-CBC-%3u (%s): ", keybits,
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001868 ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001869
1870 memset( iv , 0, 16 );
1871 memset( prv, 0, 16 );
1872 memset( buf, 0, 16 );
1873
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001874 if( mode == MBEDTLS_AES_DECRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +00001875 {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001876 ret = mbedtls_aes_setkey_dec( &ctx, key, keybits );
1877 aes_tests = aes_test_cbc_dec[u];
Paul Bakker5121ce52009-01-03 21:22:43 +00001878 }
1879 else
1880 {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001881 ret = mbedtls_aes_setkey_enc( &ctx, key, keybits );
1882 aes_tests = aes_test_cbc_enc[u];
1883 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001884
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01001885 /*
1886 * AES-192 is an optional feature that may be unavailable when
1887 * there is an alternative underlying implementation i.e. when
1888 * MBEDTLS_AES_ALT is defined.
1889 */
Ron Eldor9924bdc2018-10-04 10:59:13 +03001890 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 )
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001891 {
1892 mbedtls_printf( "skipped\n" );
1893 continue;
1894 }
1895 else if( ret != 0 )
1896 {
1897 goto exit;
1898 }
1899
1900 for( j = 0; j < 10000; j++ )
1901 {
1902 if( mode == MBEDTLS_AES_ENCRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +00001903 {
1904 unsigned char tmp[16];
1905
Paul Bakker5121ce52009-01-03 21:22:43 +00001906 memcpy( tmp, prv, 16 );
1907 memcpy( prv, buf, 16 );
1908 memcpy( buf, tmp, 16 );
1909 }
1910
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001911 ret = mbedtls_aes_crypt_cbc( &ctx, mode, 16, iv, buf, buf );
1912 if( ret != 0 )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001913 goto exit;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001914
1915 }
1916
1917 if( memcmp( buf, aes_tests, 16 ) != 0 )
1918 {
1919 ret = 1;
1920 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001921 }
1922
1923 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001924 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001925 }
1926
1927 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001928 mbedtls_printf( "\n" );
1929#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001930
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001931#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001932 /*
1933 * CFB128 mode
1934 */
1935 for( i = 0; i < 6; i++ )
1936 {
1937 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001938 keybits = 128 + u * 64;
1939 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001940
1941 if( verbose != 0 )
Kenneth Soerensen518d4352020-04-01 17:22:45 +02001942 mbedtls_printf( " AES-CFB128-%3u (%s): ", keybits,
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001943 ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001944
1945 memcpy( iv, aes_test_cfb128_iv, 16 );
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001946 memcpy( key, aes_test_cfb128_key[u], keybits / 8 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001947
1948 offset = 0;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001949 ret = mbedtls_aes_setkey_enc( &ctx, key, keybits );
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01001950 /*
1951 * AES-192 is an optional feature that may be unavailable when
1952 * there is an alternative underlying implementation i.e. when
1953 * MBEDTLS_AES_ALT is defined.
1954 */
Ron Eldor9924bdc2018-10-04 10:59:13 +03001955 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 )
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001956 {
1957 mbedtls_printf( "skipped\n" );
1958 continue;
1959 }
1960 else if( ret != 0 )
1961 {
1962 goto exit;
1963 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001964
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001965 if( mode == MBEDTLS_AES_DECRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +00001966 {
1967 memcpy( buf, aes_test_cfb128_ct[u], 64 );
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001968 aes_tests = aes_test_cfb128_pt;
Paul Bakker5121ce52009-01-03 21:22:43 +00001969 }
1970 else
1971 {
1972 memcpy( buf, aes_test_cfb128_pt, 64 );
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001973 aes_tests = aes_test_cfb128_ct[u];
1974 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001975
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001976 ret = mbedtls_aes_crypt_cfb128( &ctx, mode, 64, &offset, iv, buf, buf );
1977 if( ret != 0 )
1978 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001979
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001980 if( memcmp( buf, aes_tests, 64 ) != 0 )
1981 {
1982 ret = 1;
1983 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001984 }
1985
1986 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001987 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001988 }
1989
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001990 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001991 mbedtls_printf( "\n" );
1992#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001993
Simon Butcherad4e4932018-04-29 00:43:47 +01001994#if defined(MBEDTLS_CIPHER_MODE_OFB)
1995 /*
1996 * OFB mode
1997 */
1998 for( i = 0; i < 6; i++ )
1999 {
2000 u = i >> 1;
2001 keybits = 128 + u * 64;
2002 mode = i & 1;
2003
2004 if( verbose != 0 )
Kenneth Soerensen518d4352020-04-01 17:22:45 +02002005 mbedtls_printf( " AES-OFB-%3u (%s): ", keybits,
Simon Butcherad4e4932018-04-29 00:43:47 +01002006 ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
2007
2008 memcpy( iv, aes_test_ofb_iv, 16 );
2009 memcpy( key, aes_test_ofb_key[u], keybits / 8 );
2010
2011 offset = 0;
2012 ret = mbedtls_aes_setkey_enc( &ctx, key, keybits );
2013 /*
2014 * AES-192 is an optional feature that may be unavailable when
2015 * there is an alternative underlying implementation i.e. when
2016 * MBEDTLS_AES_ALT is defined.
2017 */
Ron Eldor9924bdc2018-10-04 10:59:13 +03002018 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 )
Simon Butcherad4e4932018-04-29 00:43:47 +01002019 {
2020 mbedtls_printf( "skipped\n" );
2021 continue;
2022 }
2023 else if( ret != 0 )
2024 {
2025 goto exit;
2026 }
2027
2028 if( mode == MBEDTLS_AES_DECRYPT )
2029 {
2030 memcpy( buf, aes_test_ofb_ct[u], 64 );
2031 aes_tests = aes_test_ofb_pt;
2032 }
2033 else
2034 {
2035 memcpy( buf, aes_test_ofb_pt, 64 );
2036 aes_tests = aes_test_ofb_ct[u];
2037 }
2038
2039 ret = mbedtls_aes_crypt_ofb( &ctx, 64, &offset, iv, buf, buf );
2040 if( ret != 0 )
2041 goto exit;
2042
2043 if( memcmp( buf, aes_tests, 64 ) != 0 )
2044 {
2045 ret = 1;
2046 goto exit;
2047 }
2048
2049 if( verbose != 0 )
2050 mbedtls_printf( "passed\n" );
2051 }
2052
2053 if( verbose != 0 )
2054 mbedtls_printf( "\n" );
2055#endif /* MBEDTLS_CIPHER_MODE_OFB */
2056
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002057#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002058 /*
2059 * CTR mode
2060 */
2061 for( i = 0; i < 6; i++ )
2062 {
2063 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002064 mode = i & 1;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002065
2066 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002067 mbedtls_printf( " AES-CTR-128 (%s): ",
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002068 ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002069
2070 memcpy( nonce_counter, aes_test_ctr_nonce_counter[u], 16 );
2071 memcpy( key, aes_test_ctr_key[u], 16 );
2072
2073 offset = 0;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002074 if( ( ret = mbedtls_aes_setkey_enc( &ctx, key, 128 ) ) != 0 )
2075 goto exit;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002076
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002077 len = aes_test_ctr_len[u];
2078
2079 if( mode == MBEDTLS_AES_DECRYPT )
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002080 {
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002081 memcpy( buf, aes_test_ctr_ct[u], len );
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002082 aes_tests = aes_test_ctr_pt[u];
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002083 }
2084 else
2085 {
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002086 memcpy( buf, aes_test_ctr_pt[u], len );
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002087 aes_tests = aes_test_ctr_ct[u];
2088 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002089
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002090 ret = mbedtls_aes_crypt_ctr( &ctx, len, &offset, nonce_counter,
2091 stream_block, buf, buf );
2092 if( ret != 0 )
2093 goto exit;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002094
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002095 if( memcmp( buf, aes_tests, len ) != 0 )
2096 {
2097 ret = 1;
2098 goto exit;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002099 }
2100
2101 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002102 mbedtls_printf( "passed\n" );
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002103 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002104
2105 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002106 mbedtls_printf( "\n" );
2107#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00002108
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002109#if defined(MBEDTLS_CIPHER_MODE_XTS)
2110 {
2111 static const int num_tests =
2112 sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key);
2113 mbedtls_aes_xts_context ctx_xts;
2114
2115 /*
2116 * XTS mode
2117 */
2118 mbedtls_aes_xts_init( &ctx_xts );
2119
2120 for( i = 0; i < num_tests << 1; i++ )
2121 {
2122 const unsigned char *data_unit;
2123 u = i >> 1;
2124 mode = i & 1;
2125
2126 if( verbose != 0 )
2127 mbedtls_printf( " AES-XTS-128 (%s): ",
2128 ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
2129
2130 memset( key, 0, sizeof( key ) );
2131 memcpy( key, aes_test_xts_key[u], 32 );
2132 data_unit = aes_test_xts_data_unit[u];
2133
2134 len = sizeof( *aes_test_xts_ct32 );
2135
2136 if( mode == MBEDTLS_AES_DECRYPT )
2137 {
2138 ret = mbedtls_aes_xts_setkey_dec( &ctx_xts, key, 256 );
2139 if( ret != 0)
2140 goto exit;
2141 memcpy( buf, aes_test_xts_ct32[u], len );
2142 aes_tests = aes_test_xts_pt32[u];
2143 }
2144 else
2145 {
2146 ret = mbedtls_aes_xts_setkey_enc( &ctx_xts, key, 256 );
2147 if( ret != 0)
2148 goto exit;
2149 memcpy( buf, aes_test_xts_pt32[u], len );
2150 aes_tests = aes_test_xts_ct32[u];
2151 }
2152
2153
2154 ret = mbedtls_aes_crypt_xts( &ctx_xts, mode, len, data_unit,
2155 buf, buf );
2156 if( ret != 0 )
2157 goto exit;
2158
2159 if( memcmp( buf, aes_tests, len ) != 0 )
2160 {
2161 ret = 1;
2162 goto exit;
2163 }
2164
2165 if( verbose != 0 )
2166 mbedtls_printf( "passed\n" );
2167 }
2168
2169 if( verbose != 0 )
2170 mbedtls_printf( "\n" );
2171
2172 mbedtls_aes_xts_free( &ctx_xts );
2173 }
2174#endif /* MBEDTLS_CIPHER_MODE_XTS */
2175
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002176 ret = 0;
2177
2178exit:
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002179 if( ret != 0 && verbose != 0 )
2180 mbedtls_printf( "failed\n" );
2181
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002182 mbedtls_aes_free( &ctx );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002183
2184 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002185}
2186
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002187#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002188
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002189#endif /* MBEDTLS_AES_C */