1 /**
2  * \brief AES block cipher, ESP DMA 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-2020, 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 
29 #include <string.h>
30 #include "mbedtls/aes.h"
31 #include "esp_intr_alloc.h"
32 #include "esp_private/periph_ctrl.h"
33 #include "esp_log.h"
34 #include "esp_attr.h"
35 #include "soc/lldesc.h"
36 #include "esp_heap_caps.h"
37 #include "esp_memory_utils.h"
38 #include "sys/param.h"
39 #if CONFIG_PM_ENABLE
40 #include "esp_pm.h"
41 #endif
42 #include "esp_crypto_lock.h"
43 #include "hal/aes_hal.h"
44 #include "aes/esp_aes_internal.h"
45 #include "esp_aes_dma_priv.h"
46 
47 #if CONFIG_IDF_TARGET_ESP32S2
48 #include "esp32s2/rom/cache.h"
49 #elif CONFIG_IDF_TARGET_ESP32S3
50 #include "esp32s3/rom/cache.h"
51 #endif
52 
53 #include "freertos/FreeRTOS.h"
54 #include "freertos/semphr.h"
55 
56 #if SOC_AES_GDMA
57 #define AES_LOCK() esp_crypto_sha_aes_lock_acquire()
58 #define AES_RELEASE() esp_crypto_sha_aes_lock_release()
59 #elif SOC_AES_CRYPTO_DMA
60 #define AES_LOCK() esp_crypto_dma_lock_acquire()
61 #define AES_RELEASE() esp_crypto_dma_lock_release()
62 #endif
63 
64 /* Max size of each chunk to process when output buffer is in unaligned external ram
65    must be a multiple of block size
66 */
67 #define AES_MAX_CHUNK_WRITE_SIZE 1600
68 
69 /* Input over this length will yield and wait for interrupt instead of
70    busy-waiting, 30000 bytes is approx 0.5 ms */
71 #define AES_DMA_INTR_TRIG_LEN 2000
72 
73 /* With buffers in PSRAM (worst condition) we still achieve a speed of 4 MB/s
74    thus a 2 second timeout value should be suffient for even very large buffers.
75  */
76 #define AES_WAIT_INTR_TIMEOUT_MS 2000
77 
78 #if defined(CONFIG_MBEDTLS_AES_USE_INTERRUPT)
79 static SemaphoreHandle_t op_complete_sem;
80 #if defined(CONFIG_PM_ENABLE)
81 static esp_pm_lock_handle_t s_pm_cpu_lock;
82 static esp_pm_lock_handle_t s_pm_sleep_lock;
83 #endif
84 #endif
85 
86 #if SOC_PSRAM_DMA_CAPABLE
87 
88 #if (CONFIG_ESP32S2_DATA_CACHE_LINE_16B || CONFIG_ESP32S3_DATA_CACHE_LINE_16B)
89 #define DCACHE_LINE_SIZE 16
90 #elif (CONFIG_ESP32S2_DATA_CACHE_LINE_32B || CONFIG_ESP32S3_DATA_CACHE_LINE_32B)
91 #define DCACHE_LINE_SIZE 32
92 #elif CONFIG_ESP32S3_DATA_CACHE_LINE_64B
93 #define DCACHE_LINE_SIZE 64
94 #endif //(CONFIG_ESP32S2_DATA_CACHE_LINE_16B || CONFIG_ESP32S3_DATA_CACHE_LINE_16B)
95 
96 #endif //SOC_PSRAM_DMA_CAPABLE
97 
98 static const char *TAG = "esp-aes";
99 static bool s_check_dma_capable(const void *p);
100 
101 /* These are static due to:
102  *  * Must be in DMA capable memory, so stack is not a safe place to put them
103  *  * To avoid having to malloc/free them for every DMA operation
104  */
105 static DRAM_ATTR lldesc_t s_stream_in_desc;
106 static DRAM_ATTR lldesc_t s_stream_out_desc;
107 static DRAM_ATTR uint8_t s_stream_in[AES_BLOCK_BYTES];
108 static DRAM_ATTR uint8_t s_stream_out[AES_BLOCK_BYTES];
109 
esp_aes_wait_dma_done(lldesc_t * output)110 static inline void esp_aes_wait_dma_done(lldesc_t *output)
111 {
112     /* Wait for DMA write operation to complete */
113     while (1) {
114         if ( esp_aes_dma_done(output) ) {
115             break;
116         }
117     }
118 }
119 
120 /* Append a descriptor to the chain, set head if chain empty */
lldesc_append(lldesc_t ** head,lldesc_t * item)121 static inline void lldesc_append(lldesc_t **head, lldesc_t *item)
122 {
123     lldesc_t *it;
124     if (*head == NULL) {
125         *head = item;
126         return;
127     }
128 
129     it = *head;
130 
131     while (it->empty != 0) {
132         it = (lldesc_t *)it->empty;
133     }
134     it->eof = 0;
135     it->empty = (uint32_t)item;
136 }
137 
esp_aes_acquire_hardware(void)138 void esp_aes_acquire_hardware( void )
139 {
140     /* Released by esp_aes_release_hardware()*/
141     AES_LOCK();
142 
143     /* Enable AES and DMA hardware */
144 #if SOC_AES_CRYPTO_DMA
145     periph_module_enable(PERIPH_AES_DMA_MODULE);
146 #elif SOC_AES_GDMA
147     periph_module_enable(PERIPH_AES_MODULE);
148 #endif
149 }
150 
151 /* Function to disable AES and Crypto DMA clocks and release locks */
esp_aes_release_hardware(void)152 void esp_aes_release_hardware( void )
153 {
154     /* Disable AES and DMA hardware */
155 #if SOC_AES_CRYPTO_DMA
156     periph_module_disable(PERIPH_AES_DMA_MODULE);
157 #elif SOC_AES_GDMA
158     periph_module_disable(PERIPH_AES_MODULE);
159 #endif
160 
161     AES_RELEASE();
162 }
163 
164 
165 #if defined (CONFIG_MBEDTLS_AES_USE_INTERRUPT)
esp_aes_complete_isr(void * arg)166 static IRAM_ATTR void esp_aes_complete_isr(void *arg)
167 {
168     BaseType_t higher_woken;
169     aes_hal_interrupt_clear();
170     xSemaphoreGiveFromISR(op_complete_sem, &higher_woken);
171     if (higher_woken) {
172         portYIELD_FROM_ISR();
173     }
174 }
175 
esp_aes_intr_alloc(void)176 void esp_aes_intr_alloc(void)
177 {
178     if (op_complete_sem == NULL) {
179 
180         esp_err_t ret = esp_intr_alloc(ETS_AES_INTR_SOURCE, 0, esp_aes_complete_isr, NULL, NULL);
181         if (ret != ESP_OK) {
182             ESP_LOGE(TAG, "Failed to allocate AES interrupt %d", ret);
183             // This should be treated as fatal error as this API would mostly
184             // be invoked within mbedTLS interface. There is no way for the system
185             // to proceed if the AES interrupt allocation fails here.
186             abort();
187         }
188 
189         static StaticSemaphore_t op_sem_buf;
190         op_complete_sem = xSemaphoreCreateBinaryStatic(&op_sem_buf);
191         // Static semaphore creation is unlikley to fail but still basic sanity
192         assert(op_complete_sem != NULL);
193     }
194 }
195 
esp_aes_isr_initialise(void)196 static esp_err_t esp_aes_isr_initialise( void )
197 {
198     aes_hal_interrupt_clear();
199     aes_hal_interrupt_enable(true);
200 
201     /* AES is clocked proportionally to CPU clock, take power management lock */
202 #ifdef CONFIG_PM_ENABLE
203     if (s_pm_cpu_lock == NULL) {
204         if (esp_pm_lock_create(ESP_PM_NO_LIGHT_SLEEP, 0, "aes_sleep", &s_pm_sleep_lock) != ESP_OK) {
205             ESP_LOGE(TAG, "Failed to create PM sleep lock");
206             return ESP_FAIL;
207         }
208         if (esp_pm_lock_create(ESP_PM_CPU_FREQ_MAX, 0, "aes_cpu", &s_pm_cpu_lock) != ESP_OK) {
209             ESP_LOGE(TAG, "Failed to create PM CPU lock");
210             return ESP_FAIL;
211         }
212     }
213     esp_pm_lock_acquire(s_pm_cpu_lock);
214     esp_pm_lock_acquire(s_pm_sleep_lock);
215 #endif
216 
217     return ESP_OK;
218 }
219 #endif // CONFIG_MBEDTLS_AES_USE_INTERRUPT
220 
221 /* Wait for AES hardware block operation to complete */
esp_aes_dma_wait_complete(bool use_intr,lldesc_t * output_desc)222 static int esp_aes_dma_wait_complete(bool use_intr, lldesc_t *output_desc)
223 {
224 #if defined (CONFIG_MBEDTLS_AES_USE_INTERRUPT)
225     if (use_intr) {
226         if (!xSemaphoreTake(op_complete_sem, AES_WAIT_INTR_TIMEOUT_MS / portTICK_PERIOD_MS)) {
227             /* indicates a fundamental problem with driver */
228             ESP_LOGE(TAG, "Timed out waiting for completion of AES Interrupt");
229             return -1;
230         }
231 #ifdef CONFIG_PM_ENABLE
232         esp_pm_lock_release(s_pm_cpu_lock);
233         esp_pm_lock_release(s_pm_sleep_lock);
234 #endif  // CONFIG_PM_ENABLE
235     }
236 #endif
237     /* Checking this if interrupt is used also, to avoid
238        issues with AES fault injection
239     */
240     aes_hal_wait_done();
241 
242     esp_aes_wait_dma_done(output_desc);
243     return 0;
244 }
245 
246 
247 static int esp_aes_process_dma(esp_aes_context *ctx, const unsigned char *input, unsigned char *output, size_t len, uint8_t *stream_out);
248 
249 
250 /* Output buffers in external ram needs to be 16-byte aligned and DMA cant access input in the iCache mem range,
251    reallocate them into internal memory and encrypt in chunks to avoid
252    having to malloc too big of a buffer
253 
254   The function esp_aes_process_dma_ext_ram zeroises the output buffer in the case of memory allocation failure.
255 */
256 
esp_aes_process_dma_ext_ram(esp_aes_context * ctx,const unsigned char * input,unsigned char * output,size_t len,uint8_t * stream_out,bool realloc_input,bool realloc_output)257 static int esp_aes_process_dma_ext_ram(esp_aes_context *ctx, const unsigned char *input, unsigned char *output, size_t len, uint8_t *stream_out, bool realloc_input, bool realloc_output)
258 {
259     size_t chunk_len;
260     int ret = 0;
261     int offset = 0;
262     unsigned char *input_buf = NULL;
263     unsigned char *output_buf = NULL;
264     const unsigned char *dma_input;
265     chunk_len = MIN(AES_MAX_CHUNK_WRITE_SIZE, len);
266 
267     if (realloc_input) {
268         input_buf = heap_caps_malloc(chunk_len, MALLOC_CAP_DMA);
269 
270         if (input_buf == NULL) {
271             mbedtls_platform_zeroize(output, len);
272             ESP_LOGE(TAG, "Failed to allocate memory");
273             return -1;
274         }
275     }
276 
277     if (realloc_output) {
278         output_buf = heap_caps_malloc(chunk_len, MALLOC_CAP_DMA);
279 
280         if (output_buf == NULL) {
281             mbedtls_platform_zeroize(output, len);
282             ESP_LOGE(TAG, "Failed to allocate memory");
283             return -1;
284         }
285     } else {
286         output_buf = output;
287     }
288 
289     while (len) {
290         chunk_len = MIN(AES_MAX_CHUNK_WRITE_SIZE, len);
291 
292         /* If input needs realloc then copy it, else use the input with offset*/
293         if (realloc_input) {
294             memcpy(input_buf, input + offset, chunk_len);
295             dma_input = input_buf;
296         } else {
297             dma_input = input + offset;
298         }
299 
300         if (esp_aes_process_dma(ctx, dma_input, output_buf, chunk_len, stream_out) != 0) {
301             ret = -1;
302             goto cleanup;
303         }
304 
305         if (realloc_output) {
306             memcpy(output + offset, output_buf, chunk_len);
307         } else {
308             output_buf = output + offset + chunk_len;
309         }
310 
311         len -= chunk_len;
312         offset += chunk_len;
313     }
314 
315 cleanup:
316 
317     if (realloc_input) {
318         free(input_buf);
319     }
320     if (realloc_output) {
321         free(output_buf);
322     }
323 
324     return ret;
325 }
326 
327 /* Encrypt/decrypt the input using DMA
328  * The function esp_aes_process_dma zeroises the output buffer in the case of following conditions:
329  * 1. If key is not written in the hardware
330  * 2. Memory allocation failures
331  * 3. If AES interrupt is enabled and ISR initialisation fails
332  * 4. Failure in any of the AES operations
333  */
esp_aes_process_dma(esp_aes_context * ctx,const unsigned char * input,unsigned char * output,size_t len,uint8_t * stream_out)334 static int esp_aes_process_dma(esp_aes_context *ctx, const unsigned char *input, unsigned char *output, size_t len, uint8_t *stream_out)
335 {
336     lldesc_t *in_desc_head = NULL, *out_desc_head = NULL;
337     lldesc_t *out_desc_tail = NULL; /* pointer to the final output descriptor */
338     lldesc_t *block_desc = NULL, *block_in_desc = NULL, *block_out_desc = NULL;
339     size_t lldesc_num;
340     unsigned stream_bytes = len % AES_BLOCK_BYTES; // bytes which aren't in a full block
341     unsigned block_bytes = len - stream_bytes;     // bytes which are in a full block
342     unsigned blocks = (block_bytes / AES_BLOCK_BYTES) + ((stream_bytes > 0) ? 1 : 0);
343     bool use_intr = false;
344     bool input_needs_realloc = false;
345     bool output_needs_realloc = false;
346     int ret = 0;
347 
348     assert(len > 0); // caller shouldn't ever have len set to zero
349     assert(stream_bytes == 0 || stream_out != NULL); // stream_out can be NULL if we're processing full block(s)
350 
351     /* If no key is written to hardware yet, either the user hasn't called
352        mbedtls_aes_setkey_enc/mbedtls_aes_setkey_dec - meaning we also don't
353        know which mode to use - or a fault skipped the
354        key write to hardware. Treat this as a fatal error and zero the output block.
355     */
356     if (ctx->key_in_hardware != ctx->key_bytes) {
357         mbedtls_platform_zeroize(output, len);
358         return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
359     }
360 
361     if (block_bytes > 0) {
362         /* Flush cache if input in external ram */
363 #if (CONFIG_SPIRAM && SOC_PSRAM_DMA_CAPABLE)
364         if (esp_ptr_external_ram(input)) {
365             Cache_WriteBack_Addr((uint32_t)input, len);
366         }
367         if (esp_ptr_external_ram(output)) {
368             if ((((intptr_t)(output) & (DCACHE_LINE_SIZE - 1)) != 0) || (block_bytes % DCACHE_LINE_SIZE != 0)) {
369                 // Non aligned ext-mem buffer
370                 output_needs_realloc = true;
371             }
372         }
373 #endif
374         /* DMA cannot access memory in the iCache range, copy input to internal ram */
375         if (!s_check_dma_capable(input)) {
376             input_needs_realloc = true;
377         }
378 
379         if (!s_check_dma_capable(output)) {
380             output_needs_realloc = true;
381         }
382 
383         /* If either input or output is unaccessible to the DMA then they need to be reallocated */
384         if (input_needs_realloc || output_needs_realloc) {
385             return esp_aes_process_dma_ext_ram(ctx, input, output, len, stream_out, input_needs_realloc, output_needs_realloc);
386         }
387 
388         /* Set up dma descriptors for input and output considering the 16 byte alignment requirement for EDMA */
389         lldesc_num = lldesc_get_required_num_constrained(block_bytes, LLDESC_MAX_NUM_PER_DESC_16B_ALIGNED);
390 
391         /* Allocate both in and out descriptors to save a malloc/free per function call */
392         block_desc = heap_caps_calloc(lldesc_num * 2, sizeof(lldesc_t), MALLOC_CAP_DMA);
393         if (block_desc == NULL) {
394             mbedtls_platform_zeroize(output, len);
395             ESP_LOGE(TAG, "Failed to allocate memory");
396             return -1;
397         }
398 
399         block_in_desc = block_desc;
400         block_out_desc = block_desc + lldesc_num;
401 
402         lldesc_setup_link(block_in_desc, input, block_bytes, 0);
403         //Limit max inlink descriptor length to be 16 byte aligned, require for EDMA
404         lldesc_setup_link_constrained(block_out_desc, output, block_bytes, LLDESC_MAX_NUM_PER_DESC_16B_ALIGNED, 0);
405 
406         /* Setup in/out start descriptors */
407         lldesc_append(&in_desc_head, block_in_desc);
408         lldesc_append(&out_desc_head, block_out_desc);
409 
410         out_desc_tail = &block_out_desc[lldesc_num - 1];
411     }
412 
413     /* Any leftover bytes which are appended as an additional DMA list */
414     if (stream_bytes > 0) {
415 
416         memset(&s_stream_in_desc, 0, sizeof(lldesc_t));
417         memset(&s_stream_out_desc, 0, sizeof(lldesc_t));
418 
419         memset(s_stream_in, 0, AES_BLOCK_BYTES);
420         memset(s_stream_out, 0, AES_BLOCK_BYTES);
421 
422         memcpy(s_stream_in, input + block_bytes, stream_bytes);
423 
424         lldesc_setup_link(&s_stream_in_desc, s_stream_in, AES_BLOCK_BYTES, 0);
425         lldesc_setup_link(&s_stream_out_desc, s_stream_out, AES_BLOCK_BYTES, 0);
426 
427         /* Link with block descriptors */
428         lldesc_append(&in_desc_head, &s_stream_in_desc);
429         lldesc_append(&out_desc_head, &s_stream_out_desc);
430 
431         out_desc_tail = &s_stream_out_desc;
432     }
433 
434 #if defined (CONFIG_MBEDTLS_AES_USE_INTERRUPT)
435     /* Only use interrupt for long AES operations */
436     if (len > AES_DMA_INTR_TRIG_LEN) {
437         use_intr = true;
438         if (esp_aes_isr_initialise() != ESP_OK) {
439             ESP_LOGE(TAG, "ESP-AES ISR initialisation failed");
440             ret = -1;
441             goto cleanup;
442         }
443     } else
444 #endif
445     {
446         aes_hal_interrupt_enable(false);
447     }
448 
449     if (esp_aes_dma_start(in_desc_head, out_desc_head) != ESP_OK) {
450         ESP_LOGE(TAG, "esp_aes_dma_start failed, no DMA channel available");
451         ret = -1;
452         goto cleanup;
453     }
454 
455     aes_hal_transform_dma_start(blocks);
456 
457     if (esp_aes_dma_wait_complete(use_intr, out_desc_tail) < 0) {
458         ESP_LOGE(TAG, "esp_aes_dma_wait_complete failed");
459         ret = -1;
460         goto cleanup;
461     }
462 
463 #if (CONFIG_SPIRAM && SOC_PSRAM_DMA_CAPABLE)
464     if (block_bytes > 0) {
465         if (esp_ptr_external_ram(output)) {
466             Cache_Invalidate_Addr((uint32_t)output, block_bytes);
467         }
468     }
469 #endif
470     aes_hal_transform_dma_finish();
471 
472     if (stream_bytes > 0) {
473         memcpy(output + block_bytes, s_stream_out, stream_bytes);
474         memcpy(stream_out, s_stream_out, AES_BLOCK_BYTES);
475     }
476 
477 cleanup:
478     if (ret != 0) {
479         mbedtls_platform_zeroize(output, len);
480     }
481     free(block_desc);
482     return ret;
483 }
484 
485 
486 #if CONFIG_MBEDTLS_HARDWARE_GCM
487 
488 /* Encrypt/decrypt with AES-GCM the input using DMA
489  * The function esp_aes_process_dma_gcm zeroises the output buffer in the case of following conditions:
490  * 1. If key is not written in the hardware
491  * 2. Memory allocation failures
492  * 3. If AES interrupt is enabled and ISR initialisation fails
493  * 4. Failure in any of the AES operations
494  */
esp_aes_process_dma_gcm(esp_aes_context * ctx,const unsigned char * input,unsigned char * output,size_t len,lldesc_t * aad_desc,size_t aad_len)495 int esp_aes_process_dma_gcm(esp_aes_context *ctx, const unsigned char *input, unsigned char *output, size_t len, lldesc_t *aad_desc, size_t aad_len)
496 {
497     lldesc_t *in_desc_head = NULL, *out_desc_head = NULL, *len_desc = NULL;
498     lldesc_t *out_desc_tail = NULL; /* pointer to the final output descriptor */
499     lldesc_t stream_in_desc, stream_out_desc;
500     lldesc_t *block_desc = NULL, *block_in_desc = NULL, *block_out_desc = NULL;
501     size_t lldesc_num;
502     uint32_t len_buf[4] = {};
503     uint8_t stream_in[16] = {};
504     uint8_t stream_out[16] = {};
505     unsigned stream_bytes = len % AES_BLOCK_BYTES; // bytes which aren't in a full block
506     unsigned block_bytes = len - stream_bytes;     // bytes which are in a full block
507 
508     unsigned blocks = (block_bytes / AES_BLOCK_BYTES) + ((stream_bytes > 0) ? 1 : 0);
509 
510     bool use_intr = false;
511     int ret = 0;
512 
513     /* If no key is written to hardware yet, either the user hasn't called
514        mbedtls_aes_setkey_enc/mbedtls_aes_setkey_dec - meaning we also don't
515        know which mode to use - or a fault skipped the
516        key write to hardware. Treat this as a fatal error and zero the output block.
517     */
518     if (ctx->key_in_hardware != ctx->key_bytes) {
519         mbedtls_platform_zeroize(output, len);
520         return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
521     }
522 
523     /* Set up dma descriptors for input and output */
524     lldesc_num = lldesc_get_required_num(block_bytes);
525 
526     /* Allocate both in and out descriptors to save a malloc/free per function call, add 1 for length descriptor */
527     block_desc = heap_caps_calloc( (lldesc_num * 2) + 1, sizeof(lldesc_t), MALLOC_CAP_DMA);
528     if (block_desc == NULL) {
529         mbedtls_platform_zeroize(output, len);
530         ESP_LOGE(TAG, "Failed to allocate memory");
531         return -1;
532     }
533 
534     block_in_desc = block_desc;
535     len_desc = block_desc + lldesc_num;
536     block_out_desc = block_desc + lldesc_num + 1;
537 
538     if (aad_desc != NULL) {
539         lldesc_append(&in_desc_head, aad_desc);
540     }
541 
542     if (block_bytes > 0) {
543         lldesc_setup_link(block_in_desc, input, block_bytes, 0);
544         lldesc_setup_link(block_out_desc, output, block_bytes, 0);
545 
546         lldesc_append(&in_desc_head, block_in_desc);
547         lldesc_append(&out_desc_head, block_out_desc);
548 
549         out_desc_tail = &block_out_desc[lldesc_num - 1];
550     }
551 
552     /* Any leftover bytes which are appended as an additional DMA list */
553     if (stream_bytes > 0) {
554         memcpy(stream_in, input + block_bytes, stream_bytes);
555 
556         lldesc_setup_link(&stream_in_desc, stream_in, AES_BLOCK_BYTES, 0);
557         lldesc_setup_link(&stream_out_desc, stream_out, AES_BLOCK_BYTES, 0);
558 
559         lldesc_append(&in_desc_head, &stream_in_desc);
560         lldesc_append(&out_desc_head, &stream_out_desc);
561 
562         out_desc_tail = &stream_out_desc;
563     }
564 
565 
566     len_buf[1] = __builtin_bswap32(aad_len * 8);
567     len_buf[3] = __builtin_bswap32(len * 8);
568 
569     len_desc->length = sizeof(len_buf);
570     len_desc->size = sizeof(len_buf);
571     len_desc->owner = 1;
572     len_desc->eof = 1;
573     len_desc->buf = (uint8_t *)len_buf;
574 
575     lldesc_append(&in_desc_head, len_desc);
576 
577 #if defined (CONFIG_MBEDTLS_AES_USE_INTERRUPT)
578     /* Only use interrupt for long AES operations */
579     if (len > AES_DMA_INTR_TRIG_LEN) {
580         use_intr = true;
581         if (esp_aes_isr_initialise() != ESP_OK) {
582             ESP_LOGE(TAG, "ESP-AES ISR initialisation failed");
583             ret = -1;
584             goto cleanup;
585         }
586     } else
587 #endif
588     {
589         aes_hal_interrupt_enable(false);
590     }
591 
592     /* Start AES operation */
593     if (esp_aes_dma_start(in_desc_head, out_desc_head) != ESP_OK) {
594         ESP_LOGE(TAG, "esp_aes_dma_start failed, no DMA channel available");
595         ret = -1;
596         goto cleanup;
597     }
598 
599     aes_hal_transform_dma_gcm_start(blocks);
600 
601     if (esp_aes_dma_wait_complete(use_intr, out_desc_tail) < 0) {
602         ESP_LOGE(TAG, "esp_aes_dma_wait_complete failed");
603         ret = -1;
604         goto cleanup;
605     }
606 
607     aes_hal_transform_dma_finish();
608 
609     if (stream_bytes > 0) {
610         memcpy(output + block_bytes, stream_out, stream_bytes);
611     }
612 
613 cleanup:
614     if (ret != 0) {
615         mbedtls_platform_zeroize(output, len);
616     }
617     free(block_desc);
618     return ret;
619 }
620 
621 #endif //CONFIG_MBEDTLS_HARDWARE_GCM
622 
esp_aes_validate_input(esp_aes_context * ctx,const unsigned char * input,unsigned char * output)623 static int esp_aes_validate_input(esp_aes_context *ctx, const unsigned char *input,
624                                   unsigned char *output )
625 {
626     if (!ctx) {
627         ESP_LOGE(TAG, "No AES context supplied");
628         return -1;
629     }
630     if (!input) {
631         ESP_LOGE(TAG, "No input supplied");
632         return -1;
633     }
634     if (!output) {
635         ESP_LOGE(TAG, "No output supplied");
636         return -1;
637     }
638 
639     return 0;
640 }
641 
642 
643 /*
644  * AES-ECB single block encryption
645  */
esp_internal_aes_encrypt(esp_aes_context * ctx,const unsigned char input[16],unsigned char output[16])646 int esp_internal_aes_encrypt(esp_aes_context *ctx,
647                              const unsigned char input[16],
648                              unsigned char output[16] )
649 {
650     int r = -1;
651 
652     if (esp_aes_validate_input(ctx, input, output)) {
653         return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
654     }
655 
656     if (!valid_key_length(ctx)) {
657         return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
658     }
659 
660     esp_aes_acquire_hardware();
661     ctx->key_in_hardware = 0;
662     ctx->key_in_hardware = aes_hal_setkey(ctx->key, ctx->key_bytes, ESP_AES_ENCRYPT);
663     aes_hal_mode_init(ESP_AES_BLOCK_MODE_ECB);
664     r = esp_aes_process_dma(ctx, input, output, AES_BLOCK_BYTES, NULL);
665     esp_aes_release_hardware();
666 
667     return r;
668 }
669 
esp_aes_encrypt(esp_aes_context * ctx,const unsigned char input[16],unsigned char output[16])670 void esp_aes_encrypt(esp_aes_context *ctx,
671                      const unsigned char input[16],
672                      unsigned char output[16] )
673 {
674     esp_internal_aes_encrypt(ctx, input, output);
675 }
676 
677 /*
678  * AES-ECB single block decryption
679  */
esp_internal_aes_decrypt(esp_aes_context * ctx,const unsigned char input[16],unsigned char output[16])680 int esp_internal_aes_decrypt(esp_aes_context *ctx,
681                              const unsigned char input[16],
682                              unsigned char output[16] )
683 {
684     int r = -1;
685 
686     if (esp_aes_validate_input(ctx, input, output)) {
687         return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
688     }
689 
690     if (!valid_key_length(ctx)) {
691         return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
692     }
693 
694     esp_aes_acquire_hardware();
695     ctx->key_in_hardware = 0;
696     ctx->key_in_hardware = aes_hal_setkey(ctx->key, ctx->key_bytes, ESP_AES_DECRYPT);
697     aes_hal_mode_init(ESP_AES_BLOCK_MODE_ECB);
698     r = esp_aes_process_dma(ctx, input, output, AES_BLOCK_BYTES, NULL);
699     esp_aes_release_hardware();
700 
701     return r;
702 }
703 
esp_aes_decrypt(esp_aes_context * ctx,const unsigned char input[16],unsigned char output[16])704 void esp_aes_decrypt(esp_aes_context *ctx,
705                      const unsigned char input[16],
706                      unsigned char output[16] )
707 {
708     esp_internal_aes_decrypt(ctx, input, output);
709 }
710 
711 
712 /*
713  * AES-ECB block encryption/decryption
714  */
esp_aes_crypt_ecb(esp_aes_context * ctx,int mode,const unsigned char input[16],unsigned char output[16])715 int esp_aes_crypt_ecb(esp_aes_context *ctx,
716                       int mode,
717                       const unsigned char input[16],
718                       unsigned char output[16] )
719 {
720     int r = -1;
721 
722     if (esp_aes_validate_input(ctx, input, output)) {
723         return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
724     }
725 
726     if (!valid_key_length(ctx)) {
727         return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
728     }
729 
730     esp_aes_acquire_hardware();
731     ctx->key_in_hardware = 0;
732     ctx->key_in_hardware = aes_hal_setkey(ctx->key, ctx->key_bytes, mode);
733     aes_hal_mode_init(ESP_AES_BLOCK_MODE_ECB);
734     r = esp_aes_process_dma(ctx, input, output, AES_BLOCK_BYTES, NULL);
735     esp_aes_release_hardware();
736 
737     return r;
738 }
739 
740 /*
741  * AES-CBC buffer encryption/decryption
742  */
esp_aes_crypt_cbc(esp_aes_context * ctx,int mode,size_t length,unsigned char iv[16],const unsigned char * input,unsigned char * output)743 int esp_aes_crypt_cbc(esp_aes_context *ctx,
744                       int mode,
745                       size_t length,
746                       unsigned char iv[16],
747                       const unsigned char *input,
748                       unsigned char *output )
749 {
750     int r = -1;
751     if (esp_aes_validate_input(ctx, input, output)) {
752         return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
753     }
754 
755     if (!iv) {
756         ESP_LOGE(TAG, "No IV supplied");
757         return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
758     }
759 
760     /* For CBC input length should be multiple of
761      * AES BLOCK BYTES
762      * */
763     if ( (length % AES_BLOCK_BYTES) || (length == 0) ) {
764         return ERR_ESP_AES_INVALID_INPUT_LENGTH;
765     }
766 
767     if (!valid_key_length(ctx)) {
768         return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
769     }
770 
771     esp_aes_acquire_hardware();
772     ctx->key_in_hardware = 0;
773     ctx->key_in_hardware = aes_hal_setkey(ctx->key, ctx->key_bytes, mode);
774     aes_hal_mode_init(ESP_AES_BLOCK_MODE_CBC);
775     aes_hal_set_iv(iv);
776 
777     r = esp_aes_process_dma(ctx, input, output, length, NULL);
778     if (r != 0) {
779         goto cleanup;
780     }
781 
782     aes_hal_read_iv(iv);
783 
784 cleanup:
785     esp_aes_release_hardware();
786     return r;
787 }
788 
789 /*
790  * AES-CFB8 buffer encryption/decryption
791  */
esp_aes_crypt_cfb8(esp_aes_context * ctx,int mode,size_t length,unsigned char iv[16],const unsigned char * input,unsigned char * output)792 int esp_aes_crypt_cfb8(esp_aes_context *ctx,
793                        int mode,
794                        size_t length,
795                        unsigned char iv[16],
796                        const unsigned char *input,
797                        unsigned char *output )
798 {
799     int r = -1;
800     unsigned char c;
801     unsigned char ov[17];
802     size_t block_bytes = length - (length % AES_BLOCK_BYTES);
803 
804     if (esp_aes_validate_input(ctx, input, output)) {
805         return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
806     }
807 
808     if (!iv) {
809         ESP_LOGE(TAG, "No IV supplied");
810         return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
811     }
812 
813 
814     if (!valid_key_length(ctx)) {
815         return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
816     }
817 
818     /* The DMA engine will only output correct IV if it runs
819        full blocks of input in CFB8 mode
820     */
821     esp_aes_acquire_hardware();
822 
823     if (block_bytes > 0) {
824 
825         ctx->key_in_hardware = 0;
826         ctx->key_in_hardware = aes_hal_setkey(ctx->key, ctx->key_bytes, mode);
827         aes_hal_mode_init(ESP_AES_BLOCK_MODE_CFB8);
828         aes_hal_set_iv(iv);
829         r = esp_aes_process_dma(ctx, input, output, block_bytes, NULL);
830         if (r != 0) {
831             goto cleanup;
832         }
833 
834         aes_hal_read_iv(iv);
835 
836         length -= block_bytes;
837         input += block_bytes;
838         output += block_bytes;
839     }
840 
841     // Process remaining bytes block-at-a-time in ECB mode
842     if (length > 0) {
843         ctx->key_in_hardware = 0;
844         ctx->key_in_hardware = aes_hal_setkey(ctx->key, ctx->key_bytes, MBEDTLS_AES_ENCRYPT);
845         aes_hal_mode_init(ESP_AES_BLOCK_MODE_ECB);
846 
847         while ( length-- ) {
848             memcpy( ov, iv, 16 );
849 
850             r = esp_aes_process_dma(ctx, iv, iv, AES_BLOCK_BYTES, NULL);
851             if (r != 0) {
852                 goto cleanup;
853             }
854 
855             if ( mode == MBEDTLS_AES_DECRYPT ) {
856                 ov[16] = *input;
857             }
858 
859             c = *output++ = ( iv[0] ^ *input++ );
860 
861             if ( mode == MBEDTLS_AES_ENCRYPT ) {
862                 ov[16] = c;
863             }
864             memcpy( iv, ov + 1, 16 );
865         }
866 
867     }
868     r = 0;
869 
870 cleanup:
871     esp_aes_release_hardware();
872     return r;
873 }
874 
875 /*
876  * AES-CFB128 buffer encryption/decryption
877  */
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)878 int esp_aes_crypt_cfb128(esp_aes_context *ctx,
879                          int mode,
880                          size_t length,
881                          size_t *iv_off,
882                          unsigned char iv[16],
883                          const unsigned char *input,
884                          unsigned char *output )
885 
886 {
887     uint8_t c;
888     size_t stream_bytes = 0;
889     size_t n;
890 
891     if (esp_aes_validate_input(ctx, input, output)) {
892         return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
893     }
894 
895     if (!iv) {
896         ESP_LOGE(TAG, "No IV supplied");
897         return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
898     }
899 
900     if (!iv_off) {
901         ESP_LOGE(TAG, "No IV offset supplied");
902         return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
903     }
904 
905     if (!valid_key_length(ctx)) {
906         return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
907     }
908 
909     n = *iv_off;
910 
911     /* First process the *iv_off bytes
912      * which are pending from the previous call to this API
913      */
914     while (n > 0 && length > 0) {
915         if (mode == MBEDTLS_AES_ENCRYPT) {
916             iv[n] = *output++ = *input++ ^ iv[n];
917         } else {
918             c = *input++;
919             *output++ = c ^ iv[n];
920             iv[n] = c;
921         }
922         n = (n + 1) % AES_BLOCK_BYTES;
923         length--;
924     }
925 
926 
927     if (length > 0) {
928         stream_bytes = length % AES_BLOCK_BYTES;
929         esp_aes_acquire_hardware();
930         ctx->key_in_hardware = 0;
931         ctx->key_in_hardware = aes_hal_setkey(ctx->key, ctx->key_bytes, mode);
932         aes_hal_mode_init(ESP_AES_BLOCK_MODE_CFB128);
933         aes_hal_set_iv(iv);
934 
935         int r = esp_aes_process_dma(ctx, input, output, length, iv);
936         if (r != 0) {
937             esp_aes_release_hardware();
938             return r;
939         }
940 
941         if (stream_bytes == 0) {
942             // if we didn't need the partial 'stream block' then the new IV is in the IV register
943             aes_hal_read_iv(iv);
944         } else {
945             // if we did process a final partial block the new IV is already processed via DMA (and has some bytes of output in it),
946             // In decrypt mode any partial bytes are output plaintext (iv ^ c) and need to be swapped back to ciphertext (as the next
947             // block uses ciphertext as its IV input)
948             //
949             // Note: It may be more efficient to not process the partial block via DMA in this case.
950             if (mode == MBEDTLS_AES_DECRYPT) {
951                 memcpy(iv, input + length - stream_bytes, stream_bytes);
952             }
953         }
954         esp_aes_release_hardware();
955     }
956 
957     *iv_off = n + stream_bytes;
958     return 0;
959 }
960 
961 /*
962  * AES-OFB (Output Feedback Mode) buffer encryption/decryption
963  */
964 
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)965 int esp_aes_crypt_ofb(esp_aes_context *ctx,
966                       size_t length,
967                       size_t *iv_off,
968                       unsigned char iv[16],
969                       const unsigned char *input,
970                       unsigned char *output )
971 {
972     size_t n;
973     size_t stream_bytes = 0;
974 
975     if (esp_aes_validate_input(ctx, input, output)) {
976         return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
977     }
978 
979     if (!iv) {
980         ESP_LOGE(TAG, "No IV supplied");
981         return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
982     }
983 
984     if (!iv_off) {
985         ESP_LOGE(TAG, "No IV offset supplied");
986         return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
987     }
988 
989     n = *iv_off;
990 
991     /* If there is an offset then use the output of the previous AES block
992         (the updated IV) to calculate the new output */
993     while (n > 0 && length > 0) {
994         *output++ = (*input++ ^ iv[n]);
995         n = (n + 1) & 0xF;
996         length--;
997     }
998     if (length > 0) {
999         stream_bytes = (length % AES_BLOCK_BYTES);
1000 
1001         esp_aes_acquire_hardware();
1002         ctx->key_in_hardware = 0;
1003         ctx->key_in_hardware = aes_hal_setkey(ctx->key, ctx->key_bytes, ESP_AES_DECRYPT);
1004         aes_hal_mode_init(ESP_AES_BLOCK_MODE_OFB);
1005         aes_hal_set_iv(iv);
1006 
1007         int r = esp_aes_process_dma(ctx, input, output, length, iv);
1008         if (r != 0) {
1009             esp_aes_release_hardware();
1010             return r;
1011         }
1012 
1013         aes_hal_read_iv(iv);
1014         esp_aes_release_hardware();
1015     }
1016 
1017     *iv_off = n + stream_bytes;
1018 
1019     return 0;
1020 }
1021 
1022 /*
1023  * AES-CTR buffer encryption/decryption
1024  */
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)1025 int esp_aes_crypt_ctr(esp_aes_context *ctx,
1026                       size_t length,
1027                       size_t *nc_off,
1028                       unsigned char nonce_counter[16],
1029                       unsigned char stream_block[16],
1030                       const unsigned char *input,
1031                       unsigned char *output )
1032 {
1033     size_t n;
1034 
1035     if (esp_aes_validate_input(ctx, input, output)) {
1036         return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1037     }
1038 
1039     if (!stream_block) {
1040         ESP_LOGE(TAG, "No stream supplied");
1041         return -1;
1042     }
1043 
1044     if (!nonce_counter) {
1045         ESP_LOGE(TAG, "No nonce supplied");
1046         return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1047     }
1048 
1049     if (!nc_off) {
1050         ESP_LOGE(TAG, "No nonce offset supplied");
1051         return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1052     }
1053 
1054     n = *nc_off;
1055 
1056     if (!valid_key_length(ctx)) {
1057         return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
1058     }
1059 
1060     /* Process any unprocessed bytes left in stream block from
1061        last operation */
1062     while (n > 0 && length > 0) {
1063         *output++ = (unsigned char)(*input++ ^ stream_block[n]);
1064         n = (n + 1) & 0xF;
1065         length--;
1066     }
1067 
1068     if (length > 0) {
1069 
1070         esp_aes_acquire_hardware();
1071         ctx->key_in_hardware = 0;
1072         ctx->key_in_hardware = aes_hal_setkey(ctx->key, ctx->key_bytes, ESP_AES_DECRYPT);
1073 
1074         aes_hal_mode_init(ESP_AES_BLOCK_MODE_CTR);
1075         aes_hal_set_iv(nonce_counter);
1076 
1077         int r = esp_aes_process_dma(ctx, input, output, length, stream_block);
1078 
1079         if (r != 0) {
1080             esp_aes_release_hardware();
1081             return r;
1082         }
1083 
1084         aes_hal_read_iv(nonce_counter);
1085 
1086         esp_aes_release_hardware();
1087 
1088     }
1089     *nc_off = n + (length % AES_BLOCK_BYTES);
1090 
1091     return 0;
1092 }
1093 
s_check_dma_capable(const void * p)1094 static bool s_check_dma_capable(const void *p)
1095 {
1096     bool is_capable = false;
1097 #if CONFIG_SPIRAM
1098     is_capable |= esp_ptr_dma_ext_capable(p);
1099 #endif
1100     is_capable |= esp_ptr_dma_capable(p);
1101 
1102     return is_capable;
1103 }
1104