From 093c98bb0f5f023aefaab20d7846a2c7af585502 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Wed, 30 May 2012 18:50:22 +0900 Subject: [PATCH] external authenticate implemented --- ChangeLog | 9 ++++++++- README | 3 +++ src/gnuk.h | 1 + src/openpgp.c | 42 +++++++++++++++++++++++++++++++----------- 4 files changed, 43 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index e01de34..9b05e18 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2012-05-30 Niibe Yutaka + + * src/openpgp.c (CHALLENGE_LEN): New. + (cmd_external_authenticate): Authentication by response with + public key. + (cmd_get_challenge): 16-byte is enough for challenge. + 2012-05-29 Niibe Yutaka * src/call-rsa.c (rsa_verify): New function. @@ -227,7 +234,7 @@ (std_set_address, std_get_descriptor, std_get_configuration) (std_set_configuration, std_get_interface, std_set_interface): Check direction. - (handle_setup0): Add length for setup_with_data + (handle_setup0): Add length for setup_with_data. 2012-05-16 Niibe Yutaka diff --git a/README b/README index d49abac..b0627b7 100644 --- a/README +++ b/README @@ -228,6 +228,9 @@ Gnuk is distributed with external source code. The file include/polarssl/bn_mul.h is heavily modified for ARM Cortex-M3. + The file library/aes.c is modified so that some constants can + go to .sys section. + USB vendor ID and product ID (USB device ID) ============================================ diff --git a/src/gnuk.h b/src/gnuk.h index 45bb99c..7e55465 100644 --- a/src/gnuk.h +++ b/src/gnuk.h @@ -121,6 +121,7 @@ extern void gpg_do_get_data (uint16_t tag, int with_tag); extern void gpg_do_put_data (uint16_t tag, const uint8_t *data, int len); extern void gpg_do_public_key (uint8_t kk_byte); +extern const uint8_t *gpg_get_firmware_update_key (uint8_t keyno); enum kind_of_key { diff --git a/src/openpgp.c b/src/openpgp.c index d062f11..076f245 100644 --- a/src/openpgp.c +++ b/src/openpgp.c @@ -50,6 +50,9 @@ #define INS_PUT_DATA 0xda #define INS_PUT_DATA_ODD 0xdb /* For key import */ +#define CHALLENGE_LEN 16 +static const uint8_t *challenge; /* Random bytes */ + static const uint8_t select_file_TOP_result[] __attribute__ ((aligned (1))) = { 0x00, 0x00, /* unused */ @@ -826,9 +829,31 @@ cmd_write_binary (void) static void cmd_external_authenticate (void) { + const uint8_t *pubkey; + const uint8_t *signature = apdu.cmd_apdu_data; + int len = apdu.cmd_apdu_data_len; + uint8_t keyno = P2 (apdu); + int r; + DEBUG_INFO (" - EXTERNAL AUTHENTICATE\r\n"); - if (!ac_check_status (AC_ADMIN_AUTHORIZED)) + if (keyno > 2) + { + GPG_CONDITION_NOT_SATISFIED (); + return; + } + + pubkey = gpg_get_firmware_update_key (keyno); + if (pubkey == NULL || len != 256) + { + GPG_CONDITION_NOT_SATISFIED (); + return; + } + + r = rsa_verify (pubkey, challenge, CHALLENGE_LEN, signature); + random_bytes_free (challenge); + challenge = NULL; + if (r < 0) { GPG_SECURITY_FAILURE (); return; @@ -842,19 +867,14 @@ cmd_external_authenticate (void) static void cmd_get_challenge (void) { - const uint8_t *rand; - int i; - DEBUG_INFO (" - GET CHALLENGE\r\n"); - for (i = 0; i < 6; i++) - { - rand = random_bytes_get (); - memcpy (res_APDU + i * 16, rand, 16); - random_bytes_free (rand); - } + if (challenge) + random_bytes_free (challenge); - res_APDU_size = 96; + challenge = random_bytes_get (); + memcpy (res_APDU, challenge, CHALLENGE_LEN); + res_APDU_size = CHALLENGE_LEN; GPG_SUCCESS (); DEBUG_INFO ("GET CHALLENGE done.\r\n"); }