Skip to content

Commit

Permalink
Merge pull request #33 from All-Your-Locks-Are-Belong-To-Us/feature/m…
Browse files Browse the repository at this point in the history
…easure-esp32

Make measurements compile for ESP32
  • Loading branch information
sirkrypt0 committed Aug 27, 2022
2 parents 5789915 + 3f9332f commit 1916feb
Show file tree
Hide file tree
Showing 42 changed files with 473 additions and 174 deletions.
2 changes: 1 addition & 1 deletion examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ target_link_libraries(nfc_simulator ${PRODUCT_NAME})
#######################################
# Test applications

add_subdirectory(measurements)
add_subdirectory(measurements/atmega)
5 changes: 5 additions & 0 deletions examples/esp32/components/clock/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
idf_component_register(
SRCS "clock_cycles.c"
INCLUDE_DIRS "."
PRIV_REQUIRES esp_hw_support esp_rom
)
12 changes: 12 additions & 0 deletions examples/esp32/components/clock/clock_cycles.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*
* Copyright (c) 2022 Felix Gohla, Konrad Hanff, Tobias Kantusch,
* Quentin Kuth, Felix Roth. All rights reserved.
*
* Use of this source code is governed by a BSD-style
* license that can be found in the LICENSE file.
*/

#include <esp_cpu.h>

// Buffer variable used for measuring elapsed clock cycles.
esp_cpu_cycle_count_t clock_cycle_start;
45 changes: 45 additions & 0 deletions examples/esp32/components/clock/clock_cycles.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright (c) 2022 Felix Gohla, Konrad Hanff, Tobias Kantusch,
* Quentin Kuth, Felix Roth. All rights reserved.
*
* Use of this source code is governed by a BSD-style
* license that can be found in the LICENSE file.
*/

#pragma once

#include <stdint.h>
#include <esp_cpu.h>
#include <esp_rom_sys.h>

extern volatile esp_cpu_cycle_count_t clock_cycle_start;

inline void clock_init() {}

/**
* @brief Starts counting clock cycles.
*
*/
static inline void clock_start_counting() {
clock_cycle_start = esp_cpu_get_cycle_count();
}

/**
* @brief Stops counting clock cycles and returns the number of elapsed cycles.
*
*/
static inline uint64_t clock_stop_counting() {
esp_cpu_cycle_count_t end = esp_cpu_get_cycle_count();
uint64_t val = end - clock_cycle_start;
return val;
}

/**
* @brief Converts clock cycles to nanoseconds.
*
* @param cycles The number of cycles.
* @return uint64_t The number of nanoseconds.
*/
static inline uint32_t clock_cyles_to_ns(uint64_t cycles) {
return cycles * 1000 / esp_rom_get_cpu_ticks_per_us();
}
5 changes: 5 additions & 0 deletions examples/esp32/components/hw_crypto/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
idf_component_register(
SRCS "hw_crypto.c"
INCLUDE_DIRS "."
PRIV_REQUIRES libmicrofido2 mbedtls
)
File renamed without changes.
120 changes: 120 additions & 0 deletions examples/esp32/components/hw_crypto/hw_crypto.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
/*
* Copyright (c) 2022 Felix Gohla, Konrad Hanff, Tobias Kantusch,
* Quentin Kuth, Felix Roth. All rights reserved.
*
* Use of this source code is governed by a BSD-style
* license that can be found in the LICENSE file.
*/

#include <sdkconfig.h>

#ifdef CONFIG_USE_HW_CRYPTO
#include "fido.h"

#include <stdio.h>
#include <mbedtls/aes.h>
#include <mbedtls/gcm.h>
#include <mbedtls/sha256.h>
#include <mbedtls/sha512.h>

static void 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);
}
}

static void 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);
}
}

static 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,
plaintext, ciphertext,
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;
}

static 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_auth_decrypt(
&ctx,
ciphertext_len,
iv, iv_len,
aad, aad_len,
tag, 16,
ciphertext, plaintext
);
if (r != 0) {
printf("[%s] mbedtls_gcm_auth_decrypt failed with %d\n", __func__, r);
return r;
}

mbedtls_gcm_free(&ctx);

return 0;
}

