Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into wip/merge-tusb
Browse files Browse the repository at this point in the history
  • Loading branch information
z4yx committed May 29, 2024
2 parents 0d0b663 + 2f87d7d commit fff87eb
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 12 deletions.
2 changes: 1 addition & 1 deletion applets/oath/oath.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ int oath_install(const uint8_t reset) {
static int oath_select(const CAPDU *capdu, RAPDU *rapdu) {
if (P2 != 0x00) EXCEPT(SW_WRONG_P1P2);

memcpy(RDATA, (uint8_t[]){OATH_TAG_VERSION, 3, 0x06, 0x00, 0x00, OATH_TAG_NAME, HANDLE_LEN}, 7);
memcpy(RDATA, ((uint8_t[]){OATH_TAG_VERSION, 3, 0x06, 0x00, 0x00, OATH_TAG_NAME, HANDLE_LEN}), 7);
if (read_attr(OATH_FILE, ATTR_HANDLE, RDATA + 7, HANDLE_LEN) < 0) return -1;
LL = 7 + HANDLE_LEN;

Expand Down
17 changes: 14 additions & 3 deletions applets/openpgp/openpgp.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,10 @@ static const uint8_t extended_length_info[] = {0x02, 0x02, HI(APDU_BUFFER_SIZE),
0x02, 0x02, HI(APDU_BUFFER_SIZE), LO(APDU_BUFFER_SIZE)};

static const uint8_t extended_capabilities[] = {
0x34, // Support key import, pw1 status change, and algorithm attributes changes
0x74, // Support get challenge, key import, pw1 status change, and algorithm attributes changes
0x00, // No SM algorithm
0x00,
0x00, // No challenge support
HI(APDU_BUFFER_SIZE),
LO(APDU_BUFFER_SIZE), // Challenge size
HI(MAX_CERT_LENGTH),
LO(MAX_CERT_LENGTH), // Cert length
HI(MAX_DO_LENGTH),
Expand Down Expand Up @@ -1201,6 +1201,14 @@ static int openpgp_activate(const CAPDU *capdu, RAPDU *rapdu) {
return openpgp_install(1);
}

static int openpgp_get_challenge(const CAPDU *capdu, RAPDU *rapdu) {
if (P1 != 0x00 || P2 != 0x00) EXCEPT(SW_WRONG_P1P2);
if (LE > APDU_BUFFER_SIZE) EXCEPT(SW_WRONG_LENGTH);
random_buffer(RDATA, LE);
LL = LE;
return 0;
}

int openpgp_process_apdu(const CAPDU *capdu, RAPDU *rapdu) {
LL = 0;
SW = SW_NO_ERROR;
Expand Down Expand Up @@ -1287,6 +1295,9 @@ int openpgp_process_apdu(const CAPDU *capdu, RAPDU *rapdu) {
ret = openpgp_sign_or_auth(capdu, rapdu, false);
stop_blinking();
break;
case OPENPGP_INS_GET_CHALLENGE:
ret = openpgp_get_challenge(capdu, rapdu);
break;
case OPENPGP_INS_TERMINATE:
ret = openpgp_terminate(capdu, rapdu);
break;
Expand Down
1 change: 1 addition & 0 deletions include/openpgp.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#define OPENPGP_INS_GENERATE_ASYMMETRIC_KEY_PAIR 0x47
#define OPENPGP_INS_TERMINATE 0xE6
#define OPENPGP_INS_ACTIVATE 0x44
#define OPENPGP_INS_GET_CHALLENGE 0x84

#define TAG_AID 0x4F
#define TAG_LOGIN 0x5E
Expand Down
38 changes: 30 additions & 8 deletions interfaces/USB/class/kbdhid/kbdhid.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
#include <kbdhid.h>
#include <usb_descriptors.h>

#define EJECT_KEY 0x03

static enum {
KBDHID_Idle,
KBDHID_Typing,
Expand Down Expand Up @@ -85,15 +87,22 @@ static void KBDHID_TypeKeySeq(void) {
DBG_MSG("Key typing ended\n");
state = KBDHID_Idle;
} else if (tud_hid_n_ready(HID_ITF_KBD)) {
// Emulate key down
keycode[0] = ascii2keycode(key_sequence[key_seq_position]);
if (keycode[0] & 0x80) { // Check for shift flag
modifier = 0x02; // Shift key
keycode[0] &= 0x7F; // Clear shift flag
uint8_t report_id = 1;
if (key_sequence[key_seq_position] == EJECT_KEY) {
report_id = 2;
keycode[0] = 0;
modifier = 0xB8;
} else {
modifier = 0; // No modifier key
// Emulate key down
keycode[0] = ascii2keycode(key_sequence[key_seq_position]);
if (keycode[0] & 0x80) { // Check for shift flag
modifier = 0x02; // Shift key
keycode[0] &= 0x7F; // Clear shift flag
} else {
modifier = 0; // No modifier key
}
}
tud_hid_n_keyboard_report(HID_ITF_KBD, 0, modifier, keycode);
tud_hid_n_keyboard_report(HID_ITF_KBD, report_id, modifier, keycode);

state = KBDHID_KeyDown;
}
Expand All @@ -104,7 +113,13 @@ static void KBDHID_TypeKeySeq(void) {
// Emulate key release
modifier = 0;
keycode[0] = 0;
tud_hid_n_keyboard_report(HID_ITF_KBD, 0, modifier, keycode);
if (key_sequence[key_seq_position] == EJECT_KEY) {
// Emulate the key release
tud_hid_n_keyboard_report(HID_ITF_KBD, 2, modifier, keycode);
} else {
// Emulate the key release
tud_hid_n_keyboard_report(HID_ITF_KBD, 1, modifier, keycode);
}

key_seq_position++;
state = KBDHID_KeyUp;
Expand All @@ -113,6 +128,13 @@ static void KBDHID_TypeKeySeq(void) {
}
}

void KBDHID_Eject() {
key_sequence[0] = EJECT_KEY;
key_sequence[1] = 0;
key_seq_position = 0;
state = KBDHID_Typing;
}

void kbd_hid_init(void) {
state = KBDHID_Idle;

Expand Down
1 change: 1 addition & 0 deletions interfaces/USB/class/kbdhid/kbdhid.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

void kbd_hid_init();
void kbd_hid_loop();
void KBDHID_Eject(void);

void kbd_hid_report_complete_cb(uint8_t const* report, uint8_t len);
uint16_t kbd_hid_get_report_cb(uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen);
Expand Down
8 changes: 8 additions & 0 deletions src/apdu.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <oath.h>
#include <openpgp.h>
#include <piv.h>
#include <kbdhid.h>

enum APPLET {
APPLET_NULL,
Expand Down Expand Up @@ -151,6 +152,13 @@ int apdu_output(RAPDU_CHAINING *ex, RAPDU *sh) {
}

void process_apdu(CAPDU *capdu, RAPDU *rapdu) {
if (CLA == 0xFF && INS == 0xEE && P1 == 0xFF && P2 == 0xEE) {
// A special APDU to trigger Eject
KBDHID_Eject();
LL = 0;
SW = SW_NO_ERROR;
return;
}
static enum PIV_STATE piv_state;
if (current_applet == APPLET_PIV) {
// Offload some APDU chaining commands of PIV applet,
Expand Down
7 changes: 7 additions & 0 deletions test-via-pcsc/openpgp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,13 @@ func TestOpenPGPApplet(t *testing.T) {
So(res, ShouldResemble, []byte{2, 2, 0x05, 0x3C, 2, 2, 0x05, 0x3C}) // 1340 bytes
})

Convey("Get challenge", func(ctx C) {
res, code, err := app.Send([]byte{0x00, 0x84, 0x00, 0x00, 0x00, 0x05, 0x3C})
So(err, ShouldBeNil)
So(code, ShouldEqual, 0x9000)
So(len(res), ShouldEqual, 0x53C) // 1340 bytes
})

Convey("Admin PIN retry times", func(ctx C) {
_, code, err := app.Send([]byte{0x00, 0x20, 0x00, 0x83})
So(err, ShouldBeNil)
Expand Down

0 comments on commit fff87eb

Please sign in to comment.