Skip to content

Commit

Permalink
usbkbd: add vendor command for programming the keyboard
Browse files Browse the repository at this point in the history
The command value is 0x51 and it accepts a single argument which is a
byte string.
  • Loading branch information
rgerganov committed Jun 16, 2020
1 parent ec8a2eb commit d444309
Show file tree
Hide file tree
Showing 8 changed files with 78 additions and 2 deletions.
18 changes: 18 additions & 0 deletions fido2/ctap.c
Expand Up @@ -1738,6 +1738,20 @@ uint8_t ctap_cred_mgmt(CborEncoder * encoder, uint8_t * request, int length)
return 0;
}

uint8_t ctap_solo_kbd(CborEncoder * encoder, uint8_t * request, int length)
{
CTAP_soloKbd KBD;
int ret = ctap_parse_solo_kbd(&KBD, request, length);
if (ret != 0)
{
printf2(TAG_ERR,"error, ctap_parse_solo_kbd failed\n");
return ret;
}
dump_hex1(TAG_CTAP, KBD.sequence, KBD.length);
ctap_store_kbd(&KBD);
return 0;
}

uint8_t ctap_get_assertion(CborEncoder * encoder, uint8_t * request, int length)
{
CTAP_getAssertion GA;
Expand Down Expand Up @@ -2318,6 +2332,10 @@ uint8_t ctap_request(uint8_t * pkt_raw, int length, CTAP_RESPONSE * resp)

dump_hex1(TAG_DUMP,buf, resp->length);
break;
case CTAP_SOLO_KBD:
printf1(TAG_CTAP,"CTAP_SOLO_KBD\n");
status = ctap_solo_kbd(&encoder, pkt_raw, length);
break;
default:
status = CTAP1_ERR_INVALID_COMMAND;
printf2(TAG_ERR,"error, invalid cmd: 0x%02x\n", cmd);
Expand Down
6 changes: 6 additions & 0 deletions fido2/ctap.h
Expand Up @@ -19,6 +19,7 @@
#define CTAP_CBOR_CRED_MGMT 0x0A
#define CTAP_VENDOR_FIRST 0x40
#define CTAP_CBOR_CRED_MGMT_PRE 0x41
#define CTAP_SOLO_KBD 0x51
#define CTAP_VENDOR_LAST 0xBF

#define MC_clientDataHash 0x01
Expand Down Expand Up @@ -338,6 +339,11 @@ typedef struct
int pinProtocol;
} CTAP_credMgmt;

typedef struct
{
uint8_t sequence[64];
uint8_t length;
} CTAP_soloKbd;

typedef struct
{
Expand Down
22 changes: 22 additions & 0 deletions fido2/ctap_parse.c
Expand Up @@ -713,6 +713,28 @@ uint8_t ctap_parse_extensions(CborValue * val, CTAP_extensions * ext)
return 0;
}

uint8_t ctap_parse_solo_kbd(CTAP_soloKbd * KBD, uint8_t * request, int length)
{
int ret;
CborParser parser;
CborValue it;

memset(KBD, 0, sizeof(CTAP_soloKbd));
ret = cbor_parser_init(request, length, CborValidateCanonicalFormat, &parser, &it);
check_retr(ret);
CborType type = cbor_value_get_type(&it);
if (type != CborByteStringType)
{
printf2(TAG_ERR,"Error, expecting cbor byte string\n");
return CTAP2_ERR_CBOR_UNEXPECTED_TYPE;
}
size_t len = sizeof(KBD->sequence);
ret = cbor_value_copy_byte_string(&it, KBD->sequence, &len, NULL);
check_ret(ret);
KBD->length = len;
return ret;
}

uint8_t ctap_parse_make_credential(CTAP_makeCredential * MC, CborEncoder * encoder, uint8_t * request, int length)
{
int ret;
Expand Down
1 change: 1 addition & 0 deletions fido2/ctap_parse.h
Expand Up @@ -38,6 +38,7 @@ uint8_t ctap_parse_get_assertion(CTAP_getAssertion * GA, uint8_t * request, int
uint8_t ctap_parse_cred_mgmt(CTAP_credMgmt * CM, uint8_t * request, int length);
uint8_t ctap_parse_client_pin(CTAP_clientPin * CP, uint8_t * request, int length);
uint8_t parse_credential_descriptor(CborValue * arr, CTAP_credentialDescriptor * cred);
uint8_t ctap_parse_solo_kbd(CTAP_soloKbd * KBD, uint8_t * request, int length);


#endif
2 changes: 2 additions & 0 deletions fido2/device.h
Expand Up @@ -162,6 +162,8 @@ void ctap_load_rk(int index,CTAP_residentKey * rk);
*/
void ctap_overwrite_rk(int index,CTAP_residentKey * rk);

void ctap_load_kbd(CTAP_soloKbd * kbd);
void ctap_store_kbd(CTAP_soloKbd * kbd);

/** Called by HID layer to indicate that a wink behavior should be performed.
* Should not block, and the wink behavior should occur in parallel to FIDO operations.
Expand Down
5 changes: 5 additions & 0 deletions pc/device.c
Expand Up @@ -449,6 +449,11 @@ void ctap_store_rk(int index, CTAP_residentKey * rk)

}

void ctap_store_kbd(CTAP_soloKbd * kbd)
{
// nop
}

void ctap_delete_rk(int index)
{
CTAP_residentKey rk;
Expand Down
22 changes: 20 additions & 2 deletions targets/stm32l432/src/device.c
Expand Up @@ -136,10 +136,14 @@ void EXTI0_IRQHandler(void)
{
__last_button_press_time = millis();
#ifndef IS_BOOTLOADER
uint8_t msg[8] = {'F', 'i', '0', '`', ']', '$', '}', '<'};
if (!_up_wait)
{
usb_kbd_send(msg, 8);
CTAP_soloKbd kbd;
ctap_load_kbd(&kbd);
if (kbd.length > 0)
{
usb_kbd_send(kbd.sequence, kbd.length);
}
}
#endif
}
Expand Down Expand Up @@ -856,6 +860,20 @@ void ctap_overwrite_rk(int index,CTAP_residentKey * rk)
printf1(TAG_GREEN, "4\r\n");
}

void ctap_store_kbd(CTAP_soloKbd * kbd)
{
uint8_t buf[PAGE_SIZE];
memmove(buf, kbd, sizeof(CTAP_soloKbd));
flash_erase_page(KEYBOARD_PAGE);
flash_write(KEYBOARD_PAGE_ADDR, buf, 2048);
}

void ctap_load_kbd(CTAP_soloKbd * kbd)
{
uint32_t * ptr = (uint32_t *) flash_addr(KEYBOARD_PAGE);
memmove(kbd, ptr, sizeof(CTAP_soloKbd));
}

void boot_st_bootloader(void)
{
__disable_irq();
Expand Down
4 changes: 4 additions & 0 deletions targets/stm32l432/src/memory_layout.h
Expand Up @@ -38,6 +38,10 @@
#define ATTESTATION_PAGE (PAGES - 15)
#define ATTESTATION_PAGE_ADDR (0x08000000 + ATTESTATION_PAGE*PAGE_SIZE)

// keyboard stuff
#define KEYBOARD_PAGE (PAGES - 16)
#define KEYBOARD_PAGE_ADDR (0x08000000 + KEYBOARD_PAGE*PAGE_SIZE)

// End of application code. Leave some extra room for future data storage.
// NOT included in application
#define APPLICATION_END_PAGE ((PAGES - 20))
Expand Down

0 comments on commit d444309

Please sign in to comment.