From 9ebb39b2e066e7fc4e7657df84c01e39cfad1285 Mon Sep 17 00:00:00 2001 From: Tobias Kantusch Date: Mon, 8 Aug 2022 19:03:38 +0200 Subject: [PATCH] Add hardware algo support for ESP32 This enables hardware support for AES,AES-GCM,SHA-256, and SHA-512 on the ESP32 in the example program. --- examples/esp32/CMakeLists.txt | 4 + examples/esp32/README.md | 6 ++ examples/esp32/main/CMakeLists.txt | 2 +- examples/esp32/main/Kconfig.projbuild | 5 + examples/esp32/main/esp32-libmicrofido2.c | 112 ++++++++++++++++++++++ examples/esp32/sdkconfig.defaults | 6 ++ 6 files changed, 134 insertions(+), 1 deletion(-) create mode 100644 examples/esp32/main/Kconfig.projbuild diff --git a/examples/esp32/CMakeLists.txt b/examples/esp32/CMakeLists.txt index bc3779d..22ee0d4 100644 --- a/examples/esp32/CMakeLists.txt +++ b/examples/esp32/CMakeLists.txt @@ -6,3 +6,7 @@ cmake_minimum_required(VERSION 3.16) include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(esp32-libmicrofido2) + +if (CONFIG_MBEDTLS_HARDWARE_AES STREQUAL "y") + idf_build_set_property(COMPILE_DEFINITIONS "-DUSE_HW_CRYPTO" APPEND) +endif() diff --git a/examples/esp32/README.md b/examples/esp32/README.md index b02c45a..11efd75 100644 --- a/examples/esp32/README.md +++ b/examples/esp32/README.md @@ -16,3 +16,9 @@ A small ESP-IDF app for the ESP32 using the libmicrofido2. 1. Connect the ESP32 to your computer and find its device node at `/dev/ttyUSBX` (note the value of `X` and replace it in the following command). 1. Run `docker run --rm -v $PWD/../../:/project -w /project/examples/esp32 --device /dev/ttyUSBX espressif/idf idf.py flash`. + +## Hardware Cryptography + +By default, hardware accelerated AES, partially AES-GCM, SHA-256, and SHA-512 are enabled. +As of now (2022), the ESP32C3 does not have hardware support for Ed25519. +To disable these, set `CONFIG_USE_HW_CRYPTO=n` in your `sdkconfig`. diff --git a/examples/esp32/main/CMakeLists.txt b/examples/esp32/main/CMakeLists.txt index bcb3d76..c0fa7b2 100644 --- a/examples/esp32/main/CMakeLists.txt +++ b/examples/esp32/main/CMakeLists.txt @@ -1,5 +1,5 @@ idf_component_register( SRCS "esp32-libmicrofido2.c" INCLUDE_DIRS "." - PRIV_REQUIRES libmicrofido2 + PRIV_REQUIRES libmicrofido2 mbedtls ) diff --git a/examples/esp32/main/Kconfig.projbuild b/examples/esp32/main/Kconfig.projbuild new file mode 100644 index 0000000..ac1eb01 --- /dev/null +++ b/examples/esp32/main/Kconfig.projbuild @@ -0,0 +1,5 @@ +config USE_HW_CRYPTO + bool "Use hardware acceleration for cryptography and hashing" + default n + help + Decides whether FIDO operations will use hardware acceleration for cryptography and hashing (if possible) diff --git a/examples/esp32/main/esp32-libmicrofido2.c b/examples/esp32/main/esp32-libmicrofido2.c index 58525ed..24e9243 100644 --- a/examples/esp32/main/esp32-libmicrofido2.c +++ b/examples/esp32/main/esp32-libmicrofido2.c @@ -11,6 +11,114 @@ #include #include #include +#include + +#ifdef CONFIG_USE_HW_CRYPTO +#include +#include +#include +#include +#endif + +#ifdef CONFIG_USE_HW_CRYPTO +int sha256(const uint8_t *data, size_t data_len, uint8_t *hash) { + int r = mbedtls_sha256(data, data_len, hash, 0); + if (r != 0) { + printf("sha256 failed with %d\n", r); + } + return r; +} + +int sha512(const uint8_t *data, size_t data_len, uint8_t *hash) { + int r = mbedtls_sha512(data, data_len, hash, 0); + if (r != 0) { + printf("sha512 failed with %d\n", r); + } + return r; +} + +int aes_gcm_encrypt( + const uint8_t *key, size_t key_len, + const uint8_t *iv, size_t iv_len, + const uint8_t *plaintext, size_t plaintext_len, + const uint8_t *aad, size_t aad_len, + uint8_t *ciphertext, uint8_t *tag +) { + mbedtls_gcm_context ctx; + int r; + + mbedtls_gcm_init(&ctx); + + r = mbedtls_gcm_setkey(&ctx, MBEDTLS_CIPHER_ID_AES, key, key_len * 8); + if (r != 0) { + printf("[%s] mbedtls_gcm_setkey failed with %d\n", __func__, r); + return r; + } + + r = mbedtls_gcm_crypt_and_tag( + &ctx, + MBEDTLS_ENCRYPT, + plaintext_len, + iv, iv_len, + aad, aad_len, + ciphertext, plaintext, + 16, tag + ); + if (r != 0) { + printf("[%s] mbedtls_gcm_crypt_and_tag failed with %d\n", __func__, r); + return r; + } + + mbedtls_gcm_free(&ctx); + + return 0; +} + +int aes_gcm_decrypt( + const uint8_t *key, size_t key_len, + const uint8_t *iv, size_t iv_len, + const uint8_t *ciphertext, size_t ciphertext_len, + const uint8_t *aad, size_t aad_len, + const uint8_t *tag, + uint8_t *plaintext +) { + mbedtls_gcm_context ctx; + int r; + + mbedtls_gcm_init(&ctx); + + r = mbedtls_gcm_setkey(&ctx, MBEDTLS_CIPHER_ID_AES, key, key_len * 8); + if (r != 0) { + printf("[%s] mbedtls_gcm_setkey failed with %d\n", __func__, r); + return r; + } + + r = mbedtls_gcm_crypt_and_tag( + &ctx, + MBEDTLS_DECRYPT, + ciphertext_len, + iv, iv_len, + aad, aad_len, + ciphertext, plaintext, + 16, tag + ); + if (r != 0) { + printf("[%s] mbedtls_gcm_crypt_and_tag failed with %d\n", __func__, r); + return r; + } + + mbedtls_gcm_free(&ctx); + + return 0; +} + +void init_crypto() { + fido_sha256 = &sha256; + fido_sha512 = &sha512; + fido_aes_gcm_encrypt = &aes_gcm_encrypt; + fido_aes_gcm_decrypt = &aes_gcm_decrypt; +} +#endif static void *example_open() { printf("open\n"); @@ -115,6 +223,10 @@ static const fido_dev_io_t nfc_io = { }; int app_main(void) { + #ifdef CONFIG_USE_HW_CRYPTO + init_crypto(); + #endif + fido_dev_t dev; if (fido_init_nfc_device(&dev, &nfc_io) != FIDO_OK) { return 1; diff --git a/examples/esp32/sdkconfig.defaults b/examples/esp32/sdkconfig.defaults index d18cabb..8ccd1c9 100644 --- a/examples/esp32/sdkconfig.defaults +++ b/examples/esp32/sdkconfig.defaults @@ -4,3 +4,9 @@ CONFIG_ESP_MAIN_TASK_STACK_SIZE=10240 # Set target to ESP32-C3 CONFIG_IDF_TARGET="esp32c3" CONFIG_IDF_TARGET_ESP32C3=y + +# Enable HW support for crypto and hashing +CONFIG_USE_HW_CRYPTO=y +CONFIG_MBEDTLS_HARDWARE_AES=y +CONFIG_MBEDTLS_HARDWARE_GCM=y +CONFIG_MBEDTLS_HARDWARE_SHA=y