Compare commits

..

6 Commits

Author SHA1 Message Date
8955a1ccf4 default up to enabled 2019-09-17 00:06:45 +08:00
16f07bfc95 allow in bootloader as well 2019-09-16 17:12:09 +08:00
0945ad264c add get_version command to hid 2019-09-16 17:00:30 +08:00
b20ca7c5f7 delete old code 2019-09-16 17:00:13 +08:00
bc73ce8d21 allow get_assertion with disabled UP 2019-09-16 16:25:58 +08:00
2051ddb180 properly check the rpId in request 2019-09-16 15:33:38 +08:00
10 changed files with 105 additions and 153 deletions

View File

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

View File

@ -1 +1 @@
2.5.3
2.5.2

View File

@ -18,7 +18,7 @@ Further progress is tracked in: <https://github.com/solokeys/solo/issues/144>.
If you still need to setup a rule, a simple way to do it is:
```
git clone https://github.com/solokeys/solo.git
git clone git@github.com:solokeys/solo.git
cd solo/udev
make setup
```

View File

@ -1761,18 +1761,7 @@ static void ctap_state_init()
printf1(TAG_STOR, "Generated 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()

View File

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

View File

@ -539,14 +539,11 @@ 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_custom_command(int len, CTAP_RESPONSE * ctap_resp, CTAPHID_WRITE_BUFFER * wb);
uint8_t ctaphid_handle_packet(uint8_t * pkt_raw)
{
uint8_t cmd = 0;
uint8_t cmd;
uint32_t cid;
int len = 0;
int len;
#ifndef DISABLE_CTAPHID_CBOR
int status;
#endif
@ -556,10 +553,6 @@ uint8_t ctaphid_handle_packet(uint8_t * pkt_raw)
CTAP_RESPONSE ctap_resp;
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)
{
@ -595,6 +588,9 @@ uint8_t ctaphid_handle_packet(uint8_t * pkt_raw)
case CTAPHID_PING:
printf1(TAG_HID,"CTAPHID_PING\n");
ctaphid_write_buffer_init(&wb);
wb.cid = cid;
wb.cmd = CTAPHID_PING;
wb.bcnt = len;
timestamp();
ctaphid_write(&wb, ctap_buffer, len);
@ -607,9 +603,13 @@ uint8_t ctaphid_handle_packet(uint8_t * pkt_raw)
case CTAPHID_WINK:
printf1(TAG_HID,"CTAPHID_WINK\n");
ctaphid_write_buffer_init(&wb);
device_wink();
wb.cid = cid;
wb.cmd = CTAPHID_WINK;
ctaphid_write(&wb,NULL,0);
break;
@ -634,6 +634,9 @@ uint8_t ctaphid_handle_packet(uint8_t * pkt_raw)
ctap_response_init(&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);
@ -664,6 +667,9 @@ uint8_t ctaphid_handle_packet(uint8_t * pkt_raw)
ctap_response_init(&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);
ctaphid_write(&wb, ctap_resp.data, ctap_resp.length);
@ -674,14 +680,76 @@ uint8_t ctaphid_handle_packet(uint8_t * pkt_raw)
printf1(TAG_HID,"CTAPHID_CANCEL\n");
is_busy = 0;
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:
if (ctaphid_custom_command(len, &ctap_resp, &wb) != 0){
is_busy = 0;
}else{
printf2(TAG_ERR, "error, unimplemented HID cmd: %02x\r\n", buffer_cmd());
ctaphid_send_error(cid, CTAP1_ERR_INVALID_COMMAND);
}
printf2(TAG_ERR,"error, unimplemented HID cmd: %02x\r\n", buffer_cmd());
ctaphid_send_error(cid, CTAP1_ERR_INVALID_COMMAND);
break;
}
cid_del(cid);
buffer_reset();
@ -691,112 +759,3 @@ uint8_t ctaphid_handle_packet(uint8_t * pkt_raw)
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,7 +29,6 @@
#define CTAPHID_ENTERSTBOOT (TYPE_INIT | 0x52)
#define CTAPHID_GETRNG (TYPE_INIT | 0x60)
#define CTAPHID_GETVERSION (TYPE_INIT | 0x61)
#define CTAPHID_LOADKEY (TYPE_INIT | 0x62)
// reserved for debug, not implemented except for HACKER and DEBUG_LEVEl > 0
#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);
// Increment atomic counter and return it.
// @param amount the amount to increase the counter by.
uint32_t ctap_atomic_count(uint32_t amount);
// Must support two counters, @sel selects counter0 or counter1.
uint32_t ctap_atomic_count(int sel);
// Verify the user
// return 1 if user is verified, 0 if not

View File

@ -313,11 +313,20 @@ int ctap_user_verification(uint8_t arg)
}
uint32_t ctap_atomic_count(uint32_t amount)
uint32_t ctap_atomic_count(int sel)
{
static uint32_t counter1 = 25;
counter1 += amount;
return counter1;
/*return 713;*/
if (sel == 0)
{
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)

View File

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