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 "esp_log.h"
32 #include "aes/esp_aes.h"
33 #include "soc/hwcrypto_periph.h"
34 #include <sys/lock.h>
35 #include "hal/aes_hal.h"
36 #include "aes/esp_aes_internal.h"
37
38 #include <freertos/FreeRTOS.h>
39
40 #include <stdio.h>
41 #include "esp_private/periph_ctrl.h"
42
43
44 static const char *TAG = "esp-aes";
45 /* AES uses a spinlock mux not a lock as the underlying block operation
46 only takes 208 cycles (to write key & compute block), +600 cycles
47 for DPORT protection but +3400 cycles again if you use a full sized lock.
48
49 For CBC, CFB, etc. this may mean that interrupts are disabled for a longer
50 period of time for bigger lengths. However at the moment this has to happen
51 anyway due to DPORT protection...
52 */
53 static portMUX_TYPE aes_spinlock = portMUX_INITIALIZER_UNLOCKED;
54
55
esp_aes_acquire_hardware(void)56 void esp_aes_acquire_hardware( void )
57 {
58 portENTER_CRITICAL(&aes_spinlock);
59
60 /* Enable AES hardware */
61 periph_module_enable(PERIPH_AES_MODULE);
62 }
63
esp_aes_release_hardware(void)64 void esp_aes_release_hardware( void )
65 {
66 /* Disable AES hardware */
67 periph_module_disable(PERIPH_AES_MODULE);
68
69 portEXIT_CRITICAL(&aes_spinlock);
70 }
71
72
73
74 /* Run a single 16 byte block of AES, using the hardware engine.
75 *
76 * Call only while holding esp_aes_acquire_hardware().
77 *
78 * The function esp_aes_block zeroises the output buffer in the case of following conditions:
79 * 1. If key is not written in the hardware
80 * 2. If the fault injection check failed
81 */
esp_aes_block(esp_aes_context * ctx,const void * input,void * output)82 static int esp_aes_block(esp_aes_context *ctx, const void *input, void *output)
83 {
84 uint32_t i0, i1, i2, i3;
85 const uint32_t *input_words = (uint32_t *)input;
86 uint32_t *output_words = (uint32_t *)output;
87
88 /* If no key is written to hardware yet, either the user hasn't called
89 mbedtls_aes_setkey_enc/mbedtls_aes_setkey_dec - meaning we also don't
90 know which mode to use - or a fault skipped the
91 key write to hardware. Treat this as a fatal error and zero the output block.
92 */
93 if (ctx->key_in_hardware != ctx->key_bytes) {
94 mbedtls_platform_zeroize(output, 16);
95 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
96 }
97 i0 = input_words[0];
98 i1 = input_words[1];
99 i2 = input_words[2];
100 i3 = input_words[3];
101
102 aes_hal_transform_block(input, output);
103
104 /* Physical security check: Verify the AES accelerator actually ran, and wasn't
105 skipped due to external fault injection while starting the peripheral.
106
107 Note that i0,i1,i2,i3 are copied from input buffer in case input==output.
108
109 Bypassing this check requires at least one additional fault.
110 */
111 if (i0 == output_words[0] && i1 == output_words[1] && i2 == output_words[2] && i3 == output_words[3]) {
112 // calling zeroing functions to narrow the
113 // window for a double-fault of the abort step, here
114 memset(output, 0, 16);
115 mbedtls_platform_zeroize(output, 16);
116 abort();
117 }
118
119 return 0;
120 }
121
esp_aes_validate_input(esp_aes_context * ctx,const unsigned char * input,const unsigned char * output)122 static int esp_aes_validate_input(esp_aes_context *ctx, const unsigned char *input,
123 const unsigned char *output )
124 {
125 if (!ctx) {
126 ESP_LOGD(TAG, "No AES context supplied");
127 return -1;
128 }
129 if (!input) {
130 ESP_LOGD(TAG, "No input supplied");
131 return -1;
132 }
133 if (!output) {
134 ESP_LOGD(TAG, "No output supplied");
135 return -1;
136 }
137
138 return 0;
139 }
140
141
esp_aes_encrypt(esp_aes_context * ctx,const unsigned char input[16],unsigned char output[16])142 void esp_aes_encrypt(esp_aes_context *ctx,
143 const unsigned char input[16],
144 unsigned char output[16] )
145 {
146 esp_internal_aes_encrypt(ctx, input, output);
147 }
148
149 /*
150 * AES-ECB block encryption
151 */
esp_internal_aes_encrypt(esp_aes_context * ctx,const unsigned char input[16],unsigned char output[16])152 int esp_internal_aes_encrypt(esp_aes_context *ctx,
153 const unsigned char input[16],
154 unsigned char output[16] )
155 {
156 int r = -1;
157
158 if (esp_aes_validate_input(ctx, input, output)) {
159 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
160 }
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_ENCRYPT);
169 r = esp_aes_block(ctx, input, output);
170 esp_aes_release_hardware();
171 return r;
172 }
173
esp_aes_decrypt(esp_aes_context * ctx,const unsigned char input[16],unsigned char output[16])174 void esp_aes_decrypt(esp_aes_context *ctx,
175 const unsigned char input[16],
176 unsigned char output[16] )
177 {
178 esp_internal_aes_decrypt(ctx, input, output);
179 }
180
181 /*
182 * AES-ECB block decryption
183 */
184
esp_internal_aes_decrypt(esp_aes_context * ctx,const unsigned char input[16],unsigned char output[16])185 int esp_internal_aes_decrypt(esp_aes_context *ctx,
186 const unsigned char input[16],
187 unsigned char output[16] )
188 {
189 int r = -1;
190
191 if (esp_aes_validate_input(ctx, input, output)) {
192 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
193 }
194
195 if (!valid_key_length(ctx)) {
196 return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
197 }
198
199 esp_aes_acquire_hardware();
200 ctx->key_in_hardware = 0;
201 ctx->key_in_hardware = aes_hal_setkey(ctx->key, ctx->key_bytes, ESP_AES_DECRYPT);
202 r = esp_aes_block(ctx, input, output);
203 esp_aes_release_hardware();
204 return r;
205 }
206
207 /*
208 * AES-ECB block encryption/decryption
209 */
esp_aes_crypt_ecb(esp_aes_context * ctx,int mode,const unsigned char input[16],unsigned char output[16])210 int esp_aes_crypt_ecb(esp_aes_context *ctx,
211 int mode,
212 const unsigned char input[16],
213 unsigned char output[16] )
214 {
215 int r = -1;
216
217 if (esp_aes_validate_input(ctx, input, output)) {
218 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
219 }
220
221 if (!valid_key_length(ctx)) {
222 return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
223 }
224
225 esp_aes_acquire_hardware();
226 ctx->key_in_hardware = 0;
227 ctx->key_in_hardware = aes_hal_setkey(ctx->key, ctx->key_bytes, mode);
228 r = esp_aes_block(ctx, input, output);
229 esp_aes_release_hardware();
230 return r;
231 }
232
233
234 /*
235 * AES-CBC buffer encryption/decryption
236 */
esp_aes_crypt_cbc(esp_aes_context * ctx,int mode,size_t length,unsigned char iv[16],const unsigned char * input,unsigned char * output)237 int esp_aes_crypt_cbc(esp_aes_context *ctx,
238 int mode,
239 size_t length,
240 unsigned char iv[16],
241 const unsigned char *input,
242 unsigned char *output )
243 {
244 int ret = -1;
245 if (esp_aes_validate_input(ctx, input, output)) {
246 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
247 }
248
249 if (!iv) {
250 ESP_LOGD(TAG, "No IV supplied");
251 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
252 }
253
254 uint32_t *output_words = (uint32_t *)output;
255 const uint32_t *input_words = (const uint32_t *)input;
256 uint32_t *iv_words = (uint32_t *)iv;
257 unsigned char temp[16];
258
259 if ( length % 16 ) {
260 return ( ERR_ESP_AES_INVALID_INPUT_LENGTH );
261 }
262
263 if (!valid_key_length(ctx)) {
264 return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
265 }
266
267 esp_aes_acquire_hardware();
268 ctx->key_in_hardware = 0;
269 ctx->key_in_hardware = aes_hal_setkey(ctx->key, ctx->key_bytes, mode);
270
271
272 if ( mode == ESP_AES_DECRYPT ) {
273 while ( length > 0 ) {
274 memcpy(temp, input_words, 16);
275 ret = esp_aes_block(ctx, input_words, output_words);
276 if (ret != 0) {
277 goto cleanup;
278 }
279
280 output_words[0] = output_words[0] ^ iv_words[0];
281 output_words[1] = output_words[1] ^ iv_words[1];
282 output_words[2] = output_words[2] ^ iv_words[2];
283 output_words[3] = output_words[3] ^ iv_words[3];
284
285 memcpy( iv_words, temp, 16 );
286
287 input_words += 4;
288 output_words += 4;
289 length -= 16;
290 }
291 } else { // ESP_AES_ENCRYPT
292 while ( length > 0 ) {
293
294 output_words[0] = input_words[0] ^ iv_words[0];
295 output_words[1] = input_words[1] ^ iv_words[1];
296 output_words[2] = input_words[2] ^ iv_words[2];
297 output_words[3] = input_words[3] ^ iv_words[3];
298
299 ret = esp_aes_block(ctx, output_words, output_words);
300 if (ret != 0) {
301 goto cleanup;
302 }
303
304 memcpy( iv_words, output_words, 16 );
305
306 input_words += 4;
307 output_words += 4;
308 length -= 16;
309 }
310 }
311 ret = 0;
312
313 cleanup:
314 esp_aes_release_hardware();
315 return ret;
316 }
317
318 /*
319 * AES-CFB128 buffer encryption/decryption
320 */
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)321 int esp_aes_crypt_cfb128(esp_aes_context *ctx,
322 int mode,
323 size_t length,
324 size_t *iv_off,
325 unsigned char iv[16],
326 const unsigned char *input,
327 unsigned char *output )
328 {
329 int ret = -1;
330 if (esp_aes_validate_input(ctx, input, output)) {
331 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
332 }
333
334 if (!iv) {
335 ESP_LOGE(TAG, "No IV supplied");
336 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
337 }
338
339 if (!iv_off) {
340 ESP_LOGE(TAG, "No IV offset supplied");
341 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
342 }
343
344 if (!valid_key_length(ctx)) {
345 return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
346 }
347
348 int c;
349 size_t n = *iv_off;
350 esp_aes_acquire_hardware();
351 ctx->key_in_hardware = 0;
352 ctx->key_in_hardware = aes_hal_setkey(ctx->key, ctx->key_bytes, ESP_AES_ENCRYPT);
353
354 if ( mode == ESP_AES_DECRYPT ) {
355 while ( length-- ) {
356 if ( n == 0 ) {
357 ret = esp_aes_block(ctx, iv, iv);
358 if (ret != 0) {
359 goto cleanup;
360 }
361 }
362
363 c = *input++;
364 *output++ = (unsigned char)( c ^ iv[n] );
365 iv[n] = (unsigned char) c;
366
367 n = ( n + 1 ) & 0x0F;
368 }
369 } else {
370 while ( length-- ) {
371 if ( n == 0 ) {
372 ret = esp_aes_block(ctx, iv, iv);
373 if (ret != 0) {
374 goto cleanup;
375 }
376 }
377
378 iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ );
379
380 n = ( n + 1 ) & 0x0F;
381 }
382 }
383
384 *iv_off = n;
385 ret = 0;
386
387 cleanup:
388 esp_aes_release_hardware();
389 return ret;
390 }
391
392 /*
393 * AES-CFB8 buffer encryption/decryption
394 */
esp_aes_crypt_cfb8(esp_aes_context * ctx,int mode,size_t length,unsigned char iv[16],const unsigned char * input,unsigned char * output)395 int esp_aes_crypt_cfb8(esp_aes_context *ctx,
396 int mode,
397 size_t length,
398 unsigned char iv[16],
399 const unsigned char *input,
400 unsigned char *output )
401 {
402 int ret = -1;
403 unsigned char c;
404 unsigned char ov[17];
405
406 if (esp_aes_validate_input(ctx, input, output)) {
407 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
408 }
409
410 if (!iv) {
411 ESP_LOGE(TAG, "No IV supplied");
412 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
413 }
414
415 if (!valid_key_length(ctx)) {
416 return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
417 }
418
419 esp_aes_acquire_hardware();
420 ctx->key_in_hardware = 0;
421 ctx->key_in_hardware = aes_hal_setkey(ctx->key, ctx->key_bytes, ESP_AES_ENCRYPT);
422
423
424 while ( length-- ) {
425 memcpy( ov, iv, 16 );
426 ret = esp_aes_block(ctx, iv, iv);
427 if (ret != 0) {
428 goto cleanup;
429 }
430
431 if ( mode == ESP_AES_DECRYPT ) {
432 ov[16] = *input;
433 }
434
435 c = *output++ = (unsigned char)( iv[0] ^ *input++ );
436
437 if ( mode == ESP_AES_ENCRYPT ) {
438 ov[16] = c;
439 }
440
441 memcpy( iv, ov + 1, 16 );
442 }
443 ret = 0;
444
445 cleanup:
446 esp_aes_release_hardware();
447 return ret;
448 }
449
450 /*
451 * AES-CTR buffer encryption/decryption
452 */
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)453 int esp_aes_crypt_ctr(esp_aes_context *ctx,
454 size_t length,
455 size_t *nc_off,
456 unsigned char nonce_counter[16],
457 unsigned char stream_block[16],
458 const unsigned char *input,
459 unsigned char *output )
460 {
461 int c, i, ret = -1;
462
463 if (esp_aes_validate_input(ctx, input, output)) {
464 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
465 }
466
467 if (!stream_block) {
468 ESP_LOGE(TAG, "No stream supplied");
469 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
470 }
471
472 if (!nonce_counter) {
473 ESP_LOGE(TAG, "No nonce supplied");
474 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
475 }
476
477 if (!nc_off) {
478 ESP_LOGE(TAG, "No nonce offset supplied");
479 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
480 }
481
482 size_t n = *nc_off;
483 if (!valid_key_length(ctx)) {
484 return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
485 }
486
487 esp_aes_acquire_hardware();
488 ctx->key_in_hardware = 0;
489 ctx->key_in_hardware = aes_hal_setkey(ctx->key, ctx->key_bytes, ESP_AES_ENCRYPT);
490
491
492 while ( length-- ) {
493 if ( n == 0 ) {
494 ret = esp_aes_block(ctx, nonce_counter, stream_block);
495 if (ret != 0) {
496 goto cleanup;
497 }
498
499 for ( i = 16; i > 0; i-- ) {
500 if ( ++nonce_counter[i - 1] != 0 ) {
501 break;
502 }
503 }
504 }
505 c = *input++;
506 *output++ = (unsigned char)( c ^ stream_block[n] );
507
508 n = ( n + 1 ) & 0x0F;
509 }
510
511 *nc_off = n;
512 ret = 0;
513
514 cleanup:
515 esp_aes_release_hardware();
516 return ret;
517 }
518
519 /*
520 * AES-OFB (Output Feedback Mode) buffer encryption/decryption
521 */
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)522 int esp_aes_crypt_ofb(esp_aes_context *ctx,
523 size_t length,
524 size_t *iv_off,
525 unsigned char iv[16],
526 const unsigned char *input,
527 unsigned char *output )
528 {
529 int ret = -1;
530 size_t n;
531
532 if (esp_aes_validate_input(ctx, input, output)) {
533 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
534 }
535
536 if (!iv) {
537 ESP_LOGE(TAG, "No IV supplied");
538 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
539 }
540
541 if (!iv_off) {
542 ESP_LOGE(TAG, "No IV offset supplied");
543 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
544 }
545
546 n = *iv_off;
547
548 if (n > 15) {
549 return (MBEDTLS_ERR_AES_BAD_INPUT_DATA);
550 }
551
552 if (!valid_key_length(ctx)) {
553 return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
554 }
555
556 esp_aes_acquire_hardware();
557 ctx->key_in_hardware = 0;
558 ctx->key_in_hardware = aes_hal_setkey(ctx->key, ctx->key_bytes, ESP_AES_ENCRYPT);
559
560
561 while (length--) {
562 if ( n == 0 ) {
563 ret = esp_aes_block(ctx, iv, iv);
564 if (ret != 0) {
565 goto cleanup;
566 }
567 }
568 *output++ = *input++ ^ iv[n];
569
570 n = ( n + 1 ) & 0x0F;
571 }
572
573 *iv_off = n;
574 ret = 0;
575
576 cleanup:
577 esp_aes_release_hardware();
578
579 return ( ret );
580 }
581