From a54cbd60a1d2d6e3ca5f11cb616f53cffe088dfd Mon Sep 17 00:00:00 2001 From: Conor Patrick Date: Sun, 15 Jul 2018 12:24:32 -0400 Subject: [PATCH] small refactoring, add efm8 reset --- .gitignore | 3 +++ efm32/.cproject | 2 +- efm32/EFM32.hwconf | 5 ++++ efm32/inc/app.h | 6 ++++- efm32/src/InitDevice.c | 3 +++ efm32/src/crypto.c | 12 ++++----- efm32/src/device.c | 59 +++++++++++++++++++++++++++++++++++------- efm32boot/inc/app.h | 4 ++- efm32boot/src/crypto.c | 17 ++++++------ efm32boot/src/main.c | 9 ++++--- fido2/ctap.c | 2 +- fido2/log.h | 8 +++++- fido2/wallet.c | 8 +++--- web/js/wallet.js | 5 ++-- 14 files changed, 104 insertions(+), 39 deletions(-) diff --git a/.gitignore b/.gitignore index 14d4f3d..d67f90e 100644 --- a/.gitignore +++ b/.gitignore @@ -71,3 +71,6 @@ mbedtls/ sl_crypto/ tools/python-fido2/* *.pem +*.bin +*.key + diff --git a/efm32/.cproject b/efm32/.cproject index 1c5ecb7..95d19eb 100644 --- a/efm32/.cproject +++ b/efm32/.cproject @@ -226,7 +226,7 @@ - + diff --git a/efm32/EFM32.hwconf b/efm32/EFM32.hwconf index 9e376b8..d359390 100644 --- a/efm32/EFM32.hwconf +++ b/efm32/EFM32.hwconf @@ -25,6 +25,11 @@ + + + + + diff --git a/efm32/inc/app.h b/efm32/inc/app.h index 528e882..2f2a2c5 100644 --- a/efm32/inc/app.h +++ b/efm32/inc/app.h @@ -8,7 +8,7 @@ #ifndef SRC_APP_H_ #define SRC_APP_H_ - +#define DEBUG_LEVEL 1 #define PRINTING_USE_VCOM @@ -16,6 +16,10 @@ #define BRIDGE_TO_WALLET +//#define DISABLE_CTAPHID_PING +//#define DISABLE_CTAPHID_WINK +#define DISABLE_CTAPHID_CBOR + void printing_init(); diff --git a/efm32/src/InitDevice.c b/efm32/src/InitDevice.c index 12891f7..d4153fc 100644 --- a/efm32/src/InitDevice.c +++ b/efm32/src/InitDevice.c @@ -615,6 +615,9 @@ extern void PORTIO_enter_DefaultMode_from_RESET(void) { // [Port A Configuration]$ // $[Port B Configuration] + + /* Pin PB13 is configured to Push-pull */ + GPIO_PinModeSet(gpioPortB, 13, gpioModePushPull, 1); // [Port B Configuration]$ // $[Port C Configuration] diff --git a/efm32/src/crypto.c b/efm32/src/crypto.c index 3d1eb7e..b9e4e9c 100644 --- a/efm32/src/crypto.c +++ b/efm32/src/crypto.c @@ -91,7 +91,7 @@ void crypto_sha256_hmac_init(uint8_t * key, uint32_t klen, uint8_t * hmac) if(klen > 64) { - printf("Error, key size must be <= 64\n"); + printf2(TAG_ERR,"Error, key size must be <= 64\n"); exit(1); } @@ -121,7 +121,7 @@ void crypto_sha256_hmac_final(uint8_t * key, uint32_t klen, uint8_t * hmac) if(klen > 64) { - printf("Error, key size must be <= 64\n"); + printf2(TAG_ERR,"Error, key size must be <= 64\n"); exit(1); } memmove(buf, key, klen); @@ -274,7 +274,7 @@ void crypto_ecc256_sign(uint8_t * data, int len, uint8_t * sig) if ( uECC_sign(_signing_key, data, len, sig, _es256_curve) == 0) { - printf("error, uECC failed\n"); + printf2(TAG_ERR,"error, uECC failed\n"); exit(1); } @@ -305,7 +305,7 @@ void crypto_ecdsa_sign(uint8_t * data, int len, uint8_t * sig, int MBEDTLS_ECP_I if (_key_len != 32) goto fail; break; default: - printf("error, invalid ECDSA alg specifier\n"); + printf2(TAG_ERR,"error, invalid ECDSA alg specifier\n"); exit(1); } @@ -568,7 +568,7 @@ void crypto_ecc256_make_key_pair(uint8_t * pubkey, uint8_t * privkey) { if (uECC_make_key(pubkey, privkey, _es256_curve) != 1) { - printf("Error, uECC_make_key failed\n"); + printf2(TAG_ERR,"Error, uECC_make_key failed\n"); exit(1); } } @@ -577,7 +577,7 @@ void crypto_ecc256_shared_secret(const uint8_t * pubkey, const uint8_t * privkey { if (uECC_shared_secret(pubkey, privkey, shared_secret, _es256_curve) != 1) { - printf("Error, uECC_shared_secret failed\n"); + printf2(TAG_ERR,"Error, uECC_shared_secret failed\n"); exit(1); } diff --git a/efm32/src/device.c b/efm32/src/device.c index ff1bab2..37b7936 100644 --- a/efm32/src/device.c +++ b/efm32/src/device.c @@ -21,10 +21,13 @@ #include "ctaphid.h" #include "util.h" #include "app.h" +#include "uECC.h" +#include "crypto.h" #define MSG_AVAIL_PIN gpioPortC,9 #define RDY_PIN gpioPortC,10 #define RW_PIN gpioPortD,11 +#define RESET_PIN gpioPortB,13 #define PAGE_SIZE 2048 #define PAGES 128 @@ -302,14 +305,22 @@ int authenticator_is_backup_initialized() } - uint8_t adc_rng(void); +void reset_efm8() +{ + // Reset EFM8 + GPIO_PinOutClear(RESET_PIN); + delay(2); + GPIO_PinOutSet(RESET_PIN); +} + void bootloader_init(void) { /* Chip errata */ - + // Reset EFM8 + GPIO_PinModeSet(RESET_PIN, gpioModePushPull, 1); // status LEDS GPIO_PinModeSet(gpioPortF, @@ -341,8 +352,6 @@ void bootloader_init(void) MSC_Init(); - - } @@ -374,6 +383,9 @@ void device_init(void) // SPI R/w Indicator GPIO_PinModeSet(RW_PIN, gpioModePushPull, 1); + // Reset EFM8 + GPIO_PinModeSet(RESET_PIN, gpioModePushPull, 1); + // USB message rdy ext int // GPIO_ExtIntConfig(gpioPortC, 9, 9, 1, 0,1); // NVIC_EnableIRQ(GPIO_ODD_IRQn); @@ -396,16 +408,17 @@ void device_init(void) uint8_t buf[64]; cbor_encoder_init(&test, buf, 20, 0); - printf("Device init\r\n"); + reset_efm8(); + + printf1(TAG_GEN,"Device init\r\n"); int i=0; for (i = 0; i < sizeof(buf); i++) { buf[i] = adc_rng(); } - dump_hex(buf,sizeof(buf)); } - +#ifdef IS_BOOTLOADER typedef enum { BootWrite = 0x40, @@ -451,6 +464,10 @@ int bootloader_bridge(uint8_t klen, uint8_t * keyh) static int has_erased = 0; BootloaderReq * req = (BootloaderReq * )keyh; uint8_t payload[256]; + uint8_t hash[32]; + uint8_t * pubkey = (uint8_t*)"\x57\xe6\x80\x39\x56\x46\x2f\x0c\x95\xac\x72\x71\xf0\xbc\xe8\x2d\x67\xd0\x59\x29\x2e\x15\x22\x89\x6a\xbd\x3f\x7f\x27\xf3\xc0\xc6\xe2\xd7\x7d\x8a\x9f\xcc\x53\xc5\x91\xb2\x0c\x9c\x3b\x4e\xa4\x87\x31\x67\xb4\xa9\x4b\x0e\x8d\x06\x67\xd8\xc5\xef\x2c\x50\x4a\x55"; + const struct uECC_Curve_t * curve = NULL; + /*printf("bootloader_bridge\n");*/ if (req->len > 255-9) { @@ -471,17 +488,39 @@ int bootloader_bridge(uint8_t klen, uint8_t * keyh) { return CTAP2_ERR_NOT_ALLOWED; } + if (!has_erased) { erase_application(); has_erased = 1; } + if (is_authorized_to_boot()) + { + printf2(TAG_ERR, "Error, boot check bypassed\n"); + exit(1); + } MSC_WriteWordFast(ptr,payload, req->len + (req->len%4)); break; case BootDone: - /*printf("BootDone\n");*/ +// printf("BootDone\n"); + ptr = APPLICATION_START_ADDR; + crypto_sha256_init(); + crypto_sha256_update(ptr, APPLICATION_END_ADDR-APPLICATION_START_ADDR); + crypto_sha256_final(hash); +// printf("hash: "); dump_hex(hash, 32); +// printf("sig: "); dump_hex(payload, 64); + curve = uECC_secp256r1(); + + if (! uECC_verify(pubkey, + hash, + 32, + payload, + curve)) + { + return CTAP2_ERR_OPERATION_DENIED; + } authorize_application(); - NVIC_SystemReset(); + REBOOT_FLAG = 1; break; case BootCheck: /*printf("BootCheck\n");*/ @@ -504,4 +543,4 @@ int is_authorized_to_boot() return *auth == 0; } - +#endif diff --git a/efm32boot/inc/app.h b/efm32boot/inc/app.h index 2fcbcaf..d22dd79 100644 --- a/efm32boot/inc/app.h +++ b/efm32boot/inc/app.h @@ -10,6 +10,8 @@ #define IS_BOOTLOADER +#define DEBUG_LEVEL 0 + #define PRINTING_USE_VCOM #define USING_DEV_BOARD @@ -20,7 +22,7 @@ #define PUSH_BUTTON gpioPortF,6 -#define DISABLE_CTAPHID_PING +//#define DISABLE_CTAPHID_PING #define DISABLE_CTAPHID_WINK #define DISABLE_CTAPHID_CBOR diff --git a/efm32boot/src/crypto.c b/efm32boot/src/crypto.c index b1efb8e..72bea32 100644 --- a/efm32boot/src/crypto.c +++ b/efm32boot/src/crypto.c @@ -19,6 +19,7 @@ #include "ctap.h" #include "device.h" #include "app.h" +#include "log.h" #if defined(USING_PC) || defined(IS_BOOTLOADER) typedef enum @@ -101,7 +102,7 @@ void crypto_sha256_hmac_init(uint8_t * key, uint32_t klen, uint8_t * hmac) if(klen > 64) { - printf("Error, key size must be <= 64\n"); + printf2(TAG_ERR,"Error, key size must be <= 64\n"); exit(1); } @@ -131,7 +132,7 @@ void crypto_sha256_hmac_final(uint8_t * key, uint32_t klen, uint8_t * hmac) if(klen > 64) { - printf("Error, key size must be <= 64\n"); + printf2(TAG_ERR,"Error, key size must be <= 64\n"); exit(1); } memmove(buf, key, klen); @@ -165,7 +166,7 @@ void crypto_ecc256_sign(uint8_t * data, int len, uint8_t * sig) { if ( uECC_sign(_signing_key, data, len, sig, _es256_curve) == 0) { - printf("error, uECC failed\n"); + printf2(TAG_ERR,"error, uECC failed\n"); exit(1); } } @@ -190,19 +191,19 @@ void crypto_ecdsa_sign(uint8_t * data, int len, uint8_t * sig, int MBEDTLS_ECP_I if (_key_len != 32) goto fail; break; default: - printf("error, invalid ECDSA alg specifier\n"); + printf2(TAG_ERR,"error, invalid ECDSA alg specifier\n"); exit(1); } if ( uECC_sign(_signing_key, data, len, sig, curve) == 0) { - printf("error, uECC failed\n"); + printf2(TAG_ERR,"error, uECC failed\n"); exit(1); } return; fail: - printf("error, invalid key length\n"); + printf2(TAG_ERR,"error, invalid key length\n"); exit(1); } @@ -242,7 +243,7 @@ void crypto_ecc256_make_key_pair(uint8_t * pubkey, uint8_t * privkey) { if (uECC_make_key(pubkey, privkey, _es256_curve) != 1) { - printf("Error, uECC_make_key failed\n"); + printf2(TAG_ERR,"Error, uECC_make_key failed\n"); exit(1); } } @@ -251,7 +252,7 @@ void crypto_ecc256_shared_secret(const uint8_t * pubkey, const uint8_t * privkey { if (uECC_shared_secret(pubkey, privkey, shared_secret, _es256_curve) != 1) { - printf("Error, uECC_shared_secret failed\n"); + printf2(TAG_ERR,"Error, uECC_shared_secret failed\n"); exit(1); } diff --git a/efm32boot/src/main.c b/efm32boot/src/main.c index 30cd67b..984600a 100644 --- a/efm32boot/src/main.c +++ b/efm32boot/src/main.c @@ -51,7 +51,7 @@ int main(void) TAG_ERR ); - printf("Bootloader init\r\n"); + printf1(TAG_GEN,"Bootloader init\r\n"); if (GPIO_PinInGet(PUSH_BUTTON) == 0) { @@ -60,8 +60,9 @@ int main(void) ; if (GPIO_PinInGet(PUSH_BUTTON) == 0) { bootmode: - printf("Reflash condition detected\n"); + printf1(TAG_GEN,"Reflash condition detected\n"); ctaphid_init(); + reset_efm8(); /* Infinite loop */ int count = 0; while (1) { @@ -97,13 +98,13 @@ bootmode: } } - printf("Normal boot\n"); + printf1(TAG_GEN,"Normal boot\n"); if (is_authorized_to_boot()) { BOOT_boot(); } else { - printf("Warning: not authorized to boot\n"); + printf1(TAG_GEN,"Warning: not authorized to boot\n"); goto bootmode; } diff --git a/fido2/ctap.c b/fido2/ctap.c index a3dc1b6..e41f829 100644 --- a/fido2/ctap.c +++ b/fido2/ctap.c @@ -890,7 +890,7 @@ uint8_t ctap_update_pin_if_verified(uint8_t * pinEnc, int len, uint8_t * platfor crypto_aes256_decrypt(pinEnc, len); - printf("new pin: %s\n", pinEnc); + printf1(TAG_CP,"new pin: %s\n", pinEnc); ret = strnlen((const char *)pinEnc, NEW_PIN_ENC_MAX_SIZE); if (ret == NEW_PIN_ENC_MAX_SIZE) diff --git a/fido2/log.h b/fido2/log.h index 2f3461c..e7fa99c 100644 --- a/fido2/log.h +++ b/fido2/log.h @@ -1,7 +1,12 @@ #ifndef _LOG_H #define _LOG_H -#define DEBUG_LEVEL 1 +#include "app.h" + +#ifndef DEBUG_LEVEL +#define DEBUG_LEVEL 0 +#endif + #define ENABLE_FILE_LOGGING void LOG(uint32_t tag, const char * filename, int num, const char * fmt, ...); @@ -44,6 +49,7 @@ typedef enum #define printf1(fmt, ...) #define printf2(fmt, ...) #define printf3(fmt, ...) +#define dump_hex1(tag,data,len) #endif diff --git a/fido2/wallet.c b/fido2/wallet.c index 329cc9b..e164435 100644 --- a/fido2/wallet.c +++ b/fido2/wallet.c @@ -390,8 +390,8 @@ int16_t bridge_u2f_to_wallet(uint8_t * _chal, uint8_t * _appid, uint8_t klen, ui { if ( ! check_pinhash(req->pinAuth, msg_buf, reqlen)) { - printf1(TAG_WALLET,"pinAuth is NOT valid\n"); - dump_hex(msg_buf,reqlen); + printf2(TAG_ERR,"pinAuth is NOT valid\n"); + dump_hex1(TAG_ERR,msg_buf,reqlen); ret = CTAP2_ERR_PIN_AUTH_INVALID; goto cleanup; } @@ -427,8 +427,8 @@ int16_t bridge_u2f_to_wallet(uint8_t * _chal, uint8_t * _appid, uint8_t klen, ui { if ( ! check_pinhash(req->pinAuth, msg_buf, reqlen)) { - printf1(TAG_WALLET,"pinAuth is NOT valid\n"); - dump_hex(msg_buf,reqlen); + printf2(TAG_ERR,"pinAuth is NOT valid\n"); + dump_hex1(TAG_ERR,msg_buf,reqlen); ret = CTAP2_ERR_PIN_AUTH_INVALID; goto cleanup; } diff --git a/web/js/wallet.js b/web/js/wallet.js index 73510fa..69acf80 100644 --- a/web/js/wallet.js +++ b/web/js/wallet.js @@ -1367,6 +1367,7 @@ async function run_tests() { p = await dev.bootloader_finish(sig); TEST(p.status == 'CTAP1_SUCCESS', 'Device booted new image with correct signature'); + document.getElementById('progress').textContent = ''+100+' %'; } //while(1) @@ -1377,9 +1378,9 @@ async function run_tests() { //await test_rng(); //} //await benchmark(); - //await test_persistence(); + await test_persistence(); - await test_bootloader(); + //await test_bootloader(); }