diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 5536211db..2f96a7c95 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -6,6 +6,7 @@ variables: V: "0" MAKEFLAGS: "-j5 --no-keep-going" IDF_PATH: "$CI_PROJECT_DIR/esp-idf" + IDF_GITHUB_REPO: "https://github.com/espressif" build_demo: stage: build @@ -23,7 +24,7 @@ build_demo: - echo -e "Host gitlab.espressif.cn\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config - git --version - git submodule update --init --recursive - - git clone --recursive --depth 1 $GITLAB_SSH_SERVER/idf/esp-idf.git + - git clone --recursive --branch master --depth 1 $IDF_GITHUB_REPO/esp-idf.git - export PATH="$IDF_PATH/tools:$PATH" - cd esp-idf - ./install.sh diff --git a/Kconfig b/Kconfig index 0e41d9689..8857af10a 100644 --- a/Kconfig +++ b/Kconfig @@ -72,6 +72,18 @@ config AWS_IOT_MQTT_MAX_RECONNECT_WAIT_INTERVAL Maximum delay between reconnection attempts. If the exponentially increased delay interval reaches this value, the client will stop automatically attempting to reconnect. +config AWS_IOT_USE_HARDWARE_SECURE_ELEMENT + bool "Use the hardware secure element for authenticating TLS connections" + depends on ATCA_MBEDTLS_ECDSA + select ATCA_MBEDTLS_ECDSA_SIGN + select ATCA_MBEDTLS_ECDSA_VERIFY + help + Enable this option to use the hardware secure element for the TLS. If you have added the + esp-cryptoauthlib (https://github.com/espressif/esp-cryptoauthlib) as a component in your project. + This will let the user to specify a slot number from the chip (in the format "#0" + where the digit is the slot number to use) which contains the stored private key. + Please refer to the component README for more details. + menu "Thing Shadow" config AWS_IOT_OVERRIDE_THING_SHADOW_RX_BUFFER diff --git a/README.md b/README.md index 57b5b1619..4386c51f9 100644 --- a/README.md +++ b/README.md @@ -12,3 +12,30 @@ This framework enables AWS IoT cloud connectivity with ESP32 based platforms usi - ESP-IDF can be downloaded from https://github.com/espressif/esp-idf/ - ESP-IDF v3.1 and above is recommended version - Please refer to [example README](examples/README.md) for more information on setting up examples + +## Using an ATECC608A with the ESP-AWS-IoT + The `esp-aws-iot` contains the support for using a `secure element` chip from microchip i.e. `ATECC608A`. This will store the private key used for the TLS communication in the `secure element` which has the hardware security. The module [ESP32-WROOM-32SE](https://www.espressif.com/sites/default/files/documentation/esp32-wroom-32se_datasheet_en.pdf) which integrates the `ATECC608A`, can be readily used for this purpose. To use the `secure element` for the TLS, configure the project with help of the following steps. +> To use the `secure element`(ATECC608A) for the TLS connection, it must be already configured. Please refer to the [eps_cryptoauth_utility](https://github.com/espressif/esp-cryptoauthlib/tree/master/esp_cryptoauth_utility) for more details. +### Project Configuration + +1. Add [esp-cryptoauthlib](https://github.com/espressif/esp-cryptoauthlib) as a component to your project with the help of following commands, + (First change directory (cd) to your project directory) +``` + mkdir components + cd components + git clone https://github.com/espressif/esp-cryptoauthlib.git +``` +2. Enable the mbedtls ECDSA support in esp-cryptoauthlib with the following config (`idf.py menuconfig`) option, + `menuconfig->Component config->esp-cryptoauthlib->Enable Hardware ECDSA keys for mbedTLS` + +3. Enable support for hardware secure element with the following config (`idf.py menuconfig`) option, + `menuconfig->Component config->Amazon Web Services IoT Platform->Use the hardware secure element for authenticating TLS connections` + +4. Ensure that you call the function `atcab_init` in the application to initialise the `secure_element` before you use the AWS IoT component. + +5. Project TLS configuration - + + i) If you have the `Trust&GO` type of ATECC608A chip then you can set `mqttInitParams.pDeviceCertLocation = "#"` in your project. It will make the `esp-aws-iot` read the certificate from `ATECC608A` and use it for the TLS. For the other types of ATECC608A chips, you will need to provide the certificate externally (embed the certificate). + + ii) Tell the `esp-aws-iot` to find the client private key in a slot by setting `mqttInitParams.pDevicePrivateKeyLocation = “#0”` in your project, where the digit 0 indicates the slot in the ATECC608A in which the private key is stored. In most circumstances, the key will be stored in slot 0. +> Along with the secure element configurations you will have to perform additional example specific configurations (if required). \ No newline at end of file diff --git a/port/network_mbedtls_wrapper.c b/port/network_mbedtls_wrapper.c index a9f6e5e18..d7ceb965e 100644 --- a/port/network_mbedtls_wrapper.c +++ b/port/network_mbedtls_wrapper.c @@ -26,6 +26,12 @@ #include "mbedtls/esp_debug.h" +#ifdef CONFIG_AWS_IOT_USE_HARDWARE_SECURE_ELEMENT +#include "mbedtls/atca_mbedtls_wrap.h" +#include "tng_atca.h" +#include "tng_atcacert_client.h" +#endif + #include "esp_log.h" #include "esp_vfs.h" @@ -154,6 +160,18 @@ IoT_Error_t iot_tls_connect(Network *pNetwork, TLSConnectParams *params) { ESP_LOGD(TAG, "ok (%d skipped)", ret); /* Load client certificate... */ +#ifdef CONFIG_AWS_IOT_USE_HARDWARE_SECURE_ELEMENT + if (pNetwork->tlsConnectParams.pDeviceCertLocation[0] == '#') { + const atcacert_def_t* cert_def = NULL; + ESP_LOGD(TAG, "Using certificate stored in ATECC608A"); + ret = tng_get_device_cert_def(&cert_def); + if (ret == 0) { + ret = atca_mbedtls_cert_add(&(tlsDataParams->clicert), cert_def); + } else { + ESP_LOGE(TAG, "failed! could not load cert from ATECC608A, tng_get_device_cert_def returned %02x", ret); + } + } else +#endif if (pNetwork->tlsConnectParams.pDeviceCertLocation[0] == '/') { ESP_LOGD(TAG, "Loading client cert from file..."); ret = mbedtls_x509_crt_parse_file(&(tlsDataParams->clicert), @@ -170,6 +188,21 @@ IoT_Error_t iot_tls_connect(Network *pNetwork, TLSConnectParams *params) { } /* Parse client private key... */ +#ifdef CONFIG_AWS_IOT_USE_HARDWARE_SECURE_ELEMENT + if (pNetwork->tlsConnectParams.pDevicePrivateKeyLocation[0] == '#') { + int8_t slot_id = pNetwork->tlsConnectParams.pDevicePrivateKeyLocation[1] - '0'; + if (slot_id < 0 || slot_id > 9) { + ESP_LOGE(TAG, "Invalid ATECC608A slot ID."); + ret = NETWORK_PK_PRIVATE_KEY_PARSE_ERROR; + } else { + ESP_LOGD(TAG, "Using ATECC608A private key from slot %d", slot_id); + ret = atca_mbedtls_pk_init(&(tlsDataParams->pkey), slot_id); + if (ret != 0) { + ESP_LOGE(TAG, "failed ! atca_mbedtls_pk_init returned %02x", ret); + } + } + } else +#endif if (pNetwork->tlsConnectParams.pDevicePrivateKeyLocation[0] == '/') { ESP_LOGD(TAG, "Loading client private key from file..."); ret = mbedtls_pk_parse_keyfile(&(tlsDataParams->pkey),