diff --git a/CMakeLists.txt b/CMakeLists.txt index 65915c7..7ea17bd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -112,7 +112,7 @@ if(NOT USE_SOFTWARE_CRYPTO_SHA256) add_compile_definitions(NO_SOFTWARE_CRYPTO_SHA256) endif() -option(USE_SOFTWARE_CRYPTO_SHA512 "include software SHA512" OFF) +option(USE_SOFTWARE_CRYPTO_SHA512 "include software SHA512" ON) if(NOT USE_SOFTWARE_CRYPTO_SHA512) add_compile_definitions(NO_SOFTWARE_CRYPTO_SHA512) endif() diff --git a/cmake/linker-map.cmake b/cmake/linker-map.cmake new file mode 100644 index 0000000..7544f59 --- /dev/null +++ b/cmake/linker-map.cmake @@ -0,0 +1,12 @@ +set(command ${CMAKE_C_COMPILER} ${flags} -Wl,--version) + + +function(add_linker_map_for_target TARGET) + if (APPLE) + # LLVM only understands this flag. + # The map output differs from GNU ld. + target_link_options(${TARGET} PRIVATE "-Wl,-map,${TARGET}.map") + else() + target_link_options(${TARGET} PRIVATE "-Wl,-Map=${TARGET}.map") + endif() +endfunction() diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 5ffcfae..83b0d06 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,11 +1,16 @@ +include(../cmake/linker-map.cmake) ####################################### # NFC example add_executable(nfc nfc.c) +add_linker_map_for_target(nfc) target_link_libraries(nfc ${PRODUCT_NAME}) +add_executable(nfc_simulator nfc_simulator.c stateless_rp.c) +add_linker_map_for_target(nfc_simulator) +target_link_libraries(nfc_simulator ${PRODUCT_NAME}) + ####################################### -# FIDO2 authenticator simulator example +# Test applications -add_executable(nfc_simulator nfc_simulator.c) -target_link_libraries(nfc_simulator ${PRODUCT_NAME}) +add_subdirectory(measurements) diff --git a/examples/measurements/CMakeLists.txt b/examples/measurements/CMakeLists.txt new file mode 100644 index 0000000..4c66d1b --- /dev/null +++ b/examples/measurements/CMakeLists.txt @@ -0,0 +1,15 @@ +include(../../cmake/linker-map.cmake) + +set(measurement_dependencies gpio.c) + +function(add_measurement name) + add_executable(${name} "${name}.c" ${measurement_dependencies}) + add_linker_map_for_target(${name}) + target_link_libraries(${name} ${PRODUCT_NAME}) +endfunction() + +add_measurement("aes_gcm_measure") +add_measurement("ed25519_measure") +add_measurement("sha256_measure") +add_measurement("sha512_measure") +add_measurement("inflate_measure") diff --git a/examples/measurements/aes_gcm_measure.c b/examples/measurements/aes_gcm_measure.c new file mode 100644 index 0000000..e999f95 --- /dev/null +++ b/examples/measurements/aes_gcm_measure.c @@ -0,0 +1,71 @@ +/* + * 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 "fido.h" +#include "gpio.h" + +#define SAMPLES 20 + +// See scripts/gen_aes_gcm.py +static const uint8_t key[] = { 0x7d, 0x1a, 0x22, 0xe8, 0x33, 0x8c, 0xf9, 0x8c, 0x18, 0x4a, 0x36, 0xd7, 0x1f, 0x53, 0x57, 0x06, 0xe7, 0x61, 0xab, 0x8c, 0xe9, 0xe3, 0xca, 0xde, 0x0e, 0x18, 0x60, 0xdf, 0xa9, 0xb2, 0x6f, 0x36 }; +static const uint8_t associated_data[12] = "fidoonmicros"; +static const uint8_t nonce[] = { 0xb7, 0x3a, 0x1b, 0x33, 0x1e, 0xe7, 0xef, 0x59, 0x44, 0xf8, 0x50, 0x73 }; +static const uint8_t ciphertext[] = { 0x20, 0x21, 0x93, 0x59, 0x35, 0x51, 0xec, 0xaa, 0x5c, 0x63, 0xe2, 0x31, 0xbb, 0x1b, 0x12, 0x29, 0x1d, 0x12, 0x24, 0xe5, 0x63, 0x28, 0xfd, 0xcd, 0x8a, 0x3a, 0xee, 0x45, 0x9c, 0x22, 0x32, 0xcb, 0xba, 0x34, 0x2e, 0x18, 0xad, 0xe5, 0xd0, 0xfa, 0x8f, 0x4f, 0xfe, 0x3d, 0xfb, 0xe6, 0xd0, 0x84, 0x4f, 0xcd, 0x1d, 0xfd, 0x34, 0xec, 0x75, 0x7f, 0xef, 0x86, 0x71, 0x37, 0x3c, 0x4b, 0xf1, 0x68, 0x64, 0x21, 0x70, 0x65, 0x82, 0x2c, 0xe6, 0xfb, 0x81, 0x55, 0xfa, 0x87, 0x12, 0xd5, 0x43, 0xfa, 0x41, 0x75, 0x36, 0x47, 0xf3, 0xfe, 0x94, 0x8e, 0xb9, 0x6d, 0xa4, 0x9d, 0x84, 0x7e, 0xb0, 0x81, 0x45, 0x19, 0x78, 0xa2, 0x79, 0x91, 0x41, 0x45, 0x08, 0x04, 0x37, 0xf5, 0xa2, 0x1c, 0xdd, 0x24, 0x90, 0xda, 0xab, 0x76, 0x4e, 0xfb, 0xdc, 0x4f, 0x59, 0x3b, 0x55, 0xd8, 0x30, 0x50, 0xcf, 0x66, 0xe9, 0x7e, 0x42, 0x79, 0xe0, 0x5d, 0x95, 0x8a, 0x59, 0x94, 0xe3, 0x02, 0xfa, 0xcf, 0xf1, 0x10, 0x0e, 0xd1, 0x9d, 0xef, 0x01, 0x53, 0x51, 0x1d, 0xeb, 0xc8, 0x5c, 0x88, 0x74, 0xb5, 0xce, 0x8d, 0x64, 0x9b, 0x55, 0x45, 0xd2, 0xcb, 0xbf, 0xce, 0x62, 0xc2, 0x86, 0x91, 0x05, 0xca, 0xca, 0x63, 0xa3, 0x56, 0x48, 0x0d, 0x14, 0x27, 0x20, 0x0a, 0xa2, 0xfe, 0x14, 0x3b, 0x15, 0x90, 0x83, 0x97, 0xa4, 0x98, 0x07, 0xeb, 0x23, 0xa2, 0x36, 0x16, 0x2c, 0x8d, 0xb6, 0x38, 0xb5, 0xa8, 0x46, 0x1d, 0xde, 0x6e, 0x6e, 0xbd, 0xeb, 0x31, 0xd1, 0x8a, 0xa9, 0x3d, 0xee, 0x10, 0x79, 0xc7, 0x2a, 0xbc, 0xa4, 0x83, 0xe7, 0xae, 0xd9, 0xaa, 0xdd, 0xef, 0x3d, 0x37, 0x1d, 0x73, 0x73, 0x19, 0x4f, 0x94, 0x2d, 0xb1, 0xa6, 0x24, 0x70, 0x36, 0x35, 0xb9, 0x10, 0x2b, 0x81, 0x2e, 0x21, 0x8c, 0x41, 0xef, 0x7b, 0x76, 0xd1, 0x49, 0x10, 0x0d, 0x18, 0x8f, 0x1e, 0x9d, 0xb6, 0x40, 0xef, 0x76, 0xf5, 0xb6, 0xc1, 0xf8, 0xc5, 0x25, 0x1c, 0x34, 0x90, 0xa2, 0xb5, 0x38, 0xa8, 0x7e, 0x27, 0x44, 0xe6, 0x21, 0xb5, 0x4b, 0xca, 0x47, 0x60, 0x42, 0x40, 0xb2, 0x61, 0x3c, 0xb7, 0x10, 0xa6, 0xaa, 0x96, 0x91, 0xc9, 0x91, 0xdc, 0xbd, 0x79, 0xdd, 0xa4, 0xf7, 0xa7, 0x5b, 0x6c, 0x41, 0x89, 0x9e, 0x82, 0xbd, 0x13, 0x01, 0x8b, 0x5b, 0xf0, 0x2f, 0xd7, 0x96, 0xa0, 0x13, 0xad, 0x07, 0x75, 0x09, 0xc7, 0x4a, 0x87, 0xe1, 0x5e, 0x5e, 0xd3, 0xb5, 0xd1, 0xd1, 0xf1, 0xc6, 0xd6, 0x9c, 0x95, 0x77, 0xa6, 0x45, 0x4c, 0x2e, 0xce, 0x12, 0xd5, 0x90, 0xbe, 0x5c, 0x12, 0x76, 0xc3, 0x3c, 0x0d, 0x49, 0x66, 0x04, 0x0a, 0xc2, 0x5e, 0x7a, 0x35, 0xd4, 0xec, 0x7c, 0x2d, 0xc1, 0xba, 0x1f, 0x6d, 0x5b, 0x3d, 0x78, 0x09, 0xf2, 0xdc, 0x6b, 0x06, 0x20, 0x2c, 0x3b, 0x57, 0x5e, 0xb2, 0xec, 0x96, 0x87, 0x27, 0x07, 0x62, 0x51, 0xa6, 0x66, 0xd0, 0x61, 0xaf, 0x8f, 0x6d, 0xea, 0x67, 0xef, 0xcb, 0xb7, 0x99, 0xf4, 0xe6, 0xe5, 0x42, 0x30, 0x44, 0xf6, 0x9f, 0xc2, 0x27, 0x0d, 0x55, 0x4b, 0xc2, 0x97, 0x15, 0x68, 0x9b, 0x13, 0x93, 0x47, 0xf5, 0x0b, 0xd0, 0x28, 0xe5, 0x3a, 0x10, 0x2f, 0xb6, 0x8d, 0xc3, 0x9c, 0x2e, 0x10, 0x35, 0xc6, 0x9c, 0x23, 0xa0, 0xf1, 0x84, 0x21, 0x9f, 0x40, 0x78, 0x67, 0x6b, 0xf8, 0x3c, 0xeb, 0x3c, 0x9b, 0xa7, 0x30, 0x50, 0xcd, 0xf5, 0x5d, 0x73, 0x38, 0x7c, 0x9a, 0xfa, 0x21, 0xbf, 0xb9, 0xa4, 0xa3, 0xa3, 0x63, 0x49, 0xe5, 0x15, 0x23, 0x0d, 0x55, 0xb0, 0xf2, 0x28, 0xb3, 0xb2, 0x81, 0x47, 0x57, 0xea, 0x66, 0x08, 0x4e, 0xd0, 0x09, 0x1e, 0xf0, 0x21, 0xc2, 0x4f, 0x8b, 0x2b, 0x1f, 0x30, 0x2a, 0x48, 0x9f, 0xd5, 0x55, 0xb9, 0xde, 0x4d, 0xf6, 0xe2, 0x3a, 0xc9, 0x9b, 0xbf, 0xbe, 0xb1, 0xd4, 0x3c, 0x74, 0x09, 0x8d, 0x98, 0xa5, 0x51, 0x98, 0x5f, 0x19, 0x39, 0x82, 0xde, 0x19, 0x97, 0xa2, 0x95, 0x2a, 0x2e, 0x2f, 0x0e, 0xe3, 0x3a, 0xdb, 0x54, 0x37, 0x17, 0x84, 0xba, 0xb5, 0x44, 0xbb, 0xed, 0xfb, 0x57, 0xb4, 0xe6, 0xc4, 0x8d, 0xe4, 0x01, 0xb7, 0x84, 0x5f }; +static const uint8_t tag[] = { 0x65, 0xc0, 0xe6, 0x07, 0x14, 0x30, 0x93, 0xde, 0x16, 0xc4, 0xa3, 0x28, 0x59, 0x54, 0x47, 0x09 }; + +int main(void) { + // Wait until the microcontroller booted up to remove increased power consumption in the measurements at the beginning. + delay(3000); + + uint8_t plain[576] = {0}; + + setup_pin(); + pin_off(); + + int e = 0; + + // Test AES GCM decryption. + for (size_t i = 0; i < SAMPLES; ++i) { + pin_on(); + e = fido_aes_gcm_decrypt( + key, + sizeof(key), + nonce, + sizeof(nonce), + ciphertext, + sizeof(ciphertext), + associated_data, + sizeof(associated_data), + tag, + plain + ); + pin_off(); + + delay(500); + } + + delay(1000); + pin_on(); + for (size_t i = 0; i < SAMPLES; ++i) { + e = fido_aes_gcm_decrypt( + key, + sizeof(key), + nonce, + sizeof(nonce), + ciphertext, + sizeof(ciphertext), + associated_data, + sizeof(associated_data), + tag, + plain + ); + } + pin_off(); + + return e; +} diff --git a/examples/measurements/ed25519_measure.c b/examples/measurements/ed25519_measure.c new file mode 100644 index 0000000..f27360d --- /dev/null +++ b/examples/measurements/ed25519_measure.c @@ -0,0 +1,61 @@ +/* + * 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 "fido.h" +#include "gpio.h" + +#include + +#define SAMPLES 20 + +// See scripts/gen_ed25519.py +// This is the DEMO private key corresponding to the public key below. +// static const uint8_t private_key[] = { 0x5b, 0x35, 0xd2, 0x98, 0x87, 0xd9, 0x2d, 0xd7, 0x8b, 0xc9, 0xf2, 0x5f, 0x19, 0xa3, 0xdf, 0xb1, 0x7c, 0xe5, 0x4d, 0x72, 0xd7, 0xe5, 0xdb, 0x29, 0xa7, 0x69, 0xe9, 0x45, 0x14, 0xc9, 0x44, 0xb3 }; +static const uint8_t public_key[] = { 0x5e, 0x51, 0x78, 0x80, 0xf9, 0x31, 0x4f, 0x44, 0x57, 0x6a, 0xfc, 0xe8, 0xd4, 0x1d, 0x77, 0xef, 0xb9, 0xd8, 0x94, 0x5a, 0x57, 0x27, 0xb6, 0x5e, 0x0f, 0xea, 0x41, 0x49, 0x2d, 0x7d, 0x68, 0x80 }; + +// 576 * 'f' +static const uint8_t message[] = { 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66 }; +static const uint8_t signature[] = { 0x2e, 0x55, 0x1a, 0x75, 0xf6, 0x48, 0x01, 0xc0, 0x1f, 0x56, 0x81, 0x22, 0xb3, 0x7a, 0xc2, 0xf5, 0x43, 0xa7, 0x9a, 0x5e, 0x0a, 0xc0, 0xba, 0x9c, 0xbe, 0xdd, 0xc8, 0x71, 0x95, 0xc6, 0x74, 0x82, 0x11, 0x66, 0xea, 0xaf, 0x17, 0x30, 0xb5, 0xbc, 0xf3, 0xef, 0x2b, 0x2c, 0xa1, 0xf0, 0xe7, 0xa4, 0x0c, 0x8a, 0x9b, 0xad, 0x55, 0x06, 0x28, 0x46, 0x2f, 0xdf, 0x51, 0x56, 0xc7, 0x51, 0x88, 0x08 }; + +int main(void) { + // Wait until the microcontroller booted up to remove increased power consumption in the measurements at the beginning. + delay(3000); + + setup_pin(); + pin_off(); + + int e = 0; + + // Test ed25519 verification. + for (size_t i = 0; i < SAMPLES; ++i) { + pin_on(); + e = fido_ed25519_verify( + signature, + public_key, + message, + sizeof(message) + ); + pin_off(); + + delay(500); + } + + delay(1000); + pin_on(); + for (size_t i = 0; i < SAMPLES; ++i) { + e = fido_ed25519_verify( + signature, + public_key, + message, + sizeof(message) + ); + } + pin_off(); + + return e; +} diff --git a/examples/measurements/gpio.c b/examples/measurements/gpio.c new file mode 100644 index 0000000..7bec0cc --- /dev/null +++ b/examples/measurements/gpio.c @@ -0,0 +1,41 @@ +/* + * 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. + */ + +#if defined(__AVR__) + +#include +#include + +#define PIN PB5 + +void setup_pin() { + DDRB |= _BV(PIN); +} + +void pin_on() { + PORTB |= _BV(PIN); +} + +void pin_off() { + PORTB &= ~_BV(PIN); +} + +void delay(double ms) { + for (double i = 0; i < ms; i++) { + _delay_ms(1); + } +} + +#else +// To make the examples compile, default to NOOP. +#warning GPIO does not work on this system, defaulting to nop +void setup_pin() {} +void pin_on() {} +void pin_off() {} +void delay(double ms) {} +#endif diff --git a/examples/measurements/gpio.h b/examples/measurements/gpio.h new file mode 100644 index 0000000..730c665 --- /dev/null +++ b/examples/measurements/gpio.h @@ -0,0 +1,29 @@ +/* + * 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. + */ + +/** + * @brief Setup the logical PPK2 output pin. + */ +void setup_pin(); + +/** + * @brief Turn the logical PPK2 output pin on. + */ +void pin_on(); + +/** + * @brief Turn the logical PPK2 output pin off. + */ +void pin_off(); + +/** + * @brief Delay program execution by given milliseconds. + * + * @param ms Milliseconds to delay program execution + */ +void delay(double ms); diff --git a/examples/measurements/inflate_measure.c b/examples/measurements/inflate_measure.c new file mode 100644 index 0000000..2150efa --- /dev/null +++ b/examples/measurements/inflate_measure.c @@ -0,0 +1,62 @@ +/* + * 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 "tinf.h" +#include "gpio.h" + +#include + +#define SAMPLES 20 + +// See scripts/gen_inflate.py +static const uint8_t uncompressed[] = { 0x0f, 0x12, 0xdc, 0x0d, 0xd9, 0xab, 0x0e, 0x00, 0x96, 0x34, 0xdc, 0xec, 0xc2, 0xcd, 0x27, 0x38, 0x29, 0x18, 0x6e, 0x0a, 0xcf, 0x90, 0xd6, 0xc2, 0xc2, 0xd1, 0x11, 0x06, 0x9c, 0x68, 0xf3, 0xbd, 0x03, 0xdf, 0xe3, 0x4a, 0x7b, 0x6c, 0x40, 0x96, 0x89, 0x00, 0x11, 0xb5, 0x6f, 0xf4, 0xb9, 0xb1, 0x28, 0x9b, 0xd8, 0xbc, 0x40, 0x5e, 0xd6, 0x3e, 0x98, 0xcd, 0xed, 0x0c, 0xea, 0x0d, 0x8f, 0x7d, 0x31, 0xf6, 0xc8, 0x46, 0x11, 0xef, 0x10, 0x69, 0x36, 0xc5, 0x1e, 0x96, 0x52, 0xf4, 0x58, 0x6d, 0xa8, 0x43, 0xf3, 0x64, 0x04, 0xcb, 0x83, 0x2c, 0x93, 0x1b, 0x53, 0x56, 0x0f, 0x3f, 0x18, 0xed, 0x01, 0x53, 0x2f, 0x90, 0xe8, 0x4d, 0xb6, 0x8a, 0xf6, 0x7f, 0x9f, 0xc1, 0xbc, 0x03, 0x90, 0xcf, 0xfa, 0x61, 0xfe, 0xba, 0xd2, 0xfa, 0x95, 0x31, 0x85, 0x51, 0xfe, 0x36, 0x8d, 0x9e, 0xb6, 0xce, 0x02, 0x13, 0xd1, 0x02, 0xa7, 0xea, 0xc4, 0x35, 0x23, 0x84, 0x13, 0x10, 0x39, 0x47, 0x41, 0xcf, 0xca, 0x45, 0xff, 0x5b, 0xf2, 0x21, 0x32, 0x1e, 0x52, 0x39, 0x44, 0x5f, 0xaa, 0x17, 0x7d, 0xd0, 0xb2, 0xc8, 0x0a, 0x2a, 0x51, 0x5d, 0x16, 0x30, 0xe0, 0x55, 0x1e, 0x09, 0x6c, 0xa3, 0x5a, 0x12, 0x33, 0xb4, 0xb2, 0x78, 0x4e, 0xf7, 0x37, 0x1c, 0x2d, 0x32, 0xd8, 0x6f, 0x8b, 0xeb, 0x2b, 0xe4, 0xc1, 0x9c, 0x81, 0x75, 0x43, 0x7d, 0xe0, 0x91, 0x7f, 0xb9, 0xcb, 0xce, 0xc5, 0x08, 0xc4, 0xe0, 0x37, 0x10, 0xcf, 0xed, 0xd7, 0x68, 0xb1, 0xcb, 0x34, 0x4b, 0x6a, 0xc6, 0x37, 0x99, 0x6d, 0x60, 0xbf, 0x1f, 0x17, 0x92, 0x6f, 0x36, 0x0b, 0x6c, 0x9e, 0x2a, 0x73, 0xdb, 0x8a, 0xdd, 0xa7, 0x0e, 0xfa, 0xcb, 0xd7, 0xfd, 0x43, 0xd6, 0x98, 0x10, 0x81, 0x4f, 0x30, 0xf0, 0x5d, 0xcd, 0xb7, 0x06, 0x9e, 0x3c, 0x91, 0x34, 0xf3, 0x3b, 0xbb, 0xc1, 0x1a, 0x5b, 0x40, 0x36, 0xc1, 0x88, 0xfc, 0x30, 0xd6, 0x02, 0xe5, 0x3f, 0xf1, 0xbd, 0xaa, 0x4d, 0xae, 0x9d, 0xc4, 0x6a, 0xd1, 0xa2, 0x54, 0xaa, 0x13, 0x88, 0x08, 0xe2, 0x2f, 0x09, 0x1d, 0xdb, 0xb5, 0x5c, 0x8e, 0xad, 0x33, 0xd2, 0x17, 0x37, 0xd3, 0xab, 0x7c, 0x9b, 0xa8, 0x34, 0xa1, 0x5b, 0xfa, 0x69, 0x48, 0x4e, 0xb5, 0xc2, 0x36, 0xed, 0x3e, 0xc3, 0x50, 0x14, 0xc9, 0x52, 0x5f, 0x53, 0x69, 0xd2, 0xe3, 0x52, 0x17, 0xd6, 0x6d, 0xd4, 0x28, 0x1b, 0x11, 0x30, 0x57, 0xca, 0xb1, 0x06, 0x2d, 0xc5, 0x93, 0x80, 0xfc, 0x5c, 0x22, 0x3a, 0x7e, 0xba, 0x36, 0x90, 0x64, 0x10, 0xfb, 0x1d, 0x4c, 0x32, 0x14, 0x8d, 0x66, 0x71, 0x04, 0x06, 0x1f, 0x79, 0x83, 0x78, 0x05, 0x5b, 0x2a, 0x83, 0x34, 0x99, 0x51, 0x57, 0xcc, 0x14, 0x91, 0x14, 0xb7, 0xe5, 0x7f, 0xa0, 0xa1, 0x74, 0x15, 0x29, 0xcc, 0xad, 0xfc, 0x35, 0x5e, 0xdc, 0xfb, 0x7f, 0xd7, 0x55, 0x27, 0xbd, 0x0e, 0xcd, 0x5f, 0x28, 0xcc, 0x67, 0x79, 0x9f, 0x0b, 0x31, 0x36, 0x95, 0x2b, 0xc5, 0xff, 0xd2, 0xe9, 0xe5, 0x83, 0xd3, 0x50, 0xad, 0xa9, 0xc4, 0xeb, 0x9e, 0xf9, 0x09, 0xe0, 0xbd, 0xca, 0xcd, 0xa5, 0x84, 0xe8, 0xde, 0xea, 0x11, 0x7d, 0xa6, 0xe2, 0xd8, 0x3f, 0x09, 0x81, 0x4c, 0x32, 0x73, 0xca, 0x6d, 0x87, 0x6b, 0x93, 0xd2, 0x21, 0x51, 0x1c, 0x43, 0xaf, 0xf2, 0xa9, 0xf6, 0xa5, 0x47, 0x30, 0x28, 0xc6, 0x24, 0x07, 0xed, 0x5e, 0xff, 0x1f, 0xfa, 0x43, 0x16, 0x10, 0x50, 0xbb, 0xef, 0x24, 0x0a, 0xfb, 0xda, 0xce, 0x05, 0xf7, 0xad, 0x67, 0x54, 0x78, 0xaa, 0xf2, 0xea, 0x5f, 0xf7, 0x4d, 0x80, 0x57, 0xec, 0x82, 0x3f, 0xf3, 0x47, 0x14, 0xf2, 0xe9, 0x56, 0x82, 0x23, 0x18, 0xea, 0xe1, 0xce, 0xed, 0x54, 0x88, 0xda, 0x37, 0x9a, 0x31, 0xa7, 0xc0, 0xd5, 0x75, 0xa6, 0xf7, 0x33, 0x28, 0x82, 0x54, 0x80, 0x6b, 0x1b, 0xcb, 0x35, 0xab, 0x12, 0x9a, 0x25, 0x0c, 0x7e, 0x45, 0x16, 0x62, 0x54, 0x43, 0x09, 0xf0, 0x7b, 0xef, 0x4b, 0xaf, 0xac, 0x88, 0x31, 0x7b, 0xb8, 0xa0, 0x55, 0xa7, 0xff, 0xb5, 0x7a, 0x51, 0x52, 0x5c, 0x9a, 0xdc, 0x1a, 0xd7, 0xf0 }; +static const uint8_t source[] = { 0x01, 0x40, 0x02, 0xbf, 0xfd, 0x0f, 0x12, 0xdc, 0x0d, 0xd9, 0xab, 0x0e, 0x00, 0x96, 0x34, 0xdc, 0xec, 0xc2, 0xcd, 0x27, 0x38, 0x29, 0x18, 0x6e, 0x0a, 0xcf, 0x90, 0xd6, 0xc2, 0xc2, 0xd1, 0x11, 0x06, 0x9c, 0x68, 0xf3, 0xbd, 0x03, 0xdf, 0xe3, 0x4a, 0x7b, 0x6c, 0x40, 0x96, 0x89, 0x00, 0x11, 0xb5, 0x6f, 0xf4, 0xb9, 0xb1, 0x28, 0x9b, 0xd8, 0xbc, 0x40, 0x5e, 0xd6, 0x3e, 0x98, 0xcd, 0xed, 0x0c, 0xea, 0x0d, 0x8f, 0x7d, 0x31, 0xf6, 0xc8, 0x46, 0x11, 0xef, 0x10, 0x69, 0x36, 0xc5, 0x1e, 0x96, 0x52, 0xf4, 0x58, 0x6d, 0xa8, 0x43, 0xf3, 0x64, 0x04, 0xcb, 0x83, 0x2c, 0x93, 0x1b, 0x53, 0x56, 0x0f, 0x3f, 0x18, 0xed, 0x01, 0x53, 0x2f, 0x90, 0xe8, 0x4d, 0xb6, 0x8a, 0xf6, 0x7f, 0x9f, 0xc1, 0xbc, 0x03, 0x90, 0xcf, 0xfa, 0x61, 0xfe, 0xba, 0xd2, 0xfa, 0x95, 0x31, 0x85, 0x51, 0xfe, 0x36, 0x8d, 0x9e, 0xb6, 0xce, 0x02, 0x13, 0xd1, 0x02, 0xa7, 0xea, 0xc4, 0x35, 0x23, 0x84, 0x13, 0x10, 0x39, 0x47, 0x41, 0xcf, 0xca, 0x45, 0xff, 0x5b, 0xf2, 0x21, 0x32, 0x1e, 0x52, 0x39, 0x44, 0x5f, 0xaa, 0x17, 0x7d, 0xd0, 0xb2, 0xc8, 0x0a, 0x2a, 0x51, 0x5d, 0x16, 0x30, 0xe0, 0x55, 0x1e, 0x09, 0x6c, 0xa3, 0x5a, 0x12, 0x33, 0xb4, 0xb2, 0x78, 0x4e, 0xf7, 0x37, 0x1c, 0x2d, 0x32, 0xd8, 0x6f, 0x8b, 0xeb, 0x2b, 0xe4, 0xc1, 0x9c, 0x81, 0x75, 0x43, 0x7d, 0xe0, 0x91, 0x7f, 0xb9, 0xcb, 0xce, 0xc5, 0x08, 0xc4, 0xe0, 0x37, 0x10, 0xcf, 0xed, 0xd7, 0x68, 0xb1, 0xcb, 0x34, 0x4b, 0x6a, 0xc6, 0x37, 0x99, 0x6d, 0x60, 0xbf, 0x1f, 0x17, 0x92, 0x6f, 0x36, 0x0b, 0x6c, 0x9e, 0x2a, 0x73, 0xdb, 0x8a, 0xdd, 0xa7, 0x0e, 0xfa, 0xcb, 0xd7, 0xfd, 0x43, 0xd6, 0x98, 0x10, 0x81, 0x4f, 0x30, 0xf0, 0x5d, 0xcd, 0xb7, 0x06, 0x9e, 0x3c, 0x91, 0x34, 0xf3, 0x3b, 0xbb, 0xc1, 0x1a, 0x5b, 0x40, 0x36, 0xc1, 0x88, 0xfc, 0x30, 0xd6, 0x02, 0xe5, 0x3f, 0xf1, 0xbd, 0xaa, 0x4d, 0xae, 0x9d, 0xc4, 0x6a, 0xd1, 0xa2, 0x54, 0xaa, 0x13, 0x88, 0x08, 0xe2, 0x2f, 0x09, 0x1d, 0xdb, 0xb5, 0x5c, 0x8e, 0xad, 0x33, 0xd2, 0x17, 0x37, 0xd3, 0xab, 0x7c, 0x9b, 0xa8, 0x34, 0xa1, 0x5b, 0xfa, 0x69, 0x48, 0x4e, 0xb5, 0xc2, 0x36, 0xed, 0x3e, 0xc3, 0x50, 0x14, 0xc9, 0x52, 0x5f, 0x53, 0x69, 0xd2, 0xe3, 0x52, 0x17, 0xd6, 0x6d, 0xd4, 0x28, 0x1b, 0x11, 0x30, 0x57, 0xca, 0xb1, 0x06, 0x2d, 0xc5, 0x93, 0x80, 0xfc, 0x5c, 0x22, 0x3a, 0x7e, 0xba, 0x36, 0x90, 0x64, 0x10, 0xfb, 0x1d, 0x4c, 0x32, 0x14, 0x8d, 0x66, 0x71, 0x04, 0x06, 0x1f, 0x79, 0x83, 0x78, 0x05, 0x5b, 0x2a, 0x83, 0x34, 0x99, 0x51, 0x57, 0xcc, 0x14, 0x91, 0x14, 0xb7, 0xe5, 0x7f, 0xa0, 0xa1, 0x74, 0x15, 0x29, 0xcc, 0xad, 0xfc, 0x35, 0x5e, 0xdc, 0xfb, 0x7f, 0xd7, 0x55, 0x27, 0xbd, 0x0e, 0xcd, 0x5f, 0x28, 0xcc, 0x67, 0x79, 0x9f, 0x0b, 0x31, 0x36, 0x95, 0x2b, 0xc5, 0xff, 0xd2, 0xe9, 0xe5, 0x83, 0xd3, 0x50, 0xad, 0xa9, 0xc4, 0xeb, 0x9e, 0xf9, 0x09, 0xe0, 0xbd, 0xca, 0xcd, 0xa5, 0x84, 0xe8, 0xde, 0xea, 0x11, 0x7d, 0xa6, 0xe2, 0xd8, 0x3f, 0x09, 0x81, 0x4c, 0x32, 0x73, 0xca, 0x6d, 0x87, 0x6b, 0x93, 0xd2, 0x21, 0x51, 0x1c, 0x43, 0xaf, 0xf2, 0xa9, 0xf6, 0xa5, 0x47, 0x30, 0x28, 0xc6, 0x24, 0x07, 0xed, 0x5e, 0xff, 0x1f, 0xfa, 0x43, 0x16, 0x10, 0x50, 0xbb, 0xef, 0x24, 0x0a, 0xfb, 0xda, 0xce, 0x05, 0xf7, 0xad, 0x67, 0x54, 0x78, 0xaa, 0xf2, 0xea, 0x5f, 0xf7, 0x4d, 0x80, 0x57, 0xec, 0x82, 0x3f, 0xf3, 0x47, 0x14, 0xf2, 0xe9, 0x56, 0x82, 0x23, 0x18, 0xea, 0xe1, 0xce, 0xed, 0x54, 0x88, 0xda, 0x37, 0x9a, 0x31, 0xa7, 0xc0, 0xd5, 0x75, 0xa6, 0xf7, 0x33, 0x28, 0x82, 0x54, 0x80, 0x6b, 0x1b, 0xcb, 0x35, 0xab, 0x12, 0x9a, 0x25, 0x0c, 0x7e, 0x45, 0x16, 0x62, 0x54, 0x43, 0x09, 0xf0, 0x7b, 0xef, 0x4b, 0xaf, 0xac, 0x88, 0x31, 0x7b, 0xb8, 0xa0, 0x55, 0xa7, 0xff, 0xb5, 0x7a, 0x51, 0x52, 0x5c, 0x9a, 0xdc, 0x1a, 0xd7, 0xf0 }; + +int main(void) { + // Wait until the microcontroller booted up to remove increased power consumption in the measurements at the beginning. + delay(3000); + + uint8_t dest[sizeof(uncompressed)] = {0}; + uint32_t dest_len = sizeof(dest); + + setup_pin(); + pin_off(); + + int e = 0; + + // Test inflate. + for (size_t i = 0; i < SAMPLES; ++i) { + pin_on(); + for (size_t j = 0; j < 100; j++) { + e = tinf_uncompress( + dest, + &dest_len, + source, + sizeof(source) + ); + } + pin_off(); + delay(500); + } + + delay(1000); + pin_on(); + for (size_t i = 0; i < SAMPLES; ++i) { + for (size_t j = 0; j < 100; j++) { + e = tinf_uncompress( + dest, + &dest_len, + source, + sizeof(source) + ); + } + } + pin_off(); + + return e; +} diff --git a/examples/measurements/scripts/gen_aes_gcm.py b/examples/measurements/scripts/gen_aes_gcm.py new file mode 100755 index 0000000..b2da056 --- /dev/null +++ b/examples/measurements/scripts/gen_aes_gcm.py @@ -0,0 +1,24 @@ +#!/bin/env python + +import os +from cryptography.hazmat.primitives.ciphers.aead import AESGCM + +hex_arrayify = lambda x: '{ ' + ', '.join([f'0x{i:02x}' for i in x]) + ' }' + +key = AESGCM.generate_key(bit_length=256) +print(f'const uint8_t key[] = {hex_arrayify(key)};') + +aad = b'fidoonmicros' +print(f'const uint8_t associated_data[] = "{aad.decode()}";') + +nonce = os.urandom(12) +print(f'const uint8_t nonce[] = {hex_arrayify(nonce)};') + +data = 576 * b'f' + +aesgcm = AESGCM(key) +encrypted = aesgcm.encrypt(nonce, data, aad) +ct = encrypted[:-16] +tag = encrypted[-16:] +print(f'const uint8_t ciphertext[] = {hex_arrayify(ct)};') +print(f'const uint8_t tag[] = {hex_arrayify(tag)};') diff --git a/examples/measurements/scripts/gen_ed25519.py b/examples/measurements/scripts/gen_ed25519.py new file mode 100755 index 0000000..84264d7 --- /dev/null +++ b/examples/measurements/scripts/gen_ed25519.py @@ -0,0 +1,19 @@ +#!/bin/env python + +from cryptography.hazmat.primitives import serialization +from cryptography.hazmat.primitives.asymmetric import ed25519 + +hex_arrayify = lambda x: '{ ' + ', '.join([f'0x{i:02x}' for i in x]) + ' }' + +key = ed25519.Ed25519PrivateKey.generate() +key_bytes = key.private_bytes(encoding=serialization.Encoding.Raw,format=serialization.PrivateFormat.Raw,encryption_algorithm=serialization.NoEncryption()) +print(f'const uint8_t private_key[] = {hex_arrayify(key_bytes)};') + +pub_bytes = key.public_key().public_bytes(encoding=serialization.Encoding.Raw,format=serialization.PublicFormat.Raw) +print(f'const uint8_t public_key[] = {hex_arrayify(pub_bytes)};') + +message = 576 * b'f' +print(f'const uint8_t message[] = {hex_arrayify(message)};') + +signature = key.sign(message) +print(f'const uint8_t signature[] = {hex_arrayify(signature)};') diff --git a/examples/measurements/scripts/gen_inflate.py b/examples/measurements/scripts/gen_inflate.py new file mode 100755 index 0000000..7c8c0f4 --- /dev/null +++ b/examples/measurements/scripts/gen_inflate.py @@ -0,0 +1,14 @@ +#!/bin/env python + +import zlib +import os + +hex_arrayify = lambda x: '{ ' + ', '.join([f'0x{i:02x}' for i in x]) + ' }' + +uncompressed = os.urandom(576) +print(f'const uint8_t uncompressed[] = {hex_arrayify(uncompressed)};') + +c = zlib.compressobj(wbits=-15) +c.compress(uncompressed) +compressed = c.flush() +print(f'const uint8_t source[] = {hex_arrayify(compressed)};') diff --git a/examples/measurements/scripts/gen_sha256.py b/examples/measurements/scripts/gen_sha256.py new file mode 100755 index 0000000..b012095 --- /dev/null +++ b/examples/measurements/scripts/gen_sha256.py @@ -0,0 +1,11 @@ +#!/bin/env python + +import hashlib + +hex_arrayify = lambda x: '{ ' + ', '.join([f'0x{i:02x}' for i in x]) + ' }' + +data = 576 * b'f' +print(f'const uint8_t data[] = {hex_arrayify(data)};') + +hash = hashlib.sha256(data).digest() +print(f'const uint8_t hash[] = {hex_arrayify(hash)};') diff --git a/examples/measurements/scripts/gen_sha512.py b/examples/measurements/scripts/gen_sha512.py new file mode 100755 index 0000000..4be6875 --- /dev/null +++ b/examples/measurements/scripts/gen_sha512.py @@ -0,0 +1,11 @@ +#!/bin/env python + +import hashlib + +hex_arrayify = lambda x: '{ ' + ', '.join([f'0x{i:02x}' for i in x]) + ' }' + +data = 576 * b'f' +print(f'const uint8_t data[] = {hex_arrayify(data)};') + +hash = hashlib.sha512(data).digest() +print(f'const uint8_t hash[] = {hex_arrayify(hash)};') diff --git a/examples/measurements/sha256_measure.c b/examples/measurements/sha256_measure.c new file mode 100644 index 0000000..3976df4 --- /dev/null +++ b/examples/measurements/sha256_measure.c @@ -0,0 +1,54 @@ +/* + * 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 "fido.h" +#include "gpio.h" + +#define SAMPLES 20 + +// See scripts/gen_sha256.py +static const uint8_t data[] = { 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66 }; +// static const uint8_t hash[] = { 0xe4, 0xe1, 0x98, 0x53, 0x7a, 0xfb, 0x1f, 0x3b, 0xb9, 0x3f, 0xae, 0xba, 0x3c, 0x07, 0x7f, 0x8a, 0xfa, 0x1a, 0xac, 0xc9, 0x56, 0xac, 0xb6, 0x58, 0x1c, 0xa4, 0x9a, 0x03, 0xcb, 0x23, 0x3b, 0xaf }; + +int main(void) { + // Wait until the microcontroller booted up to remove increased power consumption in the measurements at the beginning. + delay(3000); + + uint8_t hash[32] = {0}; + + setup_pin(); + pin_off(); + + int e = 0; + + // Test SHA256. + for (size_t i = 0; i < SAMPLES; ++i) { + pin_on(); + fido_sha256( + data, + sizeof(data), + hash + ); + pin_off(); + + delay(500); + } + + delay(1000); + pin_on(); + for (size_t i = 0; i < SAMPLES; ++i) { + fido_sha256( + data, + sizeof(data), + hash + ); + } + pin_off(); + + return e; +} diff --git a/examples/measurements/sha512_measure.c b/examples/measurements/sha512_measure.c new file mode 100644 index 0000000..f0107e5 --- /dev/null +++ b/examples/measurements/sha512_measure.c @@ -0,0 +1,53 @@ +/* + * 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 "fido.h" +#include "gpio.h" + +#define SAMPLES 20 + +// See scripts/gen_sha512.py +static const uint8_t data[] = { 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66 }; +// static const uint8_t hash[] = { 0xb5, 0xe3, 0x6d, 0x53, 0xed, 0x80, 0x78, 0xdb, 0xda, 0xfa, 0xde, 0xe3, 0x97, 0x04, 0xbf, 0x09, 0xf9, 0xb6, 0x1e, 0xc5, 0xee, 0xd6, 0xd0, 0x3a, 0xda, 0x60, 0x32, 0x73, 0x62, 0x6a, 0x03, 0xcd, 0x4f, 0x5b, 0x52, 0x16, 0xea, 0x71, 0x87, 0xa6, 0x3f, 0x0a, 0x48, 0xa4, 0x31, 0x42, 0x6b, 0xff, 0xb9, 0xbc, 0x91, 0xeb, 0x3e, 0xf6, 0xe6, 0xa1, 0xd1, 0xab, 0xb8, 0x47, 0x49, 0xba, 0x30, 0x8b }; + +int main(void) { + // Wait until the microcontroller booted up to remove increased power consumption in the measurements at the beginning. + delay(3000); + + uint8_t hash[64] = {0}; + + setup_pin(); + pin_off(); + + int e = 0; + + // Test SHA512. + for (size_t i = 0; i < SAMPLES; ++i) { + pin_on(); + fido_sha512( + data, + sizeof(data), + hash + ); + pin_off(); + delay(500); + } + + delay(1000); + pin_on(); + for (size_t i = 0; i < SAMPLES; ++i) { + fido_sha512( + data, + sizeof(data), + hash + ); + } + pin_off(); + + return e; +} diff --git a/examples/nfc_simulator.c b/examples/nfc_simulator.c index fab1461..c070c60 100644 --- a/examples/nfc_simulator.c +++ b/examples/nfc_simulator.c @@ -7,17 +7,18 @@ */ #include "fido.h" +#include "stateless_rp.h" #include #include #include -static void *example_open() { +static void *mock_open() { printf("open\n"); return (void*)1; // Just return a fake handle for this device. }; -static void example_close(void *handle) { +static void mock_close(void *handle) { printf("close\n"); } @@ -32,7 +33,7 @@ enum fido_state { static enum fido_state sim_state = FIDO_STATE_UNINIT; static size_t read_offset = 0; -static int example_read(void *handle, unsigned char *buf, const size_t len) { +static int mock_read(void *handle, unsigned char *buf, const size_t len) { printf("trying to read %zu bytes\n", len); const uint8_t *copy_pointer = NULL; size_t copy_len = 0; @@ -52,7 +53,17 @@ static int example_read(void *handle, unsigned char *buf, const size_t len) { // https://fidoalliance.org/specs/fido-v2.1-ps-20210615/fido-client-to-authenticator-protocol-v2.1-ps-20210615.html#authenticatorGetInfo static const uint8_t get_info_response[] = { FIDO_OK, - // {1: ["FIDO_2_1"], 2: ["largeBlobKey"], 3: h'30313233343536373839303132333435', 4: {"largeBlobs": true}, 5: 2048, 9: ["nfc"], 11: 1024} + /* + { + 1: ["FIDO_2_1"], + 2: ["largeBlobKey"], + 3: h'30313233343536373839303132333435', + 4: {"largeBlobs": true}, + 5: 2048, + 9: ["nfc"], + 11: 1024 + } + */ 0xA7, 0x01, 0x81, 0x68, 0x46, 0x49, 0x44, 0x4F, 0x5F, 0x32, 0x5F, 0x31, 0x02, 0x81, 0x6C, 0x6C, 0x61, 0x72, 0x67, 0x65, 0x42, 0x6C, 0x6F, 0x62, 0x4B, 0x65, 0x79, 0x03, 0x50, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x04, 0xA1, 0x6A, 0x6C, 0x61, 0x72, 0x67, 0x65, 0x42, 0x6C, 0x6F, 0x62, 0x73, 0xF5, 0x05, 0x19, 0x08, 0x00, 0x09, 0x81, 0x63, 0x6E, 0x66, 0x63, 0x0B, 0x19, 0x04, 0x00, }; copy_pointer = get_info_response; @@ -61,15 +72,34 @@ static int example_read(void *handle, unsigned char *buf, const size_t len) { } case FIDO_STATE_GET_LARGE_BLOB: { - // plaintext: kitten - // key: 0xCA, 0x97, 0x81, 0x12, 0xCA, 0x1B, 0xBD, 0xCA, 0xFA, 0xC2, 0x31, 0xB3, 0x9A, 0x23, 0xDC, 0x4D, 0xA7, 0x86, 0xEF, 0xF8, 0x14, 0x7C, 0x4E, 0x72, 0xB9, 0x80, 0x77, 0x85, 0xAF, 0xEE, 0x48, 0xBB - // [{1: h'53cbebb35d0cf479372a10a94892d8bbfc47a67257cb22958ad655455efb98cd', 2: h'33582CB89E78D63967801A77', 3: 6}] + /* plaintext = credential public key (32) | sign(credential public key, updater private key) (64) + * plaintext: 5AED41A105274508E24A11827FA9054E4E330EC40F82868D122EC7F0A9D80D04EB9B093245D9E76102F67103B9DDE76C79D1803AF60D39230954C3BF627BC8F284E2CFFC8E33CEB6D958F290A70A2F8F6A4FB0CB761EF4BA14AB771ED908A202 + * key: 59454c4c4f57205355424d4152494e4559454c4c4f57205355424d4152494e45 + * iv: 1800788e6a01f9ca493d40b9 + * ciphertext: d23d47fe7fa834f11edd1bd0f8ec2d70937bfa8089d97b9dbca7f389770e793cdb3a6932ac629243ab048284e56c6ec7d688cf39518188b7b5ba1650f0b1ede1983683f6f1a95995a16425038f1b5cc01d78b111100daee82c6961060000094b17762570a3 + * tag: 28e31509a387b77ee87fee5af7e841d9 + * updater private key: a8ee4d2bd5ae090abca98a066ca5b3a6228489f59e3090876562b9798ae70515 + * updater public key: fe38c2fd0b68c6f70ac333c39d282d263f833a4808901a46ee0ee7e8e0c12d77 + */ static const uint8_t get_large_blob_response[] = { FIDO_OK, - // {1: h'81A301582053CBEBB35D0CF479372A10A94892D8BBFC47A67257CB22958AD655455EFB98CD024C33582CB89E78D63967801A7703060b66d4ae669185b3f4722c5f576e172d'} - 0xA1, 0x01, 0x58, 0x45, 0x81, 0xA3, 0x01, 0x58, 0x20, 0x53, 0xCB, 0xEB, 0xB3, 0x5D, 0x0C, 0xF4, 0x79, 0x37, 0x2A, 0x10, 0xA9, 0x48, 0x92, 0xD8, 0xBB, 0xFC, 0x47, 0xA6, 0x72, 0x57, 0xCB, 0x22, 0x95, 0x8A, 0xD6, 0x55, 0x45, 0x5E, 0xFB, 0x98, 0xCD, 0x02, 0x4C, 0x33, 0x58, 0x2C, 0xB8, 0x9E, 0x78, 0xD6, 0x39, 0x67, 0x80, 0x1A, 0x77, 0x03, 0x06, 0x0B, 0x66, 0xD4, 0xAE, 0x66, 0x91, 0x85, 0xB3, 0xF4, 0x72, 0x2C, 0x5F, 0x57, 0x6E, 0x17, 0x2D, - // from Chromium. - // 0xA1, 0x01, 0x58, 0xAC, 0x81, 0xA3, 0x01, 0x58, 0x86, 0x7D, 0xB9, 0x8C, 0x5B, 0x62, 0xC6, 0x84, 0x4A, 0x89, 0xAC, 0x92, 0x87, 0x25, 0x32, 0xE0, 0x09, 0xCF, 0xD6, 0xFB, 0x86, 0x5A, 0xB8, 0x36, 0xF3, 0xD2, 0x46, 0xC7, 0xBD, 0x98, 0x69, 0x9C, 0x9B, 0x6F, 0x42, 0x2F, 0x25, 0xB0, 0x29, 0xCC, 0x6B, 0xAF, 0xB0, 0xE8, 0x33, 0xB4, 0x5F, 0xF7, 0x96, 0x33, 0x3D, 0xED, 0x38, 0x59, 0x95, 0x2F, 0x8B, 0x02, 0x9C, 0x03, 0x09, 0xC9, 0xAE, 0x75, 0xAC, 0x37, 0xC8, 0xB4, 0x70, 0x5D, 0xBB, 0x9D, 0x7D, 0x75, 0xE4, 0x90, 0x50, 0x71, 0xF2, 0x43, 0x7E, 0x77, 0x4C, 0xD6, 0xE1, 0xC1, 0xBA, 0xE2, 0x69, 0x95, 0x23, 0x72, 0xC9, 0x8E, 0xEE, 0xB7, 0x51, 0xED, 0xB5, 0xB0, 0x25, 0x00, 0x81, 0x18, 0xAA, 0xD4, 0xAF, 0x59, 0xC6, 0xF4, 0x8E, 0x84, 0x63, 0x91, 0x97, 0x6F, 0x10, 0xF8, 0xF6, 0x92, 0x34, 0x15, 0x1E, 0x34, 0x52, 0xD4, 0x2A, 0x9E, 0xCA, 0x96, 0x9C, 0x34, 0x5F, 0x68, 0x95, 0x02, 0x4C, 0x6A, 0x26, 0x7B, 0x79, 0x97, 0xBE, 0x23, 0x44, 0x60, 0x33, 0x65, 0xA1, 0x03, 0x18, 0x71, 0x46, 0x86, 0x64, 0x52, 0x87, 0xB8, 0x0B, 0x74, 0x11, 0xEA, 0x56, 0x19, 0xB9, 0xD2, 0x96, 0xDD, + /* + { + 1: h'81A3015875D23D47FE7FA834F11EDD1BD0F8EC2D70937BFA8089D97B9DBCA7F389770E793CDB3A6932AC629243AB048284E56C6EC7D688CF39518188B7B5BA1650F0B1EDE1983683F6F1A95995A16425038F1B5CC01D78B111100DAEE82C6961060000094B17762570A328E31509A387B77EE87FEE5AF7E841D9024C1800788E6A01F9CA493D40B90318605bbf3b0e2479184eb3761cfbbe44aa07' + } + + The value of for the entry with key 1 is the cbor-encoded version of: + [ + { + 1: h'd23d47fe7fa834f11edd1bd0f8ec2d70937bfa8089d97b9dbca7f389770e793cdb3a6932ac629243ab048284e56c6ec7d688cf39518188b7b5ba1650f0b1ede1983683f6f1a95995a16425038f1b5cc01d78b111100daee82c6961060000094b17762570a328e31509a387b77ee87fee5af7e841d9', + 2: h'1800788e6a01f9ca493d40b9', + 3: 96 + } + ] + */ + 0xA1, 0x01, 0x58, 0x9B, + 0x81, 0xA3, 0x01, 0x58, 0x75, 0xD2, 0x3D, 0x47, 0xFE, 0x7F, 0xA8, 0x34, 0xF1, 0x1E, 0xDD, 0x1B, 0xD0, 0xF8, 0xEC, 0x2D, 0x70, 0x93, 0x7B, 0xFA, 0x80, 0x89, 0xD9, 0x7B, 0x9D, 0xBC, 0xA7, 0xF3, 0x89, 0x77, 0x0E, 0x79, 0x3C, 0xDB, 0x3A, 0x69, 0x32, 0xAC, 0x62, 0x92, 0x43, 0xAB, 0x04, 0x82, 0x84, 0xE5, 0x6C, 0x6E, 0xC7, 0xD6, 0x88, 0xCF, 0x39, 0x51, 0x81, 0x88, 0xB7, 0xB5, 0xBA, 0x16, 0x50, 0xF0, 0xB1, 0xED, 0xE1, 0x98, 0x36, 0x83, 0xF6, 0xF1, 0xA9, 0x59, 0x95, 0xA1, 0x64, 0x25, 0x03, 0x8F, 0x1B, 0x5C, 0xC0, 0x1D, 0x78, 0xB1, 0x11, 0x10, 0x0D, 0xAE, 0xE8, 0x2C, 0x69, 0x61, 0x06, 0x00, 0x00, 0x09, 0x4B, 0x17, 0x76, 0x25, 0x70, 0xA3, 0x28, 0xE3, 0x15, 0x09, 0xA3, 0x87, 0xB7, 0x7E, 0xE8, 0x7F, 0xEE, 0x5A, 0xF7, 0xE8, 0x41, 0xD9, 0x02, 0x4C, 0x18, 0x00, 0x78, 0x8E, 0x6A, 0x01, 0xF9, 0xCA, 0x49, 0x3D, 0x40, 0xB9, 0x03, 0x18, 0x60, 0x5B, 0xBF, 0x3B, 0x0E, 0x24, 0x79, 0x18, 0x4E, 0xB3, 0x76, 0x1C, 0xFB, 0xBE, 0x44, 0xAA, 0x07, + 0x90, 0x00, }; copy_pointer = get_large_blob_response; copy_len = sizeof(get_large_blob_response); @@ -77,42 +107,34 @@ static int example_read(void *handle, unsigned char *buf, const size_t len) { } case FIDO_STATE_GET_ASSERTION: { - // RPID: wau.felixgohla.de - // credential id: A30058B6D6BB6F08D40953DA8B8C68EF61BD5C0FD69AF7E33E14E549FA34F817713BF00F938B64E8BCF65FAA4AF46FFB58C540CFDC992CC29C10FF5366575FE2806F97216A0D548A5372299EAAA642356E1A35DAC6BA60E31C0A7011B1471435E5A5E9E9DA2B5533AF93C4DF9C6438D5E5231BBAA98009D20DBC976350408E3866F1CE79CAAD58E2FF1845A3122938702EE295E9C3F564D6505C094493D9CCEADB01EECE6348C7981BF3AC54E0C35DFAAFE98D6B8639474E9528014C4A3867D15064ED2976EE16A70250DF74DF81C00014BEA89467E2073154D0 - // signature count: 5 - // so authdata hex is: 50569158BE61D7A1BA084F80E45E938FD326E0A8DFF07B37036E6C82303AE26B0000000005 - // expected client data hash: 039058C6F2C0CB492C533B0A4D14EF77CC0F78ABCCCED5287D84A1A2011CFB81 - // preimage (authdata + cdh): 50569158BE61D7A1BA084F80E45E938FD326E0A8DFF07B37036E6C82303AE26B0000000005039058C6F2C0CB492C533B0A4D14EF77CC0F78ABCCCED5287D84A1A2011CFB81 - // signature: FF08AB2BD13DCAFCD9FBE0004C14FEA5D7A0D06F198A531DDE6BDF4B55086BC80EC7FC4DFF4B2959F7957B15A9B86099E3DCE6F47559FF751C0ACE902E88E004 - // - // Python script to verify signature: - // from cryptography.hazmat.primitives.asymmetric import ed25519 - // public_key_bytes = bytes.fromhex("C8B0CCF2BD4CB1ABEAE0F6C4C9A7A315BB7A1F6F9E98F5DA6A727E38C9F145A8") - // loaded_public_key = ed25519.Ed25519PublicKey.from_public_bytes(public_key_bytes) - // authdata = bytes.fromhex("50569158BE61D7A1BA084F80E45E938FD326E0A8DFF07B37036E6C82303AE26B0000000005") - // client_data_hash = bytes.fromhex("039058C6F2C0CB492C533B0A4D14EF77CC0F78ABCCCED5287D84A1A2011CFB81") - // preimage = authdata + client_data_hash - // signature = bytes.fromhex("FF08AB2BD13DCAFCD9FBE0004C14FEA5D7A0D06F198A531DDE6BDF4B55086BC80EC7FC4DFF4B2959F7957B15A9B86099E3DCE6F47559FF751C0ACE902E88E004") - // loaded_public_key.verify(signature, preimage) - // - // Python script to sign stuff: - // from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey - // from cryptography.hazmat.primitives.serialization import Encoding, PrivateFormat, PublicFormat, NoEncryption - // private_key = Ed25519PrivateKey.generate() - // print('private key:', private_key.private_bytes(Encoding.Raw, PrivateFormat.Raw, NoEncryption()).hex()) - // signature = private_key.sign(b"blub") - // public_key = private_key.public_key() - // print('public key: ', public_key.public_bytes(Encoding.Raw, PublicFormat.Raw).hex()) - // print('signature:', signature.hex()) - // - // generated private key: 073fc2b58607166290f3e7eaec08d09422a28ce0df26c229674220add2372703 - // thus public key is: 63afd18bf452923564f557c77726d63b730ccca29dabf392bfd52bb5d25e9f60 - // - // complete cbor: {1: {"id": h'A30058B6D6BB6F08D40953DA8B8C68EF61BD5C0FD69AF7E33E14E549FA34F817713BF00F938B64E8BCF65FAA4AF46FFB58C540CFDC992CC29C10FF5366575FE2806F97216A0D548A5372299EAAA642356E1A35DAC6BA60E31C0A7011B1471435E5A5E9E9DA2B5533AF93C4DF9C6438D5E5231BBAA98009D20DBC976350408E3866F1CE79CAAD58E2FF1845A3122938702EE295E9C3F564D6505C094493D9CCEADB01EECE6348C7981BF3AC54E0C35DFAAFE98D6B8639474E9528014C4A3867D15064ED2976EE16A70250DF74DF81C00014BEA89467E2073154D0', "type": "public-key"}, 2: h'50569158BE61D7A1BA084F80E45E938FD326E0A8DFF07B37036E6C82303AE26B0000000005', 3: h'FF08AB2BD13DCAFCD9FBE0004C14FEA5D7A0D06F198A531DDE6BDF4B55086BC80EC7FC4DFF4B2959F7957B15A9B86099E3DCE6F47559FF751C0ACE902E88E004', 4: {"id": h'34313937613430662D393263662D343366622D393438352D323630343163666663633636'}} + /* + * RPID: example.com + * auth data: a379a6f6eeafb9a55e378c118034e2751e682fab9f2d30ab13d2125586ce19470100000042 + * signature count: 42 + * client data hash: 2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a + * signed over data (auth data + client data hash): a379a6f6eeafb9a55e378c118034e2751e682fab9f2d30ab13d2125586ce194701000000422a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a + * signature: c19f47bca338a717b1417d220bf382f0b9202eb26396a8a4df278047a6cd10fe52dfcfd4a4dbc6ca364c805bc820e0e285f3dd036d59522f32bf2b63a3c87f05 + * credential public key: 5aed41a105274508e24a11827fa9054e4e330ec40f82868d122ec7f0a9d80d04 + * credential private key: 382ab5f566242a455d17d4e777bd6ed5e064cf616af392fbb1f94056b9f1f05d + * Used https://cyphr.me/ed25519_applet/ed.html to generate and verify signatures. + */ static const uint8_t get_assertion_response[] = { FIDO_OK, - 0xa4, 0x01, 0xa2, 0x62, 0x69, 0x64, 0x58, 0xda, 0xa3, 0x00, 0x58, 0xb6, 0xd6, 0xbb, 0x6f,0x08, 0xd4, 0x09, 0x53, 0xda, 0x8b, 0x8c, 0x68, 0xef, 0x61, 0xbd, 0x5c, 0x0f, 0xd6, 0x9a, 0xf7,0xe3, 0x3e, 0x14, 0xe5, 0x49, 0xfa, 0x34, 0xf8, 0x17, 0x71, 0x3b, 0xf0, 0x0f, 0x93, 0x8b, 0x64,0xe8, 0xbc, 0xf6, 0x5f, 0xaa, 0x4a, 0xf4, 0x6f, 0xfb, 0x58, 0xc5, 0x40, 0xcf, 0xdc, 0x99, 0x2c,0xc2, 0x9c, 0x10, 0xff, 0x53, 0x66, 0x57, 0x5f, 0xe2, 0x80, 0x6f, 0x97, 0x21, 0x6a, 0x0d, 0x54,0x8a, 0x53, 0x72, 0x29, 0x9e, 0xaa, 0xa6, 0x42, 0x35, 0x6e, 0x1a, 0x35, 0xda, 0xc6, 0xba, 0x60,0xe3, 0x1c, 0x0a, 0x70, 0x11, 0xb1, 0x47, 0x14, 0x35, 0xe5, 0xa5, 0xe9, 0xe9, 0xda, 0x2b, 0x55,0x33, 0xaf, 0x93, 0xc4, 0xdf, 0x9c, 0x64, 0x38, 0xd5, 0xe5, 0x23, 0x1b, 0xba, 0xa9, 0x80, 0x09,0xd2, 0x0d, 0xbc, 0x97, 0x63, 0x50, 0x40, 0x8e, 0x38, 0x66, 0xf1, 0xce, 0x79, 0xca, 0xad, 0x58,0xe2, 0xff, 0x18, 0x45, 0xa3, 0x12, 0x29, 0x38, 0x70, 0x2e, 0xe2, 0x95, 0xe9, 0xc3, 0xf5, 0x64,0xd6, 0x50, 0x5c, 0x09, 0x44, 0x93, 0xd9, 0xcc, 0xea, 0xdb, 0x01, 0xee, 0xce, 0x63, 0x48, 0xc7,0x98, 0x1b, 0xf3, 0xac, 0x54, 0xe0, 0xc3, 0x5d, 0xfa, 0xaf, 0xe9, 0x8d, 0x6b, 0x86, 0x39, 0x47,0x4e, 0x95, 0x28, 0x01, 0x4c, 0x4a, 0x38, 0x67, 0xd1, 0x50, 0x64, 0xed, 0x29, 0x76, 0xee, 0x16,0xa7, 0x02, 0x50, 0xdf, 0x74, 0xdf, 0x81, 0xc0, 0x00, 0x14, 0xbe, 0xa8, 0x94, 0x67, 0xe2, 0x07,0x31, 0x54, 0xd0, 0x64, 0x74, 0x79, 0x70, 0x65, 0x6a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2d,0x6b, 0x65, 0x79, 0x02, 0x58, 0x25, 0x50, 0x56, 0x91, 0x58, 0xbe, 0x61, 0xd7, 0xa1, 0xba, 0x08,0x4f, 0x80, 0xe4, 0x5e, 0x93, 0x8f, 0xd3, 0x26, 0xe0, 0xa8, 0xdf, 0xf0, 0x7b, 0x37, 0x03, 0x6e,0x6c, 0x82, 0x30, 0x3a, 0xe2, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x05, 0x03, 0x58, 0x40, 0xff, 0x08,0xab, 0x2b, 0xd1, 0x3d, 0xca, 0xfc, 0xd9, 0xfb, 0xe0, 0x00, 0x4c, 0x14, 0xfe, 0xa5, 0xd7, 0xa0,0xd0, 0x6f, 0x19, 0x8a, 0x53, 0x1d, 0xde, 0x6b, 0xdf, 0x4b, 0x55, 0x08, 0x6b, 0xc8, 0x0e, 0xc7,0xfc, 0x4d, 0xff, 0x4b, 0x29, 0x59, 0xf7, 0x95, 0x7b, 0x15, 0xa9, 0xb8, 0x60, 0x99, 0xe3, 0xdc,0xe6, 0xf4, 0x75, 0x59, 0xff, 0x75, 0x1c, 0x0a, 0xce, 0x90, 0x2e, 0x88, 0xe0, 0x04, 0x04, 0xa1,0x62, 0x69, 0x64, 0x58, 0x24, 0x34, 0x31, 0x39, 0x37, 0x61, 0x34, 0x30, 0x66, 0x2d, 0x39, 0x32,0x63, 0x66, 0x2d, 0x34, 0x33, 0x66, 0x62, 0x2d, 0x39, 0x34, 0x38, 0x35, 0x2d, 0x32, 0x36, 0x30,0x34, 0x31, 0x63, 0x66, 0x66, 0x63, 0x63, 0x36, 0x36 - }; + /* + { + 1: { + "type": "public-key", + "id": h'a9d55f830fedd3aeb44be2a25eb8afbd2fe041abc45240145d14ea28be1ab2ea', + "transports": ["nfc"]}, + 2: h'a379a6f6eeafb9a55e378c118034e2751e682fab9f2d30ab13d2125586ce19470100000042', + 3: h'C19F47BCA338A717B1417D220BF382F0B9202EB26396A8A4DF278047A6CD10FE52DFCFD4A4DBC6CA364C805BC820E0E285F3DD036D59522F32BF2B63A3C87F05', + 4: {"id": h'416c696365'}, + 7: h'59454c4c4f57205355424d4152494e4559454c4c4f57205355424d4152494e45' + } + */ + 0xA5, 0x01, 0xA3, 0x64, 0x74, 0x79, 0x70, 0x65, 0x6A, 0x70, 0x75, 0x62, 0x6C, 0x69, 0x63, 0x2D, 0x6B, 0x65, 0x79, 0x62, 0x69, 0x64, 0x58, 0x20, 0xA9, 0xD5, 0x5F, 0x83, 0x0F, 0xED, 0xD3, 0xAE, 0xB4, 0x4B, 0xE2, 0xA2, 0x5E, 0xB8, 0xAF, 0xBD, 0x2F, 0xE0, 0x41, 0xAB, 0xC4, 0x52, 0x40, 0x14, 0x5D, 0x14, 0xEA, 0x28, 0xBE, 0x1A, 0xB2, 0xEA, 0x6A, 0x74, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72, 0x74, 0x73, 0x81, 0x63, 0x6E, 0x66, 0x63, 0x02, 0x58, 0x25, 0xA3, 0x79, 0xA6, 0xF6, 0xEE, 0xAF, 0xB9, 0xA5, 0x5E, 0x37, 0x8C, 0x11, 0x80, 0x34, 0xE2, 0x75, 0x1E, 0x68, 0x2F, 0xAB, 0x9F, 0x2D, 0x30, 0xAB, 0x13, 0xD2, 0x12, 0x55, 0x86, 0xCE, 0x19, 0x47, 0x01, 0x00, 0x00, 0x00, 0x42, 0x03, 0x58, 0x40, 0xC1, 0x9F, 0x47, 0xBC, 0xA3, 0x38, 0xA7, 0x17, 0xB1, 0x41, 0x7D, 0x22, 0x0B, 0xF3, 0x82, 0xF0, 0xB9, 0x20, 0x2E, 0xB2, 0x63, 0x96, 0xA8, 0xA4, 0xDF, 0x27, 0x80, 0x47, 0xA6, 0xCD, 0x10, 0xFE, 0x52, 0xDF, 0xCF, 0xD4, 0xA4, 0xDB, 0xC6, 0xCA, 0x36, 0x4C, 0x80, 0x5B, 0xC8, 0x20, 0xE0, 0xE2, 0x85, 0xF3, 0xDD, 0x03, 0x6D, 0x59, 0x52, 0x2F, 0x32, 0xBF, 0x2B, 0x63, 0xA3, 0xC8, 0x7F, 0x05, 0x04, 0xA1, 0x62, 0x69, 0x64, 0x45, 0x41, 0x6C, 0x69, 0x63, 0x65, 0x07, 0x58, 0x20, 0x59, 0x45, 0x4C, 0x4C, 0x4F, 0x57, 0x20, 0x53, 0x55, 0x42, 0x4D, 0x41, 0x52, 0x49, 0x4E, 0x45, 0x59, 0x45, 0x4C, 0x4C, 0x4F, 0x57, 0x20, 0x53, 0x55, 0x42, 0x4D, 0x41, 0x52, 0x49, 0x4E, 0x45, + 0x90, 0x00, + }; copy_pointer = get_assertion_response; copy_len = sizeof(get_assertion_response); break; @@ -157,7 +179,7 @@ static int example_read(void *handle, unsigned char *buf, const size_t len) { #define NFC_GET_RESPONSE 0xc0 -static int example_write(void *handle, const unsigned char *buf, const size_t len) { +static int mock_write(void *handle, const unsigned char *buf, const size_t len) { // Output the buffer. printf("writing: "); for (size_t i = 0; i < len; ++i) { @@ -180,76 +202,32 @@ static int example_write(void *handle, const unsigned char *buf, const size_t le sim_state = FIDO_STATE_GET_INFO; break; case FIDO_STATE_GET_INFO: - sim_state = FIDO_STATE_GET_LARGE_BLOB; - break; - case FIDO_STATE_GET_LARGE_BLOB: sim_state = FIDO_STATE_GET_ASSERTION; break; + case FIDO_STATE_GET_ASSERTION: + sim_state = FIDO_STATE_GET_LARGE_BLOB; + break; default: break; } read_offset = 0; return (int)len; } -static const fido_dev_io_t nfc_io = { - .open = example_open, - .close = example_close, - .read = example_read, - .write = example_write +static const fido_dev_io_t mock_nfc_io = { + .open = mock_open, + .close = mock_close, + .read = mock_read, + .write = mock_write }; int main(void) { fido_dev_t dev; - if (fido_init_nfc_device(&dev, &nfc_io) != FIDO_OK) { - return 1; - } - - if (fido_dev_open(&dev) != FIDO_OK) { - return 2; - } - { - // Retrieve large blob. - uint8_t key[] = { - 0xCA, 0x97, 0x81, 0x12, 0xCA, 0x1B, 0xBD, 0xCA, 0xFA, 0xC2, 0x31, 0xB3, 0x9A, 0x23, 0xDC, 0x4D, 0xA7, 0x86, 0xEF, 0xF8, 0x14, 0x7C, 0x4E, 0x72, 0xB9, 0x80, 0x77, 0x85, 0xAF, 0xEE, 0x48, 0xBB, - // from Chromium - // 0xF7, 0x8E, 0x65, 0x59, 0xF4, 0xE8, 0x70, 0xF2, 0xF0, 0x37, 0x41, 0x63, 0x85, 0x31, 0xEF, 0x31, 0x50, 0x8F, 0x76, 0x18, 0x73, 0x4B, 0x68, 0x7A, 0x4A, 0x42, 0x16, 0x65, 0xEA, 0x6A, 0x7F, 0xA2, - }; - fido_blob_t blob; - uint8_t outbuf[2048] = {0}; - fido_blob_reset(&blob, outbuf, sizeof(outbuf)); - if (fido_dev_largeblob_get(&dev, key, sizeof(key), &blob) != FIDO_OK) { - return 3; - } - } - - // Assertion. - { - const uint8_t client_data_hash[] = { - 0x03, 0x90, 0x58, 0xC6, 0xF2, 0xC0, 0xCB, 0x49, 0x2C, 0x53, 0x3B, 0x0A, 0x4D, 0x14, 0xEF, 0x77, 0xCC, 0x0F, 0x78, 0xAB, 0xCC, 0xCE, 0xD5, 0x28, 0x7D, 0x84, 0xA1, 0xA2, 0x01, 0x1C, 0xFB, 0x81, - }; - const uint8_t pubkey[] = { - 0xC8, 0xB0, 0xCC, 0xF2, 0xBD, 0x4C, 0xB1, 0xAB, 0xEA, 0xE0, 0xF6, 0xC4, 0xC9, 0xA7, 0xA3, 0x15, 0xBB, 0x7A, 0x1F, 0x6F, 0x9E, 0x98, 0xF5, 0xDA, 0x6A, 0x72, 0x7E, 0x38, 0xC9, 0xF1, 0x45, 0xA8, - }; - fido_assert_t assertion; - fido_assert_reset(&assertion); - fido_assert_set_client_data_hash(&assertion, client_data_hash); - fido_assert_set_rp(&assertion, "wau.felixgohla.de"); - //fido_assert_set_options(&assertion, FIDO_ASSERT_OPTION_UP); - //fido_assert_set_extensions(&assertion, FIDO_ASSERT_EXTENSION_LARGE_BLOB_KEY); - if (fido_dev_get_assert(&dev, &assertion) != FIDO_OK) { - return 4; - } - int ret; - if ((ret = fido_assert_verify(&assertion, COSE_ALGORITHM_EdDSA, pubkey)) != FIDO_OK) { - printf("%d\n", ret); - return 5; - } - } - - if (fido_dev_close(&dev) != FIDO_OK) { - return 7; + // Initialize device with mock io handlers. + if (fido_init_nfc_device(&dev, &mock_nfc_io) != FIDO_OK) { + return 1; } - return 0; + 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); } diff --git a/examples/stateless_rp.c b/examples/stateless_rp.c new file mode 100644 index 0000000..f0d8750 --- /dev/null +++ b/examples/stateless_rp.c @@ -0,0 +1,59 @@ +#include "stateless_rp.h" + +#include + +int stateless_assert(fido_dev_t *dev, const char *rp_id, const uint8_t *updater_public_key) { + int error = FIDO_OK; + + // Open the device. This also gets the device info. + if ((error = fido_dev_open(dev)) != FIDO_OK) { + return error; + } + + // Prepare assertion. + fido_assert_t assert; + fido_assert_reset(&assert); + uint8_t client_data_hash[ASSERTION_CLIENT_DATA_HASH_LEN]; + + // Just use a constant client data hash for now. + memset(client_data_hash, 42, sizeof(client_data_hash)); + + fido_assert_set_rp(&assert, rp_id); + fido_assert_set_extensions(&assert, FIDO_ASSERT_EXTENSION_LARGE_BLOB_KEY); + fido_assert_set_client_data_hash(&assert, client_data_hash); + + // Perform assertion. It is not verified yet, as this credential public key is unknown at this point in time. + if ((error = fido_dev_get_assert(dev, &assert)) != FIDO_OK) { + return error; + } else if (!assert.reply.has_large_blob_key) { + return FIDO_ERR_UNSUPPORTED_EXTENSION; + } + + // Read the per-credential large blob for this credential. + fido_blob_t blob; + uint8_t blob_buffer[1024] = {0}; + fido_blob_reset(&blob, blob_buffer, sizeof(blob_buffer)); + if ((error = fido_dev_largeblob_get(dev, assert.reply.large_blob_key, LARGEBLOB_KEY_SIZE, &blob)) != FIDO_OK) { + return error; + } + + // blob = credential_public_key (32) | signature(credential_public_key) (64) + uint8_t *credential_public_key = blob.buffer; + uint8_t *credential_public_key_signature = blob.buffer + 32; + + // Verify the signature of the credential public key stored in the large blob. + if((error = fido_ed25519_verify(credential_public_key_signature, updater_public_key, credential_public_key, 32)) != 0) { + return error; + } + + // Now, verify the assertion with the public key from the large blob. + if ((error = fido_assert_verify(&assert, COSE_ALGORITHM_EdDSA, credential_public_key)) != FIDO_OK) { + return error; + } + + if ((error = fido_dev_close(dev)) != FIDO_OK) { + return error; + } + + return error; +} diff --git a/examples/stateless_rp.h b/examples/stateless_rp.h new file mode 100644 index 0000000..87db459 --- /dev/null +++ b/examples/stateless_rp.h @@ -0,0 +1,13 @@ +#pragma once + +#include "fido.h" + +/** + * @brief Perform a stateless RP assertion (à la Baumann et al.). + * + * @param dev The (initialized) device to use. + * @param rp_id The RP ID to use. + * @param updater_public_key The public key of the updater that signed the content of the large blob. + * @return 0 on success, an error code otherwise. + */ +int stateless_assert(fido_dev_t *dev_t, const char *rp_id, const uint8_t *updater_public_key); diff --git a/include/assertion.h b/include/assertion.h index 2b5289c..4f40452 100644 --- a/include/assertion.h +++ b/include/assertion.h @@ -95,7 +95,7 @@ typedef struct fido_assert { /** * @brief Reset an assertion request to a known state. - * + * * @param assert A pointer to the assertion data structure to reset. */ void fido_assert_reset(fido_assert_t *assert); @@ -133,11 +133,11 @@ void fido_assert_set_client_data_hash(fido_assert_t *assert, const uint8_t hash[ /** * @brief Set the client data for an assertion. - * + * * Computes the (SHA256) hash from the given data and stores it in the assertion request. - * + * * Note: This should be non-predictable. - * + * * @param assert A pointer to an assertion request to set the client data hash on. * @param client_data A pointer to the client data buffer. * @param client_data_len The length of the client data. @@ -162,10 +162,10 @@ void fido_assert_set_extensions(fido_assert_t *assert, const fido_assert_ext_t e /** * @brief Verify an assertion. - * + * * @param assert A pointer to an assertion request/reply struct. * @param cose_alg A COSE algorithm identifier. * @param pk The public key to verify the signature with. - * @return int + * @return int */ int fido_assert_verify(const fido_assert_t *assert, const int cose_alg, const uint8_t *pk);