Compare commits

...

7 Commits

Author SHA1 Message Date
Conor Patrick
279ab1b7f0 reduce lines/size 2019-10-08 12:09:20 -04:00
Conor Patrick
e67d05e3c1 fix warnings 2019-10-08 11:58:23 -04:00
Conor Patrick
03e0479f1a typo 2019-10-08 11:52:55 -04:00
Conor Patrick
92aadb3da5 fix pointer 2019-10-08 11:42:17 -04:00
Conor Patrick
1493c6f131 change ctap_atomic_count to increase by user-specified amount 2019-10-08 11:35:35 -04:00
Conor Patrick
ccb3753d2b refactor custom commands and add LOADKEY 2019-10-08 11:34:58 -04:00
Conor Patrick
1427c1d48e add ctap function to overwrite key bytes 2019-10-08 11:34:15 -04:00
8 changed files with 151 additions and 103 deletions

View File

@ -39,7 +39,7 @@ INCLUDES += -I./crypto/cifra/src
CFLAGS += $(INCLUDES) CFLAGS += $(INCLUDES)
# for crypto/tiny-AES-c # for crypto/tiny-AES-c
CFLAGS += -DAES256=1 -DAPP_CONFIG=\"app.h\" CFLAGS += -DAES256=1 -DAPP_CONFIG=\"app.h\" -DSOLO_EXPERIMENTAL=1
name = main name = main

View File

@ -1761,7 +1761,18 @@ static void ctap_state_init()
printf1(TAG_STOR, "Generated PIN SALT: "); printf1(TAG_STOR, "Generated PIN SALT: ");
dump_hex1(TAG_STOR, STATE.PIN_SALT, sizeof STATE.PIN_SALT); dump_hex1(TAG_STOR, STATE.PIN_SALT, sizeof STATE.PIN_SALT);
}
/** Overwrite master secret from external source.
* @param keybytes an array of KEY_SPACE_BYTES length.
*
* This function should only be called from a privilege mode.
*/
void ctap_load_external_keys(uint8_t * keybytes){
memmove(STATE.key_space, keybytes, KEY_SPACE_BYTES);
authenticator_write_state(&STATE, 0);
authenticator_write_state(&STATE, 1);
crypto_load_master_secret(STATE.key_space);
} }
void ctap_init() void ctap_init()

View File

@ -361,4 +361,6 @@ extern uint8_t KEY_AGREEMENT_PUB[64];
void lock_device_permanently(); void lock_device_permanently();
void ctap_load_external_keys(uint8_t * keybytes);
#endif #endif

View File

