diff --git a/.gitmodules b/.gitmodules index 1d7815356..64828e742 100644 --- a/.gitmodules +++ b/.gitmodules @@ -82,3 +82,7 @@ [submodule "components/tinyusb/tinyusb"] path = components/tinyusb/tinyusb url = ../../espressif/tinyusb.git + +[submodule "examples/peripherals/secure_element/atecc608_ecdsa/components/esp-cryptoauthlib"] + path = examples/peripherals/secure_element/atecc608_ecdsa/components/esp-cryptoauthlib + url = ../../espressif/esp-cryptoauthlib.git diff --git a/components/esp-tls/CMakeLists.txt b/components/esp-tls/CMakeLists.txt index bf32e96ea..d8a73c145 100644 --- a/components/esp-tls/CMakeLists.txt +++ b/components/esp-tls/CMakeLists.txt @@ -19,3 +19,8 @@ if(CONFIG_ESP_TLS_USING_WOLFSSL) idf_component_get_property(wolfssl esp-wolfssl COMPONENT_LIB) target_link_libraries(${COMPONENT_LIB} PUBLIC ${wolfssl}) endif() + +if(CONFIG_ESP_TLS_USE_SE) + idf_component_get_property(cryptoauthlib esp-cryptoauthlib COMPONENT_LIB) + target_link_libraries(${COMPONENT_LIB} PUBLIC ${cryptoauthlib}) +endif() diff --git a/components/esp-tls/Kconfig b/components/esp-tls/Kconfig index 2ae7a0727..1f20cc6cf 100644 --- a/components/esp-tls/Kconfig +++ b/components/esp-tls/Kconfig @@ -13,6 +13,17 @@ menu "ESP-TLS" bool "wolfSSL (License info in wolfSSL directory README)" endchoice + config ESP_TLS_USE_SECURE_ELEMENT + bool "Use Secure Element (ATECC608A) with ESP-TLS" + depends on IDF_TARGET_ESP32 && ESP_TLS_USING_MBEDTLS + select ATCA_MBEDTLS_ECDSA + select ATCA_MBEDTLS_ECDSA_SIGN + select ATCA_MBEDTLS_ECDSA_VERIFY + default n + help + Enable use of Secure Element for ESP-TLS, this enables internal support for + ATECC608A peripheral on ESPWROOM32SE, which can be used for TLS connection. + config ESP_TLS_SERVER bool "Enable ESP-TLS Server" default n diff --git a/components/esp-tls/esp_tls.h b/components/esp-tls/esp_tls.h index f2f641b95..109417004 100644 --- a/components/esp-tls/esp_tls.h +++ b/components/esp-tls/esp_tls.h @@ -64,6 +64,7 @@ extern "C" { #define ESP_ERR_WOLFSSL_SSL_SETUP_FAILED (ESP_ERR_ESP_TLS_BASE + 0x19) /*!< wolfSSL api returned failed */ #define ESP_ERR_WOLFSSL_SSL_WRITE_FAILED (ESP_ERR_ESP_TLS_BASE + 0x1A) /*!< wolfSSL api returned failed */ +#define ESP_ERR_ESP_TLS_SE_FAILED (ESP_ERR_ESP_TLS_BASE + 0x1B) /*< esp-tls use Secure Element returned failed */ #ifdef CONFIG_ESP_TLS_USING_MBEDTLS #define ESP_TLS_ERR_SSL_WANT_READ MBEDTLS_ERR_SSL_WANT_READ #define ESP_TLS_ERR_SSL_WANT_WRITE MBEDTLS_ERR_SSL_WANT_WRITE @@ -183,6 +184,9 @@ typedef struct esp_tls_cfg { underneath socket will be configured in non blocking mode after tls session is established */ + bool use_secure_element; /*!< Enable this option to use secure element or + atecc608a chip ( Integrated with ESP32-WROOM-32SE ) */ + int timeout_ms; /*!< Network timeout in milliseconds */ bool use_global_ca_store; /*!< Use a global ca_store for all the connections in which diff --git a/components/esp-tls/esp_tls_mbedtls.c b/components/esp-tls/esp_tls_mbedtls.c index 245921fd0..2b6e697b8 100644 --- a/components/esp-tls/esp_tls_mbedtls.c +++ b/components/esp-tls/esp_tls_mbedtls.c @@ -30,6 +30,19 @@ #include "esp_crt_bundle.h" #endif +#ifdef CONFIG_ESP_TLS_USE_SECURE_ELEMENT + +#define ATECC608A_TNG_SLAVE_ADDR 0x6A +#define ATECC608A_TFLEX_SLAVE_ADDR 0x6C +#define ATECC608A_TCUSTOM_SLAVE_ADDR 0xC0 +/* cryptoauthlib includes */ +#include "mbedtls/atca_mbedtls_wrap.h" +#include "tng_atca.h" +#include "cryptoauthlib.h" +static const atcacert_def_t* cert_def = NULL; +/* Prototypes for functions */ +static esp_err_t esp_set_atecc608a_pki_context(esp_tls_t *tls, esp_tls_cfg_t *cfg); +#endif /* CONFIG_ESP_TLS_USE_SECURE_ELEMENT */ static const char *TAG = "esp-tls-mbedtls"; static mbedtls_x509_crt *global_cacert = NULL; @@ -231,6 +244,9 @@ void esp_mbedtls_cleanup(esp_tls_t *tls) mbedtls_ssl_config_free(&tls->conf); mbedtls_ctr_drbg_free(&tls->ctr_drbg); mbedtls_ssl_free(&tls->ssl); +#ifdef CONFIG_ESP_TLS_USE_SECURE_ELEMENT + atcab_release(); +#endif } static esp_err_t set_ca_cert(esp_tls_t *tls, const unsigned char *cacert, size_t cacert_len) @@ -448,7 +464,17 @@ esp_err_t set_client_config(const char *hostname, size_t hostlen, esp_tls_cfg_t mbedtls_ssl_conf_authmode(&tls->conf, MBEDTLS_SSL_VERIFY_NONE); } - if (cfg->clientcert_buf != NULL && cfg->clientkey_buf != NULL) { + if (cfg->use_secure_element) { +#ifdef CONFIG_ESP_TLS_USE_SECURE_ELEMENT + ret = esp_set_atecc608a_pki_context(tls, (esp_tls_cfg_t *)cfg); + if (ret != ESP_OK) { + return ret; + } +#else + ESP_LOGE(TAG, "Please enable secure element support for ESP-TLS in menuconfig"); + return ESP_FAIL; +#endif /* CONFIG_ESP_TLS_USE_SECURE_ELEMENT */ + } else if (cfg->clientcert_pem_buf != NULL && cfg->clientkey_pem_buf != NULL) { esp_tls_pki_t pki = { .public_cert = &tls->clientcert, .pk_key = &tls->clientkey, @@ -564,3 +590,81 @@ void esp_mbedtls_free_global_ca_store(void) global_cacert = NULL; } } + +#ifdef CONFIG_ESP_TLS_USE_SECURE_ELEMENT +static esp_err_t esp_init_atecc608a(uint8_t slave_addr) +{ + cfg_ateccx08a_i2c_default.atcai2c.slave_address = slave_addr; + int ret = atcab_init(&cfg_ateccx08a_i2c_default); + if(ret != 0) { + ESP_LOGE(TAG, "Failed\n !atcab_init returned %02x", ret); + return ESP_FAIL; + } + return ESP_OK; +} + +static esp_err_t esp_set_atecc608a_pki_context(esp_tls_t *tls, esp_tls_cfg_t *cfg) +{ + int ret = 0; + int esp_ret = ESP_FAIL; + ESP_LOGI(TAG, "Initialize the ATECC interface..."); +#if defined(CONFIG_ATECC608A_TNG) || defined(CONFIG_ATECC608A_TFLEX) +#ifdef CONFIG_ATECC608A_TNG + esp_ret = esp_init_atecc608a(ATECC608A_TNG_SLAVE_ADDR); + if (ret != ESP_OK) { + return ESP_ERR_ESP_TLS_SE_FAILED; + } +#elif CONFIG_ATECC608A_TFLEX /* CONFIG_ATECC608A_TNG */ + esp_ret = esp_init_atecc608a(ATECC608A_TFLEX_SLAVE_ADDR); + if (ret != ESP_OK) { + return ESP_ERR_ESP_TLS_SE_FAILED; + } +#endif /* CONFIG_ATECC608A_TFLEX */ + mbedtls_x509_crt_init(&tls->clientcert); + ret = tng_get_device_cert_def(&cert_def); + if (ret != 0) { + ESP_LOGE(TAG, "Failed to get device cert def"); + return ESP_ERR_ESP_TLS_SE_FAILED; + } + + /* Extract the device certificate and convert to mbedtls cert */ + ret = atca_mbedtls_cert_add(&tls->clientcert, cert_def); + if (ret != 0) { + ESP_LOGE(TAG, "Failed to parse cert from device, return %02x", ret); + return ESP_ERR_ESP_TLS_SE_FAILED; + } +#elif CONFIG_ATECC608A_TCUSTOM + esp_ret = esp_init_atecc608a(ATECC608A_TCUSTOM_SLAVE_ADDR); + if (ret != ESP_OK) { + return ESP_ERR_ESP_TLS_SE_FAILED; + } + mbedtls_x509_crt_init(&tls->clientcert); + + if(cfg->clientcert_buf != NULL) { + ret = mbedtls_x509_crt_parse(&tls->clientcert, (const unsigned char*)cfg->clientcert_buf, cfg->clientcert_bytes); + if (ret < 0) { + ESP_LOGE(TAG, "mbedtls_x509_crt_parse returned -0x%x", -ret); + ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ERR_TYPE_MBEDTLS, -ret); + return ESP_ERR_MBEDTLS_X509_CRT_PARSE_FAILED; + } + } else { + ESP_LOGE(TAG, "Device certificate must be provided for TrustCustom Certs"); + return ESP_FAIL; + } +#endif /* CONFIG_ATECC608A_TCUSTOM */ + ret = atca_mbedtls_pk_init(&tls->clientkey, 0); + if (ret != 0) { + ESP_LOGE(TAG, "Failed to parse key from device"); + ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ERR_TYPE_MBEDTLS, -ret); + return ESP_ERR_ESP_TLS_SE_FAILED; + } + + ret = mbedtls_ssl_conf_own_cert(&tls->conf, &tls->clientcert, &tls->clientkey); + if (ret != 0) { + ESP_LOGE(TAG, "Failed\n ! mbedtls_ssl_conf_own_cert returned -0x%x", ret); + ESP_INT_EVENT_TRACKER_CAPTURE(tls->error_handle, ERR_TYPE_MBEDTLS, -ret); + return ESP_ERR_ESP_TLS_SE_FAILED; + } + return ESP_OK; +} +#endif /* CONFIG_ESP_TLS_USE_SECURE_ELEMENT */ diff --git a/components/esp_common/src/esp_err_to_name.c b/components/esp_common/src/esp_err_to_name.c index cf05b05df..daf22a1ec 100644 --- a/components/esp_common/src/esp_err_to_name.c +++ b/components/esp_common/src/esp_err_to_name.c @@ -643,6 +643,9 @@ static const esp_err_msg_t esp_err_msg_table[] = { # endif # ifdef ESP_ERR_WOLFSSL_SSL_WRITE_FAILED ERR_TBL_IT(ESP_ERR_WOLFSSL_SSL_WRITE_FAILED), /* 32794 0x801a wolfSSL api returned failed */ +# endif +# ifdef ESP_ERR_ESP_TLS_SE_FAILED + ERR_TBL_IT(ESP_ERR_ESP_TLS_SE_FAILED), /* 32795 0x801b */ # endif // components/esp_https_ota/include/esp_https_ota.h # ifdef ESP_ERR_HTTPS_OTA_BASE diff --git a/components/mbedtls/CMakeLists.txt b/components/mbedtls/CMakeLists.txt index 0eac1a12d..597c70495 100644 --- a/components/mbedtls/CMakeLists.txt +++ b/components/mbedtls/CMakeLists.txt @@ -122,4 +122,8 @@ set_property(TARGET mbedcrypto APPEND PROPERTY LINK_INTERFACE_LIBRARIES mbedtls) # Link mbedtls libraries to component library target_link_libraries(${COMPONENT_LIB} INTERFACE ${mbedtls_targets}) - +# Link esp-cryptoauthlib to mbedtls +if(CONFIG_ATCA_MBEDTLS_ECDSA) + idf_component_get_property(cryptoauthlib esp-cryptoauthlib COMPONENT_LIB) + target_link_libraries(${COMPONENT_LIB} PUBLIC ${cryptoauthlib}) +endif() diff --git a/components/mbedtls/Kconfig b/components/mbedtls/Kconfig index de1f3d29e..6c7a20322 100644 --- a/components/mbedtls/Kconfig +++ b/components/mbedtls/Kconfig @@ -280,6 +280,20 @@ menu "mbedTLS" SHA hardware acceleration is faster than software in some situations but slower in others. You should benchmark to find the best setting for you. + config MBEDTLS_ATCA_HW_ECDSA_SIGN + bool "Enable hardware ECDSA sign acceleration when using ATECC608A" + default n + help + This option enables hardware acceleration for ECDSA sign function, only + when using ATECC608A cryptoauth chip (integrated with ESP32-WROOM-32SE) + + config MBEDTLS_ATCA_HW_ECDSA_VERIFY + bool "Enable hardware ECDSA verify acceleration when using ATECC608A" + default n + help + This option enables hardware acceleration for ECDSA sign function, only + when using ATECC608A cryptoauth chip (integrated with ESP32-WROOM-32SE) + config MBEDTLS_HAVE_TIME bool "Enable mbedtls time" depends on !ESP32_TIME_SYSCALL_USE_NONE @@ -650,14 +664,14 @@ menu "mbedTLS" config MBEDTLS_ECP_DP_SECP192R1_ENABLED bool "Enable SECP192R1 curve" depends on MBEDTLS_ECP_C - default y + default y if !(MBEDTLS_ATCA_HW_ECDSA_SIGN || MBEDTLS_ATCA_HW_ECDSA_VERIFY) help Enable support for SECP192R1 Elliptic Curve. config MBEDTLS_ECP_DP_SECP224R1_ENABLED bool "Enable SECP224R1 curve" depends on MBEDTLS_ECP_C - default y + default y if !(MBEDTLS_ATCA_HW_ECDSA_SIGN || MBEDTLS_ATCA_HW_ECDSA_VERIFY) help Enable support for SECP224R1 Elliptic Curve. @@ -671,63 +685,63 @@ menu "mbedTLS" config MBEDTLS_ECP_DP_SECP384R1_ENABLED bool "Enable SECP384R1 curve" depends on MBEDTLS_ECP_C - default y + default y if !(MBEDTLS_ATCA_HW_ECDSA_SIGN || MBEDTLS_ATCA_HW_ECDSA_VERIFY) help Enable support for SECP384R1 Elliptic Curve. config MBEDTLS_ECP_DP_SECP521R1_ENABLED bool "Enable SECP521R1 curve" depends on MBEDTLS_ECP_C - default y + default y if !(MBEDTLS_ATCA_HW_ECDSA_SIGN || MBEDTLS_ATCA_HW_ECDSA_VERIFY) help Enable support for SECP521R1 Elliptic Curve. config MBEDTLS_ECP_DP_SECP192K1_ENABLED bool "Enable SECP192K1 curve" depends on MBEDTLS_ECP_C - default y + default y if !(MBEDTLS_ATCA_HW_ECDSA_SIGN || MBEDTLS_ATCA_HW_ECDSA_VERIFY) help Enable support for SECP192K1 Elliptic Curve. config MBEDTLS_ECP_DP_SECP224K1_ENABLED bool "Enable SECP224K1 curve" depends on MBEDTLS_ECP_C - default y + default y if !(MBEDTLS_ATCA_HW_ECDSA_SIGN || MBEDTLS_ATCA_HW_ECDSA_VERIFY) help Enable support for SECP224K1 Elliptic Curve. config MBEDTLS_ECP_DP_SECP256K1_ENABLED bool "Enable SECP256K1 curve" depends on MBEDTLS_ECP_C - default y + default y if !(MBEDTLS_ATCA_HW_ECDSA_SIGN || MBEDTLS_ATCA_HW_ECDSA_VERIFY) help Enable support for SECP256K1 Elliptic Curve. config MBEDTLS_ECP_DP_BP256R1_ENABLED bool "Enable BP256R1 curve" depends on MBEDTLS_ECP_C - default y + default y if !(MBEDTLS_ATCA_HW_ECDSA_SIGN || MBEDTLS_ATCA_HW_ECDSA_VERIFY) help support for DP Elliptic Curve. config MBEDTLS_ECP_DP_BP384R1_ENABLED bool "Enable BP384R1 curve" depends on MBEDTLS_ECP_C - default y + default y if !(MBEDTLS_ATCA_HW_ECDSA_SIGN || MBEDTLS_ATCA_HW_ECDSA_VERIFY) help support for DP Elliptic Curve. config MBEDTLS_ECP_DP_BP512R1_ENABLED bool "Enable BP512R1 curve" depends on MBEDTLS_ECP_C - default y + default y if !(MBEDTLS_ATCA_HW_ECDSA_SIGN || MBEDTLS_ATCA_HW_ECDSA_VERIFY) help support for DP Elliptic Curve. config MBEDTLS_ECP_DP_CURVE25519_ENABLED bool "Enable CURVE25519 curve" depends on MBEDTLS_ECP_C - default y + default y if !(MBEDTLS_ATCA_HW_ECDSA_SIGN || MBEDTLS_ATCA_HW_ECDSA_VERIFY) help Enable support for CURVE25519 Elliptic Curve. diff --git a/components/mbedtls/port/include/mbedtls/esp_config.h b/components/mbedtls/port/include/mbedtls/esp_config.h index 4f522d37d..93c8ce285 100644 --- a/components/mbedtls/port/include/mbedtls/esp_config.h +++ b/components/mbedtls/port/include/mbedtls/esp_config.h @@ -149,6 +149,14 @@ #undef MBEDTLS_MPI_MUL_MPI_ALT #endif +#ifdef CONFIG_MBEDTLS_ATCA_HW_ECDSA_SIGN +#define MBEDTLS_ECDSA_SIGN_ALT +#endif + +#ifdef CONFIG_MBEDTLS_ATCA_HW_ECDSA_VERIFY +#define MBEDTLS_ECDSA_VERIFY_ALT +#endif + /** * \def MBEDTLS_ENTROPY_HARDWARE_ALT * diff --git a/components/tcp_transport/include/esp_transport_ssl.h b/components/tcp_transport/include/esp_transport_ssl.h index 9ce0b19c3..ff3f9d623 100644 --- a/components/tcp_transport/include/esp_transport_ssl.h +++ b/components/tcp_transport/include/esp_transport_ssl.h @@ -132,6 +132,15 @@ void esp_transport_ssl_set_alpn_protocol(esp_transport_handle_t t, const char ** */ void esp_transport_ssl_skip_common_name_check(esp_transport_handle_t t); +/** + * @brief Set the ssl context to use secure element (atecc608a) for client(device) private key and certificate + * + * @note Recommended to be used with ESP32-WROOM-32SE (which has inbuilt ATECC608A a.k.a Secure Element) + * + * @param t ssl transport + */ +void esp_transport_ssl_use_secure_element(esp_transport_handle_t t); + /** * @brief Set PSK key and hint for PSK server/client verification in esp-tls component. * Important notes: diff --git a/components/tcp_transport/transport_ssl.c b/components/tcp_transport/transport_ssl.c index 98bda19a0..a413c8461 100644 --- a/components/tcp_transport/transport_ssl.c +++ b/components/tcp_transport/transport_ssl.c @@ -280,6 +280,14 @@ void esp_transport_ssl_skip_common_name_check(esp_transport_handle_t t) } } +void esp_transport_ssl_use_secure_element(esp_transport_handle_t t) +{ + transport_ssl_t *ssl = esp_transport_get_context_data(t); + if (t && ssl) { + ssl->cfg.use_secure_element = true; + } +} + esp_transport_handle_t esp_transport_ssl_init(void) { esp_transport_handle_t t = esp_transport_init(); diff --git a/docs/conf_common.py b/docs/conf_common.py index fb6243b1b..ddc4583f8 100644 --- a/docs/conf_common.py +++ b/docs/conf_common.py @@ -152,6 +152,7 @@ ESP32_DOCS = ['api-guides/ulp_instruction_set.rst', 'api-reference/system/ipc.rst', 'security/secure-boot-v1.rst', 'security/secure-boot-v2.rst', + 'api-reference/peripherals/secure_element.rst', 'hw-reference/esp32/**'] + LEGACY_DOCS ESP32S2_DOCS = ['esp32s2.rst', diff --git a/docs/en/COPYRIGHT.rst b/docs/en/COPYRIGHT.rst index 8b4aacbd0..3cbd5844c 100644 --- a/docs/en/COPYRIGHT.rst +++ b/docs/en/COPYRIGHT.rst @@ -63,6 +63,7 @@ These third party libraries can be included into the application (firmware) prod * `mynewt-nimble`_ Apache Mynewt NimBLE, Copyright 2015-2018, The Apache Software Foundation, is licensed under Apache License 2.0 as described in :component_file:`LICENSE file`. +* `cryptoauthlib`_ Microchip CryptoAuthentication Library - Copyright (c) 2015 - 2018 Microchip Technology Inc, is licensed under common Microchip software License as described in :example_file:`LICENSE file ` Build Tools ----------- @@ -180,4 +181,4 @@ Copyright (C) 2011, ChaN, all right reserved. .. _ESP-IDF Programming Guide: https://docs.espressif.com/projects/esp-idf/en/latest/ .. _sphinx_idf_theme: https://github.com/espressif/sphinx_idf_theme .. _sphinx_rtd_theme: https://github.com/readthedocs/sphinx_rtd_theme - +.. _cryptoauthlib: https://github.com/MicrochipTech/cryptoauthlib diff --git a/docs/en/api-reference/peripherals/index.rst b/docs/en/api-reference/peripherals/index.rst index 77de48111..6da97bc37 100644 --- a/docs/en/api-reference/peripherals/index.rst +++ b/docs/en/api-reference/peripherals/index.rst @@ -25,6 +25,7 @@ Peripherals API Sigma-delta Modulation SPI Master SPI Slave + :esp32: Secure Element :esp32s2: Temp sensor Timer Touch Sensor diff --git a/docs/en/api-reference/peripherals/secure_element.rst b/docs/en/api-reference/peripherals/secure_element.rst new file mode 100644 index 000000000..f315f1ac1 --- /dev/null +++ b/docs/en/api-reference/peripherals/secure_element.rst @@ -0,0 +1,24 @@ +ESP32-WROOM-32SE (Secure Element) +================================= + +Overview +-------- + +The ESP32-WROOM-32SE has integrated Microchip's ATECC608A cryptoauth chip in the module. ATECC608A is secure element +which would generate and store ECC private key in the hardware.The ECC private key can be used to enhance security +to connect to IoT cloud services with use of X.509 based mutual authentication. +The application example demonstrates ECDSA sign and verify functions using ECC private key stored in ATECC608A + +Application Example +------------------- + +Secure Element ECDSA Sign/Verify example: :example:`peripherals/secure_element/atecc608_ecdsa`. + +How to configure and provision ESP32-WROOM-32SE for TLS +------------------------------------------------------- +To configure and provision ATECC608A chip on ESP32-WROOM-32SE please visit `esp_cryptoauth_utility `_ + +How to use ATECC608A of ESP32-WROOM-32SE for TLS +------------------------------------------------ +ATECC608A can be used for TLS connections using ESP-TLS. +To configure ESP-TLS for using secure element please refer `ATECC608A with ESP-TLS` in :doc:`ESP-TLS documentation.<../protocols/esp_tls>` diff --git a/docs/en/api-reference/protocols/esp_tls.rst b/docs/en/api-reference/protocols/esp_tls.rst index 13a27c7a9..a46911e43 100644 --- a/docs/en/api-reference/protocols/esp_tls.rst +++ b/docs/en/api-reference/protocols/esp_tls.rst @@ -88,6 +88,38 @@ SSL/TLS libraries and with all respective configurations set to default. .. note:: `These values are subject to change with change in configuration options and version of respective libraries`. +ATECC608A (Secure Element) with ESP-TLS +-------------------------------------------------- + +ESP-TLS provides support for using ATECC608A cryptoauth chip with ESP32-WROOM-32SE. +Use of ATECC608A is supported only when ESP-TLS is used with mbedTLS as its underlying SSL/TLS stack. +ESP-TLS uses mbedtls as its underlying TLS/SSL stack by default unless changed manually. + +.. note:: ATECC608A chip on ESP32-WROOM-32SE must be already configured and provisioned, for details refer `esp_cryptoauth_utility `_ + +To enable the secure element support, and use it in you project for TLS connection, you will have to follow below steps + +1) Add `esp-cryptoauthlib `_ in your project, for details please refer `esp-cryptoauthlib with ESP_IDF `_ + +2) Enable following menuconfig option:: + + menuconfig->Component config->ESP-TLS->Use Secure Element (ATECC608A) with ESP-TLS + +3) Select type of ATECC608A chip with following option:: + + menuconfig->Component config->esp-cryptoauthlib->Choose Type of ATECC608A chip + +to know more about different types of ATECC608A chips and how to obtain type of ATECC608A connected to your ESP module please visit `ATECC608A chip type `_ + +4) Enable use of ATECC608A in ESP-TLS by providing following config option in `esp_tls_cfg_t` + +.. code-block:: c + + esp_tls_cfg_t cfg = { + /* other configurations options */ + .use_secure_element = true, + }; + API Reference ------------- diff --git a/docs/zh_CN/api-reference/peripherals/index.rst b/docs/zh_CN/api-reference/peripherals/index.rst index 0c27a6fed..18a370869 100644 --- a/docs/zh_CN/api-reference/peripherals/index.rst +++ b/docs/zh_CN/api-reference/peripherals/index.rst @@ -23,6 +23,7 @@ Sigma-delta Modulation SPI Master SPI Slave + :esp32: Secure Element :esp32s2: Temp sensor Timer Touch Sensor diff --git a/docs/zh_CN/api-reference/peripherals/secure_element.rst b/docs/zh_CN/api-reference/peripherals/secure_element.rst new file mode 100644 index 000000000..67c448091 --- /dev/null +++ b/docs/zh_CN/api-reference/peripherals/secure_element.rst @@ -0,0 +1 @@ +.. include:: ../../../en/api-reference/peripherals/secure_element.rst diff --git a/examples/peripherals/secure_element/atecc608_ecdsa/CMakeLists.txt b/examples/peripherals/secure_element/atecc608_ecdsa/CMakeLists.txt new file mode 100644 index 000000000..0d931277c --- /dev/null +++ b/examples/peripherals/secure_element/atecc608_ecdsa/CMakeLists.txt @@ -0,0 +1,6 @@ +# The following lines of boilerplate have to be in your project's CMakeLists +# in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.5) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(atecc608a_ecdsa) diff --git a/examples/peripherals/secure_element/atecc608_ecdsa/Makefile b/examples/peripherals/secure_element/atecc608_ecdsa/Makefile new file mode 100644 index 000000000..fd1ab02a1 --- /dev/null +++ b/examples/peripherals/secure_element/atecc608_ecdsa/Makefile @@ -0,0 +1,9 @@ +# +# This is a project Makefile. It is assumed the directory this Makefile resides in is a +# project subdirectory. +# + +PROJECT_NAME := atecc608a_ecdsa + +include $(IDF_PATH)/make/project.mk + diff --git a/examples/peripherals/secure_element/atecc608_ecdsa/README.md b/examples/peripherals/secure_element/atecc608_ecdsa/README.md new file mode 100644 index 000000000..4df1b8964 --- /dev/null +++ b/examples/peripherals/secure_element/atecc608_ecdsa/README.md @@ -0,0 +1,34 @@ +| Supported Targets | ESP32 | +| ----------------- | ----- | + +# ESP32-WROOM-32SE ECDSA sign/verify example +## Description +This example requires [ESP32-WROOM-32SE](https://www.espressif.com/sites/default/files/documentation/esp32-wroom-32se_datasheet_en.pdf) which has Microchip's [ATECC608A](https://www.microchip.com/wwwproducts/en/ATECC608A) (Secure Element) integrated on the module. The example performs `ECDSA sign/verify` functions on sample data using hardware private key stored in ATECC608A chip.If you want to use bare `ATECC608A` chip (Secure Element) with `ESP32-WROOM-32` module by making external connections, please refer [this](https://github.com/espressif/esp-cryptoauthlib/blob/master/esp_cryptoauth_utility/README.md#using-atecc608a-with-esp32-wroom-32) for details. +See the README.md file in the upper level examples directory for more information about examples. +## Hardware +To get started you will need a `ESP32-WROOM-32SE` development board which integrates Microchip’s ATECC608A CryptoAuth chip in the module. + +## Configuration +ATECC608A chip on ESP32-WROOM-32SE should be configured to run the example, for details on configuration of ATECC608A chip, please refer [esp_cryptoauth_utility](https://github.com/espressif/esp-cryptoauthlib/blob/master/esp_cryptoauth_utility/README.md#esp_cryptoauth_utility) + +1) Set type of `ATECC608A` chip in menuconfig. + +* `menuconfig->Component config->esp-cryptoauthlib->Choose Type of ATECC608A chip`. +for more details refer [Find ATECC608A chip type](https://github.com/espressif/esp-cryptoauthlib/blob/master/esp_cryptoauth_utility/README.md#find-type-of-atecc608a-chip-connected-to-esp32-wroom32-se). + +2) Enable `Hardware ECDSA sign/verify` in menuconfig as by enabling following. (Enabled by default for this example) + +* `menuconfig->Component config->esp-cryptoauthlib->Enable Hardware ECDSA keys for mbedTLS` +* `menuconfig->Component config->esp-cryptoauthlib->Enable ATECC608A sign operations in mbedTLS` +* `menuconfig->Component config->esp-cryptoauthlib->Enable ATECC608A verify operations in mbedTLS` + +## Build and Flash + +Run following command to build and flash the project. +``` +idf.py -p PORT flash monitor +``` + +(To exit the serial monitor, type ``Ctrl-]``.) + +See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html) for full steps to configure and use ESP-IDF to build projects. diff --git a/examples/peripherals/secure_element/atecc608_ecdsa/components/esp-cryptoauthlib b/examples/peripherals/secure_element/atecc608_ecdsa/components/esp-cryptoauthlib new file mode 160000 index 000000000..f31ff0b12 --- /dev/null +++ b/examples/peripherals/secure_element/atecc608_ecdsa/components/esp-cryptoauthlib @@ -0,0 +1 @@ +Subproject commit f31ff0b1252158b9a19a0494d7dc6f81313c6ef0 diff --git a/examples/peripherals/secure_element/atecc608_ecdsa/main/CMakeLists.txt b/examples/peripherals/secure_element/atecc608_ecdsa/main/CMakeLists.txt new file mode 100644 index 000000000..0122eb954 --- /dev/null +++ b/examples/peripherals/secure_element/atecc608_ecdsa/main/CMakeLists.txt @@ -0,0 +1,5 @@ +# Main component CMakeLists.txt +idf_component_register( + SRC_DIRS "." + INCLUDE_DIRS "." + ) diff --git a/examples/peripherals/secure_element/atecc608_ecdsa/main/component.mk b/examples/peripherals/secure_element/atecc608_ecdsa/main/component.mk new file mode 100644 index 000000000..0b9d7585e --- /dev/null +++ b/examples/peripherals/secure_element/atecc608_ecdsa/main/component.mk @@ -0,0 +1,5 @@ +# +# "main" pseudo-component makefile. +# +# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) + diff --git a/examples/peripherals/secure_element/atecc608_ecdsa/main/ecdsa_example_main.c b/examples/peripherals/secure_element/atecc608_ecdsa/main/ecdsa_example_main.c new file mode 100644 index 000000000..c6d0738f8 --- /dev/null +++ b/examples/peripherals/secure_element/atecc608_ecdsa/main/ecdsa_example_main.c @@ -0,0 +1,241 @@ +/** + * atecc608a_ecdsa example + * + * Original Copyright (C) 2006-2016, ARM Limited, All Rights Reserved, Apache 2.0 License. + * Additions Copyright (C) Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD, Apache 2.0 License. + * + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * 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. + */ + +/* This is mbedtls boilerplate for library configuration */ +#include "mbedtls/config.h" + +/* System Includes*/ +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "esp_system.h" +#include "esp_spi_flash.h" +#include "esp_log.h" + +/* Cryptoauthlib includes */ +#include "cryptoauthlib.h" +#include "mbedtls/atca_mbedtls_wrap.h" + +/* mbedTLS includes */ +#include "mbedtls/platform.h" +#include "mbedtls/debug.h" +#include "mbedtls/ssl.h" +#include "mbedtls/entropy.h" +#include "mbedtls/ctr_drbg.h" +#include "mbedtls/pk.h" + +static const char *TAG = "atecc_example"; +/* globals for mbedtls RNG */ +static mbedtls_entropy_context entropy; +static mbedtls_ctr_drbg_context ctr_drbg; + +static int configure_mbedtls_rng(void) +{ + int ret; + const char * seed = "some random seed string"; + mbedtls_ctr_drbg_init(&ctr_drbg); + + ESP_LOGI(TAG, "Seeding the random number generator..."); + + mbedtls_entropy_init(&entropy); + ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, + (const unsigned char *)seed, strlen(seed)); + if (ret != 0) { + ESP_LOGI(TAG, " failed ! mbedtls_ctr_drbg_seed returned %d", ret); + } else { + ESP_LOGI(TAG, " ok"); + } + return ret; +} + +static void close_mbedtls_rng(void) +{ + mbedtls_ctr_drbg_free(&ctr_drbg); + mbedtls_entropy_free(&entropy); +} + +/* An example hash */ +static unsigned char hash[32] = { + 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23, + 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c, 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad +}; + +static const uint8_t public_key_x509_header[] = { + 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01, 0x06, 0x08, 0x2A, + 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04 +}; + +static void print_public_key(uint8_t *pubkey) +{ + uint8_t buf[128]; + uint8_t * tmp; + size_t buf_len = sizeof(buf); + + /* Calculate where the raw data will fit into the buffer */ + tmp = buf + sizeof(buf) - ATCA_PUB_KEY_SIZE - sizeof(public_key_x509_header); + + /* Copy the header */ + memcpy(tmp, public_key_x509_header, sizeof(public_key_x509_header)); + + /* Copy the key bytes */ + memcpy(tmp + sizeof(public_key_x509_header), pubkey, ATCA_PUB_KEY_SIZE); + + /* Convert to base 64 */ + (void)atcab_base64encode(tmp, ATCA_PUB_KEY_SIZE + sizeof(public_key_x509_header), (char*)buf, &buf_len); + + /* Add a null terminator */ + buf[buf_len] = '\0'; + + /* Print out the key */ + ESP_LOGI(TAG, "\r\n-----BEGIN PUBLIC KEY-----\r\n%s\r\n-----END PUBLIC KEY-----", buf); +} + +static int atca_ecdsa_test(void) +{ + mbedtls_pk_context pkey; + int ret; + unsigned char buf[MBEDTLS_MPI_MAX_SIZE]; + size_t olen = 0; + + /* ECDSA Sign/Verify */ + +#ifdef MBEDTLS_ECDSA_SIGN_ALT + /* Convert to an mbedtls key */ + ESP_LOGI(TAG, " Using a hardware private key ..." ); + ret = atca_mbedtls_pk_init(&pkey, 0); + if (ret != 0) { + ESP_LOGI(TAG, " failed ! atca_mbedtls_pk_init returned %02x", ret); + goto exit; + } + ESP_LOGI(TAG, " ok"); +#else + ESP_LOGI(TAG, " Generating a software private key ..." ); + mbedtls_pk_init(&pkey); + ret = mbedtls_pk_setup(&pkey, + mbedtls_pk_info_from_type( MBEDTLS_PK_ECDSA )); + if (ret != 0) { + ESP_LOGI(TAG, " failed ! mbedtls_pk_setup returned -0x%04x", -ret ); + goto exit; + } + + ret = mbedtls_ecp_gen_key( MBEDTLS_ECP_DP_SECP256R1, + mbedtls_pk_ec( pkey ), + mbedtls_ctr_drbg_random, &ctr_drbg ); + if (ret != 0) { + ESP_LOGI(TAG, " failed ! mbedtls_ecp_gen_key returned -0x%04x", -ret ); + goto exit; + } + ESP_LOGI(TAG, " ok"); +#endif + + ESP_LOGI(TAG, " Generating ECDSA Signature..."); + ret = mbedtls_pk_sign(&pkey, MBEDTLS_MD_SHA256, hash, 0, buf, &olen, + mbedtls_ctr_drbg_random, &ctr_drbg); + if (ret != 0) { + ESP_LOGI(TAG, " failed ! mbedtls_pk_sign returned -0x%04x", -ret); + goto exit; + } + ESP_LOGI(TAG, " ok"); + + ESP_LOGI(TAG, " Verifying ECDSA Signature..."); + ret = mbedtls_pk_verify(&pkey, MBEDTLS_MD_SHA256, hash, 0, + buf, olen); + if (ret != 0) { + ESP_LOGI(TAG, " failed ! mbedtls_pk_verify returned -0x%04x", -ret); + goto exit; + } + ESP_LOGI(TAG, " ok"); + +exit: + fflush(stdout); + return ret; +} + +void app_main(void) +{ + int ret = 0; + bool lock; + uint8_t buf[ATCA_ECC_CONFIG_SIZE]; + uint8_t pubkey[ATCA_PUB_KEY_SIZE]; + + /* Initialize the mbedtls library */ + ret = configure_mbedtls_rng(); +#ifdef CONFIG_ATECC608A_TNG + ESP_LOGI(TAG, " . Initialize the ATECC interface for Trust & GO ..."); + cfg_ateccx08a_i2c_default.atcai2c.slave_address = 0x6A; +#elif CONFIG_ATECC608A_TFLEX /* CONFIG_ATECC608A_TNGO */ + ESP_LOGI(TAG, " . Initialize the ATECC interface for TrustFlex ..."); + cfg_ateccx08a_i2c_default.atcai2c.slave_address = 0x6C; +#elif CONFIG_ATECC608A_TCUSTOM /* CONFIG_ATECC608A_TFLEX */ + ESP_LOGI(TAG, " . Initialize the ATECC interface for TrustCustom ..."); + /* Default slave address is same as that of TCUSTOM ATECC608A chips */ +#endif /* CONFIG_ATECC608A_TCUSTOM */ + ret = atcab_init(&cfg_ateccx08a_i2c_default); + if (ret != 0) { + ESP_LOGI(TAG, " failed ! atcab_init returned %02x", ret); + goto exit; + } + ESP_LOGI(TAG, " ok"); + + lock = 0; + ESP_LOGI(TAG, " Check the data zone lock status..."); + ret = atcab_is_locked(LOCK_ZONE_DATA, &lock); + if (ret != 0) { + ESP_LOGI(TAG, " failed\n ! atcab_is_locked returned %02x", ret); + goto exit; + } + + if (lock) { + ESP_LOGI(TAG, " ok: locked"); + } else { + ESP_LOGE(TAG, "unlocked, please lock(configure) the ATECC608A chip with help of esp_cryptoauth_utility and try again"); + goto exit; + } + + ESP_LOGI(TAG, " Get the device info (type)..."); + ret = atcab_info(buf); + if (ret != 0) { + ESP_LOGI(TAG, " failed\n ! atcab_info returned %02x", ret); + goto exit; + } + ESP_LOGI(TAG, " ok: %02x %02x", buf[2], buf[3]); + + ESP_LOGI(TAG, " Get the public key..."); + ret = atcab_get_pubkey(0, pubkey); + if (ret != 0) { + ESP_LOGI(TAG, " failed\n ! atcab_get_pubkey returned %02x", ret); + goto exit; + } + ESP_LOGI(TAG, " ok"); + print_public_key(pubkey); + + /* Perform a Sign/Verify Test */ + ret = atca_ecdsa_test(); + if (ret != 0) { + ESP_LOGE(TAG, " ECDSA sign/verify failed"); + goto exit; + } + +exit: + fflush(stdout); + close_mbedtls_rng(); + +} + diff --git a/examples/peripherals/secure_element/atecc608_ecdsa/sdkconfig.defaults b/examples/peripherals/secure_element/atecc608_ecdsa/sdkconfig.defaults new file mode 100644 index 000000000..b704bedef --- /dev/null +++ b/examples/peripherals/secure_element/atecc608_ecdsa/sdkconfig.defaults @@ -0,0 +1,3 @@ +CONFIG_ATCA_MBEDTLS_ECDSA=y +CONFIG_ATCA_MBEDTLS_ECDSA_SIGN=y +CONFIG_ATCA_MBEDTLS_ECDSA_VERIFY=y