From 5fbf53559a7273195f6b0830b33ba36ac4ac93a8 Mon Sep 17 00:00:00 2001 From: Conor Patrick Date: Mon, 18 Nov 2019 14:55:14 -0500 Subject: [PATCH] reorganize crypto and device.c to be more based on fido2/ --- fido2/crypto.c | 145 +++++------ fido2/crypto.h | 6 - fido2/ctap.c | 2 +- fido2/device.c | 63 +++++ fido2/device.h | 7 + targets/stm32l432/src/attestation.c | 10 +- targets/stm32l432/src/crypto.c | 369 ---------------------------- 7 files changed, 140 insertions(+), 462 deletions(-) create mode 100644 fido2/device.c delete mode 100644 targets/stm32l432/src/crypto.c diff --git a/fido2/crypto.c b/fido2/crypto.c index 1c785b6..86cef9b 100644 --- a/fido2/crypto.c +++ b/fido2/crypto.c @@ -5,29 +5,33 @@ // http://opensource.org/licenses/MIT>, at your option. This file may not be // copied, modified, or distributed except according to those terms. /* - * Wrapper for crypto implementation on device + * Wrapper for crypto implementation on device. + * + * Can be replaced with different crypto implementation by + * defining EXTERNAL_SOLO_CRYPTO * * */ +#ifndef EXTERNAL_SOLO_CRYPTO + #include #include #include - - #include "util.h" #include "crypto.h" -#ifdef USE_SOFTWARE_IMPLEMENTATION - #include "sha256.h" #include "uECC.h" #include "aes.h" #include "ctap.h" #include "device.h" -#include "log.h" +// stuff for SHA512 +#include "sha2.h" +#include "blockwise.h" #include APP_CONFIG +#include "log.h" + -#ifdef USING_PC typedef enum { MBEDTLS_ECP_DP_NONE = 0, @@ -44,53 +48,56 @@ typedef enum MBEDTLS_ECP_DP_SECP224K1, /*!< 224-bits "Koblitz" curve */ MBEDTLS_ECP_DP_SECP256K1, /*!< 256-bits "Koblitz" curve */ } mbedtls_ecp_group_id; -#endif - - -const uint8_t * attestation_cert_der; -const uint16_t attestation_cert_der_size; -const uint8_t attestation_key[]; -const uint16_t attestation_key_size; - static SHA256_CTX sha256_ctx; +static cf_sha512_context sha512_ctx; static const struct uECC_Curve_t * _es256_curve = NULL; static const uint8_t * _signing_key = NULL; static int _key_len = 0; // Secrets for testing only static uint8_t master_secret[64]; - static uint8_t transport_secret[32]; - -void crypto_sha256_init() +void crypto_sha256_init(void) { sha256_init(&sha256_ctx); } -void crypto_reset_master_secret() +void crypto_sha512_init(void) { - ctap_generate_rng(master_secret, 64); - ctap_generate_rng(transport_secret, 32); + cf_sha512_init(&sha512_ctx); } void crypto_load_master_secret(uint8_t * key) { - #if KEY_SPACE_BYTES < 96 - #error "need more key bytes" - #endif +#if KEY_SPACE_BYTES < 96 +#error "need more key bytes" +#endif memmove(master_secret, key, 64); memmove(transport_secret, key+64, 32); } +void crypto_reset_master_secret(void) +{ + memset(master_secret, 0, 64); + memset(transport_secret, 0, 32); + ctap_generate_rng(master_secret, 64); + ctap_generate_rng(transport_secret, 32); +} + + void crypto_sha256_update(uint8_t * data, size_t len) { sha256_update(&sha256_ctx, data, len); } +void crypto_sha512_update(const uint8_t * data, size_t len) { + cf_sha512_update(&sha512_ctx, data, len); +} + void crypto_sha256_update_secret() { sha256_update(&sha256_ctx, master_secret, 32); @@ -101,26 +108,32 @@ void crypto_sha256_final(uint8_t * hash) sha256_final(&sha256_ctx, hash); } +void crypto_sha512_final(uint8_t * hash) +{ + // NB: there is also cf_sha512_digest + cf_sha512_digest_final(&sha512_ctx, hash); +} + void crypto_sha256_hmac_init(uint8_t * key, uint32_t klen, uint8_t * hmac) { uint8_t buf[64]; - int i; + unsigned int i; memset(buf, 0, sizeof(buf)); if (key == CRYPTO_MASTER_KEY) { key = master_secret; - klen = sizeof(master_secret); + klen = sizeof(master_secret)/2; } else if (key == CRYPTO_TRANSPORT_KEY) { key = transport_secret; klen = 32; } - + if(klen > 64) { - printf2(TAG_ERR,"Error, key size must be <= 64\n"); + printf2(TAG_ERR, "Error, key size must be <= 64\n"); exit(1); } @@ -138,19 +151,24 @@ void crypto_sha256_hmac_init(uint8_t * key, uint32_t klen, uint8_t * hmac) void crypto_sha256_hmac_final(uint8_t * key, uint32_t klen, uint8_t * hmac) { uint8_t buf[64]; - int i; + unsigned int i; crypto_sha256_final(hmac); memset(buf, 0, sizeof(buf)); if (key == CRYPTO_MASTER_KEY) { key = master_secret; - klen = sizeof(master_secret); + klen = sizeof(master_secret)/2; + } + else if (key == CRYPTO_TRANSPORT_KEY2) + { + key = transport_secret; + klen = 32; } if(klen > 64) { - printf2(TAG_ERR,"Error, key size must be <= 64\n"); + printf2(TAG_ERR, "Error, key size must be <= 64\n"); exit(1); } memmove(buf, key, klen); @@ -167,16 +185,16 @@ void crypto_sha256_hmac_final(uint8_t * key, uint32_t klen, uint8_t * hmac) } -void crypto_ecc256_init() +void crypto_ecc256_init(void) { uECC_set_rng((uECC_RNG_Function)ctap_generate_rng); _es256_curve = uECC_secp256r1(); } -void crypto_ecc256_load_attestation_key() +void crypto_ecc256_load_attestation_key(void) { - _signing_key = attestation_key; + _signing_key = device_get_attestation_key(); _key_len = 32; } @@ -184,7 +202,7 @@ void crypto_ecc256_sign(uint8_t * data, int len, uint8_t * sig) { if ( uECC_sign(_signing_key, data, len, sig, _es256_curve) == 0) { - printf2(TAG_ERR,"error, uECC failed\n"); + printf2(TAG_ERR, "error, uECC failed\n"); exit(1); } } @@ -221,19 +239,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: - printf2(TAG_ERR,"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) { - printf2(TAG_ERR,"error, uECC failed\n"); + printf2(TAG_ERR, "error, uECC failed\n"); exit(1); } return; fail: - printf2(TAG_ERR,"error, invalid key length\n"); + printf2(TAG_ERR, "error, invalid key length\n"); exit(1); } @@ -243,8 +261,11 @@ void generate_private_key(uint8_t * data, int len, uint8_t * data2, int len2, ui crypto_sha256_hmac_init(CRYPTO_MASTER_KEY, 0, privkey); crypto_sha256_update(data, len); crypto_sha256_update(data2, len2); - crypto_sha256_update(master_secret, 32); + crypto_sha256_update(master_secret, 32); // TODO AES crypto_sha256_hmac_final(CRYPTO_MASTER_KEY, 0, privkey); + + crypto_aes256_init(master_secret + 32, NULL); + crypto_aes256_encrypt(privkey, 32); } @@ -261,12 +282,12 @@ void crypto_ecc256_derive_public_key(uint8_t * data, int len, uint8_t * x, uint8 memmove(x,pubkey,32); memmove(y,pubkey+32,32); } - void crypto_ecc256_compute_public_key(uint8_t * privkey, uint8_t * pubkey) { uECC_compute_public_key(privkey, pubkey, _es256_curve); } + void crypto_load_external_key(uint8_t * key, int len) { _signing_key = key; @@ -278,7 +299,7 @@ void crypto_ecc256_make_key_pair(uint8_t * pubkey, uint8_t * privkey) { if (uECC_make_key(pubkey, privkey, _es256_curve) != 1) { - printf2(TAG_ERR,"Error, uECC_make_key failed\n"); + printf2(TAG_ERR, "Error, uECC_make_key failed\n"); exit(1); } } @@ -287,7 +308,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) { - printf2(TAG_ERR,"Error, uECC_shared_secret failed\n"); + printf2(TAG_ERR, "Error, uECC_shared_secret failed\n"); exit(1); } @@ -338,44 +359,4 @@ void crypto_aes256_encrypt(uint8_t * buf, int length) } -const uint8_t _attestation_cert_der[] = -"\x30\x82\x01\xfb\x30\x82\x01\xa1\xa0\x03\x02\x01\x02\x02\x01\x00\x30\x0a\x06\x08" -"\x2a\x86\x48\xce\x3d\x04\x03\x02\x30\x2c\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13" -"\x02\x55\x53\x31\x0b\x30\x09\x06\x03\x55\x04\x08\x0c\x02\x4d\x44\x31\x10\x30\x0e" -"\x06\x03\x55\x04\x0a\x0c\x07\x54\x45\x53\x54\x20\x43\x41\x30\x20\x17\x0d\x31\x38" -"\x30\x35\x31\x30\x30\x33\x30\x36\x32\x30\x5a\x18\x0f\x32\x30\x36\x38\x30\x34\x32" -"\x37\x30\x33\x30\x36\x32\x30\x5a\x30\x7c\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13" -"\x02\x55\x53\x31\x0b\x30\x09\x06\x03\x55\x04\x08\x0c\x02\x4d\x44\x31\x0f\x30\x0d" -"\x06\x03\x55\x04\x07\x0c\x06\x4c\x61\x75\x72\x65\x6c\x31\x15\x30\x13\x06\x03\x55" -"\x04\x0a\x0c\x0c\x54\x45\x53\x54\x20\x43\x4f\x4d\x50\x41\x4e\x59\x31\x22\x30\x20" -"\x06\x03\x55\x04\x0b\x0c\x19\x41\x75\x74\x68\x65\x6e\x74\x69\x63\x61\x74\x6f\x72" -"\x20\x41\x74\x74\x65\x73\x74\x61\x74\x69\x6f\x6e\x31\x14\x30\x12\x06\x03\x55\x04" -"\x03\x0c\x0b\x63\x6f\x6e\x6f\x72\x70\x70\x2e\x63\x6f\x6d\x30\x59\x30\x13\x06\x07" -"\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00" -"\x04\x45\xa9\x02\xc1\x2e\x9c\x0a\x33\xfa\x3e\x84\x50\x4a\xb8\x02\xdc\x4d\xb9\xaf" -"\x15\xb1\xb6\x3a\xea\x8d\x3f\x03\x03\x55\x65\x7d\x70\x3f\xb4\x02\xa4\x97\xf4\x83" -"\xb8\xa6\xf9\x3c\xd0\x18\xad\x92\x0c\xb7\x8a\x5a\x3e\x14\x48\x92\xef\x08\xf8\xca" -"\xea\xfb\x32\xab\x20\xa3\x62\x30\x60\x30\x46\x06\x03\x55\x1d\x23\x04\x3f\x30\x3d" -"\xa1\x30\xa4\x2e\x30\x2c\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13\x02\x55\x53\x31" -"\x0b\x30\x09\x06\x03\x55\x04\x08\x0c\x02\x4d\x44\x31\x10\x30\x0e\x06\x03\x55\x04" -"\x0a\x0c\x07\x54\x45\x53\x54\x20\x43\x41\x82\x09\x00\xf7\xc9\xec\x89\xf2\x63\x94" -"\xd9\x30\x09\x06\x03\x55\x1d\x13\x04\x02\x30\x00\x30\x0b\x06\x03\x55\x1d\x0f\x04" -"\x04\x03\x02\x04\xf0\x30\x0a\x06\x08\x2a\x86\x48\xce\x3d\x04\x03\x02\x03\x48\x00" -"\x30\x45\x02\x20\x18\x38\xb0\x45\x03\x69\xaa\xa7\xb7\x38\x62\x01\xaf\x24\x97\x5e" -"\x7e\x74\x64\x1b\xa3\x7b\xf7\xe6\xd3\xaf\x79\x28\xdb\xdc\xa5\x88\x02\x21\x00\xcd" -"\x06\xf1\xe3\xab\x16\x21\x8e\xd8\xc0\x14\xaf\x09\x4f\x5b\x73\xef\x5e\x9e\x4b\xe7" -"\x35\xeb\xdd\x9b\x6d\x8f\x7d\xf3\xc4\x3a\xd7"; -const uint8_t * attestation_cert_der = (const uint8_t *)_attestation_cert_der; - -uint16_t attestation_cert_der_get_size(){ - return sizeof(_attestation_cert_der)-1; -} - - -const uint8_t attestation_key[] = "\xcd\x67\xaa\x31\x0d\x09\x1e\xd1\x6e\x7e\x98\x92\xaa\x07\x0e\x19\x94\xfc\xd7\x14\xae\x7c\x40\x8f\xb9\x46\xb7\x2e\x5f\xe7\x5d\x30"; -const uint16_t attestation_key_size = sizeof(attestation_key)-1; - - -#else -#error "No crypto implementation defined" #endif diff --git a/fido2/crypto.h b/fido2/crypto.h index 4ad5760..6e079e4 100644 --- a/fido2/crypto.h +++ b/fido2/crypto.h @@ -9,8 +9,6 @@ #include -#define USE_SOFTWARE_IMPLEMENTATION - void crypto_sha256_init(); void crypto_sha256_update(uint8_t * data, size_t len); void crypto_sha256_update_secret(); @@ -23,7 +21,6 @@ void crypto_sha512_init(); void crypto_sha512_update(const uint8_t * data, size_t len); void crypto_sha512_final(uint8_t * hash); - void crypto_ecc256_init(); void crypto_ecc256_derive_public_key(uint8_t * data, int len, uint8_t * x, uint8_t * y); void crypto_ecc256_compute_public_key(uint8_t * privkey, uint8_t * pubkey); @@ -54,7 +51,4 @@ void crypto_reset_master_secret(); void crypto_load_master_secret(uint8_t * key); -extern const uint8_t * attestation_cert_der; -uint16_t attestation_cert_der_get_size(); - #endif diff --git a/fido2/ctap.c b/fido2/ctap.c index 97865eb..e71d1b9 100644 --- a/fido2/ctap.c +++ b/fido2/ctap.c @@ -661,7 +661,7 @@ uint8_t ctap_add_attest_statement(CborEncoder * map, uint8_t * sigder, int len) ret = cbor_encoder_create_array(&stmtmap, &x5carr, 1); check_ret(ret); { - ret = cbor_encode_byte_string(&x5carr, attestation_cert_der, attestation_cert_der_get_size()); + ret = cbor_encode_byte_string(&x5carr, attestation_cert_der, device_attestation_cert_der_get_size()); check_ret(ret); ret = cbor_encoder_close_container(&stmtmap, &x5carr); check_ret(ret); diff --git a/fido2/device.c b/fido2/device.c new file mode 100644 index 0000000..3ebe677 --- /dev/null +++ b/fido2/device.c @@ -0,0 +1,63 @@ +// Copyright 2019 SoloKeys Developers +// +// Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be +// copied, modified, or distributed except according to those terms. + +/** device.c + * + * This contains (weak) implementations + * to get FIDO2 working initially on a device. They probably + * aren't what you want to keep, but are designed to be replaced + * with some other platform specific implementation. + * +*/ + +#include +#include +#include APP_CONFIG + + +static uint8_t _attestation_cert_der[] = +"\x30\x82\x01\xfb\x30\x82\x01\xa1\xa0\x03\x02\x01\x02\x02\x01\x00\x30\x0a\x06\x08" +"\x2a\x86\x48\xce\x3d\x04\x03\x02\x30\x2c\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13" +"\x02\x55\x53\x31\x0b\x30\x09\x06\x03\x55\x04\x08\x0c\x02\x4d\x44\x31\x10\x30\x0e" +"\x06\x03\x55\x04\x0a\x0c\x07\x54\x45\x53\x54\x20\x43\x41\x30\x20\x17\x0d\x31\x38" +"\x30\x35\x31\x30\x30\x33\x30\x36\x32\x30\x5a\x18\x0f\x32\x30\x36\x38\x30\x34\x32" +"\x37\x30\x33\x30\x36\x32\x30\x5a\x30\x7c\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13" +"\x02\x55\x53\x31\x0b\x30\x09\x06\x03\x55\x04\x08\x0c\x02\x4d\x44\x31\x0f\x30\x0d" +"\x06\x03\x55\x04\x07\x0c\x06\x4c\x61\x75\x72\x65\x6c\x31\x15\x30\x13\x06\x03\x55" +"\x04\x0a\x0c\x0c\x54\x45\x53\x54\x20\x43\x4f\x4d\x50\x41\x4e\x59\x31\x22\x30\x20" +"\x06\x03\x55\x04\x0b\x0c\x19\x41\x75\x74\x68\x65\x6e\x74\x69\x63\x61\x74\x6f\x72" +"\x20\x41\x74\x74\x65\x73\x74\x61\x74\x69\x6f\x6e\x31\x14\x30\x12\x06\x03\x55\x04" +"\x03\x0c\x0b\x63\x6f\x6e\x6f\x72\x70\x70\x2e\x63\x6f\x6d\x30\x59\x30\x13\x06\x07" +"\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00" +"\x04\x45\xa9\x02\xc1\x2e\x9c\x0a\x33\xfa\x3e\x84\x50\x4a\xb8\x02\xdc\x4d\xb9\xaf" +"\x15\xb1\xb6\x3a\xea\x8d\x3f\x03\x03\x55\x65\x7d\x70\x3f\xb4\x02\xa4\x97\xf4\x83" +"\xb8\xa6\xf9\x3c\xd0\x18\xad\x92\x0c\xb7\x8a\x5a\x3e\x14\x48\x92\xef\x08\xf8\xca" +"\xea\xfb\x32\xab\x20\xa3\x62\x30\x60\x30\x46\x06\x03\x55\x1d\x23\x04\x3f\x30\x3d" +"\xa1\x30\xa4\x2e\x30\x2c\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13\x02\x55\x53\x31" +"\x0b\x30\x09\x06\x03\x55\x04\x08\x0c\x02\x4d\x44\x31\x10\x30\x0e\x06\x03\x55\x04" +"\x0a\x0c\x07\x54\x45\x53\x54\x20\x43\x41\x82\x09\x00\xf7\xc9\xec\x89\xf2\x63\x94" +"\xd9\x30\x09\x06\x03\x55\x1d\x13\x04\x02\x30\x00\x30\x0b\x06\x03\x55\x1d\x0f\x04" +"\x04\x03\x02\x04\xf0\x30\x0a\x06\x08\x2a\x86\x48\xce\x3d\x04\x03\x02\x03\x48\x00" +"\x30\x45\x02\x20\x18\x38\xb0\x45\x03\x69\xaa\xa7\xb7\x38\x62\x01\xaf\x24\x97\x5e" +"\x7e\x74\x64\x1b\xa3\x7b\xf7\xe6\xd3\xaf\x79\x28\xdb\xdc\xa5\x88\x02\x21\x00\xcd" +"\x06\xf1\xe3\xab\x16\x21\x8e\xd8\xc0\x14\xaf\x09\x4f\x5b\x73\xef\x5e\x9e\x4b\xe7" +"\x35\xeb\xdd\x9b\x6d\x8f\x7d\xf3\xc4\x3a\xd7"; + +uint8_t * attestation_cert_der = _attestation_cert_der; + +uint8_t * device_get_attestation_key(){ + static uint8_t attestation_key[] = + "\xcd\x67\xaa\x31\x0d\x09\x1e\xd1\x6e\x7e\x98\x92\xaa" + "\x07\x0e\x19\x94\xfc\xd7\x14\xae\x7c\x40\x8f\xb9\x46" + "\xb7\x2e\x5f\xe7\x5d\x30"; + return attestation_key; +} + +uint16_t device_attestation_cert_der_get_size(){ + return sizeof(_attestation_cert_der)-1; +} + diff --git a/fido2/device.h b/fido2/device.h index 4692323..c1e391c 100644 --- a/fido2/device.h +++ b/fido2/device.h @@ -110,4 +110,11 @@ void device_disable_up(bool request_active); void device_init_button(); +/** Return pointer to attestation key. +*/ +uint8_t * device_get_attestation_key(); +extern const uint8_t * attestation_cert_der; + +uint16_t device_attestation_cert_der_get_size(); + #endif diff --git a/targets/stm32l432/src/attestation.c b/targets/stm32l432/src/attestation.c index 59527c7..df359ba 100644 --- a/targets/stm32l432/src/attestation.c +++ b/targets/stm32l432/src/attestation.c @@ -95,12 +95,14 @@ const uint8_t attestation_hacker_cert_der[] = const uint16_t attestation_solo_cert_der_size = sizeof(attestation_solo_cert_der)-1; const uint16_t attestation_hacker_cert_der_size = sizeof(attestation_hacker_cert_der)-1; -// const uint16_t attestation_key_size = 32; const uint8_t * attestation_cert_der = ((flash_attestation_page *)ATTESTATION_PAGE_ADDR)->attestation_cert; -#include "log.h" -uint16_t attestation_cert_der_get_size(){ +uint8_t * device_get_attestation_key(){ + flash_attestation_page * page =(flash_attestation_page *)ATTESTATION_PAGE_ADDR; + return page->attestation_key; +} + +uint16_t device_attestation_cert_der_get_size(){ uint16_t sz = (uint16_t)((flash_attestation_page *)ATTESTATION_PAGE_ADDR)->attestation_cert_size; return sz; } - diff --git a/targets/stm32l432/src/crypto.c b/targets/stm32l432/src/crypto.c deleted file mode 100644 index 0e842de..0000000 --- a/targets/stm32l432/src/crypto.c +++ /dev/null @@ -1,369 +0,0 @@ -// Copyright 2019 SoloKeys Developers -// -// Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be -// copied, modified, or distributed except according to those terms. -/* - * Wrapper for crypto implementation on device - * - * */ -#include -#include -#include - - - -#include "util.h" -#include "crypto.h" - -#ifdef USE_SOFTWARE_IMPLEMENTATION - -#include "sha256.h" -#include "uECC.h" -#include "aes.h" -#include "ctap.h" -#include "device.h" -// stuff for SHA512 -#include "sha2.h" -#include "blockwise.h" -#include APP_CONFIG -#include "log.h" -#include "memory_layout.h" - - -typedef enum -{ - MBEDTLS_ECP_DP_NONE = 0, - MBEDTLS_ECP_DP_SECP192R1, /*!< 192-bits NIST curve */ - MBEDTLS_ECP_DP_SECP224R1, /*!< 224-bits NIST curve */ - MBEDTLS_ECP_DP_SECP256R1, /*!< 256-bits NIST curve */ - MBEDTLS_ECP_DP_SECP384R1, /*!< 384-bits NIST curve */ - MBEDTLS_ECP_DP_SECP521R1, /*!< 521-bits NIST curve */ - MBEDTLS_ECP_DP_BP256R1, /*!< 256-bits Brainpool curve */ - MBEDTLS_ECP_DP_BP384R1, /*!< 384-bits Brainpool curve */ - MBEDTLS_ECP_DP_BP512R1, /*!< 512-bits Brainpool curve */ - MBEDTLS_ECP_DP_CURVE25519, /*!< Curve25519 */ - MBEDTLS_ECP_DP_SECP192K1, /*!< 192-bits "Koblitz" curve */ - MBEDTLS_ECP_DP_SECP224K1, /*!< 224-bits "Koblitz" curve */ - MBEDTLS_ECP_DP_SECP256K1, /*!< 256-bits "Koblitz" curve */ -} mbedtls_ecp_group_id; - - -static SHA256_CTX sha256_ctx; -static cf_sha512_context sha512_ctx; -static const struct uECC_Curve_t * _es256_curve = NULL; -static const uint8_t * _signing_key = NULL; -static int _key_len = 0; - -// Secrets for testing only -static uint8_t master_secret[64]; -static uint8_t transport_secret[32]; - - -void crypto_sha256_init(void) -{ - sha256_init(&sha256_ctx); -} - -void crypto_sha512_init(void) -{ - cf_sha512_init(&sha512_ctx); -} - -void crypto_load_master_secret(uint8_t * key) -{ -#if KEY_SPACE_BYTES < 96 -#error "need more key bytes" -#endif - memmove(master_secret, key, 64); - memmove(transport_secret, key+64, 32); -} - -void crypto_reset_master_secret(void) -{ - memset(master_secret, 0, 64); - memset(transport_secret, 0, 32); - ctap_generate_rng(master_secret, 64); - ctap_generate_rng(transport_secret, 32); -} - - -void crypto_sha256_update(uint8_t * data, size_t len) -{ - sha256_update(&sha256_ctx, data, len); -} - -void crypto_sha512_update(const uint8_t * data, size_t len) { - cf_sha512_update(&sha512_ctx, data, len); -} - -void crypto_sha256_update_secret() -{ - sha256_update(&sha256_ctx, master_secret, 32); -} - -void crypto_sha256_final(uint8_t * hash) -{ - sha256_final(&sha256_ctx, hash); -} - -void crypto_sha512_final(uint8_t * hash) -{ - // NB: there is also cf_sha512_digest - cf_sha512_digest_final(&sha512_ctx, hash); -} - -void crypto_sha256_hmac_init(uint8_t * key, uint32_t klen, uint8_t * hmac) -{ - uint8_t buf[64]; - unsigned int i; - memset(buf, 0, sizeof(buf)); - - if (key == CRYPTO_MASTER_KEY) - { - key = master_secret; - klen = sizeof(master_secret)/2; - } - else if (key == CRYPTO_TRANSPORT_KEY) - { - key = transport_secret; - klen = 32; - } - - if(klen > 64) - { - printf2(TAG_ERR, "Error, key size must be <= 64\n"); - exit(1); - } - - memmove(buf, key, klen); - - for (i = 0; i < sizeof(buf); i++) - { - buf[i] = buf[i] ^ 0x36; - } - - crypto_sha256_init(); - crypto_sha256_update(buf, 64); -} - -void crypto_sha256_hmac_final(uint8_t * key, uint32_t klen, uint8_t * hmac) -{ - uint8_t buf[64]; - unsigned int i; - crypto_sha256_final(hmac); - memset(buf, 0, sizeof(buf)); - if (key == CRYPTO_MASTER_KEY) - { - key = master_secret; - klen = sizeof(master_secret)/2; - } - else if (key == CRYPTO_TRANSPORT_KEY2) - { - key = transport_secret; - klen = 32; - } - - - if(klen > 64) - { - printf2(TAG_ERR, "Error, key size must be <= 64\n"); - exit(1); - } - memmove(buf, key, klen); - - for (i = 0; i < sizeof(buf); i++) - { - buf[i] = buf[i] ^ 0x5c; - } - - crypto_sha256_init(); - crypto_sha256_update(buf, 64); - crypto_sha256_update(hmac, 32); - crypto_sha256_final(hmac); -} - - -void crypto_ecc256_init(void) -{ - uECC_set_rng((uECC_RNG_Function)ctap_generate_rng); - _es256_curve = uECC_secp256r1(); -} - - -void crypto_ecc256_load_attestation_key(void) -{ - // static uint8_t _key [32]; - flash_attestation_page * page =(flash_attestation_page *)ATTESTATION_PAGE_ADDR; - // memmove(_key, (uint8_t *)ATTESTATION_KEY_ADDR, 32); - _signing_key = page->attestation_key; - _key_len = 32; -} - -void crypto_ecc256_sign(uint8_t * data, int len, uint8_t * sig) -{ - if ( uECC_sign(_signing_key, data, len, sig, _es256_curve) == 0) - { - printf2(TAG_ERR, "error, uECC failed\n"); - exit(1); - } -} - -void crypto_ecc256_load_key(uint8_t * data, int len, uint8_t * data2, int len2) -{ - static uint8_t privkey[32]; - generate_private_key(data,len,data2,len2,privkey); - _signing_key = privkey; - _key_len = 32; -} - -void crypto_ecdsa_sign(uint8_t * data, int len, uint8_t * sig, int MBEDTLS_ECP_ID) -{ - - const struct uECC_Curve_t * curve = NULL; - - switch(MBEDTLS_ECP_ID) - { - case MBEDTLS_ECP_DP_SECP192R1: - curve = uECC_secp192r1(); - if (_key_len != 24) goto fail; - break; - case MBEDTLS_ECP_DP_SECP224R1: - curve = uECC_secp224r1(); - if (_key_len != 28) goto fail; - break; - case MBEDTLS_ECP_DP_SECP256R1: - curve = uECC_secp256r1(); - if (_key_len != 32) goto fail; - break; - case MBEDTLS_ECP_DP_SECP256K1: - curve = uECC_secp256k1(); - if (_key_len != 32) goto fail; - break; - default: - printf2(TAG_ERR, "error, invalid ECDSA alg specifier\n"); - exit(1); - } - - if ( uECC_sign(_signing_key, data, len, sig, curve) == 0) - { - printf2(TAG_ERR, "error, uECC failed\n"); - exit(1); - } - return; - -fail: - printf2(TAG_ERR, "error, invalid key length\n"); - exit(1); - -} - -void generate_private_key(uint8_t * data, int len, uint8_t * data2, int len2, uint8_t * privkey) -{ - crypto_sha256_hmac_init(CRYPTO_MASTER_KEY, 0, privkey); - crypto_sha256_update(data, len); - crypto_sha256_update(data2, len2); - crypto_sha256_update(master_secret, 32); // TODO AES - crypto_sha256_hmac_final(CRYPTO_MASTER_KEY, 0, privkey); - - crypto_aes256_init(master_secret + 32, NULL); - crypto_aes256_encrypt(privkey, 32); -} - - -/*int uECC_compute_public_key(const uint8_t *private_key, uint8_t *public_key, uECC_Curve curve);*/ -void crypto_ecc256_derive_public_key(uint8_t * data, int len, uint8_t * x, uint8_t * y) -{ - uint8_t privkey[32]; - uint8_t pubkey[64]; - - generate_private_key(data,len,NULL,0,privkey); - - memset(pubkey,0,sizeof(pubkey)); - uECC_compute_public_key(privkey, pubkey, _es256_curve); - memmove(x,pubkey,32); - memmove(y,pubkey+32,32); -} -void crypto_ecc256_compute_public_key(uint8_t * privkey, uint8_t * pubkey) -{ - uECC_compute_public_key(privkey, pubkey, _es256_curve); -} - - -void crypto_load_external_key(uint8_t * key, int len) -{ - _signing_key = key; - _key_len = len; -} - - -void crypto_ecc256_make_key_pair(uint8_t * pubkey, uint8_t * privkey) -{ - if (uECC_make_key(pubkey, privkey, _es256_curve) != 1) - { - printf2(TAG_ERR, "Error, uECC_make_key failed\n"); - exit(1); - } -} - -void crypto_ecc256_shared_secret(const uint8_t * pubkey, const uint8_t * privkey, uint8_t * shared_secret) -{ - if (uECC_shared_secret(pubkey, privkey, shared_secret, _es256_curve) != 1) - { - printf2(TAG_ERR, "Error, uECC_shared_secret failed\n"); - exit(1); - } - -} - -struct AES_ctx aes_ctx; -void crypto_aes256_init(uint8_t * key, uint8_t * nonce) -{ - if (key == CRYPTO_TRANSPORT_KEY) - { - AES_init_ctx(&aes_ctx, transport_secret); - } - else - { - AES_init_ctx(&aes_ctx, key); - } - if (nonce == NULL) - { - memset(aes_ctx.Iv, 0, 16); - } - else - { - memmove(aes_ctx.Iv, nonce, 16); - } -} - -// prevent round key recomputation -void crypto_aes256_reset_iv(uint8_t * nonce) -{ - if (nonce == NULL) - { - memset(aes_ctx.Iv, 0, 16); - } - else - { - memmove(aes_ctx.Iv, nonce, 16); - } -} - -void crypto_aes256_decrypt(uint8_t * buf, int length) -{ - AES_CBC_decrypt_buffer(&aes_ctx, buf, length); -} - -void crypto_aes256_encrypt(uint8_t * buf, int length) -{ - AES_CBC_encrypt_buffer(&aes_ctx, buf, length); -} - - - - -#else -#error "No crypto implementation defined" -#endif