int init_hw_crypto() {
fido_sha256 = &sha256;
fido_sha512 = &sha512;
fido_aes_gcm_encrypt = &aes_gcm_encrypt;
fido_aes_gcm_decrypt = &aes_gcm_decrypt;

return 0;
}
#else
int init_hw_crypto() {
return 0;
}
#endif
File renamed without changes.
2 changes: 1 addition & 1 deletion examples/esp32/main/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
idf_component_register(
SRCS "esp32-libmicrofido2.c" "stateless_rp/stateless_rp.c" "stateless_rp/stateless_rp_nfc_simulator.c"
INCLUDE_DIRS "."
PRIV_REQUIRES libmicrofido2 mbedtls
PRIV_REQUIRES libmicrofido2 hw_crypto clock
)
138 changes: 17 additions & 121 deletions examples/esp32/main/esp32-libmicrofido2.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,135 +6,31 @@
* license that can be found in the LICENSE file.
*/

#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <sdkconfig.h>

#include <fido.h>

#ifdef CONFIG_USE_HW_CRYPTO
#include <mbedtls/aes.h>
#include <mbedtls/gcm.h>
#include <mbedtls/sha256.h>
#include <mbedtls/sha512.h>
#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

#include <fido.h>
#include <stdio.h>
#include "hw_crypto.h"
#include "clock_cycles.h"
#include "stateless_rp/stateless_rp.h"
#include "stateless_rp/stateless_rp_nfc_simulator.h"

int app_main(void) {
#ifdef CONFIG_USE_HW_CRYPTO
init_crypto();
#endif
clock_init();
if (init_hw_crypto() != 0) {
return -1;
} else {
printf("Initialized cryptography.\n");
}

fido_dev_t dev;

if (prepare_stateless_rp_nfc_simulator_device(&dev) != 0) {
return 1;
printf("Could not setup simulator device.\n");
return -1;
}

const uint8_t updater_public_key[] = {0xA8, 0xEE, 0x4D, 0x2B, 0xD5, 0xAE, 0x09, 0x0A, 0xBC, 0xA9, 0x8A, 0x06, 0x6C, 0xA5, 0xB3, 0xA6, 0x22, 0x84, 0x89, 0xF5, 0x9E, 0x30, 0x90, 0x87, 0x65, 0x62, 0xB9, 0x79, 0x8A, 0xE7, 0x05, 0x15};
return stateless_assert(&dev, "example.com", updater_public_key);
clock_start_counting();
const int ret = stateless_assert(&dev, "example.com", updater_public_key);
uint64_t elapsed_cycles = clock_stop_counting();
printf("Elapsed cycles for stateless assertion: %zu\n", elapsed_cycles);
printf("Elapsed nanoseconds for stateless assertion: %zu\n", clock_cyles_to_ns(elapsed_cycles));
return ret;
}
9 changes: 9 additions & 0 deletions examples/measurements/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,12 @@ Then, make sure to select the algorithm you want to measure in the `CMakeLists.t
Finally, the build procedure is similar to the one in the [nrf52 example](../nrf52/README.md).
To initially build the program, execute: `sudo docker run --rm -v $PWD/../../../:/libmicrofido2 nrf52-sdk west -v build -b nrf52840dk_nrf52840 -d /libmicrofido2/examples/measurements/nrf52/build /libmicrofido2/examples/measurements/nrf52`.
To build the program and flash it, execute: `docker run --rm -v $PWD/../../../:/libmicrofido2 --privileged --device=/dev/ttyACM? nrf52-sdk west flash -d /libmicrofido2/examples/measurements/nrf52/build`.

## Compiling for ESP32

The examples must be compiled explicitly for the ESP32.

First, navigate to the [esp32](./esp32/) folder.
Then, make sure to select the algorithm you want to measure in the `sdkconfig` (or using `idf.py menuconfig`).
Finally, the build procedure is similar to the one in the [esp32 example](../esp32/README.md).
Therefore, to build and flash the program execute the following command from inside the [esp32](./esp32/) folder: `docker run --rm -v $PWD/../../../:/project -w /project/examples/measurements/esp32 --device /dev/ttyUSB0 espressif/idf idf.py flash`.
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
include(../../cmake/linker-map.cmake)
include(../../../cmake/linker-map.cmake)

function(add_measurement name)
add_executable(${name} "common/${name}.c" common/gpio.c)
target_include_directories(${name} PRIVATE common/)
add_executable(${name} "common/${name}.c" gpio.c hw_crypto.c)
target_include_directories(${name} PRIVATE common/ .)
add_linker_map_for_target(${name})
target_link_libraries(${name} ${PRODUCT_NAME})
endfunction()
Expand Down
1 change: 1 addition & 0 deletions examples/measurements/atmega/common

0 comments on commit 1916feb

Please sign in to comment.