diff --git a/fido2/ctaphid.c b/fido2/ctaphid.c index 6452cde..4fa4ab0 100644 --- a/fido2/ctaphid.c +++ b/fido2/ctaphid.c @@ -534,6 +534,10 @@ static int ctaphid_buffer_packet(uint8_t * pkt_raw, uint8_t * cmd, uint32_t * ci 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 cmd; @@ -725,7 +729,134 @@ uint8_t ctaphid_handle_packet(uint8_t * pkt_raw) is_busy = 0; break; #endif -#if defined(SOLO_HACKER) +#if defined(SOLO_HACKER) && (DEBUG_LEVEL > 0) + 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"); @@ -745,6 +876,7 @@ uint8_t ctaphid_handle_packet(uint8_t * pkt_raw) ctaphid_write(&wb, NULL, 0); is_busy = 0; break; + */ #endif default: printf2(TAG_ERR,"error, unimplemented HID cmd: %02x\r\n", buffer_cmd()); diff --git a/fido2/ctaphid.h b/fido2/ctaphid.h index 7224ca5..135260b 100644 --- a/fido2/ctaphid.h +++ b/fido2/ctaphid.h @@ -28,8 +28,8 @@ #define CTAPHID_ENTERBOOT (TYPE_INIT | 0x51) #define CTAPHID_ENTERSTBOOT (TYPE_INIT | 0x52) #define CTAPHID_GETRNG (TYPE_INIT | 0x60) -#define CTAPHID_SHA256 (TYPE_INIT | 0x70) // not implemented -#define CTAPHID_SHA512 (TYPE_INIT | 0x71) +// 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_PAR 0x02 diff --git a/targets/stm32l432/Makefile b/targets/stm32l432/Makefile index 0ac5843..19abebd 100644 --- a/targets/stm32l432/Makefile +++ b/targets/stm32l432/Makefile @@ -15,6 +15,12 @@ merge_hex=../../tools/solotool.py mergehex firmware-hacker: $(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: $(MAKE) -f $(APPMAKE) -j8 solo.hex PREFIX=$(PREFIX) DEBUG=0 EXTRA_DEFINES='-DUSE_SOLOKEYS_CERT -DFLASH_ROP=2'