commit
32f2436380
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -10,3 +10,6 @@
|
|||||||
[submodule "targets/stm32l442/dfuse-tool"]
|
[submodule "targets/stm32l442/dfuse-tool"]
|
||||||
path = targets/stm32l442/dfuse-tool
|
path = targets/stm32l442/dfuse-tool
|
||||||
url = https://github.com/solokeys/dfuse-tool
|
url = https://github.com/solokeys/dfuse-tool
|
||||||
|
[submodule "crypto/cifra"]
|
||||||
|
path = crypto/cifra
|
||||||
|
url = https://github.com/solokeys/cifra.git
|
||||||
|
1
Makefile
1
Makefile
@ -23,6 +23,7 @@ LDFLAGS += $(LIBCBOR)
|
|||||||
CFLAGS = -O2 -fdata-sections -ffunction-sections
|
CFLAGS = -O2 -fdata-sections -ffunction-sections
|
||||||
|
|
||||||
INCLUDES = -I./tinycbor/src -I./crypto/sha256 -I./crypto/micro-ecc/ -Icrypto/tiny-AES-c/ -I./fido2/ -I./pc -I./fido2/extensions
|
INCLUDES = -I./tinycbor/src -I./crypto/sha256 -I./crypto/micro-ecc/ -Icrypto/tiny-AES-c/ -I./fido2/ -I./pc -I./fido2/extensions
|
||||||
|
INCLUDES += -I./crypto/cifra/src
|
||||||
|
|
||||||
CFLAGS += $(INCLUDES)
|
CFLAGS += $(INCLUDES)
|
||||||
# for crypto/tiny-AES-c
|
# for crypto/tiny-AES-c
|
||||||
|
1
crypto/cifra
Submodule
1
crypto/cifra
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit d04dd318609733d809904d4f2973597240655cde
|
@ -19,6 +19,10 @@ void crypto_sha256_final(uint8_t * hash);
|
|||||||
void crypto_sha256_hmac_init(uint8_t * key, uint32_t klen, uint8_t * hmac);
|
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);
|
void crypto_sha256_hmac_final(uint8_t * key, uint32_t klen, uint8_t * hmac);
|
||||||
|
|
||||||
|
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_init();
|
||||||
void crypto_ecc256_derive_public_key(uint8_t * data, int len, uint8_t * x, uint8_t * y);
|
void crypto_ecc256_derive_public_key(uint8_t * data, int len, uint8_t * x, uint8_t * y);
|
||||||
|
159
fido2/ctaphid.c
159
fido2/ctaphid.c
@ -16,6 +16,12 @@
|
|||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "extensions.h"
|
#include "extensions.h"
|
||||||
|
|
||||||
|
// move custom SHA512 command out,
|
||||||
|
// and the following headers too
|
||||||
|
#include "sha2.h"
|
||||||
|
#include "crypto.h"
|
||||||
|
|
||||||
#include APP_CONFIG
|
#include APP_CONFIG
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
@ -528,6 +534,10 @@ static int ctaphid_buffer_packet(uint8_t * pkt_raw, uint8_t * cmd, uint32_t * ci
|
|||||||
return buffer_status();
|
return buffer_status();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern void _check_ret(CborError ret, int line, const char * filename);
|
||||||
|
#define check_hardcore(r) _check_ret(r,__LINE__, __FILE__);\
|
||||||
|
if ((r) != CborNoError) exit(1);
|
||||||
|
|
||||||
uint8_t ctaphid_handle_packet(uint8_t * pkt_raw)
|
uint8_t ctaphid_handle_packet(uint8_t * pkt_raw)
|
||||||
{
|
{
|
||||||
uint8_t cmd;
|
uint8_t cmd;
|
||||||
@ -718,6 +728,155 @@ uint8_t ctaphid_handle_packet(uint8_t * pkt_raw)
|
|||||||
ctaphid_write(&wb, NULL, 0);
|
ctaphid_write(&wb, NULL, 0);
|
||||||
is_busy = 0;
|
is_busy = 0;
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
|
#if defined(SOLO_HACKER) && (DEBUG_LEVEL > 0) && (!IS_BOOTLOADER == 1)
|
||||||
|
case CTAPHID_PROBE:
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Expects CBOR-serialized data of the form
|
||||||
|
* {"subcommand": "hash_type", "data": b"the_data"}
|
||||||
|
* with hash_type in SHA256, SHA512
|
||||||
|
*/
|
||||||
|
|
||||||
|
// some random logging
|
||||||
|
printf1(TAG_HID,"CTAPHID_PROBE\n");
|
||||||
|
// initialise CTAP response object
|
||||||
|
ctap_response_init(&ctap_resp);
|
||||||
|
// initialise write buffer
|
||||||
|
ctaphid_write_buffer_init(&wb);
|
||||||
|
wb.cid = cid;
|
||||||
|
wb.cmd = CTAPHID_PROBE;
|
||||||
|
|
||||||
|
// prepare parsing (or halt)
|
||||||
|
int ret;
|
||||||
|
CborParser parser;
|
||||||
|
CborValue it, map;
|
||||||
|
ret = cbor_parser_init(
|
||||||
|
ctap_buffer, (size_t) buffer_len(),
|
||||||
|
// strictly speaking, CTAP is not RFC canonical...
|
||||||
|
CborValidateCanonicalFormat,
|
||||||
|
&parser, &it);
|
||||||
|
check_hardcore(ret);
|
||||||
|
|
||||||
|
CborType type = cbor_value_get_type(&it);
|
||||||
|
if (type != CborMapType) exit(1);
|
||||||
|
|
||||||
|
ret = cbor_value_enter_container(&it,&map);
|
||||||
|
check_hardcore(ret);
|
||||||
|
|
||||||
|
size_t map_length = 0;
|
||||||
|
ret = cbor_value_get_map_length(&it, &map_length);
|
||||||
|
if (map_length != 2) exit(1);
|
||||||
|
|
||||||
|
// parse subcommand (or halt)
|
||||||
|
CborValue val;
|
||||||
|
ret = cbor_value_map_find_value(&it, "subcommand", &val);
|
||||||
|
check_hardcore(ret);
|
||||||
|
if (!cbor_value_is_text_string(&val))
|
||||||
|
exit(1);
|
||||||
|
|
||||||
|
int sha_version = 0;
|
||||||
|
bool found = false;
|
||||||
|
if (!found) {
|
||||||
|
ret = cbor_value_text_string_equals(
|
||||||
|
&val, "SHA256", &found);
|
||||||
|
check_hardcore(ret);
|
||||||
|
if (found)
|
||||||
|
sha_version = 256;
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
ret = cbor_value_text_string_equals(
|
||||||
|
&val, "SHA512", &found);
|
||||||
|
check_hardcore(ret);
|
||||||
|
if (found)
|
||||||
|
sha_version = 512;
|
||||||
|
}
|
||||||
|
if (sha_version == 0)
|
||||||
|
exit(1);
|
||||||
|
|
||||||
|
// parse data (or halt)
|
||||||
|
ret = cbor_value_map_find_value(&it, "data", &val);
|
||||||
|
check_hardcore(ret);
|
||||||
|
if (!cbor_value_is_byte_string(&val))
|
||||||
|
exit(1);
|
||||||
|
|
||||||
|
size_t data_length = 0;
|
||||||
|
ret = cbor_value_calculate_string_length(&val, &data_length);
|
||||||
|
check_hardcore(ret);
|
||||||
|
if (data_length > 6*1024)
|
||||||
|
exit(1);
|
||||||
|
|
||||||
|
unsigned char data[6*1024];
|
||||||
|
ret = cbor_value_copy_byte_string (
|
||||||
|
&val, &data[0], &data_length, &val);
|
||||||
|
check_hardcore(ret);
|
||||||
|
|
||||||
|
// execute subcommand
|
||||||
|
if (sha_version == 256) {
|
||||||
|
// calculate hash
|
||||||
|
crypto_sha256_init();
|
||||||
|
crypto_sha256_update(data, data_length);
|
||||||
|
crypto_sha256_final(ctap_buffer);
|
||||||
|
// write output
|
||||||
|
wb.bcnt = CF_SHA256_HASHSZ; // 32 bytes
|
||||||
|
ctaphid_write(&wb, &ctap_buffer, CF_SHA256_HASHSZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sha_version == 512) {
|
||||||
|
// calculate hash
|
||||||
|
crypto_sha512_init();
|
||||||
|
crypto_sha512_update(data, data_length);
|
||||||
|
crypto_sha512_final(ctap_buffer);
|
||||||
|
// write output
|
||||||
|
wb.bcnt = CF_SHA512_HASHSZ; // 64 bytes
|
||||||
|
ctaphid_write(&wb, &ctap_buffer, CF_SHA512_HASHSZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
// finalize
|
||||||
|
ctaphid_write(&wb, NULL, 0);
|
||||||
|
is_busy = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
/*
|
||||||
|
case CTAPHID_SHA256:
|
||||||
|
// some random logging
|
||||||
|
printf1(TAG_HID,"CTAPHID_SHA256\n");
|
||||||
|
// initialise CTAP response object
|
||||||
|
ctap_response_init(&ctap_resp);
|
||||||
|
// initialise write buffer
|
||||||
|
ctaphid_write_buffer_init(&wb);
|
||||||
|
wb.cid = cid;
|
||||||
|
wb.cmd = CTAPHID_SHA256;
|
||||||
|
wb.bcnt = CF_SHA256_HASHSZ; // 32 bytes
|
||||||
|
// calculate hash
|
||||||
|
crypto_sha256_init();
|
||||||
|
crypto_sha256_update(ctap_buffer, buffer_len());
|
||||||
|
crypto_sha256_final(ctap_buffer);
|
||||||
|
// copy to output
|
||||||
|
ctaphid_write(&wb, &ctap_buffer, CF_SHA256_HASHSZ);
|
||||||
|
ctaphid_write(&wb, NULL, 0);
|
||||||
|
is_busy = 0;
|
||||||
|
break;
|
||||||
|
case CTAPHID_SHA512:
|
||||||
|
// some random logging
|
||||||
|
printf1(TAG_HID,"CTAPHID_SHA512\n");
|
||||||
|
// initialise CTAP response object
|
||||||
|
ctap_response_init(&ctap_resp);
|
||||||
|
// initialise write buffer
|
||||||
|
ctaphid_write_buffer_init(&wb);
|
||||||
|
wb.cid = cid;
|
||||||
|
wb.cmd = CTAPHID_SHA512;
|
||||||
|
wb.bcnt = CF_SHA512_HASHSZ; // 64 bytes
|
||||||
|
// calculate hash
|
||||||
|
crypto_sha512_init();
|
||||||
|
crypto_sha512_update(ctap_buffer, buffer_len());
|
||||||
|
crypto_sha512_final(ctap_buffer);
|
||||||
|
// copy to output
|
||||||
|
ctaphid_write(&wb, &ctap_buffer, CF_SHA512_HASHSZ);
|
||||||
|
ctaphid_write(&wb, NULL, 0);
|
||||||
|
is_busy = 0;
|
||||||
|
break;
|
||||||
|
*/
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
printf2(TAG_ERR,"error, unimplemented HID cmd: %02x\r\n", buffer_cmd());
|
printf2(TAG_ERR,"error, unimplemented HID cmd: %02x\r\n", buffer_cmd());
|
||||||
|
@ -28,6 +28,8 @@
|
|||||||
#define CTAPHID_ENTERBOOT (TYPE_INIT | 0x51)
|
#define CTAPHID_ENTERBOOT (TYPE_INIT | 0x51)
|
||||||
#define CTAPHID_ENTERSTBOOT (TYPE_INIT | 0x52)
|
#define CTAPHID_ENTERSTBOOT (TYPE_INIT | 0x52)
|
||||||
#define CTAPHID_GETRNG (TYPE_INIT | 0x60)
|
#define CTAPHID_GETRNG (TYPE_INIT | 0x60)
|
||||||
|
// reserved for debug, not implemented except for HACKER and DEBUG_LEVEl > 0
|
||||||
|
#define CTAPHID_PROBE (TYPE_INIT | 0x70)
|
||||||
|
|
||||||
#define ERR_INVALID_CMD 0x01
|
#define ERR_INVALID_CMD 0x01
|
||||||
#define ERR_INVALID_PAR 0x02
|
#define ERR_INVALID_PAR 0x02
|
||||||
|
@ -15,6 +15,12 @@ merge_hex=solo mergehex
|
|||||||
firmware-hacker:
|
firmware-hacker:
|
||||||
$(MAKE) -f $(APPMAKE) -j8 solo.hex PREFIX=$(PREFIX) DEBUG=0 EXTRA_DEFINES='-DSOLO_HACKER -DFLASH_ROP=0'
|
$(MAKE) -f $(APPMAKE) -j8 solo.hex PREFIX=$(PREFIX) DEBUG=0 EXTRA_DEFINES='-DSOLO_HACKER -DFLASH_ROP=0'
|
||||||
|
|
||||||
|
firmware-hacker-debug-1:
|
||||||
|
$(MAKE) -f $(APPMAKE) -j8 solo.hex PREFIX=$(PREFIX) DEBUG=1 EXTRA_DEFINES='-DSOLO_HACKER -DFLASH_ROP=0'
|
||||||
|
|
||||||
|
firmware-hacker-debug-2:
|
||||||
|
$(MAKE) -f $(APPMAKE) -j8 solo.hex PREFIX=$(PREFIX) DEBUG=2 EXTRA_DEFINES='-DSOLO_HACKER -DFLASH_ROP=0'
|
||||||
|
|
||||||
firmware-secure:
|
firmware-secure:
|
||||||
$(MAKE) -f $(APPMAKE) -j8 solo.hex PREFIX=$(PREFIX) DEBUG=0 EXTRA_DEFINES='-DUSE_SOLOKEYS_CERT -DFLASH_ROP=2'
|
$(MAKE) -f $(APPMAKE) -j8 solo.hex PREFIX=$(PREFIX) DEBUG=0 EXTRA_DEFINES='-DUSE_SOLOKEYS_CERT -DFLASH_ROP=2'
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@ SRC += ../../fido2/extensions/extensions.c ../../fido2/extensions/solo.c
|
|||||||
|
|
||||||
# Crypto libs
|
# Crypto libs
|
||||||
SRC += ../../crypto/sha256/sha256.c ../../crypto/micro-ecc/uECC.c ../../crypto/tiny-AES-c/aes.c
|
SRC += ../../crypto/sha256/sha256.c ../../crypto/micro-ecc/uECC.c ../../crypto/tiny-AES-c/aes.c
|
||||||
|
SRC += ../../crypto/cifra/src/sha512.c ../../crypto/cifra/src/blockwise.c
|
||||||
|
|
||||||
OBJ1=$(SRC:.c=.o)
|
OBJ1=$(SRC:.c=.o)
|
||||||
OBJ=$(OBJ1:.s=.o)
|
OBJ=$(OBJ1:.s=.o)
|
||||||
@ -21,6 +22,7 @@ OBJ=$(OBJ1:.s=.o)
|
|||||||
INC = -Isrc/ -Isrc/cmsis/ -Ilib/ -Ilib/usbd/ -I../../fido2/ -I../../fido2/extensions
|
INC = -Isrc/ -Isrc/cmsis/ -Ilib/ -Ilib/usbd/ -I../../fido2/ -I../../fido2/extensions
|
||||||
INC += -I../../tinycbor/src -I../../crypto/sha256 -I../../crypto/micro-ecc
|
INC += -I../../tinycbor/src -I../../crypto/sha256 -I../../crypto/micro-ecc
|
||||||
INC += -I../../crypto/tiny-AES-c
|
INC += -I../../crypto/tiny-AES-c
|
||||||
|
INC += -I../../crypto/cifra/src -I../../crypto/cifra/src/ext
|
||||||
|
|
||||||
SEARCH=-L../../tinycbor/lib
|
SEARCH=-L../../tinycbor/lib
|
||||||
|
|
||||||
@ -66,6 +68,7 @@ all: $(TARGET).elf
|
|||||||
$(CC) $^ $(HW) $(LDFLAGS) -o $@
|
$(CC) $^ $(HW) $(LDFLAGS) -o $@
|
||||||
|
|
||||||
%.hex: %.elf
|
%.hex: %.elf
|
||||||
|
$(SZ) $^
|
||||||
$(CP) -O ihex $^ $(TARGET).hex
|
$(CP) -O ihex $^ $(TARGET).hex
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
|
@ -13,6 +13,7 @@ SRC += ../../fido2/stubs.c ../../fido2/log.c ../../fido2/ctaphid.c ../../fido2
|
|||||||
|
|
||||||
# Crypto libs
|
# Crypto libs
|
||||||
SRC += ../../crypto/sha256/sha256.c ../../crypto/micro-ecc/uECC.c
|
SRC += ../../crypto/sha256/sha256.c ../../crypto/micro-ecc/uECC.c
|
||||||
|
SRC += ../../crypto/cifra/src/sha512.c ../../crypto/cifra/src/blockwise.c
|
||||||
|
|
||||||
OBJ1=$(SRC:.c=.o)
|
OBJ1=$(SRC:.c=.o)
|
||||||
OBJ=$(OBJ1:.s=.o)
|
OBJ=$(OBJ1:.s=.o)
|
||||||
@ -21,6 +22,7 @@ OBJ=$(OBJ1:.s=.o)
|
|||||||
INC = -Ibootloader/ -Isrc/ -Isrc/cmsis/ -Ilib/ -Ilib/usbd/ -I../../fido2/ -I../../fido2/extensions
|
INC = -Ibootloader/ -Isrc/ -Isrc/cmsis/ -Ilib/ -Ilib/usbd/ -I../../fido2/ -I../../fido2/extensions
|
||||||
INC += -I../../tinycbor/src -I../../crypto/sha256 -I../../crypto/micro-ecc
|
INC += -I../../tinycbor/src -I../../crypto/sha256 -I../../crypto/micro-ecc
|
||||||
INC += -I../../crypto/tiny-AES-c
|
INC += -I../../crypto/tiny-AES-c
|
||||||
|
INC += -I../../crypto/cifra/src -I../../crypto/cifra/src/ext
|
||||||
|
|
||||||
ifndef LDSCRIPT
|
ifndef LDSCRIPT
|
||||||
LDSCRIPT=linker/bootloader_stm32l4xx.ld
|
LDSCRIPT=linker/bootloader_stm32l4xx.ld
|
||||||
|
@ -24,6 +24,9 @@
|
|||||||
#include "aes.h"
|
#include "aes.h"
|
||||||
#include "ctap.h"
|
#include "ctap.h"
|
||||||
#include "device.h"
|
#include "device.h"
|
||||||
|
// stuff for SHA512
|
||||||
|
#include "sha2.h"
|
||||||
|
#include "blockwise.h"
|
||||||
#include APP_CONFIG
|
#include APP_CONFIG
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "memory_layout.h"
|
#include "memory_layout.h"
|
||||||
@ -48,6 +51,7 @@ typedef enum
|
|||||||
|
|
||||||
|
|
||||||
static SHA256_CTX sha256_ctx;
|
static SHA256_CTX sha256_ctx;
|
||||||
|
static cf_sha512_context sha512_ctx;
|
||||||
static const struct uECC_Curve_t * _es256_curve = NULL;
|
static const struct uECC_Curve_t * _es256_curve = NULL;
|
||||||
static const uint8_t * _signing_key = NULL;
|
static const uint8_t * _signing_key = NULL;
|
||||||
static int _key_len = 0;
|
static int _key_len = 0;
|
||||||
@ -62,6 +66,9 @@ void crypto_sha256_init()
|
|||||||
sha256_init(&sha256_ctx);
|
sha256_init(&sha256_ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void crypto_sha512_init() {
|
||||||
|
cf_sha512_init(&sha512_ctx);
|
||||||
|
}
|
||||||
|
|
||||||
void crypto_load_master_secret(uint8_t * key)
|
void crypto_load_master_secret(uint8_t * key)
|
||||||
{
|
{
|
||||||
@ -86,6 +93,10 @@ void crypto_sha256_update(uint8_t * data, size_t len)
|
|||||||
sha256_update(&sha256_ctx, data, 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()
|
void crypto_sha256_update_secret()
|
||||||
{
|
{
|
||||||
sha256_update(&sha256_ctx, master_secret, 32);
|
sha256_update(&sha256_ctx, master_secret, 32);
|
||||||
@ -96,6 +107,11 @@ void crypto_sha256_final(uint8_t * hash)
|
|||||||
sha256_final(&sha256_ctx, 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)
|
void crypto_sha256_hmac_init(uint8_t * key, uint32_t klen, uint8_t * hmac)
|
||||||
{
|
{
|
||||||
uint8_t buf[64];
|
uint8_t buf[64];
|
||||||
|
Loading…
x
Reference in New Issue
Block a user