@ -539,11 +539,14 @@ extern void _check_ret(CborError ret, int line, const char * filename);
#define check_hardcore(r) _check_ret(r,__LINE__, __FILE__);\ #define check_hardcore(r) _check_ret(r,__LINE__, __FILE__);\
if ((r) != CborNoError) exit(1); if ((r) != CborNoError) exit(1);
uint8_t ctaphid_custom_command(int len, CTAP_RESPONSE * ctap_resp, CTAPHID_WRITE_BUFFER * wb);
uint8_t ctaphid_handle_packet(uint8_t * pkt_raw) uint8_t ctaphid_handle_packet(uint8_t * pkt_raw)
{ {
uint8_t cmd; uint8_t cmd = 0;
uint32_t cid; uint32_t cid;
int len; int len = 0;
#ifndef DISABLE_CTAPHID_CBOR #ifndef DISABLE_CTAPHID_CBOR
int status; int status;
#endif #endif
@ -553,6 +556,10 @@ uint8_t ctaphid_handle_packet(uint8_t * pkt_raw)
CTAP_RESPONSE ctap_resp; CTAP_RESPONSE ctap_resp;
int bufstatus = ctaphid_buffer_packet(pkt_raw, &cmd, &cid, &len); int bufstatus = ctaphid_buffer_packet(pkt_raw, &cmd, &cid, &len);
ctaphid_write_buffer_init(&wb);
wb.cid = cid;
wb.cmd = cmd;
if (bufstatus == HID_IGNORE) if (bufstatus == HID_IGNORE)
{ {
@ -588,9 +595,6 @@ uint8_t ctaphid_handle_packet(uint8_t * pkt_raw)
case CTAPHID_PING: case CTAPHID_PING:
printf1(TAG_HID,"CTAPHID_PING\n"); printf1(TAG_HID,"CTAPHID_PING\n");
ctaphid_write_buffer_init(&wb);
wb.cid = cid;
wb.cmd = CTAPHID_PING;
wb.bcnt = len; wb.bcnt = len;
timestamp(); timestamp();
ctaphid_write(&wb, ctap_buffer, len); ctaphid_write(&wb, ctap_buffer, len);
@ -603,13 +607,9 @@ uint8_t ctaphid_handle_packet(uint8_t * pkt_raw)
case CTAPHID_WINK: case CTAPHID_WINK:
printf1(TAG_HID,"CTAPHID_WINK\n"); printf1(TAG_HID,"CTAPHID_WINK\n");
ctaphid_write_buffer_init(&wb);
device_wink(); device_wink();
wb.cid = cid;
wb.cmd = CTAPHID_WINK;
ctaphid_write(&wb,NULL,0); ctaphid_write(&wb,NULL,0);
break; break;
@ -634,9 +634,6 @@ uint8_t ctaphid_handle_packet(uint8_t * pkt_raw)
ctap_response_init(&ctap_resp); ctap_response_init(&ctap_resp);
status = ctap_request(ctap_buffer, len, &ctap_resp); status = ctap_request(ctap_buffer, len, &ctap_resp);
ctaphid_write_buffer_init(&wb);
wb.cid = cid;
wb.cmd = CTAPHID_CBOR;
wb.bcnt = (ctap_resp.length+1); wb.bcnt = (ctap_resp.length+1);
@ -667,9 +664,6 @@ uint8_t ctaphid_handle_packet(uint8_t * pkt_raw)
ctap_response_init(&ctap_resp); ctap_response_init(&ctap_resp);
u2f_request((struct u2f_request_apdu*)ctap_buffer, &ctap_resp); u2f_request((struct u2f_request_apdu*)ctap_buffer, &ctap_resp);
ctaphid_write_buffer_init(&wb);
wb.cid = cid;
wb.cmd = CTAPHID_MSG;
wb.bcnt = (ctap_resp.length); wb.bcnt = (ctap_resp.length);
ctaphid_write(&wb, ctap_resp.data, ctap_resp.length); ctaphid_write(&wb, ctap_resp.data, ctap_resp.length);
@ -680,76 +674,14 @@ uint8_t ctaphid_handle_packet(uint8_t * pkt_raw)
printf1(TAG_HID,"CTAPHID_CANCEL\n"); printf1(TAG_HID,"CTAPHID_CANCEL\n");
is_busy = 0; is_busy = 0;
break; break;
#if defined(IS_BOOTLOADER)
case CTAPHID_BOOT:
printf1(TAG_HID,"CTAPHID_BOOT\n");
ctap_response_init(&ctap_resp);
u2f_set_writeback_buffer(&ctap_resp);
is_busy = bootloader_bridge(len, ctap_buffer);
ctaphid_write_buffer_init(&wb);
wb.cid = cid;
wb.cmd = CTAPHID_BOOT;
wb.bcnt = (ctap_resp.length + 1);
ctaphid_write(&wb, &is_busy, 1);
ctaphid_write(&wb, ctap_resp.data, ctap_resp.length);
ctaphid_write(&wb, NULL, 0);
is_busy = 0;
break;
#endif
#if defined(SOLO_HACKER)
case CTAPHID_ENTERBOOT:
printf1(TAG_HID,"CTAPHID_ENTERBOOT\n");
boot_solo_bootloader();
ctaphid_write_buffer_init(&wb);
wb.cid = cid;
wb.cmd = CTAPHID_ENTERBOOT;
wb.bcnt = 0;
ctaphid_write(&wb, NULL, 0);
is_busy = 0;
break;
case CTAPHID_ENTERSTBOOT:
printf1(TAG_HID,"CTAPHID_ENTERBOOT\n");
boot_st_bootloader();
break;
#endif
#if !defined(IS_BOOTLOADER)
case CTAPHID_GETRNG:
printf1(TAG_HID,"CTAPHID_GETRNG\n");
ctap_response_init(&ctap_resp);
ctaphid_write_buffer_init(&wb);
wb.cid = cid;
wb.cmd = CTAPHID_GETRNG;
wb.bcnt = ctap_buffer[0];
if (!wb.bcnt)
wb.bcnt = 57;
memset(ctap_buffer,0,wb.bcnt);
ctap_generate_rng(ctap_buffer, wb.bcnt);
ctaphid_write(&wb, &ctap_buffer, wb.bcnt);
ctaphid_write(&wb, NULL, 0);
is_busy = 0;
break;
#endif
case CTAPHID_GETVERSION:
printf1(TAG_HID,"CTAPHID_GETVERSION\n");
ctap_response_init(&ctap_resp);
ctaphid_write_buffer_init(&wb);
wb.cid = cid;
wb.cmd = CTAPHID_GETVERSION;
wb.bcnt = 3;
ctap_buffer[0] = SOLO_VERSION_MAJ;
ctap_buffer[1] = SOLO_VERSION_MIN;
ctap_buffer[2] = SOLO_VERSION_PATCH;
ctaphid_write(&wb, &ctap_buffer, 3);
ctaphid_write(&wb, NULL, 0);
is_busy = 0;
break;
default: default:
printf2(TAG_ERR,"error, unimplemented HID cmd: %02x\r\n", buffer_cmd()); if (ctaphid_custom_command(len, &ctap_resp, &wb) != 0){
ctaphid_send_error(cid, CTAP1_ERR_INVALID_COMMAND); is_busy = 0;
break; }else{
printf2(TAG_ERR, "error, unimplemented HID cmd: %02x\r\n", buffer_cmd());
ctaphid_send_error(cid, CTAP1_ERR_INVALID_COMMAND);
}
} }
cid_del(cid); cid_del(cid);
buffer_reset(); buffer_reset();
@ -759,3 +691,112 @@ uint8_t ctaphid_handle_packet(uint8_t * pkt_raw)
else return 0; else return 0;
} }
uint8_t ctaphid_custom_command(int len, CTAP_RESPONSE * ctap_resp, CTAPHID_WRITE_BUFFER * wb)
{
ctap_response_init(ctap_resp);
#if !defined(IS_BOOTLOADER) && (defined(SOLO_HACKER) || defined(SOLO_EXPERIMENTAL))
uint32_t param;
#endif
#if defined(IS_BOOTLOADER)
uint8_t is_busy;
#endif
switch(wb->cmd)
{
#if defined(IS_BOOTLOADER)
case CTAPHID_BOOT:
printf1(TAG_HID,"CTAPHID_BOOT\n");
u2f_set_writeback_buffer(ctap_resp);
is_busy = bootloader_bridge(len, ctap_buffer);
ctaphid_write(wb, &is_busy, 1);
ctaphid_write(wb, ctap_resp->data, ctap_resp->length);
ctaphid_write(wb, NULL, 0);
return 1;
#endif
#if defined(SOLO_HACKER)
case CTAPHID_ENTERBOOT:
printf1(TAG_HID,"CTAPHID_ENTERBOOT\n");
boot_solo_bootloader();
wb->bcnt = 0;
ctaphid_write(wb, NULL, 0);
return 1;
case CTAPHID_ENTERSTBOOT:
printf1(TAG_HID,"CTAPHID_ENTERBOOT\n");
boot_st_bootloader();
return 1;
#endif
#if !defined(IS_BOOTLOADER)
case CTAPHID_GETRNG:
printf1(TAG_HID,"CTAPHID_GETRNG\n");
wb->bcnt = ctap_buffer[0];
if (!wb->bcnt)
wb->bcnt = 57;
memset(ctap_buffer,0,wb->bcnt);
ctap_generate_rng(ctap_buffer, wb->bcnt);
ctaphid_write(wb, ctap_buffer, wb->bcnt);
ctaphid_write(wb, NULL, 0);
return 1;
break;
#endif
case CTAPHID_GETVERSION:
printf1(TAG_HID,"CTAPHID_GETVERSION\n");
wb->bcnt = 3;
ctap_buffer[0] = SOLO_VERSION_MAJ;
ctap_buffer[1] = SOLO_VERSION_MIN;
ctap_buffer[2] = SOLO_VERSION_PATCH;
ctaphid_write(wb, ctap_buffer, 3);
ctaphid_write(wb, NULL, 0);
return 1;
break;
#if !defined(IS_BOOTLOADER) && (defined(SOLO_HACKER) || defined(SOLO_EXPERIMENTAL))
case CTAPHID_LOADKEY:
/**
* Load external key. Useful for enabling backups.
* bytes: 4 96
* payload: | counter_increase (BE) | master_key |
*
* Counter should be increased by a large amount, e.g. (0x10000000)
* to outdo any previously lost/broken keys.
*/
printf1(TAG_HID,"CTAPHID_LOADKEY\n");
if (len != 100)
{
printf2(TAG_ERR,"Error, invalid length.\n");
ctaphid_send_error(wb->cid, CTAP1_ERR_INVALID_LENGTH);
return 1;
}
// Ask for THREE button presses
if (ctap_user_presence_test(8000) > 0)
if (ctap_user_presence_test(8000) > 0)
if (ctap_user_presence_test(8000) > 0)
{
ctap_load_external_keys(ctap_buffer + 4);
param = ctap_buffer[3];
param |= ctap_buffer[2] << 8;
param |= ctap_buffer[1] << 16;
param |= ctap_buffer[0] << 24;
ctap_atomic_count(param);
wb->bcnt = 0;
ctaphid_write(wb, NULL, 0);
return 1;
}
printf2(TAG_ERR, "Error, invalid length.\n");
ctaphid_send_error(wb->cid, CTAP2_ERR_OPERATION_DENIED);
return 1;
#endif
}
return 0;
}

