blob: 555d32ea112e17b8f805bc98e228e85bb2bbc111 [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é-Gonnard7f809972015-03-09 17:05:11 +000043#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010044
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020045#if !defined(MBEDTLS_AES_ALT)
Paul Bakker90995b52013-06-24 19:20:35 +020046
Manuel Pégourié-Gonnard0e9cddb2018-12-10 16:37:51 +010047/* Parameter validation macros based on platform_util.h */
48#define AES_VALIDATE_RET( cond ) \
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +010049 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_AES_BAD_INPUT_DATA )
Manuel Pégourié-Gonnard0e9cddb2018-12-10 16:37:51 +010050#define AES_VALIDATE( cond ) \
51 MBEDTLS_INTERNAL_VALIDATE( cond )
52
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020053#if defined(MBEDTLS_PADLOCK_C) && \
54 ( defined(MBEDTLS_HAVE_X86) || defined(MBEDTLS_PADLOCK_ALIGN16) )
Paul Bakker048d04e2012-02-12 17:31:04 +000055static int aes_padlock_ace = -1;
56#endif
57
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020058#if defined(MBEDTLS_AES_ROM_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +000059/*
60 * Forward S-box
61 */
62static const unsigned char FSb[256] =
63{
64 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
65 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
66 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
67 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
68 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
69 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
70 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
71 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
72 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
73 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
74 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
75 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
76 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
77 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
78 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
79 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
80 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
81 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
82 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
83 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
84 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
85 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
86 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
87 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
88 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
89 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
90 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
91 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
92 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
93 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
94 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
95 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
96};
97
98/*
99 * Forward tables
100 */
101#define FT \
102\
103 V(A5,63,63,C6), V(84,7C,7C,F8), V(99,77,77,EE), V(8D,7B,7B,F6), \
104 V(0D,F2,F2,FF), V(BD,6B,6B,D6), V(B1,6F,6F,DE), V(54,C5,C5,91), \
105 V(50,30,30,60), V(03,01,01,02), V(A9,67,67,CE), V(7D,2B,2B,56), \
106 V(19,FE,FE,E7), V(62,D7,D7,B5), V(E6,AB,AB,4D), V(9A,76,76,EC), \
107 V(45,CA,CA,8F), V(9D,82,82,1F), V(40,C9,C9,89), V(87,7D,7D,FA), \
108 V(15,FA,FA,EF), V(EB,59,59,B2), V(C9,47,47,8E), V(0B,F0,F0,FB), \
109 V(EC,AD,AD,41), V(67,D4,D4,B3), V(FD,A2,A2,5F), V(EA,AF,AF,45), \
110 V(BF,9C,9C,23), V(F7,A4,A4,53), V(96,72,72,E4), V(5B,C0,C0,9B), \
111 V(C2,B7,B7,75), V(1C,FD,FD,E1), V(AE,93,93,3D), V(6A,26,26,4C), \
112 V(5A,36,36,6C), V(41,3F,3F,7E), V(02,F7,F7,F5), V(4F,CC,CC,83), \
113 V(5C,34,34,68), V(F4,A5,A5,51), V(34,E5,E5,D1), V(08,F1,F1,F9), \
114 V(93,71,71,E2), V(73,D8,D8,AB), V(53,31,31,62), V(3F,15,15,2A), \
115 V(0C,04,04,08), V(52,C7,C7,95), V(65,23,23,46), V(5E,C3,C3,9D), \
116 V(28,18,18,30), V(A1,96,96,37), V(0F,05,05,0A), V(B5,9A,9A,2F), \
117 V(09,07,07,0E), V(36,12,12,24), V(9B,80,80,1B), V(3D,E2,E2,DF), \
118 V(26,EB,EB,CD), V(69,27,27,4E), V(CD,B2,B2,7F), V(9F,75,75,EA), \
119 V(1B,09,09,12), V(9E,83,83,1D), V(74,2C,2C,58), V(2E,1A,1A,34), \
120 V(2D,1B,1B,36), V(B2,6E,6E,DC), V(EE,5A,5A,B4), V(FB,A0,A0,5B), \
121 V(F6,52,52,A4), V(4D,3B,3B,76), V(61,D6,D6,B7), V(CE,B3,B3,7D), \
122 V(7B,29,29,52), V(3E,E3,E3,DD), V(71,2F,2F,5E), V(97,84,84,13), \
123 V(F5,53,53,A6), V(68,D1,D1,B9), V(00,00,00,00), V(2C,ED,ED,C1), \
124 V(60,20,20,40), V(1F,FC,FC,E3), V(C8,B1,B1,79), V(ED,5B,5B,B6), \
125 V(BE,6A,6A,D4), V(46,CB,CB,8D), V(D9,BE,BE,67), V(4B,39,39,72), \
126 V(DE,4A,4A,94), V(D4,4C,4C,98), V(E8,58,58,B0), V(4A,CF,CF,85), \
127 V(6B,D0,D0,BB), V(2A,EF,EF,C5), V(E5,AA,AA,4F), V(16,FB,FB,ED), \
128 V(C5,43,43,86), V(D7,4D,4D,9A), V(55,33,33,66), V(94,85,85,11), \
129 V(CF,45,45,8A), V(10,F9,F9,E9), V(06,02,02,04), V(81,7F,7F,FE), \
130 V(F0,50,50,A0), V(44,3C,3C,78), V(BA,9F,9F,25), V(E3,A8,A8,4B), \
131 V(F3,51,51,A2), V(FE,A3,A3,5D), V(C0,40,40,80), V(8A,8F,8F,05), \
132 V(AD,92,92,3F), V(BC,9D,9D,21), V(48,38,38,70), V(04,F5,F5,F1), \
133 V(DF,BC,BC,63), V(C1,B6,B6,77), V(75,DA,DA,AF), V(63,21,21,42), \
134 V(30,10,10,20), V(1A,FF,FF,E5), V(0E,F3,F3,FD), V(6D,D2,D2,BF), \
135 V(4C,CD,CD,81), V(14,0C,0C,18), V(35,13,13,26), V(2F,EC,EC,C3), \
136 V(E1,5F,5F,BE), V(A2,97,97,35), V(CC,44,44,88), V(39,17,17,2E), \
137 V(57,C4,C4,93), V(F2,A7,A7,55), V(82,7E,7E,FC), V(47,3D,3D,7A), \
138 V(AC,64,64,C8), V(E7,5D,5D,BA), V(2B,19,19,32), V(95,73,73,E6), \
139 V(A0,60,60,C0), V(98,81,81,19), V(D1,4F,4F,9E), V(7F,DC,DC,A3), \
140 V(66,22,22,44), V(7E,2A,2A,54), V(AB,90,90,3B), V(83,88,88,0B), \
141 V(CA,46,46,8C), V(29,EE,EE,C7), V(D3,B8,B8,6B), V(3C,14,14,28), \
142 V(79,DE,DE,A7), V(E2,5E,5E,BC), V(1D,0B,0B,16), V(76,DB,DB,AD), \
143 V(3B,E0,E0,DB), V(56,32,32,64), V(4E,3A,3A,74), V(1E,0A,0A,14), \
144 V(DB,49,49,92), V(0A,06,06,0C), V(6C,24,24,48), V(E4,5C,5C,B8), \
145 V(5D,C2,C2,9F), V(6E,D3,D3,BD), V(EF,AC,AC,43), V(A6,62,62,C4), \
146 V(A8,91,91,39), V(A4,95,95,31), V(37,E4,E4,D3), V(8B,79,79,F2), \
147 V(32,E7,E7,D5), V(43,C8,C8,8B), V(59,37,37,6E), V(B7,6D,6D,DA), \
148 V(8C,8D,8D,01), V(64,D5,D5,B1), V(D2,4E,4E,9C), V(E0,A9,A9,49), \
149 V(B4,6C,6C,D8), V(FA,56,56,AC), V(07,F4,F4,F3), V(25,EA,EA,CF), \
150 V(AF,65,65,CA), V(8E,7A,7A,F4), V(E9,AE,AE,47), V(18,08,08,10), \
151 V(D5,BA,BA,6F), V(88,78,78,F0), V(6F,25,25,4A), V(72,2E,2E,5C), \
152 V(24,1C,1C,38), V(F1,A6,A6,57), V(C7,B4,B4,73), V(51,C6,C6,97), \
153 V(23,E8,E8,CB), V(7C,DD,DD,A1), V(9C,74,74,E8), V(21,1F,1F,3E), \
154 V(DD,4B,4B,96), V(DC,BD,BD,61), V(86,8B,8B,0D), V(85,8A,8A,0F), \
155 V(90,70,70,E0), V(42,3E,3E,7C), V(C4,B5,B5,71), V(AA,66,66,CC), \
156 V(D8,48,48,90), V(05,03,03,06), V(01,F6,F6,F7), V(12,0E,0E,1C), \
157 V(A3,61,61,C2), V(5F,35,35,6A), V(F9,57,57,AE), V(D0,B9,B9,69), \
158 V(91,86,86,17), V(58,C1,C1,99), V(27,1D,1D,3A), V(B9,9E,9E,27), \
159 V(38,E1,E1,D9), V(13,F8,F8,EB), V(B3,98,98,2B), V(33,11,11,22), \
160 V(BB,69,69,D2), V(70,D9,D9,A9), V(89,8E,8E,07), V(A7,94,94,33), \
161 V(B6,9B,9B,2D), V(22,1E,1E,3C), V(92,87,87,15), V(20,E9,E9,C9), \
162 V(49,CE,CE,87), V(FF,55,55,AA), V(78,28,28,50), V(7A,DF,DF,A5), \
163 V(8F,8C,8C,03), V(F8,A1,A1,59), V(80,89,89,09), V(17,0D,0D,1A), \
164 V(DA,BF,BF,65), V(31,E6,E6,D7), V(C6,42,42,84), V(B8,68,68,D0), \
165 V(C3,41,41,82), V(B0,99,99,29), V(77,2D,2D,5A), V(11,0F,0F,1E), \
166 V(CB,B0,B0,7B), V(FC,54,54,A8), V(D6,BB,BB,6D), V(3A,16,16,2C)
167
168#define V(a,b,c,d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000169static const uint32_t FT0[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000170#undef V
171
Hanno Beckerad049a92017-06-19 16:31:54 +0100172#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200173
Paul Bakker5121ce52009-01-03 21:22:43 +0000174#define V(a,b,c,d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000175static const uint32_t FT1[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000176#undef V
177
178#define V(a,b,c,d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000179static const uint32_t FT2[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000180#undef V
181
182#define V(a,b,c,d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000183static const uint32_t FT3[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000184#undef V
185
Hanno Becker177d3cf2017-06-07 15:52:48 +0100186#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200187
Paul Bakker5121ce52009-01-03 21:22:43 +0000188#undef FT
189
190/*
191 * Reverse S-box
192 */
193static const unsigned char RSb[256] =
194{
195 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
196 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
197 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
198 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
199 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
200 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
201 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
202 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
203 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
204 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
205 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
206 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
207 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
208 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
209 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
210 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
211 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
212 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
213 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
214 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
215 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
216 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
217 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
218 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
219 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
220 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
221 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
222 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
223 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
224 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
225 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
226 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
227};
228
229/*
230 * Reverse tables
231 */
232#define RT \
233\
234 V(50,A7,F4,51), V(53,65,41,7E), V(C3,A4,17,1A), V(96,5E,27,3A), \
235 V(CB,6B,AB,3B), V(F1,45,9D,1F), V(AB,58,FA,AC), V(93,03,E3,4B), \
236 V(55,FA,30,20), V(F6,6D,76,AD), V(91,76,CC,88), V(25,4C,02,F5), \
237 V(FC,D7,E5,4F), V(D7,CB,2A,C5), V(80,44,35,26), V(8F,A3,62,B5), \
238 V(49,5A,B1,DE), V(67,1B,BA,25), V(98,0E,EA,45), V(E1,C0,FE,5D), \
239 V(02,75,2F,C3), V(12,F0,4C,81), V(A3,97,46,8D), V(C6,F9,D3,6B), \
240 V(E7,5F,8F,03), V(95,9C,92,15), V(EB,7A,6D,BF), V(DA,59,52,95), \
241 V(2D,83,BE,D4), V(D3,21,74,58), V(29,69,E0,49), V(44,C8,C9,8E), \
242 V(6A,89,C2,75), V(78,79,8E,F4), V(6B,3E,58,99), V(DD,71,B9,27), \
243 V(B6,4F,E1,BE), V(17,AD,88,F0), V(66,AC,20,C9), V(B4,3A,CE,7D), \
244 V(18,4A,DF,63), V(82,31,1A,E5), V(60,33,51,97), V(45,7F,53,62), \
245 V(E0,77,64,B1), V(84,AE,6B,BB), V(1C,A0,81,FE), V(94,2B,08,F9), \
246 V(58,68,48,70), V(19,FD,45,8F), V(87,6C,DE,94), V(B7,F8,7B,52), \
247 V(23,D3,73,AB), V(E2,02,4B,72), V(57,8F,1F,E3), V(2A,AB,55,66), \
248 V(07,28,EB,B2), V(03,C2,B5,2F), V(9A,7B,C5,86), V(A5,08,37,D3), \
249 V(F2,87,28,30), V(B2,A5,BF,23), V(BA,6A,03,02), V(5C,82,16,ED), \
250 V(2B,1C,CF,8A), V(92,B4,79,A7), V(F0,F2,07,F3), V(A1,E2,69,4E), \
251 V(CD,F4,DA,65), V(D5,BE,05,06), V(1F,62,34,D1), V(8A,FE,A6,C4), \
252 V(9D,53,2E,34), V(A0,55,F3,A2), V(32,E1,8A,05), V(75,EB,F6,A4), \
253 V(39,EC,83,0B), V(AA,EF,60,40), V(06,9F,71,5E), V(51,10,6E,BD), \
254 V(F9,8A,21,3E), V(3D,06,DD,96), V(AE,05,3E,DD), V(46,BD,E6,4D), \
255 V(B5,8D,54,91), V(05,5D,C4,71), V(6F,D4,06,04), V(FF,15,50,60), \
256 V(24,FB,98,19), V(97,E9,BD,D6), V(CC,43,40,89), V(77,9E,D9,67), \
257 V(BD,42,E8,B0), V(88,8B,89,07), V(38,5B,19,E7), V(DB,EE,C8,79), \
258 V(47,0A,7C,A1), V(E9,0F,42,7C), V(C9,1E,84,F8), V(00,00,00,00), \
259 V(83,86,80,09), V(48,ED,2B,32), V(AC,70,11,1E), V(4E,72,5A,6C), \
260 V(FB,FF,0E,FD), V(56,38,85,0F), V(1E,D5,AE,3D), V(27,39,2D,36), \
261 V(64,D9,0F,0A), V(21,A6,5C,68), V(D1,54,5B,9B), V(3A,2E,36,24), \
262 V(B1,67,0A,0C), V(0F,E7,57,93), V(D2,96,EE,B4), V(9E,91,9B,1B), \
263 V(4F,C5,C0,80), V(A2,20,DC,61), V(69,4B,77,5A), V(16,1A,12,1C), \
264 V(0A,BA,93,E2), V(E5,2A,A0,C0), V(43,E0,22,3C), V(1D,17,1B,12), \
265 V(0B,0D,09,0E), V(AD,C7,8B,F2), V(B9,A8,B6,2D), V(C8,A9,1E,14), \
266 V(85,19,F1,57), V(4C,07,75,AF), V(BB,DD,99,EE), V(FD,60,7F,A3), \
267 V(9F,26,01,F7), V(BC,F5,72,5C), V(C5,3B,66,44), V(34,7E,FB,5B), \
268 V(76,29,43,8B), V(DC,C6,23,CB), V(68,FC,ED,B6), V(63,F1,E4,B8), \
269 V(CA,DC,31,D7), V(10,85,63,42), V(40,22,97,13), V(20,11,C6,84), \
270 V(7D,24,4A,85), V(F8,3D,BB,D2), V(11,32,F9,AE), V(6D,A1,29,C7), \
271 V(4B,2F,9E,1D), V(F3,30,B2,DC), V(EC,52,86,0D), V(D0,E3,C1,77), \
272 V(6C,16,B3,2B), V(99,B9,70,A9), V(FA,48,94,11), V(22,64,E9,47), \
273 V(C4,8C,FC,A8), V(1A,3F,F0,A0), V(D8,2C,7D,56), V(EF,90,33,22), \
274 V(C7,4E,49,87), V(C1,D1,38,D9), V(FE,A2,CA,8C), V(36,0B,D4,98), \
275 V(CF,81,F5,A6), V(28,DE,7A,A5), V(26,8E,B7,DA), V(A4,BF,AD,3F), \
276 V(E4,9D,3A,2C), V(0D,92,78,50), V(9B,CC,5F,6A), V(62,46,7E,54), \
277 V(C2,13,8D,F6), V(E8,B8,D8,90), V(5E,F7,39,2E), V(F5,AF,C3,82), \
278 V(BE,80,5D,9F), V(7C,93,D0,69), V(A9,2D,D5,6F), V(B3,12,25,CF), \
279 V(3B,99,AC,C8), V(A7,7D,18,10), V(6E,63,9C,E8), V(7B,BB,3B,DB), \
280 V(09,78,26,CD), V(F4,18,59,6E), V(01,B7,9A,EC), V(A8,9A,4F,83), \
281 V(65,6E,95,E6), V(7E,E6,FF,AA), V(08,CF,BC,21), V(E6,E8,15,EF), \
282 V(D9,9B,E7,BA), V(CE,36,6F,4A), V(D4,09,9F,EA), V(D6,7C,B0,29), \
283 V(AF,B2,A4,31), V(31,23,3F,2A), V(30,94,A5,C6), V(C0,66,A2,35), \
284 V(37,BC,4E,74), V(A6,CA,82,FC), V(B0,D0,90,E0), V(15,D8,A7,33), \
285 V(4A,98,04,F1), V(F7,DA,EC,41), V(0E,50,CD,7F), V(2F,F6,91,17), \
286 V(8D,D6,4D,76), V(4D,B0,EF,43), V(54,4D,AA,CC), V(DF,04,96,E4), \
287 V(E3,B5,D1,9E), V(1B,88,6A,4C), V(B8,1F,2C,C1), V(7F,51,65,46), \
288 V(04,EA,5E,9D), V(5D,35,8C,01), V(73,74,87,FA), V(2E,41,0B,FB), \
289 V(5A,1D,67,B3), V(52,D2,DB,92), V(33,56,10,E9), V(13,47,D6,6D), \
290 V(8C,61,D7,9A), V(7A,0C,A1,37), V(8E,14,F8,59), V(89,3C,13,EB), \
291 V(EE,27,A9,CE), V(35,C9,61,B7), V(ED,E5,1C,E1), V(3C,B1,47,7A), \
292 V(59,DF,D2,9C), V(3F,73,F2,55), V(79,CE,14,18), V(BF,37,C7,73), \
293 V(EA,CD,F7,53), V(5B,AA,FD,5F), V(14,6F,3D,DF), V(86,DB,44,78), \
294 V(81,F3,AF,CA), V(3E,C4,68,B9), V(2C,34,24,38), V(5F,40,A3,C2), \
295 V(72,C3,1D,16), V(0C,25,E2,BC), V(8B,49,3C,28), V(41,95,0D,FF), \
296 V(71,01,A8,39), V(DE,B3,0C,08), V(9C,E4,B4,D8), V(90,C1,56,64), \
297 V(61,84,CB,7B), V(70,B6,32,D5), V(74,5C,6C,48), V(42,57,B8,D0)
298
299#define V(a,b,c,d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000300static const uint32_t RT0[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000301#undef V
302
Hanno Beckerad049a92017-06-19 16:31:54 +0100303#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200304
Paul Bakker5121ce52009-01-03 21:22:43 +0000305#define V(a,b,c,d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000306static const uint32_t RT1[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000307#undef V
308
309#define V(a,b,c,d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000310static const uint32_t RT2[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000311#undef V
312
313#define V(a,b,c,d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000314static const uint32_t RT3[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000315#undef V
316
Hanno Becker177d3cf2017-06-07 15:52:48 +0100317#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200318
Paul Bakker5121ce52009-01-03 21:22:43 +0000319#undef RT
320
321/*
322 * Round constants
323 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000324static const uint32_t RCON[10] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000325{
326 0x00000001, 0x00000002, 0x00000004, 0x00000008,
327 0x00000010, 0x00000020, 0x00000040, 0x00000080,
328 0x0000001B, 0x00000036
329};
330
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200331#else /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000332
333/*
334 * Forward S-box & tables
335 */
336static unsigned char FSb[256];
Paul Bakker9af723c2014-05-01 13:03:14 +0200337static uint32_t FT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100338#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker9af723c2014-05-01 13:03:14 +0200339static uint32_t FT1[256];
340static uint32_t FT2[256];
341static uint32_t FT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100342#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000343
344/*
345 * Reverse S-box & tables
346 */
347static unsigned char RSb[256];
Paul Bakker5c2364c2012-10-01 14:41:15 +0000348static uint32_t RT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100349#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker5c2364c2012-10-01 14:41:15 +0000350static uint32_t RT1[256];
351static uint32_t RT2[256];
352static uint32_t RT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100353#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000354
355/*
356 * Round constants
357 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000358static uint32_t RCON[10];
Paul Bakker5121ce52009-01-03 21:22:43 +0000359
360/*
361 * Tables generation code
362 */
Hanno Becker1eeca412018-10-15 12:01:35 +0100363#define ROTL8(x) ( ( (x) << 8 ) & 0xFFFFFFFF ) | ( (x) >> 24 )
364#define XTIME(x) ( ( (x) << 1 ) ^ ( ( (x) & 0x80 ) ? 0x1B : 0x00 ) )
Hanno Becker818bac52018-10-26 09:13:26 +0100365#define MUL(x,y) ( ( (x) && (y) ) ? pow[(log[(x)]+log[(y)]) % 255] : 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000366
367static int aes_init_done = 0;
368
369static void aes_gen_tables( void )
370{
371 int i, x, y, z;
372 int pow[256];
373 int log[256];
374
375 /*
376 * compute pow and log tables over GF(2^8)
377 */
378 for( i = 0, x = 1; i < 256; i++ )
379 {
380 pow[i] = x;
381 log[x] = i;
Joe Subbiani6b897c92021-07-08 14:59:52 +0100382 x = MBEDTLS_BYTE_0( x ^ XTIME( x ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000383 }
384
385 /*
386 * calculate the round constants
387 */
388 for( i = 0, x = 1; i < 10; i++ )
389 {
Paul Bakker5c2364c2012-10-01 14:41:15 +0000390 RCON[i] = (uint32_t) x;
Joe Subbiani6b897c92021-07-08 14:59:52 +0100391 x = MBEDTLS_BYTE_0( XTIME( x ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000392 }
393
394 /*
395 * generate the forward and reverse S-boxes
396 */
397 FSb[0x00] = 0x63;
398 RSb[0x63] = 0x00;
399
400 for( i = 1; i < 256; i++ )
401 {
402 x = pow[255 - log[i]];
403
Joe Subbiani6b897c92021-07-08 14:59:52 +0100404 y = x; y = MBEDTLS_BYTE_0( ( y << 1 ) | ( y >> 7 ) );
405 x ^= y; y = MBEDTLS_BYTE_0( ( y << 1 ) | ( y >> 7 ) );
406 x ^= y; y = MBEDTLS_BYTE_0( ( y << 1 ) | ( y >> 7 ) );
407 x ^= y; y = MBEDTLS_BYTE_0( ( y << 1 ) | ( y >> 7 ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000408 x ^= y ^ 0x63;
409
410 FSb[i] = (unsigned char) x;
411 RSb[x] = (unsigned char) i;
412 }
413
414 /*
415 * generate the forward and reverse tables
416 */
417 for( i = 0; i < 256; i++ )
418 {
419 x = FSb[i];
Joe Subbiani6b897c92021-07-08 14:59:52 +0100420 y = MBEDTLS_BYTE_0( XTIME( x ) );
421 z = MBEDTLS_BYTE_0( y ^ x );
Paul Bakker5121ce52009-01-03 21:22:43 +0000422
Paul Bakker5c2364c2012-10-01 14:41:15 +0000423 FT0[i] = ( (uint32_t) y ) ^
424 ( (uint32_t) x << 8 ) ^
425 ( (uint32_t) x << 16 ) ^
426 ( (uint32_t) z << 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000427
Hanno Beckerad049a92017-06-19 16:31:54 +0100428#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +0000429 FT1[i] = ROTL8( FT0[i] );
430 FT2[i] = ROTL8( FT1[i] );
431 FT3[i] = ROTL8( FT2[i] );
Hanno Becker177d3cf2017-06-07 15:52:48 +0100432#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000433
434 x = RSb[i];
435
Paul Bakker5c2364c2012-10-01 14:41:15 +0000436 RT0[i] = ( (uint32_t) MUL( 0x0E, x ) ) ^
437 ( (uint32_t) MUL( 0x09, x ) << 8 ) ^
438 ( (uint32_t) MUL( 0x0D, x ) << 16 ) ^
439 ( (uint32_t) MUL( 0x0B, x ) << 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000440
Hanno Beckerad049a92017-06-19 16:31:54 +0100441#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +0000442 RT1[i] = ROTL8( RT0[i] );
443 RT2[i] = ROTL8( RT1[i] );
444 RT3[i] = ROTL8( RT2[i] );
Hanno Becker177d3cf2017-06-07 15:52:48 +0100445#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000446 }
447}
448
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200449#undef ROTL8
450
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200451#endif /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000452
Hanno Beckerad049a92017-06-19 16:31:54 +0100453#if defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200454
455#define ROTL8(x) ( (uint32_t)( ( x ) << 8 ) + (uint32_t)( ( x ) >> 24 ) )
456#define ROTL16(x) ( (uint32_t)( ( x ) << 16 ) + (uint32_t)( ( x ) >> 16 ) )
457#define ROTL24(x) ( (uint32_t)( ( x ) << 24 ) + (uint32_t)( ( x ) >> 8 ) )
458
459#define AES_RT0(idx) RT0[idx]
460#define AES_RT1(idx) ROTL8( RT0[idx] )
461#define AES_RT2(idx) ROTL16( RT0[idx] )
462#define AES_RT3(idx) ROTL24( RT0[idx] )
463
464#define AES_FT0(idx) FT0[idx]
465#define AES_FT1(idx) ROTL8( FT0[idx] )
466#define AES_FT2(idx) ROTL16( FT0[idx] )
467#define AES_FT3(idx) ROTL24( FT0[idx] )
468
Hanno Becker177d3cf2017-06-07 15:52:48 +0100469#else /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200470
471#define AES_RT0(idx) RT0[idx]
472#define AES_RT1(idx) RT1[idx]
473#define AES_RT2(idx) RT2[idx]
474#define AES_RT3(idx) RT3[idx]
475
476#define AES_FT0(idx) FT0[idx]
477#define AES_FT1(idx) FT1[idx]
478#define AES_FT2(idx) FT2[idx]
479#define AES_FT3(idx) FT3[idx]
480
Hanno Becker177d3cf2017-06-07 15:52:48 +0100481#endif /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200482
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200483void mbedtls_aes_init( mbedtls_aes_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200484{
Manuel Pégourié-Gonnard0e9cddb2018-12-10 16:37:51 +0100485 AES_VALIDATE( ctx != NULL );
Simon Butcher5201e412018-12-06 17:40:14 +0000486
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200487 memset( ctx, 0, sizeof( mbedtls_aes_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200488}
489
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200490void mbedtls_aes_free( mbedtls_aes_context *ctx )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200491{
492 if( ctx == NULL )
493 return;
494
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500495 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_aes_context ) );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200496}
497
Jaeden Amero9366feb2018-05-29 18:55:17 +0100498#if defined(MBEDTLS_CIPHER_MODE_XTS)
499void mbedtls_aes_xts_init( mbedtls_aes_xts_context *ctx )
500{
Manuel Pégourié-Gonnard0e9cddb2018-12-10 16:37:51 +0100501 AES_VALIDATE( ctx != NULL );
Simon Butcher5201e412018-12-06 17:40:14 +0000502
Jaeden Amero9366feb2018-05-29 18:55:17 +0100503 mbedtls_aes_init( &ctx->crypt );
504 mbedtls_aes_init( &ctx->tweak );
505}
506
507void mbedtls_aes_xts_free( mbedtls_aes_xts_context *ctx )
508{
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100509 if( ctx == NULL )
510 return;
Simon Butcher5201e412018-12-06 17:40:14 +0000511
Jaeden Amero9366feb2018-05-29 18:55:17 +0100512 mbedtls_aes_free( &ctx->crypt );
513 mbedtls_aes_free( &ctx->tweak );
514}
515#endif /* MBEDTLS_CIPHER_MODE_XTS */
516
Paul Bakker5121ce52009-01-03 21:22:43 +0000517/*
518 * AES key schedule (encryption)
519 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200520#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200521int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key,
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200522 unsigned int keybits )
Paul Bakker5121ce52009-01-03 21:22:43 +0000523{
Paul Bakker23986e52011-04-24 08:57:21 +0000524 unsigned int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000525 uint32_t *RK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000526
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100527 AES_VALIDATE_RET( ctx != NULL );
528 AES_VALIDATE_RET( key != NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000529
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200530 switch( keybits )
Paul Bakker5121ce52009-01-03 21:22:43 +0000531 {
532 case 128: ctx->nr = 10; break;
533 case 192: ctx->nr = 12; break;
534 case 256: ctx->nr = 14; break;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200535 default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH );
Paul Bakker5121ce52009-01-03 21:22:43 +0000536 }
537
Simon Butcher5201e412018-12-06 17:40:14 +0000538#if !defined(MBEDTLS_AES_ROM_TABLES)
539 if( aes_init_done == 0 )
540 {
541 aes_gen_tables();
542 aes_init_done = 1;
Simon Butcher5201e412018-12-06 17:40:14 +0000543 }
544#endif
545
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200546#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_PADLOCK_ALIGN16)
Paul Bakker048d04e2012-02-12 17:31:04 +0000547 if( aes_padlock_ace == -1 )
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100548 aes_padlock_ace = mbedtls_padlock_has_support( MBEDTLS_PADLOCK_ACE );
Paul Bakker048d04e2012-02-12 17:31:04 +0000549
550 if( aes_padlock_ace )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200551 ctx->rk = RK = MBEDTLS_PADLOCK_ALIGN16( ctx->buf );
Paul Bakker048d04e2012-02-12 17:31:04 +0000552 else
Paul Bakker5121ce52009-01-03 21:22:43 +0000553#endif
Paul Bakker048d04e2012-02-12 17:31:04 +0000554 ctx->rk = RK = ctx->buf;
Paul Bakker5121ce52009-01-03 21:22:43 +0000555
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200556#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100557 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) )
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200558 return( mbedtls_aesni_setkey_enc( (unsigned char *) ctx->rk, key, keybits ) );
Manuel Pégourié-Gonnard47a35362013-12-28 20:45:04 +0100559#endif
560
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200561 for( i = 0; i < ( keybits >> 5 ); i++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000562 {
Joe Subbiani9231d5f2021-07-07 16:56:29 +0100563 RK[i] = MBEDTLS_GET_UINT32_LE( key, i << 2 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000564 }
565
566 switch( ctx->nr )
567 {
568 case 10:
569
570 for( i = 0; i < 10; i++, RK += 4 )
571 {
572 RK[4] = RK[0] ^ RCON[i] ^
Joe Subbiani6b897c92021-07-08 14:59:52 +0100573 ( (uint32_t) FSb[ MBEDTLS_BYTE_1( RK[3] ) ] ) ^
574 ( (uint32_t) FSb[ MBEDTLS_BYTE_2( RK[3] ) ] << 8 ) ^
575 ( (uint32_t) FSb[ MBEDTLS_BYTE_3( RK[3] ) ] << 16 ) ^
576 ( (uint32_t) FSb[ MBEDTLS_BYTE_0( RK[3] ) ] << 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000577
578 RK[5] = RK[1] ^ RK[4];
579 RK[6] = RK[2] ^ RK[5];
580 RK[7] = RK[3] ^ RK[6];
581 }
582 break;
583
584 case 12:
585
586 for( i = 0; i < 8; i++, RK += 6 )
587 {
588 RK[6] = RK[0] ^ RCON[i] ^
Joe Subbiani6b897c92021-07-08 14:59:52 +0100589 ( (uint32_t) FSb[ MBEDTLS_BYTE_1( RK[5] ) ] ) ^
590 ( (uint32_t) FSb[ MBEDTLS_BYTE_2( RK[5] ) ] << 8 ) ^
591 ( (uint32_t) FSb[ MBEDTLS_BYTE_3( RK[5] ) ] << 16 ) ^
592 ( (uint32_t) FSb[ MBEDTLS_BYTE_0( RK[5] ) ] << 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000593
594 RK[7] = RK[1] ^ RK[6];
595 RK[8] = RK[2] ^ RK[7];
596 RK[9] = RK[3] ^ RK[8];
597 RK[10] = RK[4] ^ RK[9];
598 RK[11] = RK[5] ^ RK[10];
599 }
600 break;
601
602 case 14:
603
604 for( i = 0; i < 7; i++, RK += 8 )
605 {
606 RK[8] = RK[0] ^ RCON[i] ^
Joe Subbiani6b897c92021-07-08 14:59:52 +0100607 ( (uint32_t) FSb[ MBEDTLS_BYTE_1( RK[7] ) ] ) ^
608 ( (uint32_t) FSb[ MBEDTLS_BYTE_2( RK[7] ) ] << 8 ) ^
609 ( (uint32_t) FSb[ MBEDTLS_BYTE_3( RK[7] ) ] << 16 ) ^
610 ( (uint32_t) FSb[ MBEDTLS_BYTE_0( RK[7] ) ] << 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000611
612 RK[9] = RK[1] ^ RK[8];
613 RK[10] = RK[2] ^ RK[9];
614 RK[11] = RK[3] ^ RK[10];
615
616 RK[12] = RK[4] ^
Joe Subbiani6b897c92021-07-08 14:59:52 +0100617 ( (uint32_t) FSb[ MBEDTLS_BYTE_0( RK[11] ) ] ) ^
618 ( (uint32_t) FSb[ MBEDTLS_BYTE_1( RK[11] ) ] << 8 ) ^
619 ( (uint32_t) FSb[ MBEDTLS_BYTE_2( RK[11] ) ] << 16 ) ^
620 ( (uint32_t) FSb[ MBEDTLS_BYTE_3( RK[11] ) ] << 24 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000621
622 RK[13] = RK[5] ^ RK[12];
623 RK[14] = RK[6] ^ RK[13];
624 RK[15] = RK[7] ^ RK[14];
625 }
626 break;
Paul Bakker5121ce52009-01-03 21:22:43 +0000627 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000628
629 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000630}
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200631#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000632
633/*
634 * AES key schedule (decryption)
635 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200636#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200637int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key,
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200638 unsigned int keybits )
Paul Bakker5121ce52009-01-03 21:22:43 +0000639{
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200640 int i, j, ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200641 mbedtls_aes_context cty;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000642 uint32_t *RK;
643 uint32_t *SK;
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200644
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100645 AES_VALIDATE_RET( ctx != NULL );
646 AES_VALIDATE_RET( key != NULL );
Simon Butcher5201e412018-12-06 17:40:14 +0000647
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200648 mbedtls_aes_init( &cty );
Paul Bakker5121ce52009-01-03 21:22:43 +0000649
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200650#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_PADLOCK_ALIGN16)
Paul Bakker048d04e2012-02-12 17:31:04 +0000651 if( aes_padlock_ace == -1 )
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100652 aes_padlock_ace = mbedtls_padlock_has_support( MBEDTLS_PADLOCK_ACE );
Paul Bakker048d04e2012-02-12 17:31:04 +0000653
654 if( aes_padlock_ace )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200655 ctx->rk = RK = MBEDTLS_PADLOCK_ALIGN16( ctx->buf );
Paul Bakker048d04e2012-02-12 17:31:04 +0000656 else
Paul Bakker5121ce52009-01-03 21:22:43 +0000657#endif
Paul Bakker048d04e2012-02-12 17:31:04 +0000658 ctx->rk = RK = ctx->buf;
Paul Bakker5121ce52009-01-03 21:22:43 +0000659
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200660 /* Also checks keybits */
661 if( ( ret = mbedtls_aes_setkey_enc( &cty, key, keybits ) ) != 0 )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200662 goto exit;
Paul Bakker2b222c82009-07-27 21:03:45 +0000663
Manuel Pégourié-Gonnardafd5a082014-05-28 21:52:59 +0200664 ctx->nr = cty.nr;
665
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200666#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100667 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) )
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100668 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200669 mbedtls_aesni_inverse_key( (unsigned char *) ctx->rk,
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100670 (const unsigned char *) cty.rk, ctx->nr );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200671 goto exit;
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100672 }
673#endif
674
Paul Bakker5121ce52009-01-03 21:22:43 +0000675 SK = cty.rk + cty.nr * 4;
676
677 *RK++ = *SK++;
678 *RK++ = *SK++;
679 *RK++ = *SK++;
680 *RK++ = *SK++;
681
682 for( i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8 )
683 {
684 for( j = 0; j < 4; j++, SK++ )
685 {
Joe Subbiani6b897c92021-07-08 14:59:52 +0100686 *RK++ = AES_RT0( FSb[ MBEDTLS_BYTE_0( *SK ) ] ) ^
687 AES_RT1( FSb[ MBEDTLS_BYTE_1( *SK ) ] ) ^
688 AES_RT2( FSb[ MBEDTLS_BYTE_2( *SK ) ] ) ^
689 AES_RT3( FSb[ MBEDTLS_BYTE_3( *SK ) ] );
Paul Bakker5121ce52009-01-03 21:22:43 +0000690 }
691 }
692
693 *RK++ = *SK++;
694 *RK++ = *SK++;
695 *RK++ = *SK++;
696 *RK++ = *SK++;
697
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200698exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200699 mbedtls_aes_free( &cty );
Paul Bakker2b222c82009-07-27 21:03:45 +0000700
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200701 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000702}
gabor-mezei-arm95db3012020-10-26 11:35:23 +0100703#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */
Jaeden Amero9366feb2018-05-29 18:55:17 +0100704
705#if defined(MBEDTLS_CIPHER_MODE_XTS)
706static int mbedtls_aes_xts_decode_keys( const unsigned char *key,
707 unsigned int keybits,
708 const unsigned char **key1,
709 unsigned int *key1bits,
710 const unsigned char **key2,
711 unsigned int *key2bits )
712{
713 const unsigned int half_keybits = keybits / 2;
714 const unsigned int half_keybytes = half_keybits / 8;
715
716 switch( keybits )
717 {
718 case 256: break;
719 case 512: break;
720 default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH );
721 }
722
723 *key1bits = half_keybits;
724 *key2bits = half_keybits;
725 *key1 = &key[0];
726 *key2 = &key[half_keybytes];
727
728 return 0;
729}
730
731int mbedtls_aes_xts_setkey_enc( mbedtls_aes_xts_context *ctx,
732 const unsigned char *key,
733 unsigned int keybits)
734{
Janos Follath24eed8d2019-11-22 13:21:35 +0000735 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100736 const unsigned char *key1, *key2;
737 unsigned int key1bits, key2bits;
738
Manuel Pégourié-Gonnard68e3dff2018-12-12 12:48:04 +0100739 AES_VALIDATE_RET( ctx != NULL );
740 AES_VALIDATE_RET( key != NULL );
741
Jaeden Amero9366feb2018-05-29 18:55:17 +0100742 ret = mbedtls_aes_xts_decode_keys( key, keybits, &key1, &key1bits,
743 &key2, &key2bits );
744 if( ret != 0 )
745 return( ret );
746
747 /* Set the tweak key. Always set tweak key for the encryption mode. */
748 ret = mbedtls_aes_setkey_enc( &ctx->tweak, key2, key2bits );
749 if( ret != 0 )
750 return( ret );
751
752 /* Set crypt key for encryption. */
753 return mbedtls_aes_setkey_enc( &ctx->crypt, key1, key1bits );
754}
755
756int mbedtls_aes_xts_setkey_dec( mbedtls_aes_xts_context *ctx,
757 const unsigned char *key,
758 unsigned int keybits)
759{
Janos Follath24eed8d2019-11-22 13:21:35 +0000760 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100761 const unsigned char *key1, *key2;
762 unsigned int key1bits, key2bits;
763
Manuel Pégourié-Gonnard68e3dff2018-12-12 12:48:04 +0100764 AES_VALIDATE_RET( ctx != NULL );
765 AES_VALIDATE_RET( key != NULL );
766
Jaeden Amero9366feb2018-05-29 18:55:17 +0100767 ret = mbedtls_aes_xts_decode_keys( key, keybits, &key1, &key1bits,
768 &key2, &key2bits );
769 if( ret != 0 )
770 return( ret );
771
772 /* Set the tweak key. Always set tweak key for encryption. */
773 ret = mbedtls_aes_setkey_enc( &ctx->tweak, key2, key2bits );
774 if( ret != 0 )
775 return( ret );
776
777 /* Set crypt key for decryption. */
778 return mbedtls_aes_setkey_dec( &ctx->crypt, key1, key1bits );
779}
780#endif /* MBEDTLS_CIPHER_MODE_XTS */
781
Joe Subbiani6b897c92021-07-08 14:59:52 +0100782#define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \
783 do \
784 { \
785 (X0) = *RK++ ^ AES_FT0( MBEDTLS_BYTE_0( Y0 ) ) ^ \
786 AES_FT1( MBEDTLS_BYTE_1( Y1 ) ) ^ \
787 AES_FT2( MBEDTLS_BYTE_2( Y2 ) ) ^ \
788 AES_FT3( MBEDTLS_BYTE_3( Y3 ) ); \
789 \
790 (X1) = *RK++ ^ AES_FT0( MBEDTLS_BYTE_0( Y1 ) ) ^ \
791 AES_FT1( MBEDTLS_BYTE_1( Y2 ) ) ^ \
792 AES_FT2( MBEDTLS_BYTE_2( Y3 ) ) ^ \
793 AES_FT3( MBEDTLS_BYTE_3( Y0 ) ); \
794 \
795 (X2) = *RK++ ^ AES_FT0( MBEDTLS_BYTE_0( Y2 ) ) ^ \
796 AES_FT1( MBEDTLS_BYTE_1( Y3 ) ) ^ \
797 AES_FT2( MBEDTLS_BYTE_2( Y0 ) ) ^ \
798 AES_FT3( MBEDTLS_BYTE_3( Y1 ) ); \
799 \
800 (X3) = *RK++ ^ AES_FT0( MBEDTLS_BYTE_0( Y3 ) ) ^ \
801 AES_FT1( MBEDTLS_BYTE_1( Y0 ) ) ^ \
802 AES_FT2( MBEDTLS_BYTE_2( Y1 ) ) ^ \
803 AES_FT3( MBEDTLS_BYTE_3( Y2 ) ); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100804 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000805
Hanno Becker1eeca412018-10-15 12:01:35 +0100806#define AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \
807 do \
808 { \
Joe Subbiani6b897c92021-07-08 14:59:52 +0100809 (X0) = *RK++ ^ AES_RT0( MBEDTLS_BYTE_0( Y0 ) ) ^ \
810 AES_RT1( MBEDTLS_BYTE_1( Y3 ) ) ^ \
811 AES_RT2( MBEDTLS_BYTE_2( Y2 ) ) ^ \
812 AES_RT3( MBEDTLS_BYTE_3( Y1 ) ); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100813 \
Joe Subbiani6b897c92021-07-08 14:59:52 +0100814 (X1) = *RK++ ^ AES_RT0( MBEDTLS_BYTE_0( Y1 ) ) ^ \
815 AES_RT1( MBEDTLS_BYTE_1( Y0 ) ) ^ \
816 AES_RT2( MBEDTLS_BYTE_2( Y3 ) ) ^ \
817 AES_RT3( MBEDTLS_BYTE_3( Y2 ) ); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100818 \
Joe Subbiani6b897c92021-07-08 14:59:52 +0100819 (X2) = *RK++ ^ AES_RT0( MBEDTLS_BYTE_0( Y2 ) ) ^ \
820 AES_RT1( MBEDTLS_BYTE_1( Y1 ) ) ^ \
821 AES_RT2( MBEDTLS_BYTE_2( Y0 ) ) ^ \
822 AES_RT3( MBEDTLS_BYTE_3( Y3 ) ); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100823 \
Joe Subbiani6b897c92021-07-08 14:59:52 +0100824 (X3) = *RK++ ^ AES_RT0( MBEDTLS_BYTE_0( Y3 ) ) ^ \
825 AES_RT1( MBEDTLS_BYTE_1( Y2 ) ) ^ \
826 AES_RT2( MBEDTLS_BYTE_2( Y1 ) ) ^ \
827 AES_RT3( MBEDTLS_BYTE_3( Y0 ) ); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100828 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000829
830/*
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200831 * AES-ECB block encryption
832 */
833#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Andres AGf5bf7182017-03-03 14:09:56 +0000834int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx,
835 const unsigned char input[16],
836 unsigned char output[16] )
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200837{
838 int i;
Gilles Peskine5197c662020-08-26 17:03:24 +0200839 uint32_t *RK = ctx->rk;
840 struct
841 {
842 uint32_t X[4];
843 uint32_t Y[4];
844 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200845
Joe Subbiani9231d5f2021-07-07 16:56:29 +0100846 t.X[0] = MBEDTLS_GET_UINT32_LE( input, 0 ); t.X[0] ^= *RK++;
847 t.X[1] = MBEDTLS_GET_UINT32_LE( input, 4 ); t.X[1] ^= *RK++;
848 t.X[2] = MBEDTLS_GET_UINT32_LE( input, 8 ); t.X[2] ^= *RK++;
849 t.X[3] = MBEDTLS_GET_UINT32_LE( input, 12 ); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200850
851 for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- )
852 {
Gilles Peskine5197c662020-08-26 17:03:24 +0200853 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] );
854 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 +0200855 }
856
Gilles Peskine5197c662020-08-26 17:03:24 +0200857 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 +0200858
Gilles Peskine5197c662020-08-26 17:03:24 +0200859 t.X[0] = *RK++ ^ \
Joe Subbiani6b897c92021-07-08 14:59:52 +0100860 ( (uint32_t) FSb[ MBEDTLS_BYTE_0( t.Y[0] ) ] ) ^
861 ( (uint32_t) FSb[ MBEDTLS_BYTE_1( t.Y[1] ) ] << 8 ) ^
862 ( (uint32_t) FSb[ MBEDTLS_BYTE_2( t.Y[2] ) ] << 16 ) ^
863 ( (uint32_t) FSb[ MBEDTLS_BYTE_3( t.Y[3] ) ] << 24 );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200864
Gilles Peskine5197c662020-08-26 17:03:24 +0200865 t.X[1] = *RK++ ^ \
Joe Subbiani6b897c92021-07-08 14:59:52 +0100866 ( (uint32_t) FSb[ MBEDTLS_BYTE_0( t.Y[1] ) ] ) ^
867 ( (uint32_t) FSb[ MBEDTLS_BYTE_1( t.Y[2] ) ] << 8 ) ^
868 ( (uint32_t) FSb[ MBEDTLS_BYTE_2( t.Y[3] ) ] << 16 ) ^
869 ( (uint32_t) FSb[ MBEDTLS_BYTE_3( t.Y[0] ) ] << 24 );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200870
Gilles Peskine5197c662020-08-26 17:03:24 +0200871 t.X[2] = *RK++ ^ \
Joe Subbiani6b897c92021-07-08 14:59:52 +0100872 ( (uint32_t) FSb[ MBEDTLS_BYTE_0( t.Y[2] ) ] ) ^
873 ( (uint32_t) FSb[ MBEDTLS_BYTE_1( t.Y[3] ) ] << 8 ) ^
874 ( (uint32_t) FSb[ MBEDTLS_BYTE_2( t.Y[0] ) ] << 16 ) ^
875 ( (uint32_t) FSb[ MBEDTLS_BYTE_3( t.Y[1] ) ] << 24 );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200876
Gilles Peskine5197c662020-08-26 17:03:24 +0200877 t.X[3] = *RK++ ^ \
Joe Subbiani6b897c92021-07-08 14:59:52 +0100878 ( (uint32_t) FSb[ MBEDTLS_BYTE_0( t.Y[3] ) ] ) ^
879 ( (uint32_t) FSb[ MBEDTLS_BYTE_1( t.Y[0] ) ] << 8 ) ^
880 ( (uint32_t) FSb[ MBEDTLS_BYTE_2( t.Y[1] ) ] << 16 ) ^
881 ( (uint32_t) FSb[ MBEDTLS_BYTE_3( t.Y[2] ) ] << 24 );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200882
Joe Subbiani2bbafda2021-06-24 13:00:03 +0100883 MBEDTLS_PUT_UINT32_LE( t.X[0], output, 0 );
884 MBEDTLS_PUT_UINT32_LE( t.X[1], output, 4 );
885 MBEDTLS_PUT_UINT32_LE( t.X[2], output, 8 );
886 MBEDTLS_PUT_UINT32_LE( t.X[3], output, 12 );
Andres AGf5bf7182017-03-03 14:09:56 +0000887
Gilles Peskine5197c662020-08-26 17:03:24 +0200888 mbedtls_platform_zeroize( &t, sizeof( t ) );
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500889
Andres AGf5bf7182017-03-03 14:09:56 +0000890 return( 0 );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200891}
892#endif /* !MBEDTLS_AES_ENCRYPT_ALT */
893
Gilles Peskine8db3efb2018-02-21 19:16:20 +0100894#if !defined(MBEDTLS_DEPRECATED_REMOVED)
Hanno Beckerbedc2052017-06-26 12:46:56 +0100895void mbedtls_aes_encrypt( mbedtls_aes_context *ctx,
896 const unsigned char input[16],
897 unsigned char output[16] )
898{
Mateusz Starzyk15a74202021-08-05 13:56:48 +0200899 MBEDTLS_IGNORE_RETURN( mbedtls_internal_aes_encrypt( ctx, input, output ) );
Hanno Beckerbedc2052017-06-26 12:46:56 +0100900}
Gilles Peskine8db3efb2018-02-21 19:16:20 +0100901#endif /* !MBEDTLS_DEPRECATED_REMOVED */
Hanno Beckerbedc2052017-06-26 12:46:56 +0100902
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200903/*
904 * AES-ECB block decryption
905 */
906#if !defined(MBEDTLS_AES_DECRYPT_ALT)
Andres AGf5bf7182017-03-03 14:09:56 +0000907int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx,
908 const unsigned char input[16],
909 unsigned char output[16] )
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200910{
911 int i;
Gilles Peskine5197c662020-08-26 17:03:24 +0200912 uint32_t *RK = ctx->rk;
913 struct
914 {
915 uint32_t X[4];
916 uint32_t Y[4];
917 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200918
Joe Subbiani9231d5f2021-07-07 16:56:29 +0100919 t.X[0] = MBEDTLS_GET_UINT32_LE( input, 0 ); t.X[0] ^= *RK++;
920 t.X[1] = MBEDTLS_GET_UINT32_LE( input, 4 ); t.X[1] ^= *RK++;
921 t.X[2] = MBEDTLS_GET_UINT32_LE( input, 8 ); t.X[2] ^= *RK++;
922 t.X[3] = MBEDTLS_GET_UINT32_LE( input, 12 ); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200923
924 for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- )
925 {
Gilles Peskine5197c662020-08-26 17:03:24 +0200926 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] );
927 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 +0200928 }
929
Gilles Peskine5197c662020-08-26 17:03:24 +0200930 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 +0200931
Gilles Peskine5197c662020-08-26 17:03:24 +0200932 t.X[0] = *RK++ ^ \
Joe Subbiani6b897c92021-07-08 14:59:52 +0100933 ( (uint32_t) RSb[ MBEDTLS_BYTE_0( t.Y[0] ) ] ) ^
934 ( (uint32_t) RSb[ MBEDTLS_BYTE_1( t.Y[3] ) ] << 8 ) ^
935 ( (uint32_t) RSb[ MBEDTLS_BYTE_2( t.Y[2] ) ] << 16 ) ^
936 ( (uint32_t) RSb[ MBEDTLS_BYTE_3( t.Y[1] ) ] << 24 );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200937
Gilles Peskine5197c662020-08-26 17:03:24 +0200938 t.X[1] = *RK++ ^ \
Joe Subbiani6b897c92021-07-08 14:59:52 +0100939 ( (uint32_t) RSb[ MBEDTLS_BYTE_0( t.Y[1] ) ] ) ^
940 ( (uint32_t) RSb[ MBEDTLS_BYTE_1( t.Y[0] ) ] << 8 ) ^
941 ( (uint32_t) RSb[ MBEDTLS_BYTE_2( t.Y[3] ) ] << 16 ) ^
942 ( (uint32_t) RSb[ MBEDTLS_BYTE_3( t.Y[2] ) ] << 24 );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200943
Gilles Peskine5197c662020-08-26 17:03:24 +0200944 t.X[2] = *RK++ ^ \
Joe Subbiani6b897c92021-07-08 14:59:52 +0100945 ( (uint32_t) RSb[ MBEDTLS_BYTE_0( t.Y[2] ) ] ) ^
946 ( (uint32_t) RSb[ MBEDTLS_BYTE_1( t.Y[1] ) ] << 8 ) ^
947 ( (uint32_t) RSb[ MBEDTLS_BYTE_2( t.Y[0] ) ] << 16 ) ^
948 ( (uint32_t) RSb[ MBEDTLS_BYTE_3( t.Y[3] ) ] << 24 );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200949
Gilles Peskine5197c662020-08-26 17:03:24 +0200950 t.X[3] = *RK++ ^ \
Joe Subbiani6b897c92021-07-08 14:59:52 +0100951 ( (uint32_t) RSb[ MBEDTLS_BYTE_0( t.Y[3] ) ] ) ^
952 ( (uint32_t) RSb[ MBEDTLS_BYTE_1( t.Y[2] ) ] << 8 ) ^
953 ( (uint32_t) RSb[ MBEDTLS_BYTE_2( t.Y[1] ) ] << 16 ) ^
954 ( (uint32_t) RSb[ MBEDTLS_BYTE_3( t.Y[0] ) ] << 24 );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200955
Joe Subbiani2bbafda2021-06-24 13:00:03 +0100956 MBEDTLS_PUT_UINT32_LE( t.X[0], output, 0 );
957 MBEDTLS_PUT_UINT32_LE( t.X[1], output, 4 );
958 MBEDTLS_PUT_UINT32_LE( t.X[2], output, 8 );
959 MBEDTLS_PUT_UINT32_LE( t.X[3], output, 12 );
Andres AGf5bf7182017-03-03 14:09:56 +0000960
Gilles Peskine5197c662020-08-26 17:03:24 +0200961 mbedtls_platform_zeroize( &t, sizeof( t ) );
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500962
Andres AGf5bf7182017-03-03 14:09:56 +0000963 return( 0 );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200964}
965#endif /* !MBEDTLS_AES_DECRYPT_ALT */
966
Gilles Peskine8db3efb2018-02-21 19:16:20 +0100967#if !defined(MBEDTLS_DEPRECATED_REMOVED)
Hanno Beckerbedc2052017-06-26 12:46:56 +0100968void mbedtls_aes_decrypt( mbedtls_aes_context *ctx,
969 const unsigned char input[16],
970 unsigned char output[16] )
971{
Mateusz Starzyk15a74202021-08-05 13:56:48 +0200972 MBEDTLS_IGNORE_RETURN( mbedtls_internal_aes_decrypt( ctx, input, output ) );
Hanno Beckerbedc2052017-06-26 12:46:56 +0100973}
Gilles Peskine8db3efb2018-02-21 19:16:20 +0100974#endif /* !MBEDTLS_DEPRECATED_REMOVED */
Hanno Beckerbedc2052017-06-26 12:46:56 +0100975
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200976/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000977 * AES-ECB block encryption/decryption
978 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200979int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx,
Manuel Pégourié-Gonnardeb6d3962018-12-18 09:59:35 +0100980 int mode,
981 const unsigned char input[16],
982 unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000983{
Manuel Pégourié-Gonnard1aca2602018-12-12 12:56:55 +0100984 AES_VALIDATE_RET( ctx != NULL );
985 AES_VALIDATE_RET( input != NULL );
986 AES_VALIDATE_RET( output != NULL );
987 AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
988 mode == MBEDTLS_AES_DECRYPT );
989
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200990#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64)
Manuel Pégourié-Gonnardc730ed32015-06-02 10:38:50 +0100991 if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200992 return( mbedtls_aesni_crypt_ecb( ctx, mode, input, output ) );
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +0100993#endif
994
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200995#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Paul Bakker048d04e2012-02-12 17:31:04 +0000996 if( aes_padlock_ace )
Paul Bakker5121ce52009-01-03 21:22:43 +0000997 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200998 if( mbedtls_padlock_xcryptecb( ctx, mode, input, output ) == 0 )
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000999 return( 0 );
1000
1001 // If padlock data misaligned, we just fall back to
1002 // unaccelerated mode
1003 //
Paul Bakker5121ce52009-01-03 21:22:43 +00001004 }
1005#endif
1006
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001007 if( mode == MBEDTLS_AES_ENCRYPT )
Andres AGf5bf7182017-03-03 14:09:56 +00001008 return( mbedtls_internal_aes_encrypt( ctx, input, output ) );
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001009 else
Andres AGf5bf7182017-03-03 14:09:56 +00001010 return( mbedtls_internal_aes_decrypt( ctx, input, output ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001011}
1012
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001013#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001014/*
1015 * AES-CBC buffer encryption/decryption
1016 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001017int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx,
Paul Bakker5121ce52009-01-03 21:22:43 +00001018 int mode,
Paul Bakker23986e52011-04-24 08:57:21 +00001019 size_t length,
Paul Bakker5121ce52009-01-03 21:22:43 +00001020 unsigned char iv[16],
Paul Bakkerff60ee62010-03-16 21:09:09 +00001021 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +00001022 unsigned char *output )
1023{
1024 int i;
Gilles Peskine377a3102021-07-07 21:08:28 +02001025 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +00001026 unsigned char temp[16];
1027
Manuel Pégourié-Gonnard3178d1a2018-12-12 13:05:00 +01001028 AES_VALIDATE_RET( ctx != NULL );
1029 AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
1030 mode == MBEDTLS_AES_DECRYPT );
1031 AES_VALIDATE_RET( iv != NULL );
1032 AES_VALIDATE_RET( input != NULL );
1033 AES_VALIDATE_RET( output != NULL );
1034
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001035 if( length % 16 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001036 return( MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH );
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001037
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001038#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Paul Bakker048d04e2012-02-12 17:31:04 +00001039 if( aes_padlock_ace )
Paul Bakker5121ce52009-01-03 21:22:43 +00001040 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001041 if( mbedtls_padlock_xcryptcbc( ctx, mode, length, iv, input, output ) == 0 )
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001042 return( 0 );
Paul Bakker9af723c2014-05-01 13:03:14 +02001043
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001044 // If padlock data misaligned, we just fall back to
1045 // unaccelerated mode
1046 //
Paul Bakker5121ce52009-01-03 21:22:43 +00001047 }
1048#endif
1049
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001050 if( mode == MBEDTLS_AES_DECRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +00001051 {
1052 while( length > 0 )
1053 {
1054 memcpy( temp, input, 16 );
Gilles Peskine377a3102021-07-07 21:08:28 +02001055 ret = mbedtls_aes_crypt_ecb( ctx, mode, input, output );
1056 if( ret != 0 )
1057 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001058
1059 for( i = 0; i < 16; i++ )
1060 output[i] = (unsigned char)( output[i] ^ iv[i] );
1061
1062 memcpy( iv, temp, 16 );
1063
1064 input += 16;
1065 output += 16;
1066 length -= 16;
1067 }
1068 }
1069 else
1070 {
1071 while( length > 0 )
1072 {
1073 for( i = 0; i < 16; i++ )
1074 output[i] = (unsigned char)( input[i] ^ iv[i] );
1075
Gilles Peskine377a3102021-07-07 21:08:28 +02001076 ret = mbedtls_aes_crypt_ecb( ctx, mode, output, output );
1077 if( ret != 0 )
1078 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001079 memcpy( iv, output, 16 );
1080
1081 input += 16;
1082 output += 16;
1083 length -= 16;
1084 }
1085 }
Gilles Peskine377a3102021-07-07 21:08:28 +02001086 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001087
Gilles Peskine377a3102021-07-07 21:08:28 +02001088exit:
1089 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001090}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001091#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001092
Aorimn5f778012016-06-09 23:22:58 +02001093#if defined(MBEDTLS_CIPHER_MODE_XTS)
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001094
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001095typedef unsigned char mbedtls_be128[16];
1096
1097/*
1098 * GF(2^128) multiplication function
1099 *
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001100 * This function multiplies a field element by x in the polynomial field
1101 * representation. It uses 64-bit word operations to gain speed but compensates
Shaun Case0e7791f2021-12-20 21:14:10 -08001102 * for machine endianness and hence works correctly on both big and little
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001103 * endian machines.
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001104 */
1105static void mbedtls_gf128mul_x_ble( unsigned char r[16],
Jaeden Amero8cfc75f2018-05-31 16:53:08 +01001106 const unsigned char x[16] )
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001107{
1108 uint64_t a, b, ra, rb;
1109
Joe Subbiani1bd5d7d2021-07-16 12:29:49 +01001110 a = MBEDTLS_GET_UINT64_LE( x, 0 );
1111 b = MBEDTLS_GET_UINT64_LE( x, 8 );
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001112
Jaeden Amero8cfc75f2018-05-31 16:53:08 +01001113 ra = ( a << 1 ) ^ 0x0087 >> ( 8 - ( ( b >> 63 ) << 3 ) );
1114 rb = ( a >> 63 ) | ( b << 1 );
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001115
Joe Subbiani1bd5d7d2021-07-16 12:29:49 +01001116 MBEDTLS_PUT_UINT64_LE( ra, r, 0 );
1117 MBEDTLS_PUT_UINT64_LE( rb, r, 8 );
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001118}
1119
Aorimn5f778012016-06-09 23:22:58 +02001120/*
1121 * AES-XTS buffer encryption/decryption
1122 */
Jaeden Amero9366feb2018-05-29 18:55:17 +01001123int mbedtls_aes_crypt_xts( mbedtls_aes_xts_context *ctx,
1124 int mode,
Jaeden Amero5162b932018-05-29 12:55:24 +01001125 size_t length,
Jaeden Amerocd9fc5e2018-05-30 15:23:24 +01001126 const unsigned char data_unit[16],
Jaeden Amero9366feb2018-05-29 18:55:17 +01001127 const unsigned char *input,
1128 unsigned char *output )
Aorimn5f778012016-06-09 23:22:58 +02001129{
Janos Follath24eed8d2019-11-22 13:21:35 +00001130 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amerod82cd862018-04-28 15:02:45 +01001131 size_t blocks = length / 16;
1132 size_t leftover = length % 16;
1133 unsigned char tweak[16];
1134 unsigned char prev_tweak[16];
1135 unsigned char tmp[16];
Aorimn5f778012016-06-09 23:22:58 +02001136
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01001137 AES_VALIDATE_RET( ctx != NULL );
1138 AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
1139 mode == MBEDTLS_AES_DECRYPT );
Manuel Pégourié-Gonnard998a3582018-12-18 10:03:13 +01001140 AES_VALIDATE_RET( data_unit != NULL );
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01001141 AES_VALIDATE_RET( input != NULL );
1142 AES_VALIDATE_RET( output != NULL );
1143
Jaeden Amero8381fcb2018-10-11 12:06:15 +01001144 /* Data units must be at least 16 bytes long. */
Aorimn5f778012016-06-09 23:22:58 +02001145 if( length < 16 )
Jaeden Amerod82cd862018-04-28 15:02:45 +01001146 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Aorimn5f778012016-06-09 23:22:58 +02001147
Jaeden Ameroa74faba2018-10-11 12:07:43 +01001148 /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */
Jaeden Amero0a8b0202018-05-30 15:36:06 +01001149 if( length > ( 1 << 20 ) * 16 )
1150 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Aorimn5f778012016-06-09 23:22:58 +02001151
Jaeden Amerod82cd862018-04-28 15:02:45 +01001152 /* Compute the tweak. */
Jaeden Amerocd9fc5e2018-05-30 15:23:24 +01001153 ret = mbedtls_aes_crypt_ecb( &ctx->tweak, MBEDTLS_AES_ENCRYPT,
1154 data_unit, tweak );
Jaeden Amerod82cd862018-04-28 15:02:45 +01001155 if( ret != 0 )
1156 return( ret );
Aorimn5f778012016-06-09 23:22:58 +02001157
Jaeden Amerod82cd862018-04-28 15:02:45 +01001158 while( blocks-- )
Aorimn5f778012016-06-09 23:22:58 +02001159 {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001160 size_t i;
1161
1162 if( leftover && ( mode == MBEDTLS_AES_DECRYPT ) && blocks == 0 )
1163 {
1164 /* We are on the last block in a decrypt operation that has
1165 * leftover bytes, so we need to use the next tweak for this block,
1166 * and this tweak for the lefover bytes. Save the current tweak for
1167 * the leftovers and then update the current tweak for use on this,
1168 * the last full block. */
1169 memcpy( prev_tweak, tweak, sizeof( tweak ) );
1170 mbedtls_gf128mul_x_ble( tweak, tweak );
1171 }
1172
1173 for( i = 0; i < 16; i++ )
1174 tmp[i] = input[i] ^ tweak[i];
1175
1176 ret = mbedtls_aes_crypt_ecb( &ctx->crypt, mode, tmp, tmp );
1177 if( ret != 0 )
1178 return( ret );
1179
1180 for( i = 0; i < 16; i++ )
1181 output[i] = tmp[i] ^ tweak[i];
1182
1183 /* Update the tweak for the next block. */
1184 mbedtls_gf128mul_x_ble( tweak, tweak );
1185
1186 output += 16;
1187 input += 16;
Aorimn5f778012016-06-09 23:22:58 +02001188 }
1189
Jaeden Amerod82cd862018-04-28 15:02:45 +01001190 if( leftover )
Aorimn5f778012016-06-09 23:22:58 +02001191 {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001192 /* If we are on the leftover bytes in a decrypt operation, we need to
1193 * use the previous tweak for these bytes (as saved in prev_tweak). */
1194 unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
Aorimn5f778012016-06-09 23:22:58 +02001195
Jaeden Amerod82cd862018-04-28 15:02:45 +01001196 /* We are now on the final part of the data unit, which doesn't divide
1197 * evenly by 16. It's time for ciphertext stealing. */
1198 size_t i;
1199 unsigned char *prev_output = output - 16;
Aorimn5f778012016-06-09 23:22:58 +02001200
Jaeden Amerod82cd862018-04-28 15:02:45 +01001201 /* Copy ciphertext bytes from the previous block to our output for each
Shaun Case0e7791f2021-12-20 21:14:10 -08001202 * byte of ciphertext we won't steal. At the same time, copy the
Jaeden Amerod82cd862018-04-28 15:02:45 +01001203 * remainder of the input for this final round (since the loop bounds
1204 * are the same). */
1205 for( i = 0; i < leftover; i++ )
Aorimn5f778012016-06-09 23:22:58 +02001206 {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001207 output[i] = prev_output[i];
1208 tmp[i] = input[i] ^ t[i];
Aorimn5f778012016-06-09 23:22:58 +02001209 }
Aorimn5f778012016-06-09 23:22:58 +02001210
Jaeden Amerod82cd862018-04-28 15:02:45 +01001211 /* Copy ciphertext bytes from the previous block for input in this
1212 * round. */
1213 for( ; i < 16; i++ )
1214 tmp[i] = prev_output[i] ^ t[i];
Aorimn5f778012016-06-09 23:22:58 +02001215
Jaeden Amerod82cd862018-04-28 15:02:45 +01001216 ret = mbedtls_aes_crypt_ecb( &ctx->crypt, mode, tmp, tmp );
1217 if( ret != 0 )
1218 return ret;
Aorimn5f778012016-06-09 23:22:58 +02001219
Jaeden Amerod82cd862018-04-28 15:02:45 +01001220 /* Write the result back to the previous block, overriding the previous
1221 * output we copied. */
1222 for( i = 0; i < 16; i++ )
1223 prev_output[i] = tmp[i] ^ t[i];
Aorimn5f778012016-06-09 23:22:58 +02001224 }
1225
1226 return( 0 );
1227}
1228#endif /* MBEDTLS_CIPHER_MODE_XTS */
1229
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001230#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001231/*
1232 * AES-CFB128 buffer encryption/decryption
1233 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001234int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx,
Paul Bakker5121ce52009-01-03 21:22:43 +00001235 int mode,
Paul Bakker23986e52011-04-24 08:57:21 +00001236 size_t length,
Paul Bakker27fdf462011-06-09 13:55:13 +00001237 size_t *iv_off,
Paul Bakker5121ce52009-01-03 21:22:43 +00001238 unsigned char iv[16],
Paul Bakkerff60ee62010-03-16 21:09:09 +00001239 const unsigned char *input,
Paul Bakker5121ce52009-01-03 21:22:43 +00001240 unsigned char *output )
1241{
Paul Bakker27fdf462011-06-09 13:55:13 +00001242 int c;
Gilles Peskine377a3102021-07-07 21:08:28 +02001243 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001244 size_t n;
1245
1246 AES_VALIDATE_RET( ctx != NULL );
1247 AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
1248 mode == MBEDTLS_AES_DECRYPT );
1249 AES_VALIDATE_RET( iv_off != NULL );
1250 AES_VALIDATE_RET( iv != NULL );
1251 AES_VALIDATE_RET( input != NULL );
1252 AES_VALIDATE_RET( output != NULL );
1253
1254 n = *iv_off;
Paul Bakker5121ce52009-01-03 21:22:43 +00001255
Manuel Pégourié-Gonnarde55e1032018-12-18 12:09:02 +01001256 if( n > 15 )
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001257 return( MBEDTLS_ERR_AES_BAD_INPUT_DATA );
1258
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001259 if( mode == MBEDTLS_AES_DECRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +00001260 {
1261 while( length-- )
1262 {
1263 if( n == 0 )
Gilles Peskine377a3102021-07-07 21:08:28 +02001264 {
1265 ret = mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
1266 if( ret != 0 )
1267 goto exit;
1268 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001269
1270 c = *input++;
1271 *output++ = (unsigned char)( c ^ iv[n] );
1272 iv[n] = (unsigned char) c;
1273
Paul Bakker66d5d072014-06-17 16:39:18 +02001274 n = ( n + 1 ) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001275 }
1276 }
1277 else
1278 {
1279 while( length-- )
1280 {
1281 if( n == 0 )
Gilles Peskine377a3102021-07-07 21:08:28 +02001282 {
1283 ret = mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
1284 if( ret != 0 )
1285 goto exit;
1286 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001287
1288 iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ );
1289
Paul Bakker66d5d072014-06-17 16:39:18 +02001290 n = ( n + 1 ) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001291 }
1292 }
1293
1294 *iv_off = n;
Gilles Peskine377a3102021-07-07 21:08:28 +02001295 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001296
Gilles Peskine377a3102021-07-07 21:08:28 +02001297exit:
1298 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001299}
Paul Bakker556efba2014-01-24 15:38:12 +01001300
1301/*
1302 * AES-CFB8 buffer encryption/decryption
1303 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001304int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx,
Manuel Pégourié-Gonnardeb6d3962018-12-18 09:59:35 +01001305 int mode,
1306 size_t length,
1307 unsigned char iv[16],
1308 const unsigned char *input,
1309 unsigned char *output )
Paul Bakker556efba2014-01-24 15:38:12 +01001310{
Gilles Peskine377a3102021-07-07 21:08:28 +02001311 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker556efba2014-01-24 15:38:12 +01001312 unsigned char c;
1313 unsigned char ov[17];
1314
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001315 AES_VALIDATE_RET( ctx != NULL );
1316 AES_VALIDATE_RET( mode == MBEDTLS_AES_ENCRYPT ||
1317 mode == MBEDTLS_AES_DECRYPT );
1318 AES_VALIDATE_RET( iv != NULL );
1319 AES_VALIDATE_RET( input != NULL );
1320 AES_VALIDATE_RET( output != NULL );
Paul Bakker556efba2014-01-24 15:38:12 +01001321 while( length-- )
1322 {
Paul Bakker66d5d072014-06-17 16:39:18 +02001323 memcpy( ov, iv, 16 );
Gilles Peskine377a3102021-07-07 21:08:28 +02001324 ret = mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
1325 if( ret != 0 )
1326 goto exit;
Paul Bakker556efba2014-01-24 15:38:12 +01001327
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001328 if( mode == MBEDTLS_AES_DECRYPT )
Paul Bakker556efba2014-01-24 15:38:12 +01001329 ov[16] = *input;
1330
1331 c = *output++ = (unsigned char)( iv[0] ^ *input++ );
1332
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001333 if( mode == MBEDTLS_AES_ENCRYPT )
Paul Bakker556efba2014-01-24 15:38:12 +01001334 ov[16] = c;
1335
Paul Bakker66d5d072014-06-17 16:39:18 +02001336 memcpy( iv, ov + 1, 16 );
Paul Bakker556efba2014-01-24 15:38:12 +01001337 }
Gilles Peskine377a3102021-07-07 21:08:28 +02001338 ret = 0;
Paul Bakker556efba2014-01-24 15:38:12 +01001339
Gilles Peskine377a3102021-07-07 21:08:28 +02001340exit:
1341 return( ret );
Paul Bakker556efba2014-01-24 15:38:12 +01001342}
Simon Butcher76a5b222018-04-22 22:57:27 +01001343#endif /* MBEDTLS_CIPHER_MODE_CFB */
1344
1345#if defined(MBEDTLS_CIPHER_MODE_OFB)
1346/*
1347 * AES-OFB (Output Feedback Mode) buffer encryption/decryption
1348 */
1349int mbedtls_aes_crypt_ofb( mbedtls_aes_context *ctx,
Simon Butcher00131442018-05-22 22:40:36 +01001350 size_t length,
1351 size_t *iv_off,
1352 unsigned char iv[16],
1353 const unsigned char *input,
1354 unsigned char *output )
Simon Butcher76a5b222018-04-22 22:57:27 +01001355{
Simon Butcherad4e4932018-04-29 00:43:47 +01001356 int ret = 0;
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001357 size_t n;
1358
1359 AES_VALIDATE_RET( ctx != NULL );
1360 AES_VALIDATE_RET( iv_off != NULL );
1361 AES_VALIDATE_RET( iv != NULL );
1362 AES_VALIDATE_RET( input != NULL );
1363 AES_VALIDATE_RET( output != NULL );
1364
1365 n = *iv_off;
Simon Butcher76a5b222018-04-22 22:57:27 +01001366
Manuel Pégourié-Gonnarde55e1032018-12-18 12:09:02 +01001367 if( n > 15 )
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001368 return( MBEDTLS_ERR_AES_BAD_INPUT_DATA );
1369
Simon Butcher76a5b222018-04-22 22:57:27 +01001370 while( length-- )
1371 {
1372 if( n == 0 )
Simon Butcherad4e4932018-04-29 00:43:47 +01001373 {
1374 ret = mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv );
1375 if( ret != 0 )
1376 goto exit;
1377 }
Simon Butcher76a5b222018-04-22 22:57:27 +01001378 *output++ = *input++ ^ iv[n];
1379
1380 n = ( n + 1 ) & 0x0F;
1381 }
1382
1383 *iv_off = n;
1384
Simon Butcherad4e4932018-04-29 00:43:47 +01001385exit:
1386 return( ret );
Simon Butcher76a5b222018-04-22 22:57:27 +01001387}
1388#endif /* MBEDTLS_CIPHER_MODE_OFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001389
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001390#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001391/*
1392 * AES-CTR buffer encryption/decryption
1393 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001394int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx,
Paul Bakker27fdf462011-06-09 13:55:13 +00001395 size_t length,
1396 size_t *nc_off,
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001397 unsigned char nonce_counter[16],
1398 unsigned char stream_block[16],
1399 const unsigned char *input,
1400 unsigned char *output )
1401{
Paul Bakker369e14b2012-04-18 14:16:09 +00001402 int c, i;
Gilles Peskine377a3102021-07-07 21:08:28 +02001403 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001404 size_t n;
1405
1406 AES_VALIDATE_RET( ctx != NULL );
1407 AES_VALIDATE_RET( nc_off != NULL );
1408 AES_VALIDATE_RET( nonce_counter != NULL );
1409 AES_VALIDATE_RET( stream_block != NULL );
1410 AES_VALIDATE_RET( input != NULL );
1411 AES_VALIDATE_RET( output != NULL );
1412
1413 n = *nc_off;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001414
Mohammad Azim Khan3f7f8172017-11-23 17:49:05 +00001415 if ( n > 0x0F )
1416 return( MBEDTLS_ERR_AES_BAD_INPUT_DATA );
1417
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001418 while( length-- )
1419 {
1420 if( n == 0 ) {
Gilles Peskine377a3102021-07-07 21:08:28 +02001421 ret = mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block );
1422 if( ret != 0 )
1423 goto exit;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001424
Paul Bakker369e14b2012-04-18 14:16:09 +00001425 for( i = 16; i > 0; i-- )
1426 if( ++nonce_counter[i - 1] != 0 )
1427 break;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001428 }
1429 c = *input++;
1430 *output++ = (unsigned char)( c ^ stream_block[n] );
1431
Paul Bakker66d5d072014-06-17 16:39:18 +02001432 n = ( n + 1 ) & 0x0F;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001433 }
1434
1435 *nc_off = n;
Gilles Peskine377a3102021-07-07 21:08:28 +02001436 ret = 0;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001437
Gilles Peskine377a3102021-07-07 21:08:28 +02001438exit:
1439 return( ret );
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001440}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001441#endif /* MBEDTLS_CIPHER_MODE_CTR */
Manuel Pégourié-Gonnard1ec220b2014-03-10 11:20:17 +01001442
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001443#endif /* !MBEDTLS_AES_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001444
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001445#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001446/*
1447 * AES test vectors from:
1448 *
1449 * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
1450 */
1451static const unsigned char aes_test_ecb_dec[3][16] =
1452{
1453 { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
1454 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
1455 { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
1456 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
1457 { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
1458 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
1459};
1460
1461static const unsigned char aes_test_ecb_enc[3][16] =
1462{
1463 { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
1464 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
1465 { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
1466 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
1467 { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
1468 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
1469};
1470
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001471#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001472static const unsigned char aes_test_cbc_dec[3][16] =
1473{
1474 { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
1475 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
1476 { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
1477 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
1478 { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
1479 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
1480};
1481
1482static const unsigned char aes_test_cbc_enc[3][16] =
1483{
1484 { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
1485 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
1486 { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
1487 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
1488 { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
1489 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
1490};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001491#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001492
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001493#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001494/*
1495 * AES-CFB128 test vectors from:
1496 *
1497 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
1498 */
1499static const unsigned char aes_test_cfb128_key[3][32] =
1500{
1501 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1502 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
1503 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1504 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1505 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1506 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1507 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1508 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1509 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
1510};
1511
1512static const unsigned char aes_test_cfb128_iv[16] =
1513{
1514 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1515 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1516};
1517
1518static const unsigned char aes_test_cfb128_pt[64] =
1519{
1520 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1521 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1522 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1523 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1524 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1525 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1526 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1527 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1528};
1529
1530static const unsigned char aes_test_cfb128_ct[3][64] =
1531{
1532 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1533 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1534 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F,
1535 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B,
1536 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40,
1537 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF,
1538 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E,
1539 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 },
1540 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1541 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1542 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21,
1543 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A,
1544 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1,
1545 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9,
1546 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0,
1547 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF },
1548 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1549 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1550 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8,
1551 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B,
1552 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92,
1553 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9,
1554 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8,
1555 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 }
1556};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001557#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001558
Simon Butcherad4e4932018-04-29 00:43:47 +01001559#if defined(MBEDTLS_CIPHER_MODE_OFB)
1560/*
1561 * AES-OFB test vectors from:
1562 *
Simon Butcher5db13622018-06-04 22:11:25 +01001563 * https://csrc.nist.gov/publications/detail/sp/800-38a/final
Simon Butcherad4e4932018-04-29 00:43:47 +01001564 */
1565static const unsigned char aes_test_ofb_key[3][32] =
1566{
1567 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1568 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
1569 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1570 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1571 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1572 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1573 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1574 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1575 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
1576};
1577
1578static const unsigned char aes_test_ofb_iv[16] =
1579{
1580 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1581 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1582};
1583
1584static const unsigned char aes_test_ofb_pt[64] =
1585{
1586 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1587 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1588 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1589 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1590 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1591 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1592 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1593 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1594};
1595
1596static const unsigned char aes_test_ofb_ct[3][64] =
1597{
1598 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1599 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1600 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
1601 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
1602 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
1603 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
1604 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
1605 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e },
1606 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1607 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1608 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
1609 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
1610 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f,
1611 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
1612 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e,
1613 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a },
1614 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1615 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1616 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
1617 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
1618 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed,
1619 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
1620 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8,
1621 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 }
1622};
1623#endif /* MBEDTLS_CIPHER_MODE_OFB */
1624
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001625#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001626/*
1627 * AES-CTR test vectors from:
1628 *
1629 * http://www.faqs.org/rfcs/rfc3686.html
1630 */
1631
1632static const unsigned char aes_test_ctr_key[3][16] =
1633{
1634 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
1635 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
1636 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
1637 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
1638 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
1639 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
1640};
1641
1642static const unsigned char aes_test_ctr_nonce_counter[3][16] =
1643{
1644 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
1645 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
1646 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
1647 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
1648 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
1649 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
1650};
1651
1652static const unsigned char aes_test_ctr_pt[3][48] =
1653{
1654 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
1655 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
1656
1657 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1658 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1659 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1660 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
1661
1662 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1663 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1664 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1665 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
1666 0x20, 0x21, 0x22, 0x23 }
1667};
1668
1669static const unsigned char aes_test_ctr_ct[3][48] =
1670{
1671 { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79,
1672 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 },
1673 { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9,
1674 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88,
1675 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8,
1676 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 },
1677 { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
1678 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
1679 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
1680 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
1681 0x25, 0xB2, 0x07, 0x2F }
1682};
1683
1684static const int aes_test_ctr_len[3] =
1685 { 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001686#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00001687
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001688#if defined(MBEDTLS_CIPHER_MODE_XTS)
1689/*
1690 * AES-XTS test vectors from:
1691 *
1692 * IEEE P1619/D16 Annex B
1693 * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf
1694 * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf)
1695 */
1696static const unsigned char aes_test_xts_key[][32] =
1697{
1698 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1699 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1700 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1701 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1702 { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1703 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1704 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1705 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1706 { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
1707 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
1708 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1709 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1710};
1711
1712static const unsigned char aes_test_xts_pt32[][32] =
1713{
1714 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1715 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1716 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1717 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1718 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1719 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1720 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1721 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1722 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1723 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1724 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1725 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1726};
1727
1728static const unsigned char aes_test_xts_ct32[][32] =
1729{
1730 { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec,
1731 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92,
1732 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85,
1733 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e },
1734 { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e,
1735 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b,
1736 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4,
1737 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 },
1738 { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a,
1739 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2,
1740 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53,
1741 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 },
1742};
1743
1744static const unsigned char aes_test_xts_data_unit[][16] =
1745{
1746 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1747 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1748 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1749 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1750 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1751 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1752};
1753
1754#endif /* MBEDTLS_CIPHER_MODE_XTS */
1755
Paul Bakker5121ce52009-01-03 21:22:43 +00001756/*
1757 * Checkup routine
1758 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001759int mbedtls_aes_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +00001760{
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001761 int ret = 0, i, j, u, mode;
1762 unsigned int keybits;
Paul Bakker5121ce52009-01-03 21:22:43 +00001763 unsigned char key[32];
1764 unsigned char buf[64];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001765 const unsigned char *aes_tests;
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03001766#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001767 unsigned char iv[16];
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03001768#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001769#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +02001770 unsigned char prv[16];
1771#endif
Simon Butcher2ff0e522018-06-14 09:57:07 +01001772#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1773 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker27fdf462011-06-09 13:55:13 +00001774 size_t offset;
Paul Bakkere91d01e2011-04-19 15:55:50 +00001775#endif
Simon Butcher66a89032018-06-15 18:20:29 +01001776#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS)
Paul Bakkere91d01e2011-04-19 15:55:50 +00001777 int len;
Simon Butcher66a89032018-06-15 18:20:29 +01001778#endif
1779#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001780 unsigned char nonce_counter[16];
1781 unsigned char stream_block[16];
1782#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001783 mbedtls_aes_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001784
1785 memset( key, 0, 32 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001786 mbedtls_aes_init( &ctx );
Paul Bakker5121ce52009-01-03 21:22:43 +00001787
1788 /*
1789 * ECB mode
1790 */
1791 for( i = 0; i < 6; i++ )
1792 {
1793 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001794 keybits = 128 + u * 64;
1795 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001796
1797 if( verbose != 0 )
Kenneth Soerensen518d4352020-04-01 17:22:45 +02001798 mbedtls_printf( " AES-ECB-%3u (%s): ", keybits,
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001799 ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001800
1801 memset( buf, 0, 16 );
1802
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001803 if( mode == MBEDTLS_AES_DECRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +00001804 {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001805 ret = mbedtls_aes_setkey_dec( &ctx, key, keybits );
1806 aes_tests = aes_test_ecb_dec[u];
Paul Bakker5121ce52009-01-03 21:22:43 +00001807 }
1808 else
1809 {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001810 ret = mbedtls_aes_setkey_enc( &ctx, key, keybits );
1811 aes_tests = aes_test_ecb_enc[u];
1812 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001813
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01001814 /*
1815 * AES-192 is an optional feature that may be unavailable when
1816 * there is an alternative underlying implementation i.e. when
1817 * MBEDTLS_AES_ALT is defined.
1818 */
Ron Eldor9924bdc2018-10-04 10:59:13 +03001819 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 )
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001820 {
1821 mbedtls_printf( "skipped\n" );
1822 continue;
1823 }
1824 else if( ret != 0 )
1825 {
1826 goto exit;
1827 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001828
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001829 for( j = 0; j < 10000; j++ )
1830 {
1831 ret = mbedtls_aes_crypt_ecb( &ctx, mode, buf, buf );
1832 if( ret != 0 )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001833 goto exit;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001834 }
1835
1836 if( memcmp( buf, aes_tests, 16 ) != 0 )
1837 {
1838 ret = 1;
1839 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001840 }
1841
1842 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001843 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001844 }
1845
1846 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001847 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001848
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001849#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001850 /*
1851 * CBC mode
1852 */
1853 for( i = 0; i < 6; i++ )
1854 {
1855 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001856 keybits = 128 + u * 64;
1857 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001858
1859 if( verbose != 0 )
Kenneth Soerensen518d4352020-04-01 17:22:45 +02001860 mbedtls_printf( " AES-CBC-%3u (%s): ", keybits,
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001861 ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001862
1863 memset( iv , 0, 16 );
1864 memset( prv, 0, 16 );
1865 memset( buf, 0, 16 );
1866
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001867 if( mode == MBEDTLS_AES_DECRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +00001868 {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001869 ret = mbedtls_aes_setkey_dec( &ctx, key, keybits );
1870 aes_tests = aes_test_cbc_dec[u];
Paul Bakker5121ce52009-01-03 21:22:43 +00001871 }
1872 else
1873 {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001874 ret = mbedtls_aes_setkey_enc( &ctx, key, keybits );
1875 aes_tests = aes_test_cbc_enc[u];
1876 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001877
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01001878 /*
1879 * AES-192 is an optional feature that may be unavailable when
1880 * there is an alternative underlying implementation i.e. when
1881 * MBEDTLS_AES_ALT is defined.
1882 */
Ron Eldor9924bdc2018-10-04 10:59:13 +03001883 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 )
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001884 {
1885 mbedtls_printf( "skipped\n" );
1886 continue;
1887 }
1888 else if( ret != 0 )
1889 {
1890 goto exit;
1891 }
1892
1893 for( j = 0; j < 10000; j++ )
1894 {
1895 if( mode == MBEDTLS_AES_ENCRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +00001896 {
1897 unsigned char tmp[16];
1898
Paul Bakker5121ce52009-01-03 21:22:43 +00001899 memcpy( tmp, prv, 16 );
1900 memcpy( prv, buf, 16 );
1901 memcpy( buf, tmp, 16 );
1902 }
1903
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001904 ret = mbedtls_aes_crypt_cbc( &ctx, mode, 16, iv, buf, buf );
1905 if( ret != 0 )
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001906 goto exit;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001907
1908 }
1909
1910 if( memcmp( buf, aes_tests, 16 ) != 0 )
1911 {
1912 ret = 1;
1913 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001914 }
1915
1916 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001917 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001918 }
1919
1920 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001921 mbedtls_printf( "\n" );
1922#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001923
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001924#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001925 /*
1926 * CFB128 mode
1927 */
1928 for( i = 0; i < 6; i++ )
1929 {
1930 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001931 keybits = 128 + u * 64;
1932 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001933
1934 if( verbose != 0 )
Kenneth Soerensen518d4352020-04-01 17:22:45 +02001935 mbedtls_printf( " AES-CFB128-%3u (%s): ", keybits,
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001936 ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001937
1938 memcpy( iv, aes_test_cfb128_iv, 16 );
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001939 memcpy( key, aes_test_cfb128_key[u], keybits / 8 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001940
1941 offset = 0;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001942 ret = mbedtls_aes_setkey_enc( &ctx, key, keybits );
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01001943 /*
1944 * AES-192 is an optional feature that may be unavailable when
1945 * there is an alternative underlying implementation i.e. when
1946 * MBEDTLS_AES_ALT is defined.
1947 */
Ron Eldor9924bdc2018-10-04 10:59:13 +03001948 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 )
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001949 {
1950 mbedtls_printf( "skipped\n" );
1951 continue;
1952 }
1953 else if( ret != 0 )
1954 {
1955 goto exit;
1956 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001957
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001958 if( mode == MBEDTLS_AES_DECRYPT )
Paul Bakker5121ce52009-01-03 21:22:43 +00001959 {
1960 memcpy( buf, aes_test_cfb128_ct[u], 64 );
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001961 aes_tests = aes_test_cfb128_pt;
Paul Bakker5121ce52009-01-03 21:22:43 +00001962 }
1963 else
1964 {
1965 memcpy( buf, aes_test_cfb128_pt, 64 );
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001966 aes_tests = aes_test_cfb128_ct[u];
1967 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001968
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001969 ret = mbedtls_aes_crypt_cfb128( &ctx, mode, 64, &offset, iv, buf, buf );
1970 if( ret != 0 )
1971 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001972
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001973 if( memcmp( buf, aes_tests, 64 ) != 0 )
1974 {
1975 ret = 1;
1976 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001977 }
1978
1979 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001980 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00001981 }
1982
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001983 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001984 mbedtls_printf( "\n" );
1985#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001986
Simon Butcherad4e4932018-04-29 00:43:47 +01001987#if defined(MBEDTLS_CIPHER_MODE_OFB)
1988 /*
1989 * OFB mode
1990 */
1991 for( i = 0; i < 6; i++ )
1992 {
1993 u = i >> 1;
1994 keybits = 128 + u * 64;
1995 mode = i & 1;
1996
1997 if( verbose != 0 )
Kenneth Soerensen518d4352020-04-01 17:22:45 +02001998 mbedtls_printf( " AES-OFB-%3u (%s): ", keybits,
Simon Butcherad4e4932018-04-29 00:43:47 +01001999 ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
2000
2001 memcpy( iv, aes_test_ofb_iv, 16 );
2002 memcpy( key, aes_test_ofb_key[u], keybits / 8 );
2003
2004 offset = 0;
2005 ret = mbedtls_aes_setkey_enc( &ctx, key, keybits );
2006 /*
2007 * AES-192 is an optional feature that may be unavailable when
2008 * there is an alternative underlying implementation i.e. when
2009 * MBEDTLS_AES_ALT is defined.
2010 */
Ron Eldor9924bdc2018-10-04 10:59:13 +03002011 if( ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192 )
Simon Butcherad4e4932018-04-29 00:43:47 +01002012 {
2013 mbedtls_printf( "skipped\n" );
2014 continue;
2015 }
2016 else if( ret != 0 )
2017 {
2018 goto exit;
2019 }
2020
2021 if( mode == MBEDTLS_AES_DECRYPT )
2022 {
2023 memcpy( buf, aes_test_ofb_ct[u], 64 );
2024 aes_tests = aes_test_ofb_pt;
2025 }
2026 else
2027 {
2028 memcpy( buf, aes_test_ofb_pt, 64 );
2029 aes_tests = aes_test_ofb_ct[u];
2030 }
2031
2032 ret = mbedtls_aes_crypt_ofb( &ctx, 64, &offset, iv, buf, buf );
2033 if( ret != 0 )
2034 goto exit;
2035
2036 if( memcmp( buf, aes_tests, 64 ) != 0 )
2037 {
2038 ret = 1;
2039 goto exit;
2040 }
2041
2042 if( verbose != 0 )
2043 mbedtls_printf( "passed\n" );
2044 }
2045
2046 if( verbose != 0 )
2047 mbedtls_printf( "\n" );
2048#endif /* MBEDTLS_CIPHER_MODE_OFB */
2049
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002050#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002051 /*
2052 * CTR mode
2053 */
2054 for( i = 0; i < 6; i++ )
2055 {
2056 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002057 mode = i & 1;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002058
2059 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002060 mbedtls_printf( " AES-CTR-128 (%s): ",
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002061 ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002062
2063 memcpy( nonce_counter, aes_test_ctr_nonce_counter[u], 16 );
2064 memcpy( key, aes_test_ctr_key[u], 16 );
2065
2066 offset = 0;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002067 if( ( ret = mbedtls_aes_setkey_enc( &ctx, key, 128 ) ) != 0 )
2068 goto exit;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002069
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002070 len = aes_test_ctr_len[u];
2071
2072 if( mode == MBEDTLS_AES_DECRYPT )
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002073 {
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002074 memcpy( buf, aes_test_ctr_ct[u], len );
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002075 aes_tests = aes_test_ctr_pt[u];
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002076 }
2077 else
2078 {
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002079 memcpy( buf, aes_test_ctr_pt[u], len );
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002080 aes_tests = aes_test_ctr_ct[u];
2081 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002082
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002083 ret = mbedtls_aes_crypt_ctr( &ctx, len, &offset, nonce_counter,
2084 stream_block, buf, buf );
2085 if( ret != 0 )
2086 goto exit;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002087
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002088 if( memcmp( buf, aes_tests, len ) != 0 )
2089 {
2090 ret = 1;
2091 goto exit;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002092 }
2093
2094 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002095 mbedtls_printf( "passed\n" );
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002096 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002097
2098 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002099 mbedtls_printf( "\n" );
2100#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00002101
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002102#if defined(MBEDTLS_CIPHER_MODE_XTS)
2103 {
2104 static const int num_tests =
2105 sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key);
2106 mbedtls_aes_xts_context ctx_xts;
2107
2108 /*
2109 * XTS mode
2110 */
2111 mbedtls_aes_xts_init( &ctx_xts );
2112
2113 for( i = 0; i < num_tests << 1; i++ )
2114 {
2115 const unsigned char *data_unit;
2116 u = i >> 1;
2117 mode = i & 1;
2118
2119 if( verbose != 0 )
2120 mbedtls_printf( " AES-XTS-128 (%s): ",
2121 ( mode == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" );
2122
2123 memset( key, 0, sizeof( key ) );
2124 memcpy( key, aes_test_xts_key[u], 32 );
2125 data_unit = aes_test_xts_data_unit[u];
2126
2127 len = sizeof( *aes_test_xts_ct32 );
2128
2129 if( mode == MBEDTLS_AES_DECRYPT )
2130 {
2131 ret = mbedtls_aes_xts_setkey_dec( &ctx_xts, key, 256 );
2132 if( ret != 0)
2133 goto exit;
2134 memcpy( buf, aes_test_xts_ct32[u], len );
2135 aes_tests = aes_test_xts_pt32[u];
2136 }
2137 else
2138 {
2139 ret = mbedtls_aes_xts_setkey_enc( &ctx_xts, key, 256 );
2140 if( ret != 0)
2141 goto exit;
2142 memcpy( buf, aes_test_xts_pt32[u], len );
2143 aes_tests = aes_test_xts_ct32[u];
2144 }
2145
2146
2147 ret = mbedtls_aes_crypt_xts( &ctx_xts, mode, len, data_unit,
2148 buf, buf );
2149 if( ret != 0 )
2150 goto exit;
2151
2152 if( memcmp( buf, aes_tests, len ) != 0 )
2153 {
2154 ret = 1;
2155 goto exit;
2156 }
2157
2158 if( verbose != 0 )
2159 mbedtls_printf( "passed\n" );
2160 }
2161
2162 if( verbose != 0 )
2163 mbedtls_printf( "\n" );
2164
2165 mbedtls_aes_xts_free( &ctx_xts );
2166 }
2167#endif /* MBEDTLS_CIPHER_MODE_XTS */
2168
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002169 ret = 0;
2170
2171exit:
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002172 if( ret != 0 && verbose != 0 )
2173 mbedtls_printf( "failed\n" );
2174
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002175 mbedtls_aes_free( &ctx );
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002176
2177 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002178}
2179
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002180#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002181
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002182#endif /* MBEDTLS_AES_C */