1 /**
2 * \brief AES block cipher, ESP block hardware accelerated version
3 * Based on mbedTLS FIPS-197 compliant version.
4 *
5 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
6 * Additions Copyright (C) 2016-2017, Espressif Systems (Shanghai) PTE Ltd
7 * SPDX-License-Identifier: Apache-2.0
8 *
9 * Licensed under the Apache License, Version 2.0 (the "License"); you may
10 * not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
12 *
13 * http://www.apache.org/licenses/LICENSE-2.0
14 *
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
17 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
20 *
21 */
22 /*
23 * The AES block cipher was designed by Vincent Rijmen and Joan Daemen.
24 *
25 * http://csrc.nist.gov/encryption/aes/rijndael/Rijndael.pdf
26 * http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
27 */
28 #include <string.h>
29 #include "mbedtls/aes.h"
30 #include "mbedtls/platform_util.h"
31 #include "aes/esp_aes.h"
32 #include "soc/hwcrypto_periph.h"
33 #include <sys/lock.h>
34 #include "hal/aes_hal.h"
35 #include "aes/esp_aes_internal.h"
36
37 #include <freertos/FreeRTOS.h>
38
39 #include "soc/cpu.h"
40 #include <stdio.h>
41 #include "driver/periph_ctrl.h"
42
43
44 /* AES uses a spinlock mux not a lock as the underlying block operation
45 only takes 208 cycles (to write key & compute block), +600 cycles
46 for DPORT protection but +3400 cycles again if you use a full sized lock.
47
48 For CBC, CFB, etc. this may mean that interrupts are disabled for a longer
49 period of time for bigger lengths. However at the moment this has to happen
50 anyway due to DPORT protection...
51 */
52 static portMUX_TYPE aes_spinlock = portMUX_INITIALIZER_UNLOCKED;
53
54
esp_aes_acquire_hardware(void)55 void esp_aes_acquire_hardware( void )
56 {
57 portENTER_CRITICAL(&aes_spinlock);
58
59 /* Enable AES hardware */
60 periph_module_enable(PERIPH_AES_MODULE);
61 }
62
esp_aes_release_hardware(void)63 void esp_aes_release_hardware( void )
64 {
65 /* Disable AES hardware */
66 periph_module_disable(PERIPH_AES_MODULE);
67
68 portEXIT_CRITICAL(&aes_spinlock);
69 }
70
71
72
73 /* Run a single 16 byte block of AES, using the hardware engine.
74 *
75 * Call only while holding esp_aes_acquire_hardware().
76 */
esp_aes_block(esp_aes_context * ctx,const void * input,void * output)77 static int esp_aes_block(esp_aes_context *ctx, const void *input, void *output)
78 {
79 uint32_t i0, i1, i2, i3;
80 const uint32_t *input_words = (uint32_t *)input;
81 uint32_t *output_words = (uint32_t *)output;
82
83 /* If no key is written to hardware yet, either the user hasn't called
84 mbedtls_aes_setkey_enc/mbedtls_aes_setkey_dec - meaning we also don't
85 know which mode to use - or a fault skipped the
86 key write to hardware. Treat this as a fatal error and zero the output block.
87 */
88 if (ctx->key_in_hardware != ctx->key_bytes) {
89 bzero(output, 16);
90 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
91 }
92 i0 = input_words[0];
93 i1 = input_words[1];
94 i2 = input_words[2];
95 i3 = input_words[3];
96
97 aes_hal_transform_block(input, output);
98
99 /* Physical security check: Verify the AES accelerator actually ran, and wasn't
100 skipped due to external fault injection while starting the peripheral.
101
102 Note that i0,i1,i2,i3 are copied from input buffer in case input==output.
103
104 Bypassing this check requires at least one additional fault.
105 */
106 if (i0 == output_words[0] && i1 == output_words[1] && i2 == output_words[2] && i3 == output_words[3]) {
107 // calling zeroing functions to narrow the
108 // window for a double-fault of the abort step, here
109 memset(output, 0, 16);
110 mbedtls_platform_zeroize(output, 16);
111 abort();
112 }
113
114 return 0;
115 }
116
esp_aes_encrypt(esp_aes_context * ctx,const unsigned char input[16],unsigned char output[16])117 void esp_aes_encrypt(esp_aes_context *ctx,
118 const unsigned char input[16],
119 unsigned char output[16] )
120 {
121 esp_internal_aes_encrypt(ctx, input, output);
122 }
123
124 /*
125 * AES-ECB block encryption
126 */
esp_internal_aes_encrypt(esp_aes_context * ctx,const unsigned char input[16],unsigned char output[16])127 int esp_internal_aes_encrypt(esp_aes_context *ctx,
128 const unsigned char input[16],
129 unsigned char output[16] )
130 {
131 int r;
132
133 if (!valid_key_length(ctx)) {
134 return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
135 }
136
137 esp_aes_acquire_hardware();
138 ctx->key_in_hardware = 0;
139 ctx->key_in_hardware = aes_hal_setkey(ctx->key, ctx->key_bytes, ESP_AES_ENCRYPT);
140 r = esp_aes_block(ctx, input, output);
141 esp_aes_release_hardware();
142 return r;
143 }
144
esp_aes_decrypt(esp_aes_context * ctx,const unsigned char input[16],unsigned char output[16])145 void esp_aes_decrypt(esp_aes_context *ctx,
146 const unsigned char input[16],
147 unsigned char output[16] )
148 {
149 esp_internal_aes_decrypt(ctx, input, output);
150 }
151
152 /*
153 * AES-ECB block decryption
154 */
155
esp_internal_aes_decrypt(esp_aes_context * ctx,const unsigned char input[16],unsigned char output[16])156 int esp_internal_aes_decrypt(esp_aes_context *ctx,
157 const unsigned char input[16],
158 unsigned char output[16] )
159 {
160 int r;
161
162 if (!valid_key_length(ctx)) {
163 return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
164 }
165
166 esp_aes_acquire_hardware();
167 ctx->key_in_hardware = 0;
168 ctx->key_in_hardware = aes_hal_setkey(ctx->key, ctx->key_bytes, ESP_AES_DECRYPT);
169 r = esp_aes_block(ctx, input, output);
170 esp_aes_release_hardware();
171 return r;
172 }
173
174 /*
175 * AES-ECB block encryption/decryption
176 */
esp_aes_crypt_ecb(esp_aes_context * ctx,int mode,const unsigned char input[16],unsigned char output[16])177 int esp_aes_crypt_ecb(esp_aes_context *ctx,
178 int mode,
179 const unsigned char input[16],
180 unsigned char output[16] )
181 {
182 int r;
183
184 if (!valid_key_length(ctx)) {
185 return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
186 }
187
188 esp_aes_acquire_hardware();
189 ctx->key_in_hardware = 0;
190 ctx->key_in_hardware = aes_hal_setkey(ctx->key, ctx->key_bytes, mode);
191 r = esp_aes_block(ctx, input, output);
192 esp_aes_release_hardware();
193
194 return r;
195 }
196
197
198 /*
199 * AES-CBC buffer encryption/decryption
200 */
esp_aes_crypt_cbc(esp_aes_context * ctx,int mode,size_t length,unsigned char iv[16],const unsigned char * input,unsigned char * output)201 int esp_aes_crypt_cbc(esp_aes_context *ctx,
202 int mode,
203 size_t length,
204 unsigned char iv[16],
205 const unsigned char *input,
206 unsigned char *output )
207 {
208 uint32_t *output_words = (uint32_t *)output;
209 const uint32_t *input_words = (const uint32_t *)input;
210 uint32_t *iv_words = (uint32_t *)iv;
211 unsigned char temp[16];
212
213 if ( length % 16 ) {
214 return ( ERR_ESP_AES_INVALID_INPUT_LENGTH );
215 }
216
217 if (!valid_key_length(ctx)) {
218 return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
219 }
220
221 esp_aes_acquire_hardware();
222 ctx->key_in_hardware = 0;
223 ctx->key_in_hardware = aes_hal_setkey(ctx->key, ctx->key_bytes, mode);
224
225
226 if ( mode == ESP_AES_DECRYPT ) {
227 while ( length > 0 ) {
228 memcpy(temp, input_words, 16);
229 esp_aes_block(ctx, input_words, output_words);
230
231 output_words[0] = output_words[0] ^ iv_words[0];
232 output_words[1] = output_words[1] ^ iv_words[1];
233 output_words[2] = output_words[2] ^ iv_words[2];
234 output_words[3] = output_words[3] ^ iv_words[3];
235
236 memcpy( iv_words, temp, 16 );
237
238 input_words += 4;
239 output_words += 4;
240 length -= 16;
241 }
242 } else { // ESP_AES_ENCRYPT
243 while ( length > 0 ) {
244
245 output_words[0] = input_words[0] ^ iv_words[0];
246 output_words[1] = input_words[1] ^ iv_words[1];
247 output_words[2] = input_words[2] ^ iv_words[2];
248 output_words[3] = input_words[3] ^ iv_words[3];
249
250 esp_aes_block(ctx, output_words, output_words);
251 memcpy( iv_words, output_words, 16 );
252
253 input_words += 4;
254 output_words += 4;
255 length -= 16;
256 }
257 }
258
259 esp_aes_release_hardware();
260
261 return 0;
262 }
263
264 /*
265 * AES-CFB128 buffer encryption/decryption
266 */
esp_aes_crypt_cfb128(esp_aes_context * ctx,int mode,size_t length,size_t * iv_off,unsigned char iv[16],const unsigned char * input,unsigned char * output)267 int esp_aes_crypt_cfb128(esp_aes_context *ctx,
268 int mode,
269 size_t length,
270 size_t *iv_off,
271 unsigned char iv[16],
272 const unsigned char *input,
273 unsigned char *output )
274 {
275 int c;
276 size_t n = *iv_off;
277
278 if (!valid_key_length(ctx)) {
279 return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
280 }
281
282 esp_aes_acquire_hardware();
283 ctx->key_in_hardware = 0;
284 ctx->key_in_hardware = aes_hal_setkey(ctx->key, ctx->key_bytes, ESP_AES_ENCRYPT);
285
286 if ( mode == ESP_AES_DECRYPT ) {
287 while ( length-- ) {
288 if ( n == 0 ) {
289 esp_aes_block(ctx, iv, iv);
290 }
291
292 c = *input++;
293 *output++ = (unsigned char)( c ^ iv[n] );
294 iv[n] = (unsigned char) c;
295
296 n = ( n + 1 ) & 0x0F;
297 }
298 } else {
299 while ( length-- ) {
300 if ( n == 0 ) {
301 esp_aes_block(ctx, iv, iv);
302 }
303
304 iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ );
305
306 n = ( n + 1 ) & 0x0F;
307 }
308 }
309
310 *iv_off = n;
311
312 esp_aes_release_hardware();
313
314 return 0;
315 }
316
317 /*
318 * AES-CFB8 buffer encryption/decryption
319 */
esp_aes_crypt_cfb8(esp_aes_context * ctx,int mode,size_t length,unsigned char iv[16],const unsigned char * input,unsigned char * output)320 int esp_aes_crypt_cfb8(esp_aes_context *ctx,
321 int mode,
322 size_t length,
323 unsigned char iv[16],
324 const unsigned char *input,
325 unsigned char *output )
326 {
327 unsigned char c;
328 unsigned char ov[17];
329
330 if (!valid_key_length(ctx)) {
331 return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
332 }
333
334 esp_aes_acquire_hardware();
335 ctx->key_in_hardware = 0;
336 ctx->key_in_hardware = aes_hal_setkey(ctx->key, ctx->key_bytes, ESP_AES_ENCRYPT);
337
338
339 while ( length-- ) {
340 memcpy( ov, iv, 16 );
341 esp_aes_block(ctx, iv, iv);
342
343 if ( mode == ESP_AES_DECRYPT ) {
344 ov[16] = *input;
345 }
346
347 c = *output++ = (unsigned char)( iv[0] ^ *input++ );
348
349 if ( mode == ESP_AES_ENCRYPT ) {
350 ov[16] = c;
351 }
352
353 memcpy( iv, ov + 1, 16 );
354 }
355
356 esp_aes_release_hardware();
357
358 return 0;
359 }
360
361 /*
362 * AES-CTR buffer encryption/decryption
363 */
esp_aes_crypt_ctr(esp_aes_context * ctx,size_t length,size_t * nc_off,unsigned char nonce_counter[16],unsigned char stream_block[16],const unsigned char * input,unsigned char * output)364 int esp_aes_crypt_ctr(esp_aes_context *ctx,
365 size_t length,
366 size_t *nc_off,
367 unsigned char nonce_counter[16],
368 unsigned char stream_block[16],
369 const unsigned char *input,
370 unsigned char *output )
371 {
372 int c, i;
373 size_t n = *nc_off;
374
375 if (!valid_key_length(ctx)) {
376 return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
377 }
378
379 esp_aes_acquire_hardware();
380 ctx->key_in_hardware = 0;
381 ctx->key_in_hardware = aes_hal_setkey(ctx->key, ctx->key_bytes, ESP_AES_ENCRYPT);
382
383
384 while ( length-- ) {
385 if ( n == 0 ) {
386 esp_aes_block(ctx, nonce_counter, stream_block);
387
388 for ( i = 16; i > 0; i-- ) {
389 if ( ++nonce_counter[i - 1] != 0 ) {
390 break;
391 }
392 }
393 }
394 c = *input++;
395 *output++ = (unsigned char)( c ^ stream_block[n] );
396
397 n = ( n + 1 ) & 0x0F;
398 }
399
400 *nc_off = n;
401
402 esp_aes_release_hardware();
403
404 return 0;
405 }
406
407 /*
408 * AES-OFB (Output Feedback Mode) buffer encryption/decryption
409 */
esp_aes_crypt_ofb(esp_aes_context * ctx,size_t length,size_t * iv_off,unsigned char iv[16],const unsigned char * input,unsigned char * output)410 int esp_aes_crypt_ofb(esp_aes_context *ctx,
411 size_t length,
412 size_t *iv_off,
413 unsigned char iv[16],
414 const unsigned char *input,
415 unsigned char *output )
416 {
417 int ret = 0;
418 size_t n;
419
420 if (ctx == NULL || iv_off == NULL || iv == NULL ||
421 input == NULL || output == NULL ) {
422 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
423 }
424
425 n = *iv_off;
426
427 if (n > 15) {
428 return (MBEDTLS_ERR_AES_BAD_INPUT_DATA);
429 }
430
431 if (!valid_key_length(ctx)) {
432 return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
433 }
434
435 esp_aes_acquire_hardware();
436 ctx->key_in_hardware = 0;
437 ctx->key_in_hardware = aes_hal_setkey(ctx->key, ctx->key_bytes, ESP_AES_ENCRYPT);
438
439
440 while (length--) {
441 if ( n == 0 ) {
442 esp_aes_block(ctx, iv, iv);
443 }
444 *output++ = *input++ ^ iv[n];
445
446 n = ( n + 1 ) & 0x0F;
447 }
448
449 *iv_off = n;
450
451 esp_aes_release_hardware();
452
453 return ( ret );
454 }
455