View File

@ -29,6 +29,7 @@
#define CTAPHID_ENTERSTBOOT (TYPE_INIT | 0x52) #define CTAPHID_ENTERSTBOOT (TYPE_INIT | 0x52)
#define CTAPHID_GETRNG (TYPE_INIT | 0x60) #define CTAPHID_GETRNG (TYPE_INIT | 0x60)
#define CTAPHID_GETVERSION (TYPE_INIT | 0x61) #define CTAPHID_GETVERSION (TYPE_INIT | 0x61)
#define CTAPHID_LOADKEY (TYPE_INIT | 0x62)
// reserved for debug, not implemented except for HACKER and DEBUG_LEVEl > 0 // reserved for debug, not implemented except for HACKER and DEBUG_LEVEl > 0
#define CTAPHID_PROBE (TYPE_INIT | 0x70) #define CTAPHID_PROBE (TYPE_INIT | 0x70)

View File

@ -61,8 +61,8 @@ int ctap_user_presence_test(uint32_t delay);
int ctap_generate_rng(uint8_t * dst, size_t num); int ctap_generate_rng(uint8_t * dst, size_t num);
// Increment atomic counter and return it. // Increment atomic counter and return it.
// Must support two counters, @sel selects counter0 or counter1. // @param amount the amount to increase the counter by.
uint32_t ctap_atomic_count(int sel); uint32_t ctap_atomic_count(uint32_t amount);
// Verify the user // Verify the user
// return 1 if user is verified, 0 if not // return 1 if user is verified, 0 if not

