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