mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-02 20:24:32 +02:00
Merge branch 'bugfix/crypto_allocate_lldesc_v4.3' into 'release/v4.3'
crypto: dont create DMA descriptors on the stack (v4.3) See merge request espressif/esp-idf!16342
This commit is contained in:
@@ -1,16 +1,8 @@
|
|||||||
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
|
/*
|
||||||
//
|
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
*
|
||||||
// you may not use this file except in compliance with the License.
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
// You may obtain a copy of the License at
|
*/
|
||||||
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
@@ -1,23 +1,15 @@
|
|||||||
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
|
/*
|
||||||
//
|
* SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
*
|
||||||
// you may not use this file except in compliance with the License.
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
// You may obtain a copy of the License at
|
*/
|
||||||
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define IDF_PERFORMANCE_MIN_AES_CBC_THROUGHPUT_MBSEC 43
|
#define IDF_PERFORMANCE_MIN_AES_CBC_THROUGHPUT_MBSEC 43
|
||||||
|
|
||||||
// SHA256 hardware throughput at 240MHz, threshold set lower than worst case
|
// SHA256 hardware throughput at 240MHz, threshold set lower than worst case
|
||||||
#define IDF_PERFORMANCE_MIN_SHA256_THROUGHPUT_MBSEC 19.8
|
#define IDF_PERFORMANCE_MIN_SHA256_THROUGHPUT_MBSEC 90
|
||||||
// esp_sha() time to process 32KB of input data from RAM
|
// esp_sha() time to process 32KB of input data from RAM
|
||||||
#define IDF_PERFORMANCE_MAX_TIME_SHA1_32KB 1000
|
#define IDF_PERFORMANCE_MAX_TIME_SHA1_32KB 1000
|
||||||
#define IDF_PERFORMANCE_MAX_TIME_SHA512_32KB 900
|
#define IDF_PERFORMANCE_MAX_TIME_SHA512_32KB 900
|
||||||
|
@@ -31,6 +31,7 @@
|
|||||||
#include "esp_intr_alloc.h"
|
#include "esp_intr_alloc.h"
|
||||||
#include "driver/periph_ctrl.h"
|
#include "driver/periph_ctrl.h"
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
|
#include "esp_attr.h"
|
||||||
#include "soc/lldesc.h"
|
#include "soc/lldesc.h"
|
||||||
#include "esp_heap_caps.h"
|
#include "esp_heap_caps.h"
|
||||||
#include "sys/param.h"
|
#include "sys/param.h"
|
||||||
@@ -79,8 +80,28 @@ static esp_pm_lock_handle_t s_pm_sleep_lock;
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if SOC_PSRAM_DMA_CAPABLE
|
||||||
|
|
||||||
|
#if (CONFIG_ESP32S2_DATA_CACHE_LINE_16B || CONFIG_ESP32S3_DATA_CACHE_LINE_16B)
|
||||||
|
#define DCACHE_LINE_SIZE 16
|
||||||
|
#elif (CONFIG_ESP32S2_DATA_CACHE_LINE_32B || CONFIG_ESP32S3_DATA_CACHE_LINE_32B)
|
||||||
|
#define DCACHE_LINE_SIZE 32
|
||||||
|
#elif CONFIG_ESP32S3_DATA_CACHE_LINE_64B
|
||||||
|
#define DCACHE_LINE_SIZE 64
|
||||||
|
#endif //(CONFIG_ESP32S2_DATA_CACHE_LINE_16B || CONFIG_ESP32S3_DATA_CACHE_LINE_16B)
|
||||||
|
|
||||||
|
#endif //SOC_PSRAM_DMA_CAPABLE
|
||||||
|
|
||||||
static const char *TAG = "esp-aes";
|
static const char *TAG = "esp-aes";
|
||||||
|
|
||||||
|
/* These are static due to:
|
||||||
|
* * Must be in DMA capable memory, so stack is not a safe place to put them
|
||||||
|
* * To avoid having to malloc/free them for every DMA operation
|
||||||
|
*/
|
||||||
|
static DRAM_ATTR lldesc_t s_stream_in_desc;
|
||||||
|
static DRAM_ATTR lldesc_t s_stream_out_desc;
|
||||||
|
static DRAM_ATTR uint8_t s_stream_in[AES_BLOCK_BYTES];
|
||||||
|
static DRAM_ATTR uint8_t s_stream_out[AES_BLOCK_BYTES];
|
||||||
|
|
||||||
static inline void esp_aes_wait_dma_done(lldesc_t *output)
|
static inline void esp_aes_wait_dma_done(lldesc_t *output)
|
||||||
{
|
{
|
||||||
@@ -289,15 +310,12 @@ cleanup:
|
|||||||
/* Encrypt/decrypt the input using DMA */
|
/* Encrypt/decrypt the input using DMA */
|
||||||
static int esp_aes_process_dma(esp_aes_context *ctx, const unsigned char *input, unsigned char *output, size_t len, uint8_t *stream_out)
|
static int esp_aes_process_dma(esp_aes_context *ctx, const unsigned char *input, unsigned char *output, size_t len, uint8_t *stream_out)
|
||||||
{
|
{
|
||||||
lldesc_t stream_in_desc, stream_out_desc;
|
|
||||||
lldesc_t *in_desc_head = NULL, *out_desc_head = NULL;
|
lldesc_t *in_desc_head = NULL, *out_desc_head = NULL;
|
||||||
lldesc_t *out_desc_tail = NULL; /* pointer to the final output descriptor */
|
lldesc_t *out_desc_tail = NULL; /* pointer to the final output descriptor */
|
||||||
lldesc_t *block_desc = NULL, *block_in_desc = NULL, *block_out_desc = NULL;
|
lldesc_t *block_desc = NULL, *block_in_desc = NULL, *block_out_desc = NULL;
|
||||||
size_t lldesc_num;
|
size_t lldesc_num;
|
||||||
uint8_t stream_in[16] = {};
|
|
||||||
unsigned stream_bytes = len % AES_BLOCK_BYTES; // bytes which aren't in a full block
|
unsigned stream_bytes = len % AES_BLOCK_BYTES; // bytes which aren't in a full block
|
||||||
unsigned block_bytes = len - stream_bytes; // bytes which are in a full block
|
unsigned block_bytes = len - stream_bytes; // bytes which are in a full block
|
||||||
unsigned char *non_icache_input = NULL;
|
|
||||||
unsigned blocks = (block_bytes / AES_BLOCK_BYTES) + ((stream_bytes > 0) ? 1 : 0);
|
unsigned blocks = (block_bytes / AES_BLOCK_BYTES) + ((stream_bytes > 0) ? 1 : 0);
|
||||||
bool use_intr = false;
|
bool use_intr = false;
|
||||||
bool input_needs_realloc = false;
|
bool input_needs_realloc = false;
|
||||||
@@ -319,12 +337,12 @@ static int esp_aes_process_dma(esp_aes_context *ctx, const unsigned char *input,
|
|||||||
|
|
||||||
if (block_bytes > 0) {
|
if (block_bytes > 0) {
|
||||||
/* Flush cache if input in external ram */
|
/* Flush cache if input in external ram */
|
||||||
#if (CONFIG_SPIRAM_USE_CAPS_ALLOC || CONFIG_SPIRAM_USE_MALLOC)
|
#if (CONFIG_SPIRAM && SOC_PSRAM_DMA_CAPABLE)
|
||||||
if (esp_ptr_external_ram(input)) {
|
if (esp_ptr_external_ram(input)) {
|
||||||
Cache_WriteBack_All();
|
Cache_WriteBack_Addr((uint32_t)input, len);
|
||||||
}
|
}
|
||||||
if (esp_ptr_external_ram(output)) {
|
if (esp_ptr_external_ram(output)) {
|
||||||
if (((intptr_t)(output) & 0xF) != 0) {
|
if ((((intptr_t)(output) & (DCACHE_LINE_SIZE - 1)) != 0) || (block_bytes % DCACHE_LINE_SIZE != 0)) {
|
||||||
// Non aligned ext-mem buffer
|
// Non aligned ext-mem buffer
|
||||||
output_needs_realloc = true;
|
output_needs_realloc = true;
|
||||||
}
|
}
|
||||||
@@ -348,7 +366,7 @@ static int esp_aes_process_dma(esp_aes_context *ctx, const unsigned char *input,
|
|||||||
lldesc_num = lldesc_get_required_num(block_bytes);
|
lldesc_num = lldesc_get_required_num(block_bytes);
|
||||||
|
|
||||||
/* Allocate both in and out descriptors to save a malloc/free per function call */
|
/* Allocate both in and out descriptors to save a malloc/free per function call */
|
||||||
block_desc = heap_caps_malloc(sizeof(lldesc_t) * lldesc_num * 2, MALLOC_CAP_DMA);
|
block_desc = heap_caps_calloc(lldesc_num * 2, sizeof(lldesc_t), MALLOC_CAP_DMA);
|
||||||
if (block_desc == NULL) {
|
if (block_desc == NULL) {
|
||||||
ESP_LOGE(TAG, "Failed to allocate memory");
|
ESP_LOGE(TAG, "Failed to allocate memory");
|
||||||
ret = -1;
|
ret = -1;
|
||||||
@@ -359,30 +377,38 @@ static int esp_aes_process_dma(esp_aes_context *ctx, const unsigned char *input,
|
|||||||
block_out_desc = block_desc + lldesc_num;
|
block_out_desc = block_desc + lldesc_num;
|
||||||
|
|
||||||
lldesc_setup_link(block_in_desc, input, block_bytes, 0);
|
lldesc_setup_link(block_in_desc, input, block_bytes, 0);
|
||||||
lldesc_setup_link(block_out_desc, output, block_bytes, 0);
|
//Limit max inlink descriptor length to be 16 byte aligned, require for EDMA
|
||||||
|
lldesc_setup_link_constrained(block_out_desc, output, block_bytes, LLDESC_MAX_NUM_PER_DESC_16B_ALIGNED, 0);
|
||||||
|
|
||||||
out_desc_tail = &block_out_desc[lldesc_num - 1];
|
out_desc_tail = &block_out_desc[lldesc_num - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Any leftover bytes which are appended as an additional DMA list */
|
/* Any leftover bytes which are appended as an additional DMA list */
|
||||||
if (stream_bytes > 0) {
|
if (stream_bytes > 0) {
|
||||||
memcpy(stream_in, input + block_bytes, stream_bytes);
|
|
||||||
|
|
||||||
lldesc_setup_link(&stream_in_desc, stream_in, AES_BLOCK_BYTES, 0);
|
memset(&s_stream_in_desc, 0, sizeof(lldesc_t));
|
||||||
lldesc_setup_link(&stream_out_desc, stream_out, AES_BLOCK_BYTES, 0);
|
memset(&s_stream_out_desc, 0, sizeof(lldesc_t));
|
||||||
|
|
||||||
|
memset(s_stream_in, 0, AES_BLOCK_BYTES);
|
||||||
|
memset(s_stream_out, 0, AES_BLOCK_BYTES);
|
||||||
|
|
||||||
|
memcpy(s_stream_in, input + block_bytes, stream_bytes);
|
||||||
|
|
||||||
|
lldesc_setup_link(&s_stream_in_desc, s_stream_in, AES_BLOCK_BYTES, 0);
|
||||||
|
lldesc_setup_link(&s_stream_out_desc, s_stream_out, AES_BLOCK_BYTES, 0);
|
||||||
|
|
||||||
if (block_bytes > 0) {
|
if (block_bytes > 0) {
|
||||||
/* Link with block descriptors*/
|
/* Link with block descriptors*/
|
||||||
block_in_desc[lldesc_num - 1].empty = (uint32_t)&stream_in_desc;
|
block_in_desc[lldesc_num - 1].empty = (uint32_t)&s_stream_in_desc;
|
||||||
block_out_desc[lldesc_num - 1].empty = (uint32_t)&stream_out_desc;
|
block_out_desc[lldesc_num - 1].empty = (uint32_t)&s_stream_out_desc;
|
||||||
}
|
}
|
||||||
|
|
||||||
out_desc_tail = &stream_out_desc;
|
out_desc_tail = &s_stream_out_desc;
|
||||||
}
|
}
|
||||||
|
|
||||||
// block buffers are sent to DMA first, unless there aren't any
|
// block buffers are sent to DMA first, unless there aren't any
|
||||||
in_desc_head = (block_bytes > 0) ? block_in_desc : &stream_in_desc;
|
in_desc_head = (block_bytes > 0) ? block_in_desc : &s_stream_in_desc;
|
||||||
out_desc_head = (block_bytes > 0) ? block_out_desc : &stream_out_desc;
|
out_desc_head = (block_bytes > 0) ? block_out_desc : &s_stream_out_desc;
|
||||||
|
|
||||||
|
|
||||||
#if defined (CONFIG_MBEDTLS_AES_USE_INTERRUPT)
|
#if defined (CONFIG_MBEDTLS_AES_USE_INTERRUPT)
|
||||||
@@ -408,21 +434,21 @@ static int esp_aes_process_dma(esp_aes_context *ctx, const unsigned char *input,
|
|||||||
aes_hal_transform_dma_start(blocks);
|
aes_hal_transform_dma_start(blocks);
|
||||||
esp_aes_dma_wait_complete(use_intr, out_desc_tail);
|
esp_aes_dma_wait_complete(use_intr, out_desc_tail);
|
||||||
|
|
||||||
#if (CONFIG_SPIRAM_USE_CAPS_ALLOC || CONFIG_SPIRAM_USE_MALLOC)
|
#if (CONFIG_SPIRAM && SOC_PSRAM_DMA_CAPABLE)
|
||||||
if (block_bytes > 0) {
|
if (block_bytes > 0) {
|
||||||
if (esp_ptr_external_ram(output)) {
|
if (esp_ptr_external_ram(output)) {
|
||||||
Cache_Invalidate_DCache_All();
|
Cache_Invalidate_Addr((uint32_t)output, block_bytes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
aes_hal_transform_dma_finish();
|
aes_hal_transform_dma_finish();
|
||||||
|
|
||||||
if (stream_bytes > 0) {
|
if (stream_bytes > 0) {
|
||||||
memcpy(output + block_bytes, stream_out, stream_bytes);
|
memcpy(output + block_bytes, s_stream_out, stream_bytes);
|
||||||
|
memcpy(stream_out, s_stream_out, AES_BLOCK_BYTES);
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
free(non_icache_input);
|
|
||||||
free(block_desc);
|
free(block_desc);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@@ -490,7 +490,7 @@ int esp_aes_gcm_finish( esp_gcm_context *ctx,
|
|||||||
/* Due to restrictions in the hardware (e.g. need to do the whole conversion in one go),
|
/* Due to restrictions in the hardware (e.g. need to do the whole conversion in one go),
|
||||||
some combinations of inputs are not supported */
|
some combinations of inputs are not supported */
|
||||||
static bool esp_aes_gcm_input_support_hw_accel(size_t length, const unsigned char *aad, size_t aad_len,
|
static bool esp_aes_gcm_input_support_hw_accel(size_t length, const unsigned char *aad, size_t aad_len,
|
||||||
const unsigned char *input, unsigned char *output)
|
const unsigned char *input, unsigned char *output, uint8_t *stream_in)
|
||||||
{
|
{
|
||||||
bool support_hw_accel = true;
|
bool support_hw_accel = true;
|
||||||
|
|
||||||
@@ -505,10 +505,15 @@ static bool esp_aes_gcm_input_support_hw_accel(size_t length, const unsigned cha
|
|||||||
} else if (!esp_ptr_dma_capable(output) && length > 0) {
|
} else if (!esp_ptr_dma_capable(output) && length > 0) {
|
||||||
/* output in non internal DMA memory */
|
/* output in non internal DMA memory */
|
||||||
support_hw_accel = false;
|
support_hw_accel = false;
|
||||||
|
} else if (!esp_ptr_dma_capable(stream_in)) {
|
||||||
|
/* Stream in (and therefor other descriptors and buffers that come from the stack)
|
||||||
|
in non internal DMA memory */
|
||||||
|
support_hw_accel = false;
|
||||||
} else if (length == 0) {
|
} else if (length == 0) {
|
||||||
support_hw_accel = false;
|
support_hw_accel = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return support_hw_accel;
|
return support_hw_accel;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -562,7 +567,7 @@ int esp_aes_gcm_crypt_and_tag( esp_gcm_context *ctx,
|
|||||||
unsigned block_bytes = aad_len - stream_bytes; // bytes which are in a full block
|
unsigned block_bytes = aad_len - stream_bytes; // bytes which are in a full block
|
||||||
|
|
||||||
/* Due to hardware limition only certain cases are fully supported in HW */
|
/* Due to hardware limition only certain cases are fully supported in HW */
|
||||||
if (!esp_aes_gcm_input_support_hw_accel(length, aad, aad_len, input, output)) {
|
if (!esp_aes_gcm_input_support_hw_accel(length, aad, aad_len, input, output, stream_in)) {
|
||||||
return esp_aes_gcm_crypt_and_tag_partial_hw(ctx, mode, length, iv, iv_len, aad, aad_len, input, output, tag_len, tag);
|
return esp_aes_gcm_crypt_and_tag_partial_hw(ctx, mode, length, iv, iv_len, aad, aad_len, input, output, tag_len, tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -31,6 +31,7 @@
|
|||||||
|
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
#include "esp_crypto_lock.h"
|
#include "esp_crypto_lock.h"
|
||||||
|
#include "esp_attr.h"
|
||||||
#include "soc/lldesc.h"
|
#include "soc/lldesc.h"
|
||||||
#include "soc/cache_memory.h"
|
#include "soc/cache_memory.h"
|
||||||
#include "soc/periph_defs.h"
|
#include "soc/periph_defs.h"
|
||||||
@@ -64,6 +65,12 @@
|
|||||||
|
|
||||||
const static char *TAG = "esp-sha";
|
const static char *TAG = "esp-sha";
|
||||||
|
|
||||||
|
/* These are static due to:
|
||||||
|
* * Must be in DMA capable memory, so stack is not a safe place to put them
|
||||||
|
* * To avoid having to malloc/free them for every DMA operation
|
||||||
|
*/
|
||||||
|
static DRAM_ATTR lldesc_t s_dma_descr_input;
|
||||||
|
static DRAM_ATTR lldesc_t s_dma_descr_buf;
|
||||||
|
|
||||||
void esp_sha_write_digest_state(esp_sha_type sha_type, void *digest_state)
|
void esp_sha_write_digest_state(esp_sha_type sha_type, void *digest_state)
|
||||||
{
|
{
|
||||||
@@ -219,7 +226,7 @@ int esp_sha_dma(esp_sha_type sha_type, const void *input, uint32_t ilen,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (CONFIG_SPIRAM_USE_CAPS_ALLOC || CONFIG_SPIRAM_USE_MALLOC)
|
#if (CONFIG_SPIRAM && SOC_PSRAM_DMA_CAPABLE)
|
||||||
if (esp_ptr_external_ram(input)) {
|
if (esp_ptr_external_ram(input)) {
|
||||||
Cache_WriteBack_Addr((uint32_t)input, ilen);
|
Cache_WriteBack_Addr((uint32_t)input, ilen);
|
||||||
}
|
}
|
||||||
@@ -273,34 +280,35 @@ static esp_err_t esp_sha_dma_process(esp_sha_type sha_type, const void *input, u
|
|||||||
const void *buf, uint32_t buf_len, bool is_first_block)
|
const void *buf, uint32_t buf_len, bool is_first_block)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
lldesc_t dma_descr_input = {};
|
|
||||||
lldesc_t dma_descr_buf = {};
|
|
||||||
lldesc_t *dma_descr_head;
|
lldesc_t *dma_descr_head;
|
||||||
size_t num_blks = (ilen + buf_len) / block_length(sha_type);
|
size_t num_blks = (ilen + buf_len) / block_length(sha_type);
|
||||||
|
|
||||||
|
memset(&s_dma_descr_input, 0, sizeof(lldesc_t));
|
||||||
|
memset(&s_dma_descr_buf, 0, sizeof(lldesc_t));
|
||||||
|
|
||||||
/* DMA descriptor for Memory to DMA-SHA transfer */
|
/* DMA descriptor for Memory to DMA-SHA transfer */
|
||||||
if (ilen) {
|
if (ilen) {
|
||||||
dma_descr_input.length = ilen;
|
s_dma_descr_input.length = ilen;
|
||||||
dma_descr_input.size = ilen;
|
s_dma_descr_input.size = ilen;
|
||||||
dma_descr_input.owner = 1;
|
s_dma_descr_input.owner = 1;
|
||||||
dma_descr_input.eof = 1;
|
s_dma_descr_input.eof = 1;
|
||||||
dma_descr_input.buf = (uint8_t *)input;
|
s_dma_descr_input.buf = (uint8_t *)input;
|
||||||
dma_descr_head = &dma_descr_input;
|
dma_descr_head = &s_dma_descr_input;
|
||||||
}
|
}
|
||||||
/* Check after input to overide head if there is any buf*/
|
/* Check after input to overide head if there is any buf*/
|
||||||
if (buf_len) {
|
if (buf_len) {
|
||||||
dma_descr_buf.length = buf_len;
|
s_dma_descr_buf.length = buf_len;
|
||||||
dma_descr_buf.size = buf_len;
|
s_dma_descr_buf.size = buf_len;
|
||||||
dma_descr_buf.owner = 1;
|
s_dma_descr_buf.owner = 1;
|
||||||
dma_descr_buf.eof = 1;
|
s_dma_descr_buf.eof = 1;
|
||||||
dma_descr_buf.buf = (uint8_t *)buf;
|
s_dma_descr_buf.buf = (uint8_t *)buf;
|
||||||
dma_descr_head = &dma_descr_buf;
|
dma_descr_head = &s_dma_descr_buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Link DMA lists */
|
/* Link DMA lists */
|
||||||
if (buf_len && ilen) {
|
if (buf_len && ilen) {
|
||||||
dma_descr_buf.eof = 0;
|
s_dma_descr_buf.eof = 0;
|
||||||
dma_descr_buf.empty = (uint32_t)(&dma_descr_input);
|
s_dma_descr_buf.empty = (uint32_t)(&s_dma_descr_input);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (esp_sha_dma_start(dma_descr_head) != ESP_OK) {
|
if (esp_sha_dma_start(dma_descr_head) != ESP_OK) {
|
||||||
|
@@ -12,6 +12,9 @@
|
|||||||
#include "esp_timer.h"
|
#include "esp_timer.h"
|
||||||
#include "esp_heap_caps.h"
|
#include "esp_heap_caps.h"
|
||||||
#include "test_utils.h"
|
#include "test_utils.h"
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/task.h"
|
||||||
|
#include "freertos/semphr.h"
|
||||||
|
|
||||||
static const uint8_t key_256[] = {
|
static const uint8_t key_256[] = {
|
||||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||||
@@ -296,7 +299,7 @@ TEST_CASE("mbedtls CFB-128 AES-256 test", "[aes]")
|
|||||||
free(decryptedtext);
|
free(decryptedtext);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("mbedtls CTR stream test", "[aes]")
|
static void aes_ctr_stream_test(void)
|
||||||
{
|
{
|
||||||
const unsigned SZ = 100;
|
const unsigned SZ = 100;
|
||||||
mbedtls_aes_context ctx;
|
mbedtls_aes_context ctx;
|
||||||
@@ -396,6 +399,11 @@ TEST_CASE("mbedtls CTR stream test", "[aes]")
|
|||||||
free(decryptedtext);
|
free(decryptedtext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("mbedtls CTR stream test", "[aes]")
|
||||||
|
{
|
||||||
|
aes_ctr_stream_test();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
TEST_CASE("mbedtls OFB stream test", "[aes]")
|
TEST_CASE("mbedtls OFB stream test", "[aes]")
|
||||||
{
|
{
|
||||||
@@ -773,24 +781,22 @@ TEST_CASE("mbedtls OFB, chained DMA descriptors", "[aes]")
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef CONFIG_SPIRAM_USE_MALLOC
|
const uint8_t expected_cipher_ctr_end[] = {
|
||||||
|
0x93, 0xca, 0xe0, 0x44, 0x96, 0x6d, 0xcb, 0xb2,
|
||||||
const uint8_t expected_cipher_psram_end[] = {
|
0xcf, 0x8a, 0x8d, 0x73, 0x8c, 0x6b, 0xfa, 0x4d,
|
||||||
0x7e, 0xdf, 0x13, 0xf3, 0x56, 0xef, 0x67, 0x01,
|
0xd6, 0xc4, 0x18, 0x49, 0xdd, 0xc6, 0xbf, 0xc2,
|
||||||
0xfc, 0x08, 0x49, 0x62, 0xfa, 0xfe, 0x0c, 0x8b,
|
0xb9, 0xf0, 0x09, 0x69, 0x45, 0x42, 0xc6, 0x05,
|
||||||
0x99, 0x39, 0x09, 0x51, 0x2c, 0x9a, 0xd5, 0x48,
|
|
||||||
0x4f, 0x76, 0xa2, 0x19, 0x2c, 0x08, 0x9d, 0x6a,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
void aes_psram_ctr_test(uint32_t input_buf_caps, uint32_t output_buf_caps)
|
void aes_ctr_alignment_test(uint32_t input_buf_caps, uint32_t output_buf_caps)
|
||||||
{
|
{
|
||||||
mbedtls_aes_context ctx;
|
mbedtls_aes_context ctx;
|
||||||
uint8_t nonce[16];
|
uint8_t nonce[16];
|
||||||
uint8_t key[16];
|
uint8_t key[16];
|
||||||
uint8_t stream_block[16];
|
uint8_t stream_block[16];
|
||||||
size_t SZ = 6000;
|
size_t SZ = 32*200;
|
||||||
size_t ALIGNMENT_SIZE_BYTES = 16;
|
size_t ALIGNMENT_SIZE_BYTES = 64;
|
||||||
memset(nonce, 0x2F, 16);
|
memset(nonce, 0x2F, 16);
|
||||||
memset(key, 0x1E, 16);
|
memset(key, 0x1E, 16);
|
||||||
|
|
||||||
@@ -815,7 +821,7 @@ void aes_psram_ctr_test(uint32_t input_buf_caps, uint32_t output_buf_caps)
|
|||||||
offset = 0;
|
offset = 0;
|
||||||
memset(nonce, 0x2F, 16);
|
memset(nonce, 0x2F, 16);
|
||||||
mbedtls_aes_crypt_ctr(&ctx, SZ, &offset, nonce, stream_block, plaintext + i, chipertext + i);
|
mbedtls_aes_crypt_ctr(&ctx, SZ, &offset, nonce, stream_block, plaintext + i, chipertext + i);
|
||||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_cipher_psram_end, chipertext + i + SZ - 32, 32);
|
TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_cipher_ctr_end, chipertext + i + SZ - 32, 32);
|
||||||
|
|
||||||
// Decrypt
|
// Decrypt
|
||||||
offset = 0;
|
offset = 0;
|
||||||
@@ -833,14 +839,23 @@ void aes_psram_ctr_test(uint32_t input_buf_caps, uint32_t output_buf_caps)
|
|||||||
free(decryptedtext);
|
free(decryptedtext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("mbedtls AES internal mem alignment tests", "[aes]")
|
||||||
|
{
|
||||||
|
uint32_t internal_dma_caps = MALLOC_CAP_DMA | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL;
|
||||||
|
aes_ctr_alignment_test(internal_dma_caps, internal_dma_caps);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef CONFIG_SPIRAM_USE_MALLOC
|
||||||
|
|
||||||
void aes_psram_one_buf_ctr_test(void)
|
void aes_psram_one_buf_ctr_test(void)
|
||||||
{
|
{
|
||||||
mbedtls_aes_context ctx;
|
mbedtls_aes_context ctx;
|
||||||
uint8_t nonce[16];
|
uint8_t nonce[16];
|
||||||
uint8_t key[16];
|
uint8_t key[16];
|
||||||
uint8_t stream_block[16];
|
uint8_t stream_block[16];
|
||||||
size_t SZ = 6000;
|
size_t SZ = 32*200;
|
||||||
size_t ALIGNMENT_SIZE_BYTES = 16;
|
size_t ALIGNMENT_SIZE_BYTES = 32;
|
||||||
memset(nonce, 0x2F, 16);
|
memset(nonce, 0x2F, 16);
|
||||||
memset(key, 0x1E, 16);
|
memset(key, 0x1E, 16);
|
||||||
|
|
||||||
@@ -862,7 +877,7 @@ void aes_psram_one_buf_ctr_test(void)
|
|||||||
memset(buf, 0x26, SZ + ALIGNMENT_SIZE_BYTES);
|
memset(buf, 0x26, SZ + ALIGNMENT_SIZE_BYTES);
|
||||||
memset(nonce, 0x2F, 16);
|
memset(nonce, 0x2F, 16);
|
||||||
mbedtls_aes_crypt_ctr(&ctx, SZ, &offset, nonce, stream_block, buf + i, buf + i);
|
mbedtls_aes_crypt_ctr(&ctx, SZ, &offset, nonce, stream_block, buf + i, buf + i);
|
||||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_cipher_psram_end, buf + i + SZ - 32, 32);
|
TEST_ASSERT_EQUAL_HEX8_ARRAY(expected_cipher_ctr_end, buf + i + SZ - 32, 32);
|
||||||
|
|
||||||
// Decrypt
|
// Decrypt
|
||||||
offset = 0;
|
offset = 0;
|
||||||
@@ -1444,9 +1459,9 @@ void aes_ext_flash_ctr_test(uint32_t output_buf_caps)
|
|||||||
/* Tests how crypto DMA handles data in external memory */
|
/* Tests how crypto DMA handles data in external memory */
|
||||||
TEST_CASE("mbedtls AES PSRAM tests", "[aes]")
|
TEST_CASE("mbedtls AES PSRAM tests", "[aes]")
|
||||||
{
|
{
|
||||||
aes_psram_ctr_test(MALLOC_CAP_DMA | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL, MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM);
|
aes_ctr_alignment_test(MALLOC_CAP_DMA | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL, MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM);
|
||||||
aes_psram_ctr_test(MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM, MALLOC_CAP_DMA | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL);
|
aes_ctr_alignment_test(MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM, MALLOC_CAP_DMA | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL);
|
||||||
aes_psram_ctr_test(MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM, MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM);
|
aes_ctr_alignment_test(MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM, MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM);
|
||||||
aes_psram_one_buf_ctr_test();
|
aes_psram_one_buf_ctr_test();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1457,3 +1472,32 @@ TEST_CASE("mbedtls AES external flash tests", "[aes]")
|
|||||||
aes_ext_flash_ctr_test(MALLOC_CAP_DMA | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL);
|
aes_ext_flash_ctr_test(MALLOC_CAP_DMA | MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL);
|
||||||
}
|
}
|
||||||
#endif // CONFIG_SPIRAM_USE_MALLOC
|
#endif // CONFIG_SPIRAM_USE_MALLOC
|
||||||
|
|
||||||
|
|
||||||
|
#if CONFIG_ESP_SYSTEM_RTC_FAST_MEM_AS_HEAP_DEPCHECK
|
||||||
|
|
||||||
|
RTC_FAST_ATTR uint8_t rtc_stack[4096];
|
||||||
|
static xSemaphoreHandle done_sem;
|
||||||
|
|
||||||
|
static void aes_ctr_stream_test_task(void *pv)
|
||||||
|
{
|
||||||
|
aes_ctr_stream_test();
|
||||||
|
xSemaphoreGive(done_sem);
|
||||||
|
vTaskDelete(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("mbedtls AES stack in RTC RAM", "[mbedtls]")
|
||||||
|
{
|
||||||
|
done_sem = xSemaphoreCreateBinary();
|
||||||
|
static StaticTask_t rtc_task;
|
||||||
|
memset(rtc_stack, 0, sizeof(rtc_stack));
|
||||||
|
|
||||||
|
TEST_ASSERT(esp_ptr_in_rtc_dram_fast(rtc_stack));
|
||||||
|
|
||||||
|
TEST_ASSERT_NOT_NULL(xTaskCreateStatic(aes_ctr_stream_test_task, "aes_ctr_task", sizeof(rtc_stack), NULL,
|
||||||
|
3, rtc_stack, &rtc_task));
|
||||||
|
TEST_ASSERT_TRUE(xSemaphoreTake(done_sem, 10000 / portTICK_PERIOD_MS));
|
||||||
|
vSemaphoreDelete(done_sem);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //CONFIG_ESP_SYSTEM_RTC_FAST_MEM_AS_HEAP_DEPCHECK
|
||||||
|
@@ -475,11 +475,11 @@ TEST_CASE("mbedtls SHA512/t", "[mbedtls]")
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif //CONFIG_MBEDTLS_HARDWARE_SHA
|
||||||
|
|
||||||
#ifdef CONFIG_SPIRAM
|
#ifdef CONFIG_SPIRAM_USE_MALLOC
|
||||||
TEST_CASE("mbedtls SHA256 PSRAM DMA", "[mbedtls]")
|
TEST_CASE("mbedtls SHA256 PSRAM DMA", "[mbedtls]")
|
||||||
{
|
{
|
||||||
|
|
||||||
const unsigned CALLS = 256;
|
const unsigned CALLS = 256;
|
||||||
const unsigned CALL_SZ = 16 * 1024;
|
const unsigned CALL_SZ = 16 * 1024;
|
||||||
mbedtls_sha256_context sha256_ctx;
|
mbedtls_sha256_context sha256_ctx;
|
||||||
@@ -510,6 +510,26 @@ TEST_CASE("mbedtls SHA256 PSRAM DMA", "[mbedtls]")
|
|||||||
TEST_ASSERT_EQUAL_STRING(expected_hash, hash_str);
|
TEST_ASSERT_EQUAL_STRING(expected_hash, hash_str);
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif //CONFIG_SPIRAM
|
#endif //CONFIG_SPIRAM_USE_MALLOC
|
||||||
|
|
||||||
#endif //CONFIG_MBEDTLS_HARDWARE_SHA
|
#if CONFIG_ESP_SYSTEM_RTC_FAST_MEM_AS_HEAP_DEPCHECK
|
||||||
|
|
||||||
|
extern RTC_FAST_ATTR uint8_t rtc_stack[4096];
|
||||||
|
|
||||||
|
static xSemaphoreHandle done_sem;
|
||||||
|
|
||||||
|
TEST_CASE("mbedtls SHA stack in RTC RAM", "[mbedtls]")
|
||||||
|
{
|
||||||
|
done_sem = xSemaphoreCreateBinary();
|
||||||
|
static StaticTask_t rtc_task;
|
||||||
|
memset(rtc_stack, 0, sizeof(rtc_stack));
|
||||||
|
|
||||||
|
TEST_ASSERT(esp_ptr_in_rtc_dram_fast(rtc_stack));
|
||||||
|
|
||||||
|
TEST_ASSERT_NOT_NULL(xTaskCreateStatic(tskRunSHA256Test, "tskRunSHA256Test_task", sizeof(rtc_stack), NULL,
|
||||||
|
3, rtc_stack, &rtc_task));
|
||||||
|
TEST_ASSERT_TRUE(xSemaphoreTake(done_sem, 10000 / portTICK_PERIOD_MS));
|
||||||
|
vSemaphoreDelete(done_sem);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //CONFIG_ESP_SYSTEM_RTC_FAST_MEM_AS_HEAP_DEPCHECK
|
||||||
|
@@ -54,6 +54,7 @@
|
|||||||
#define SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS 3
|
#define SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS 3
|
||||||
|
|
||||||
#define SOC_CACHE_SUPPORT_WRAP 1
|
#define SOC_CACHE_SUPPORT_WRAP 1
|
||||||
|
#define SOC_PSRAM_DMA_CAPABLE 1
|
||||||
|
|
||||||
/*-------------------------- ADC CAPS ----------------------------------------*/
|
/*-------------------------- ADC CAPS ----------------------------------------*/
|
||||||
#define SOC_ADC_PERIPH_NUM (2)
|
#define SOC_ADC_PERIPH_NUM (2)
|
||||||
|
@@ -19,6 +19,7 @@
|
|||||||
#define SOC_DIG_SIGN_SUPPORTED 1
|
#define SOC_DIG_SIGN_SUPPORTED 1
|
||||||
#define SOC_HMAC_SUPPORTED 1
|
#define SOC_HMAC_SUPPORTED 1
|
||||||
#define SOC_ASYNC_MEMCPY_SUPPORTED 1
|
#define SOC_ASYNC_MEMCPY_SUPPORTED 1
|
||||||
|
#define SOC_PSRAM_DMA_CAPABLE 1
|
||||||
#define SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS 3
|
#define SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS 3
|
||||||
|
|
||||||
/*-------------------------- ADC CAPS ----------------------------------------*/
|
/*-------------------------- ADC CAPS ----------------------------------------*/
|
||||||
|
@@ -31,6 +31,24 @@
|
|||||||
/** Maximum size of data in the buffer that a DMA descriptor can hold. */
|
/** Maximum size of data in the buffer that a DMA descriptor can hold. */
|
||||||
#define LLDESC_MAX_NUM_PER_DESC (4096-4)
|
#define LLDESC_MAX_NUM_PER_DESC (4096-4)
|
||||||
|
|
||||||
|
// Some DMA operations might impose certain alignment restrictions on the length
|
||||||
|
#define LLDESC_MAX_NUM_PER_DESC_16B_ALIGNED (4096 - 16)
|
||||||
|
#define LLDESC_MAX_NUM_PER_DESC_32B_ALIGNED (4096 - 32)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a linked list pointing to a (huge) buffer in an descriptor array.
|
||||||
|
*
|
||||||
|
* The caller should ensure there is enough size to hold the array, by calling
|
||||||
|
* ``lldesc_get_required_num_constrained`` with the same max_desc_size argument.
|
||||||
|
*
|
||||||
|
* @param[out] out_desc_array Output of a descriptor array, the head should be fed to the DMA.
|
||||||
|
* @param buffer Buffer for the descriptors to point to.
|
||||||
|
* @param size Size (or length for TX) of the buffer
|
||||||
|
* @param max_desc_size Maximum length of each descriptor
|
||||||
|
* @param isrx The RX DMA may require the buffer to be word-aligned, set to true for a RX link, otherwise false.
|
||||||
|
*/
|
||||||
|
void lldesc_setup_link_constrained(lldesc_t *out_desc_array, const void *buffer, int size, int max_desc_size, bool isrx);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate a linked list pointing to a (huge) buffer in an descriptor array.
|
* Generate a linked list pointing to a (huge) buffer in an descriptor array.
|
||||||
*
|
*
|
||||||
@@ -42,7 +60,7 @@
|
|||||||
* @param size Size (or length for TX) of the buffer
|
* @param size Size (or length for TX) of the buffer
|
||||||
* @param isrx The RX DMA may require the buffer to be word-aligned, set to true for a RX link, otherwise false.
|
* @param isrx The RX DMA may require the buffer to be word-aligned, set to true for a RX link, otherwise false.
|
||||||
*/
|
*/
|
||||||
void lldesc_setup_link(lldesc_t *out_desc_array, const void *buffer, int size, bool isrx);
|
#define lldesc_setup_link(out_desc_array, buffer, size, isrx) lldesc_setup_link_constrained(out_desc_array, buffer, size, LLDESC_MAX_NUM_PER_DESC, isrx)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the received length of a linked list, until end of the link or eof.
|
* @brief Get the received length of a linked list, until end of the link or eof.
|
||||||
@@ -54,6 +72,18 @@ void lldesc_setup_link(lldesc_t *out_desc_array, const void *buffer, int size, b
|
|||||||
*/
|
*/
|
||||||
int lldesc_get_received_len(lldesc_t* head, lldesc_t** out_next);
|
int lldesc_get_received_len(lldesc_t* head, lldesc_t** out_next);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the number of descriptors required for a given buffer size.
|
||||||
|
*
|
||||||
|
* @param data_size Size to check descriptor num.
|
||||||
|
* @param max_desc_size Maximum length of each descriptor
|
||||||
|
* @return Numbers required.
|
||||||
|
*/
|
||||||
|
static inline int lldesc_get_required_num_constrained(int data_size, int max_desc_size)
|
||||||
|
{
|
||||||
|
return (data_size + max_desc_size - 1) / max_desc_size;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the number of descriptors required for a given buffer size.
|
* Get the number of descriptors required for a given buffer size.
|
||||||
*
|
*
|
||||||
@@ -61,7 +91,4 @@ int lldesc_get_received_len(lldesc_t* head, lldesc_t** out_next);
|
|||||||
*
|
*
|
||||||
* @return Numbers required.
|
* @return Numbers required.
|
||||||
*/
|
*/
|
||||||
static inline int lldesc_get_required_num(int data_size)
|
#define lldesc_get_required_num(data_size) lldesc_get_required_num_constrained(data_size, LLDESC_MAX_NUM_PER_DESC)
|
||||||
{
|
|
||||||
return (data_size + LLDESC_MAX_NUM_PER_DESC - 1) / LLDESC_MAX_NUM_PER_DESC;
|
|
||||||
}
|
|
||||||
|
@@ -1,12 +1,12 @@
|
|||||||
#include "soc/lldesc.h"
|
#include "soc/lldesc.h"
|
||||||
|
|
||||||
void lldesc_setup_link(lldesc_t *dmadesc, const void *data, int len, bool isrx)
|
void lldesc_setup_link_constrained(lldesc_t *dmadesc, const void *data, int len, int max_desc_size, bool isrx)
|
||||||
{
|
{
|
||||||
int n = 0;
|
int n = 0;
|
||||||
while (len) {
|
while (len) {
|
||||||
int dmachunklen = len;
|
int dmachunklen = len;
|
||||||
if (dmachunklen > LLDESC_MAX_NUM_PER_DESC) {
|
if (dmachunklen > max_desc_size) {
|
||||||
dmachunklen = LLDESC_MAX_NUM_PER_DESC;
|
dmachunklen = max_desc_size;
|
||||||
}
|
}
|
||||||
if (isrx) {
|
if (isrx) {
|
||||||
//Receive needs DMA length rounded to next 32-bit boundary
|
//Receive needs DMA length rounded to next 32-bit boundary
|
||||||
|
@@ -1810,8 +1810,6 @@ components/heap/test_multi_heap_host/test_multi_heap.cpp
|
|||||||
components/idf_test/include/esp32/idf_performance_target.h
|
components/idf_test/include/esp32/idf_performance_target.h
|
||||||
components/idf_test/include/esp32c3/idf_performance_target.h
|
components/idf_test/include/esp32c3/idf_performance_target.h
|
||||||
components/idf_test/include/esp32h2/idf_performance_target.h
|
components/idf_test/include/esp32h2/idf_performance_target.h
|
||||||
components/idf_test/include/esp32s2/idf_performance_target.h
|
|
||||||
components/idf_test/include/esp32s3/idf_performance_target.h
|
|
||||||
components/idf_test/include/idf_performance.h
|
components/idf_test/include/idf_performance.h
|
||||||
components/ieee802154/include/esp_ieee802154.h
|
components/ieee802154/include/esp_ieee802154.h
|
||||||
components/ieee802154/include/esp_ieee802154_types.h
|
components/ieee802154/include/esp_ieee802154_types.h
|
||||||
|
Reference in New Issue
Block a user