View File

@ -313,20 +313,11 @@ int ctap_user_verification(uint8_t arg)
} }
uint32_t ctap_atomic_count(int sel) uint32_t ctap_atomic_count(uint32_t amount)
{ {
static uint32_t counter1 = 25; static uint32_t counter1 = 25;
/*return 713;*/ counter1 += amount;
if (sel == 0) return counter1;
{
printf1(TAG_RED,"counter1: %d\n", counter1);
return counter1++;
}
else
{
printf2(TAG_ERR,"counter2 not imple\n");
exit(1);
}
} }
int ctap_generate_rng(uint8_t * dst, size_t num) int ctap_generate_rng(uint8_t * dst, size_t num)

View File

@ -407,7 +407,7 @@ void authenticator_write_state(AuthenticatorState * a, int backup)
} }
} }
uint32_t ctap_atomic_count(int sel) uint32_t ctap_atomic_count(uint32_t amount)
{ {
int offset = 0; int offset = 0;
uint32_t * ptr = (uint32_t *)flash_addr(COUNTER1_PAGE); uint32_t * ptr = (uint32_t *)flash_addr(COUNTER1_PAGE);
@ -422,10 +422,12 @@ uint32_t ctap_atomic_count(int sel)
uint32_t lastc = 0; uint32_t lastc = 0;
if (sel != 0) if (amount == 0)
{ {
printf2(TAG_ERR,"counter2 not imple\n"); // Use a random count [1-16].
exit(1); uint8_t rng[1];
ctap_generate_rng(rng, 1);
amount = (rng[0] & 0x0f) + 1;
} }
for (offset = 0; offset < PAGE_SIZE/4; offset += 2) // wear-level the flash for (offset = 0; offset < PAGE_SIZE/4; offset += 2) // wear-level the flash
@ -458,7 +460,7 @@ uint32_t ctap_atomic_count(int sel)
return lastc; return lastc;
} }
lastc++; lastc += amount;
if (lastc/256 > erases) if (lastc/256 > erases)
{ {