Merge branch 'feature/esp_wroom32_se_example' into 'master'

Feature/esp wroom32 se example

See merge request espressif/esp-idf!8552
This commit is contained in:
Mahavir Jain 2020-05-21 19:51:19 +08:00
commit 6272cb842f
26 changed files with 553 additions and 14 deletions

4
.gitmodules vendored
View file

@ -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

View file

@ -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()

View file

@ -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

View file

@ -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

View file

@ -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 */

View file

@ -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

View file

@ -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()

View file

@ -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.

View file

@ -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
*

View file

@ -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:

View file

@ -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();

View file

@ -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',

View file

@ -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<bt/host/nimble/nimble/LICENSE>`.
* `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 <peripherals/secure_element/atecc608_ecdsa/components/esp-cryptoauthlib/cryptoauthlib/LICENSE>`
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

View file

@ -25,6 +25,7 @@ Peripherals API
Sigma-delta Modulation <sigmadelta>
SPI Master <spi_master>
SPI Slave <spi_slave>
:esp32: Secure Element <secure_element>
:esp32s2: Temp sensor <temp_sensor>
Timer <timer>
Touch Sensor <touch_pad>

View file

@ -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 <https://github.com/espressif/esp-cryptoauthlib/blob/master/esp_cryptoauth_utility/README.md#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>`

View file

@ -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 <https://github.com/espressif/esp-cryptoauthlib/blob/master/esp_cryptoauth_utility/README.md#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 <https://github.com/espressif/esp-cryptoauthlib>`_ in your project, for details please refer `esp-cryptoauthlib with ESP_IDF <https://github.com/espressif/esp-cryptoauthlib#how-to-use-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 <https://github.com/espressif/esp-cryptoauthlib/blob/master/esp_cryptoauth_utility/README.md#find-type-of-atecc608a-chip-connected-to-esp32-wroom32-se>`_
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
-------------

View file

@ -23,6 +23,7 @@
Sigma-delta Modulation <sigmadelta>
SPI Master <spi_master>
SPI Slave <spi_slave>
:esp32: Secure Element <secure_element>
:esp32s2: Temp sensor <temp_sensor>
Timer <timer>
Touch Sensor <touch_pad>

View file

@ -0,0 +1 @@
.. include:: ../../../en/api-reference/peripherals/secure_element.rst

View file

@ -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)

View file

@ -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

View file

@ -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 Microchips 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.

@ -0,0 +1 @@
Subproject commit f31ff0b1252158b9a19a0494d7dc6f81313c6ef0

View file

@ -0,0 +1,5 @@
# Main component CMakeLists.txt
idf_component_register(
SRC_DIRS "."
INCLUDE_DIRS "."
)

View file

@ -0,0 +1,5 @@
#
# "main" pseudo-component makefile.
#
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)

View file

@ -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 <stdio.h>
#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();
}

View file

@ -0,0 +1,3 @@
CONFIG_ATCA_MBEDTLS_ECDSA=y
CONFIG_ATCA_MBEDTLS_ECDSA_SIGN=y
CONFIG_ATCA_MBEDTLS_ECDSA_VERIFY=y