mirror of
https://github.com/espressif/esp-idf.git
synced 2026-04-27 19:13:21 +00:00
feat(esp-tls): Add crypto callbacks to custom TLS stack interface
Added crypto_sha1 and crypto_base64_encode callbacks to esp_tls_stack_ops_t to allow custom TLS stacks to provide implementations for esp_crypto_* APIs.
This commit is contained in:
@@ -17,8 +17,6 @@ endif()
|
||||
idf_component_register(SRCS "${srcs}"
|
||||
INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} esp-tls-crypto
|
||||
PRIV_INCLUDE_DIRS "private_include"
|
||||
# mbedtls is public requirements because esp_tls.h
|
||||
# includes mbedtls header files.
|
||||
REQUIRES mbedtls
|
||||
PRIV_REQUIRES ${priv_req})
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2020-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -8,15 +8,21 @@
|
||||
#include "esp_log.h"
|
||||
#include "esp_err.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#if CONFIG_ESP_TLS_USING_MBEDTLS
|
||||
#include "mbedtls/base64.h"
|
||||
#include "mbedtls/error.h"
|
||||
#include "psa/crypto.h"
|
||||
#endif
|
||||
|
||||
__attribute__((unused)) static const char *TAG = "esp_crypto";
|
||||
#if CONFIG_ESP_TLS_CUSTOM_STACK
|
||||
#include "esp_tls_custom_stack.h"
|
||||
#endif
|
||||
|
||||
static int esp_crypto_sha1_mbedtls( const unsigned char *input,
|
||||
size_t ilen,
|
||||
unsigned char output[20])
|
||||
#if CONFIG_ESP_TLS_USING_MBEDTLS
|
||||
static int esp_crypto_sha1_mbedtls(const unsigned char *input,
|
||||
size_t ilen,
|
||||
unsigned char output[20])
|
||||
{
|
||||
#if CONFIG_MBEDTLS_SHA1_C || CONFIG_MBEDTLS_HARDWARE_SHA
|
||||
psa_hash_operation_t ctx = PSA_HASH_OPERATION_INIT;
|
||||
@@ -39,27 +45,52 @@ exit:
|
||||
psa_hash_abort(&ctx);
|
||||
return status == PSA_SUCCESS ? 0 : -1;
|
||||
#else
|
||||
ESP_LOGE(TAG, "Please enable CONFIG_MBEDTLS_SHA1_C or CONFIG_MBEDTLS_HARDWARE_SHA to support SHA1 operations");
|
||||
ESP_LOGE("esp_crypto", "Please enable CONFIG_MBEDTLS_SHA1_C or CONFIG_MBEDTLS_HARDWARE_SHA to support SHA1 operations");
|
||||
return MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED;
|
||||
#endif /* CONFIG_MBEDTLS_SHA1_C || CONFIG_MBEDTLS_HARDWARE_SHA*/
|
||||
}
|
||||
|
||||
static int esp_crypto_bas64_encode_mbedtls( unsigned char *dst, size_t dlen,
|
||||
size_t *olen, const unsigned char *src,
|
||||
size_t slen)
|
||||
static int esp_crypto_base64_encode_mbedtls(unsigned char *dst, size_t dlen,
|
||||
size_t *olen, const unsigned char *src,
|
||||
size_t slen)
|
||||
{
|
||||
return mbedtls_base64_encode(dst, dlen, olen, src, slen);
|
||||
}
|
||||
#endif /* CONFIG_ESP_TLS_USING_MBEDTLS */
|
||||
|
||||
int esp_crypto_sha1( const unsigned char *input,
|
||||
size_t ilen,
|
||||
unsigned char output[20])
|
||||
int esp_crypto_sha1(const unsigned char *input,
|
||||
size_t ilen,
|
||||
unsigned char output[20])
|
||||
{
|
||||
#if CONFIG_ESP_TLS_USING_MBEDTLS
|
||||
return esp_crypto_sha1_mbedtls(input, ilen, output);
|
||||
#elif CONFIG_ESP_TLS_CUSTOM_STACK
|
||||
int ret = esp_tls_custom_stack_crypto_sha1(input, ilen, output);
|
||||
if (ret == ESP_ERR_NOT_SUPPORTED) {
|
||||
ESP_LOGE("esp_crypto", "Custom TLS stack must implement crypto_sha1 callback");
|
||||
return -1;
|
||||
}
|
||||
return ret;
|
||||
#else
|
||||
ESP_LOGE("esp_crypto", "No TLS stack configured");
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
int esp_crypto_base64_encode(unsigned char *dst, size_t dlen, size_t *olen,
|
||||
const unsigned char *src, size_t slen )
|
||||
const unsigned char *src, size_t slen)
|
||||
{
|
||||
return esp_crypto_bas64_encode_mbedtls(dst, dlen, olen, src, slen);
|
||||
#if CONFIG_ESP_TLS_USING_MBEDTLS
|
||||
return esp_crypto_base64_encode_mbedtls(dst, dlen, olen, src, slen);
|
||||
#elif CONFIG_ESP_TLS_CUSTOM_STACK
|
||||
int ret = esp_tls_custom_stack_crypto_base64_encode(dst, dlen, olen, src, slen);
|
||||
if (ret == ESP_ERR_NOT_SUPPORTED) {
|
||||
ESP_LOGE("esp_crypto", "Custom TLS stack must implement crypto_base64_encode callback");
|
||||
return -1;
|
||||
}
|
||||
return ret;
|
||||
#else
|
||||
ESP_LOGE("esp_crypto", "No TLS stack configured");
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -230,11 +230,30 @@ int esp_tls_custom_stack_server_session_continue_async(esp_tls_t *tls)
|
||||
|
||||
void esp_tls_custom_stack_server_session_delete(esp_tls_t *tls)
|
||||
{
|
||||
if (s_esp_tls_custom_stack == NULL || !s_esp_tls_custom_stack->server_session_delete) {
|
||||
ESP_LOGE(TAG, "No TLS stack registered or server session not supported.");
|
||||
return;
|
||||
CHECK_STACK_REGISTERED_VOID();
|
||||
if (s_esp_tls_custom_stack->server_session_delete) {
|
||||
s_esp_tls_custom_stack->server_session_delete(s_esp_tls_custom_stack_user_ctx, tls);
|
||||
} else {
|
||||
/* Fall back to conn_delete as documented */
|
||||
s_esp_tls_custom_stack->conn_delete(s_esp_tls_custom_stack_user_ctx, tls);
|
||||
}
|
||||
s_esp_tls_custom_stack->server_session_delete(s_esp_tls_custom_stack_user_ctx, tls);
|
||||
}
|
||||
|
||||
int esp_tls_custom_stack_crypto_sha1(const unsigned char *input, size_t ilen, unsigned char output[20])
|
||||
{
|
||||
if (s_esp_tls_custom_stack == NULL || !s_esp_tls_custom_stack->crypto_sha1) {
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
return s_esp_tls_custom_stack->crypto_sha1(s_esp_tls_custom_stack_user_ctx, input, ilen, output);
|
||||
}
|
||||
|
||||
int esp_tls_custom_stack_crypto_base64_encode(unsigned char *dst, size_t dlen, size_t *olen,
|
||||
const unsigned char *src, size_t slen)
|
||||
{
|
||||
if (s_esp_tls_custom_stack == NULL || !s_esp_tls_custom_stack->crypto_base64_encode) {
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
return s_esp_tls_custom_stack->crypto_base64_encode(s_esp_tls_custom_stack_user_ctx, dst, dlen, olen, src, slen);
|
||||
}
|
||||
|
||||
#else /* CONFIG_ESP_TLS_CUSTOM_STACK */
|
||||
|
||||
@@ -478,15 +478,63 @@ typedef struct esp_tls_stack_ops {
|
||||
* @note If NULL, conn_delete() will be used instead.
|
||||
*/
|
||||
void (*server_session_delete)(void *user_ctx, esp_tls_t *tls);
|
||||
|
||||
/**
|
||||
* @brief Calculate SHA1 hash (optional, for esp_crypto_sha1 API)
|
||||
*
|
||||
* This function calculates the SHA1 hash of the input data. It is used by
|
||||
* esp_crypto_sha1() API which is needed by components like esp_http_server
|
||||
* for WebSocket key calculation.
|
||||
*
|
||||
* @param user_ctx User context pointer passed to esp_tls_register_stack()
|
||||
* @param input Input data buffer
|
||||
* @param ilen Length of input data
|
||||
* @param output Output buffer for SHA1 hash (must be at least 20 bytes)
|
||||
*
|
||||
* @return
|
||||
* - 0: Success
|
||||
* - Negative value: Error occurred
|
||||
*
|
||||
* @note If NULL, esp_crypto_sha1() API calls will fail. This callback must be implemented
|
||||
* if your application or any dependent component (e.g., esp_http_server for WebSocket)
|
||||
* uses the esp_crypto_sha1() API.
|
||||
*/
|
||||
int (*crypto_sha1)(void *user_ctx, const unsigned char *input, size_t ilen, unsigned char output[20]);
|
||||
|
||||
/**
|
||||
* @brief Base64 encode data (optional, for esp_crypto_base64_encode API)
|
||||
*
|
||||
* This function performs Base64 encoding of the source data. It is used by
|
||||
* esp_crypto_base64_encode() API which is needed by components like esp_http_server
|
||||
* for WebSocket key encoding.
|
||||
*
|
||||
* @param user_ctx User context pointer passed to esp_tls_register_stack()
|
||||
* @param dst Destination buffer for encoded data
|
||||
* @param dlen Size of destination buffer
|
||||
* @param olen Pointer to store the number of bytes written
|
||||
* @param src Source data buffer
|
||||
* @param slen Length of source data
|
||||
*
|
||||
* @return
|
||||
* - 0: Success
|
||||
* - -0x002A: Buffer too small
|
||||
* - Other negative value: Error occurred
|
||||
*
|
||||
* @note If NULL, esp_crypto_base64_encode() API calls will fail. This callback must be
|
||||
* implemented if your application or any dependent component (e.g., esp_http_server
|
||||
* for WebSocket) uses the esp_crypto_base64_encode() API.
|
||||
*/
|
||||
int (*crypto_base64_encode)(void *user_ctx, unsigned char *dst, size_t dlen, size_t *olen,
|
||||
const unsigned char *src, size_t slen);
|
||||
} esp_tls_stack_ops_t;
|
||||
|
||||
/**
|
||||
* Compile-time check to detect structure layout changes.
|
||||
* If this assertion fails, you MUST increment ESP_TLS_STACK_OPS_VERSION.
|
||||
*
|
||||
* Field count: 1 (version) + 21 (function pointers) = 22
|
||||
* Field count: 1 (version) + 23 (function pointers) = 24
|
||||
*/
|
||||
ESP_STATIC_ASSERT(sizeof(esp_tls_stack_ops_t) == 22 * sizeof(void *), "esp_tls_stack_ops_t layout changed - update ESP_TLS_STACK_OPS_VERSION!");
|
||||
ESP_STATIC_ASSERT(sizeof(esp_tls_stack_ops_t) == 24 * sizeof(void *), "esp_tls_stack_ops_t layout changed - update ESP_TLS_STACK_OPS_VERSION!");
|
||||
|
||||
/**
|
||||
* @brief Register a custom TLS stack implementation
|
||||
@@ -672,6 +720,13 @@ int esp_tls_custom_stack_server_session_continue_async(esp_tls_t *tls);
|
||||
/** @brief Delete server session */
|
||||
void esp_tls_custom_stack_server_session_delete(esp_tls_t *tls);
|
||||
|
||||
/** @brief Calculate SHA1 hash using registered stack's implementation */
|
||||
int esp_tls_custom_stack_crypto_sha1(const unsigned char *input, size_t ilen, unsigned char output[20]);
|
||||
|
||||
/** @brief Base64 encode using registered stack's implementation */
|
||||
int esp_tls_custom_stack_crypto_base64_encode(unsigned char *dst, size_t dlen, size_t *olen,
|
||||
const unsigned char *src, size_t slen);
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
Reference in New Issue
Block a user