diff --git a/src/hsm/sc_hsm.c b/src/hsm/sc_hsm.c index 3cff83a..21c6ee6 100644 --- a/src/hsm/sc_hsm.c +++ b/src/hsm/sc_hsm.c @@ -478,56 +478,62 @@ static int cmd_verify() { } static int cmd_reset_retry() { + if (P2(apdu) != 0x81) + return SW_REFERENCE_NOT_FOUND(); + if (!file_sopin || !file_pin1) { + return SW_FILE_NOT_FOUND(); + } + if (!file_sopin->data) { + return SW_REFERENCE_NOT_FOUND(); + } uint16_t opts = get_device_options(); - if (P1(apdu) == 0x0) { - if (P2(apdu) == 0x81) { - if (!file_sopin || !file_pin1) { - return SW_FILE_NOT_FOUND(); - } - if (!file_sopin->data) { - return SW_REFERENCE_NOT_FOUND(); - } + if (!(opts & HSM_OPT_RRC)) + return SW_COMMAND_NOT_ALLOWED(); + if (P1(apdu) == 0x0 || P1(apdu) == 0x2) { + int newpin_len = 0; + if (P1(apdu) == 0x0) { if (apdu.cmd_apdu_data_len <= 8) return SW_WRONG_LENGTH(); - if (!(opts & HSM_OPT_RRC)) - return SW_COMMAND_NOT_ALLOWED(); uint16_t r = check_pin(file_sopin, apdu.cmd_apdu_data, 8); if (r != 0x9000) return r; - uint8_t dhash[33]; - dhash[0] = apdu.cmd_apdu_data_len-8; - double_hash_pin(apdu.cmd_apdu_data+8, apdu.cmd_apdu_data_len-8, dhash+1); - flash_write_data_to_file(file_pin1, dhash, sizeof(dhash)); - if (pin_reset_retries(file_pin1, true) != HSM_OK) - return SW_MEMORY_FAILURE(); - low_flash_available(); - return SW_OK(); + newpin_len = apdu.cmd_apdu_data_len-8; } - else - return SW_REFERENCE_NOT_FOUND(); + else if (P1(apdu) == 0x2) { + if (!has_session_sopin) + return SW_CONDITIONS_NOT_SATISFIED(); + if (apdu.cmd_apdu_data_len > 16) + return SW_WRONG_LENGTH(); + newpin_len = apdu.cmd_apdu_data_len; + } + uint8_t dhash[33]; + dhash[0] = newpin_len; + double_hash_pin(apdu.cmd_apdu_data+(apdu.cmd_apdu_data_len-newpin_len), newpin_len, dhash+1); + flash_write_data_to_file(file_pin1, dhash, sizeof(dhash)); + if (pin_reset_retries(file_pin1, true) != HSM_OK) + return SW_MEMORY_FAILURE(); + low_flash_available(); + return SW_OK(); } - else if (P1(apdu) == 0x1) { - if (P2(apdu) == 0x81) { - if (!file_sopin || !file_pin1) { - return SW_FILE_NOT_FOUND(); - } - if (!file_sopin->data) { - return SW_REFERENCE_NOT_FOUND(); - } + else if (P1(apdu) == 0x1 || P1(apdu) == 0x3) { + if (!(opts & HSM_OPT_RRC_RESET_ONLY)) + return SW_COMMAND_NOT_ALLOWED(); + if (P1(apdu) == 0x1) { if (apdu.cmd_apdu_data_len != 8) return SW_WRONG_LENGTH(); - if (!(opts & HSM_OPT_RRC) || !(opts & HSM_OPT_RRC_RESET_ONLY)) - return SW_COMMAND_NOT_ALLOWED(); uint16_t r = check_pin(file_sopin, apdu.cmd_apdu_data, 8); if (r != 0x9000) return r; - if (pin_reset_retries(file_pin1, true) != HSM_OK) - return SW_MEMORY_FAILURE(); - low_flash_available(); - return SW_OK(); } - else - return SW_REFERENCE_NOT_FOUND(); + else if (P1(apdu) == 0x3) { + if (!has_session_sopin) + return SW_CONDITIONS_NOT_SATISFIED(); + if (apdu.cmd_apdu_data_len != 0) + return SW_WRONG_LENGTH(); + } + if (pin_reset_retries(file_pin1, true) != HSM_OK) + return SW_MEMORY_FAILURE(); + return SW_OK(); } return SW_INCORRECT_P1P2(); }