Adding support for Transport PIN.
Adding support for initialize options.
This commit is contained in:
@@ -51,7 +51,7 @@ target_sources(pico_hsm PUBLIC
|
|||||||
${CMAKE_CURRENT_LIST_DIR}/src/fs/low_flash.c
|
${CMAKE_CURRENT_LIST_DIR}/src/fs/low_flash.c
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/rng/random.c
|
${CMAKE_CURRENT_LIST_DIR}/src/rng/random.c
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/rng/neug.c
|
${CMAKE_CURRENT_LIST_DIR}/src/rng/neug.c
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/hsm/hash_utils.c
|
${CMAKE_CURRENT_LIST_DIR}/src/hsm/crypto_utils.c
|
||||||
${CMAKE_CURRENT_LIST_DIR}/src/hsm/dkek.c
|
${CMAKE_CURRENT_LIST_DIR}/src/hsm/dkek.c
|
||||||
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/sha256.c
|
${CMAKE_CURRENT_LIST_DIR}/mbedtls/library/sha256.c
|
||||||
@@ -119,7 +119,7 @@ pico_add_extra_outputs(pico_hsm)
|
|||||||
|
|
||||||
#target_compile_definitions(pico_hsm PRIVATE MBEDTLS_ECDSA_DETERMINISTIC=1)
|
#target_compile_definitions(pico_hsm PRIVATE MBEDTLS_ECDSA_DETERMINISTIC=1)
|
||||||
|
|
||||||
target_link_libraries(pico_hsm PRIVATE pico_stdlib tinyusb_device tinyusb_board pico_multicore hardware_flash hardware_sync hardware_adc pico_unique_id)
|
target_link_libraries(pico_hsm PRIVATE pico_stdlib tinyusb_device tinyusb_board pico_multicore hardware_flash hardware_sync hardware_adc pico_unique_id hardware_rtc)
|
||||||
|
|
||||||
#
|
#
|
||||||
#project(flash_nuke C CXX ASM)
|
#project(flash_nuke C CXX ASM)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
VERSION_MAJOR="1"
|
VERSION_MAJOR="1"
|
||||||
VERSION_MINOR="8"
|
VERSION_MINOR="10"
|
||||||
|
|
||||||
rm -rf release/*
|
rm -rf release/*
|
||||||
cd build_release
|
cd build_release
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
VERSION_MAJOR="1"
|
VERSION_MAJOR="1"
|
||||||
VERSION_MINOR="8"
|
VERSION_MINOR="0A"
|
||||||
|
|
||||||
echo "----------------------------"
|
echo "----------------------------"
|
||||||
echo "VID/PID patcher for Pico HSM"
|
echo "VID/PID patcher for Pico HSM"
|
||||||
|
|||||||
@@ -99,15 +99,16 @@ file_t file_entries[] = {
|
|||||||
/* 13 */ { .fid = 0x1089 , .parent = 5, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0xff} }, //max retries PIN (SOPIN)
|
/* 13 */ { .fid = 0x1089 , .parent = 5, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0xff} }, //max retries PIN (SOPIN)
|
||||||
/* 14 */ { .fid = 0x108A , .parent = 5, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0xff} }, //retries PIN (SOPIN)
|
/* 14 */ { .fid = 0x108A , .parent = 5, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0xff} }, //retries PIN (SOPIN)
|
||||||
/* 15 */ { .fid = EF_DKEK , .parent = 5, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0xff} }, //DKEK
|
/* 15 */ { .fid = EF_DKEK , .parent = 5, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0xff} }, //DKEK
|
||||||
/* 16 */ { .fid = EF_PRKDFS , .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.PrKDFs
|
/* 16 */ { .fid = EF_DEVOPS , .parent = 5, .name = NULL, .type = FILE_TYPE_INTERNAL_EF | FILE_DATA_FLASH, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0xff} }, //Device options
|
||||||
/* 17 */ { .fid = EF_PUKDFS , .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.PuKDFs
|
/* 17 */ { .fid = EF_PRKDFS , .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.PrKDFs
|
||||||
/* 18 */ { .fid = EF_CDFS , .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.CDFs
|
/* 18 */ { .fid = EF_PUKDFS , .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.PuKDFs
|
||||||
/* 19 */ { .fid = EF_AODFS , .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.AODFs
|
/* 19 */ { .fid = EF_CDFS , .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.CDFs
|
||||||
/* 20 */ { .fid = EF_DODFS , .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.DODFs
|
/* 20 */ { .fid = EF_AODFS , .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.AODFs
|
||||||
/* 21 */ { .fid = EF_SKDFS , .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.SKDFs
|
/* 21 */ { .fid = EF_DODFS , .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.DODFs
|
||||||
///* 22 */ { .fid = 0x0000, .parent = 0, .name = openpgpcard_aid, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} },
|
/* 22 */ { .fid = EF_SKDFS , .parent = 5, .name = NULL, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} }, //EF.SKDFs
|
||||||
/* 23 */ { .fid = 0x0000, .parent = 5, .name = sc_hsm_aid, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} },
|
///* 23 */ { .fid = 0x0000, .parent = 0, .name = openpgpcard_aid, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} },
|
||||||
/* 24 */ { .fid = 0x0000, .parent = 0xff, .name = NULL, .type = FILE_TYPE_UNKNOWN, .data = NULL, .ef_structure = 0, .acl = {0} } //end
|
/* 24 */ { .fid = 0x0000, .parent = 5, .name = sc_hsm_aid, .type = FILE_TYPE_WORKING_EF, .data = NULL, .ef_structure = FILE_EF_TRANSPARENT, .acl = {0} },
|
||||||
|
/* 25 */ { .fid = 0x0000, .parent = 0xff, .name = NULL, .type = FILE_TYPE_UNKNOWN, .data = NULL, .ef_structure = 0, .acl = {0} } //end
|
||||||
};
|
};
|
||||||
|
|
||||||
const file_t *MF = &file_entries[0];
|
const file_t *MF = &file_entries[0];
|
||||||
|
|||||||
@@ -60,6 +60,7 @@
|
|||||||
#define EF_AODFS 0x6043
|
#define EF_AODFS 0x6043
|
||||||
#define EF_DODFS 0x6044
|
#define EF_DODFS 0x6044
|
||||||
#define EF_SKDFS 0x6045
|
#define EF_SKDFS 0x6045
|
||||||
|
#define EF_DEVOPS 0x100E
|
||||||
|
|
||||||
#define MAX_DEPTH 4
|
#define MAX_DEPTH 4
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
#include "mbedtls/md.h"
|
#include "mbedtls/md.h"
|
||||||
#include "mbedtls/sha256.h"
|
#include "mbedtls/sha256.h"
|
||||||
#include "mbedtls/aes.h"
|
#include "mbedtls/aes.h"
|
||||||
#include "hash_utils.h"
|
#include "crypto_utils.h"
|
||||||
#include "sc_hsm.h"
|
#include "sc_hsm.h"
|
||||||
#include "libopensc/card-sc-hsm.h"
|
#include "libopensc/card-sc-hsm.h"
|
||||||
|
|
||||||
@@ -15,8 +15,8 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _HASH_UTILS_H_
|
#ifndef _CRYPTO_UTILS_H_
|
||||||
#define _HASH_UTILS_H_
|
#define _CRYPTO_UTILS_H_
|
||||||
|
|
||||||
#include "stdlib.h"
|
#include "stdlib.h"
|
||||||
#include "pico/stdlib.h"
|
#include "pico/stdlib.h"
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
#include "stdlib.h"
|
#include "stdlib.h"
|
||||||
#include "pico/stdlib.h"
|
#include "pico/stdlib.h"
|
||||||
#include "dkek.h"
|
#include "dkek.h"
|
||||||
#include "hash_utils.h"
|
#include "crypto_utils.h"
|
||||||
#include "random.h"
|
#include "random.h"
|
||||||
#include "sc_hsm.h"
|
#include "sc_hsm.h"
|
||||||
#include "mbedtls/md.h"
|
#include "mbedtls/md.h"
|
||||||
@@ -88,6 +88,7 @@ int dkek_kcv(uint8_t *kcv) { //kcv 8 bytes
|
|||||||
hash256(dkek+IV_SIZE, 32, hsh);
|
hash256(dkek+IV_SIZE, 32, hsh);
|
||||||
release_dkek();
|
release_dkek();
|
||||||
memcpy(kcv, hsh, 8);
|
memcpy(kcv, hsh, 8);
|
||||||
|
return HSM_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dkek_kenc(uint8_t *kenc) { //kenc 32 bytes
|
int dkek_kenc(uint8_t *kenc) { //kenc 32 bytes
|
||||||
|
|||||||
@@ -33,6 +33,7 @@
|
|||||||
#include "pico/multicore.h"
|
#include "pico/multicore.h"
|
||||||
#include "random.h"
|
#include "random.h"
|
||||||
#include "hsm2040.h"
|
#include "hsm2040.h"
|
||||||
|
#include "hardware/rtc.h"
|
||||||
|
|
||||||
extern void do_flash();
|
extern void do_flash();
|
||||||
extern void low_flash_init();
|
extern void low_flash_init();
|
||||||
@@ -1629,6 +1630,7 @@ int main(void)
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
led_off_all();
|
led_off_all();
|
||||||
|
|
||||||
tusb_init();
|
tusb_init();
|
||||||
@@ -1639,6 +1641,8 @@ int main(void)
|
|||||||
|
|
||||||
low_flash_init();
|
low_flash_init();
|
||||||
|
|
||||||
|
rtc_init();
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
prev_millis = board_millis();
|
prev_millis = board_millis();
|
||||||
|
|||||||
129
src/hsm/sc_hsm.c
129
src/hsm/sc_hsm.c
@@ -30,8 +30,9 @@
|
|||||||
#include "mbedtls/hkdf.h"
|
#include "mbedtls/hkdf.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
#include "cvcerts.h"
|
#include "cvcerts.h"
|
||||||
#include "hash_utils.h"
|
#include "crypto_utils.h"
|
||||||
#include "dkek.h"
|
#include "dkek.h"
|
||||||
|
#include "hardware/rtc.h"
|
||||||
|
|
||||||
const uint8_t sc_hsm_aid[] = {
|
const uint8_t sc_hsm_aid[] = {
|
||||||
11,
|
11,
|
||||||
@@ -92,6 +93,14 @@ void select_file(file_t *pe) {
|
|||||||
//sc_hsm_unload(); //reset auth status
|
//sc_hsm_unload(); //reset auth status
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint16_t get_device_options() {
|
||||||
|
file_t *ef = search_by_fid(EF_DEVOPS, NULL, SPECIFY_EF);
|
||||||
|
if (ef && ef->data)
|
||||||
|
return (file_read_uint8(ef->data+2) << 8) | file_read_uint8(ef->data+3);
|
||||||
|
return 0x0;
|
||||||
|
}
|
||||||
|
|
||||||
static int cmd_select() {
|
static int cmd_select() {
|
||||||
uint8_t p1 = P1(apdu);
|
uint8_t p1 = P1(apdu);
|
||||||
uint8_t p2 = P2(apdu);
|
uint8_t p2 = P2(apdu);
|
||||||
@@ -171,8 +180,9 @@ static int cmd_select() {
|
|||||||
if (pe == file_sc_hsm) {
|
if (pe == file_sc_hsm) {
|
||||||
res_APDU[res_APDU_size++] = 0x85;
|
res_APDU[res_APDU_size++] = 0x85;
|
||||||
res_APDU[res_APDU_size++] = 4;
|
res_APDU[res_APDU_size++] = 4;
|
||||||
res_APDU[res_APDU_size++] = 0xff; //options
|
uint16_t opts = get_device_options();
|
||||||
res_APDU[res_APDU_size++] = 0xff;
|
res_APDU[res_APDU_size++] = opts & 0xff;
|
||||||
|
res_APDU[res_APDU_size++] = opts >> 8;
|
||||||
res_APDU[res_APDU_size++] = HSM_VERSION_MAJOR;
|
res_APDU[res_APDU_size++] = HSM_VERSION_MAJOR;
|
||||||
res_APDU[res_APDU_size++] = HSM_VERSION_MINOR;
|
res_APDU[res_APDU_size++] = HSM_VERSION_MINOR;
|
||||||
res_APDU[1] = res_APDU_size-2;
|
res_APDU[1] = res_APDU_size-2;
|
||||||
@@ -400,11 +410,12 @@ int pin_wrong_retry(const file_t *pin) {
|
|||||||
|
|
||||||
int check_pin(const file_t *pin, const uint8_t *data, size_t len) {
|
int check_pin(const file_t *pin, const uint8_t *data, size_t len) {
|
||||||
if (!pin)
|
if (!pin)
|
||||||
return SW_FILE_NOT_FOUND();
|
return SW_REFERENCE_NOT_FOUND();
|
||||||
if (!pin->data) {
|
if (!pin->data) {
|
||||||
return SW_REFERENCE_NOT_FOUND();
|
return SW_REFERENCE_NOT_FOUND();
|
||||||
}
|
}
|
||||||
isUserAuthenticated = false;
|
isUserAuthenticated = false;
|
||||||
|
has_session_pin = has_session_sopin = false;
|
||||||
uint8_t dhash[32];
|
uint8_t dhash[32];
|
||||||
double_hash_pin(data, len, dhash);
|
double_hash_pin(data, len, dhash);
|
||||||
if (sizeof(dhash) != file_read_uint16(pin->data)-1) //1 byte for pin len
|
if (sizeof(dhash) != file_read_uint16(pin->data)-1) //1 byte for pin len
|
||||||
@@ -422,7 +433,10 @@ int check_pin(const file_t *pin, const uint8_t *data, size_t len) {
|
|||||||
return SW_MEMORY_FAILURE();
|
return SW_MEMORY_FAILURE();
|
||||||
isUserAuthenticated = true;
|
isUserAuthenticated = true;
|
||||||
hash_multi(data, len, session_pin);
|
hash_multi(data, len, session_pin);
|
||||||
has_session_pin = true;
|
if (pin == file_pin1)
|
||||||
|
has_session_pin = true;
|
||||||
|
else if (pin == file_sopin)
|
||||||
|
has_session_sopin = true;
|
||||||
return SW_OK();
|
return SW_OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -434,46 +448,94 @@ static int cmd_verify() {
|
|||||||
return SW_WRONG_P1P2();
|
return SW_WRONG_P1P2();
|
||||||
uint8_t qualifier = p2&0x1f;
|
uint8_t qualifier = p2&0x1f;
|
||||||
if (p2 == 0x81) { //UserPin
|
if (p2 == 0x81) { //UserPin
|
||||||
|
uint16_t opts = get_device_options();
|
||||||
|
if (opts & HSM_OPT_TRANSPORT_PIN)
|
||||||
|
return SW_DATA_INVALID();
|
||||||
|
if (file_read_uint8(file_pin1->data+2) == 0) //not initialized
|
||||||
|
return SW_REFERENCE_NOT_FOUND();
|
||||||
if (apdu.cmd_apdu_data_len > 0) {
|
if (apdu.cmd_apdu_data_len > 0) {
|
||||||
return check_pin(file_pin1, apdu.cmd_apdu_data, apdu.cmd_apdu_data_len);
|
return check_pin(file_pin1, apdu.cmd_apdu_data, apdu.cmd_apdu_data_len);
|
||||||
}
|
}
|
||||||
if (file_read_uint8(file_retries_pin1->data+2) == 0)
|
if (file_read_uint8(file_retries_pin1->data+2) == 0)
|
||||||
return SW_PIN_BLOCKED();
|
return SW_PIN_BLOCKED();
|
||||||
|
if (has_session_pin)
|
||||||
|
return SW_OK();
|
||||||
return set_res_sw(0x63, 0xc0 | file_read_uint8(file_retries_pin1->data+2));
|
return set_res_sw(0x63, 0xc0 | file_read_uint8(file_retries_pin1->data+2));
|
||||||
}
|
}
|
||||||
else if (p2 == 0x88) { //SOPin
|
else if (p2 == 0x88) { //SOPin
|
||||||
|
if (file_read_uint8(file_sopin->data+2) == 0) //not initialized
|
||||||
|
return SW_REFERENCE_NOT_FOUND();
|
||||||
if (apdu.cmd_apdu_data_len > 0) {
|
if (apdu.cmd_apdu_data_len > 0) {
|
||||||
return check_pin(file_sopin, apdu.cmd_apdu_data, apdu.cmd_apdu_data_len);
|
return check_pin(file_sopin, apdu.cmd_apdu_data, apdu.cmd_apdu_data_len);
|
||||||
}
|
}
|
||||||
if (file_read_uint8(file_retries_sopin->data+2) == 0)
|
if (file_read_uint8(file_retries_sopin->data+2) == 0)
|
||||||
return SW_PIN_BLOCKED();
|
return SW_PIN_BLOCKED();
|
||||||
|
if (has_session_sopin)
|
||||||
|
return SW_OK();
|
||||||
return set_res_sw(0x63, 0xc0 | file_read_uint8(file_retries_sopin->data+2));
|
return set_res_sw(0x63, 0xc0 | file_read_uint8(file_retries_sopin->data+2));
|
||||||
}
|
}
|
||||||
return SW_REFERENCE_NOT_FOUND();
|
return SW_REFERENCE_NOT_FOUND();
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cmd_reset_retry() {
|
static int cmd_reset_retry() {
|
||||||
if (P1(apdu) == 0x0) {
|
if (P2(apdu) != 0x81)
|
||||||
if (P2(apdu) == 0x81) {
|
return SW_REFERENCE_NOT_FOUND();
|
||||||
if (!file_sopin || !file_pin1) {
|
if (!file_sopin || !file_pin1) {
|
||||||
return SW_FILE_NOT_FOUND();
|
return SW_FILE_NOT_FOUND();
|
||||||
}
|
}
|
||||||
if (!file_sopin->data) {
|
if (!file_sopin->data) {
|
||||||
return SW_REFERENCE_NOT_FOUND();
|
return SW_REFERENCE_NOT_FOUND();
|
||||||
}
|
}
|
||||||
|
uint16_t opts = get_device_options();
|
||||||
|
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();
|
||||||
uint16_t r = check_pin(file_sopin, apdu.cmd_apdu_data, 8);
|
uint16_t r = check_pin(file_sopin, apdu.cmd_apdu_data, 8);
|
||||||
if (r != 0x9000)
|
if (r != 0x9000)
|
||||||
return r;
|
return r;
|
||||||
uint8_t dhash[33];
|
newpin_len = apdu.cmd_apdu_data_len-8;
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
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 || 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();
|
||||||
|
uint16_t r = check_pin(file_sopin, apdu.cmd_apdu_data, 8);
|
||||||
|
if (r != 0x9000)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cmd_challenge() {
|
static int cmd_challenge() {
|
||||||
@@ -503,6 +565,8 @@ static int cmd_initialize() {
|
|||||||
uint8_t tag = *p++;
|
uint8_t tag = *p++;
|
||||||
uint8_t tag_len = *p++;
|
uint8_t tag_len = *p++;
|
||||||
if (tag == 0x80) { //options
|
if (tag == 0x80) { //options
|
||||||
|
file_t *tf = search_by_fid(EF_DEVOPS, NULL, SPECIFY_EF);
|
||||||
|
flash_write_data_to_file(tf, p, tag_len);
|
||||||
}
|
}
|
||||||
else if (tag == 0x81) { //user pin
|
else if (tag == 0x81) { //user pin
|
||||||
if (file_pin1 && file_pin1->data) {
|
if (file_pin1 && file_pin1->data) {
|
||||||
@@ -581,6 +645,7 @@ static int cmd_import_dkek() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
memset(res_APDU,0,10);
|
||||||
res_APDU[0] = dkeks;
|
res_APDU[0] = dkeks;
|
||||||
res_APDU[1] = dkeks-current_dkeks;
|
res_APDU[1] = dkeks-current_dkeks;
|
||||||
dkek_kcv(res_APDU+2);
|
dkek_kcv(res_APDU+2);
|
||||||
@@ -1036,7 +1101,7 @@ static int cmd_delete_file() {
|
|||||||
if (apdu.cmd_apdu_data_len == 0) {
|
if (apdu.cmd_apdu_data_len == 0) {
|
||||||
ef = currentEF;
|
ef = currentEF;
|
||||||
if (!(ef = search_dynamic_file(ef->fid)))
|
if (!(ef = search_dynamic_file(ef->fid)))
|
||||||
return SW_FILE_INVALID();
|
return SW_FILE_NOT_FOUND();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
uint16_t fid = (apdu.cmd_apdu_data[0] << 8) | apdu.cmd_apdu_data[1];
|
uint16_t fid = (apdu.cmd_apdu_data[0] << 8) | apdu.cmd_apdu_data[1];
|
||||||
@@ -1649,6 +1714,24 @@ static int cmd_derive_asym() {
|
|||||||
return SW_OK();
|
return SW_OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int cmd_datetime() {
|
||||||
|
if (P1(apdu) != 0x0 || P2(apdu) != 0x0)
|
||||||
|
return SW_INCORRECT_P1P2();
|
||||||
|
if (apdu.cmd_apdu_data_len != 8)
|
||||||
|
return SW_WRONG_LENGTH();
|
||||||
|
datetime_t dt;
|
||||||
|
dt.year = (apdu.cmd_apdu_data[0] << 8) | (apdu.cmd_apdu_data[1]);
|
||||||
|
dt.month = apdu.cmd_apdu_data[2];
|
||||||
|
dt.day = apdu.cmd_apdu_data[3];
|
||||||
|
dt.dotw = apdu.cmd_apdu_data[4];
|
||||||
|
dt.hour = apdu.cmd_apdu_data[5];
|
||||||
|
dt.min = apdu.cmd_apdu_data[6];
|
||||||
|
dt.sec = apdu.cmd_apdu_data[7];
|
||||||
|
if (!rtc_set_datetime(&dt))
|
||||||
|
return SW_WRONG_DATA();
|
||||||
|
return SW_OK();
|
||||||
|
}
|
||||||
|
|
||||||
typedef struct cmd
|
typedef struct cmd
|
||||||
{
|
{
|
||||||
uint8_t ins;
|
uint8_t ins;
|
||||||
@@ -1670,6 +1753,7 @@ typedef struct cmd
|
|||||||
#define INS_DERIVE_ASYM 0x76
|
#define INS_DERIVE_ASYM 0x76
|
||||||
#define INS_CIPHER_SYM 0x78
|
#define INS_CIPHER_SYM 0x78
|
||||||
#define INS_CHALLENGE 0x84
|
#define INS_CHALLENGE 0x84
|
||||||
|
#define INS_DATETIME 0x88
|
||||||
#define INS_SELECT_FILE 0xA4
|
#define INS_SELECT_FILE 0xA4
|
||||||
#define INS_READ_BINARY 0xB0
|
#define INS_READ_BINARY 0xB0
|
||||||
#define INS_READ_BINARY_ODD 0xB1
|
#define INS_READ_BINARY_ODD 0xB1
|
||||||
@@ -1697,6 +1781,7 @@ static const cmd_t cmds[] = {
|
|||||||
{ INS_DECRYPT_ASYM, cmd_decrypt_asym },
|
{ INS_DECRYPT_ASYM, cmd_decrypt_asym },
|
||||||
{ INS_CIPHER_SYM, cmd_cipher_sym },
|
{ INS_CIPHER_SYM, cmd_cipher_sym },
|
||||||
{ INS_DERIVE_ASYM, cmd_derive_asym },
|
{ INS_DERIVE_ASYM, cmd_derive_asym },
|
||||||
|
{ INS_DATETIME, cmd_datetime },
|
||||||
{ 0x00, 0x0}
|
{ 0x00, 0x0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ extern const uint8_t sc_hsm_aid[];
|
|||||||
|
|
||||||
#define SW_BYTES_REMAINING_00() set_res_sw (0x61, 0x00)
|
#define SW_BYTES_REMAINING_00() set_res_sw (0x61, 0x00)
|
||||||
#define SW_WARNING_STATE_UNCHANGED() set_res_sw (0x62, 0x00)
|
#define SW_WARNING_STATE_UNCHANGED() set_res_sw (0x62, 0x00)
|
||||||
#define SW_PIN_BLOCKED() set_res_sw (0x63, 0x00)
|
|
||||||
#define SW_EXEC_ERROR() set_res_sw (0x64, 0x00)
|
#define SW_EXEC_ERROR() set_res_sw (0x64, 0x00)
|
||||||
#define SW_MEMORY_FAILURE() set_res_sw (0x65, 0x81)
|
#define SW_MEMORY_FAILURE() set_res_sw (0x65, 0x81)
|
||||||
#define SW_WRONG_LENGTH() set_res_sw (0x67, 0x00)
|
#define SW_WRONG_LENGTH() set_res_sw (0x67, 0x00)
|
||||||
@@ -34,7 +33,7 @@ extern const uint8_t sc_hsm_aid[];
|
|||||||
#define SW_LOGICAL_CHANNEL_NOT_SUPPORTED() set_res_sw (0x68, 0x81)
|
#define SW_LOGICAL_CHANNEL_NOT_SUPPORTED() set_res_sw (0x68, 0x81)
|
||||||
#define SW_SECURE_MESSAGING_NOT_SUPPORTED() set_res_sw (0x68, 0x82)
|
#define SW_SECURE_MESSAGING_NOT_SUPPORTED() set_res_sw (0x68, 0x82)
|
||||||
#define SW_SECURITY_STATUS_NOT_SATISFIED() set_res_sw (0x69, 0x82)
|
#define SW_SECURITY_STATUS_NOT_SATISFIED() set_res_sw (0x69, 0x82)
|
||||||
#define SW_FILE_INVALID() set_res_sw (0x69, 0x83)
|
#define SW_PIN_BLOCKED() set_res_sw (0x69, 0x83)
|
||||||
#define SW_DATA_INVALID() set_res_sw (0x69, 0x84)
|
#define SW_DATA_INVALID() set_res_sw (0x69, 0x84)
|
||||||
#define SW_CONDITIONS_NOT_SATISFIED() set_res_sw (0x69, 0x85)
|
#define SW_CONDITIONS_NOT_SATISFIED() set_res_sw (0x69, 0x85)
|
||||||
#define SW_COMMAND_NOT_ALLOWED() set_res_sw (0x69, 0x86)
|
#define SW_COMMAND_NOT_ALLOWED() set_res_sw (0x69, 0x86)
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
#ifndef __VERSION_H_
|
#ifndef __VERSION_H_
|
||||||
#define __VERSION_H_
|
#define __VERSION_H_
|
||||||
|
|
||||||
#define HSM_VERSION 0x0108
|
#define HSM_VERSION 0x010A
|
||||||
|
|
||||||
#define HSM_VERSION_MAJOR ((HSM_VERSION >> 8) & 0xff)
|
#define HSM_VERSION_MAJOR ((HSM_VERSION >> 8) & 0xff)
|
||||||
#define HSM_VERSION_MINOR (HSM_VERSION & 0xff)
|
#define HSM_VERSION_MINOR (HSM_VERSION & 0xff)
|
||||||
|
|||||||
Reference in New Issue
Block a user