Harmonize coding style.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
269
src/hsm/sc_hsm.c
269
src/hsm/sc_hsm.c
@@ -29,12 +29,13 @@
|
||||
|
||||
const uint8_t sc_hsm_aid[] = {
|
||||
11,
|
||||
0xE8,0x2B,0x06,0x01,0x04,0x01,0x81,0xC3,0x1F,0x02,0x01
|
||||
0xE8, 0x2B, 0x06, 0x01, 0x04, 0x01, 0x81, 0xC3, 0x1F, 0x02, 0x01
|
||||
};
|
||||
|
||||
const uint8_t atr_sc_hsm[] = {
|
||||
24,
|
||||
0x3B,0xFE,0x18,0x00,0x00,0x81,0x31,0xFE,0x45,0x80,0x31,0x81,0x54,0x48,0x53,0x4D,0x31,0x73,0x80,0x21,0x40,0x81,0x07,0xFA
|
||||
0x3B, 0xFE, 0x18, 0x00, 0x00, 0x81, 0x31, 0xFE, 0x45, 0x80, 0x31, 0x81, 0x54, 0x48, 0x53, 0x4D,
|
||||
0x31, 0x73, 0x80, 0x21, 0x40, 0x81, 0x07, 0xFA
|
||||
};
|
||||
|
||||
uint8_t session_pin[32], session_sopin[32];
|
||||
@@ -77,8 +78,9 @@ extern int cmd_pso();
|
||||
|
||||
extern const uint8_t *ccid_atr;
|
||||
|
||||
app_t *sc_hsm_select_aid(app_t *a, const uint8_t *aid, uint8_t aid_len) {
|
||||
if (!memcmp(aid, sc_hsm_aid+1, MIN(aid_len,sc_hsm_aid[0]))) {
|
||||
app_t *sc_hsm_select_aid(app_t *a, const uint8_t *aid, uint8_t aid_len)
|
||||
{
|
||||
if (!memcmp(aid, sc_hsm_aid+1, MIN(aid_len, sc_hsm_aid[0]))) {
|
||||
a->aid = sc_hsm_aid;
|
||||
a->process_apdu = sc_hsm_process_apdu;
|
||||
a->unload = sc_hsm_unload;
|
||||
@@ -88,12 +90,14 @@ app_t *sc_hsm_select_aid(app_t *a, const uint8_t *aid, uint8_t aid_len) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void __attribute__ ((constructor)) sc_hsm_ctor() {
|
||||
void __attribute__((constructor)) sc_hsm_ctor()
|
||||
{
|
||||
ccid_atr = atr_sc_hsm;
|
||||
register_app(sc_hsm_select_aid);
|
||||
}
|
||||
|
||||
void scan_files() {
|
||||
void scan_files()
|
||||
{
|
||||
file_pin1 = search_by_fid(0x1081, NULL, SPECIFY_EF);
|
||||
if (file_pin1) {
|
||||
if (!file_pin1->data) {
|
||||
@@ -101,8 +105,7 @@ void scan_files() {
|
||||
const uint8_t empty[33] = { 0 };
|
||||
flash_write_data_to_file(file_pin1, empty, sizeof(empty));
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
printf("FATAL ERROR: PIN1 not found in memory!\r\n");
|
||||
}
|
||||
file_sopin = search_by_fid(0x1088, NULL, SPECIFY_EF);
|
||||
@@ -112,8 +115,7 @@ void scan_files() {
|
||||
const uint8_t empty[33] = { 0 };
|
||||
flash_write_data_to_file(file_sopin, empty, sizeof(empty));
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
printf("FATAL ERROR: SOPIN not found in memory!\r\n");
|
||||
}
|
||||
file_retries_pin1 = search_by_fid(0x1083, NULL, SPECIFY_EF);
|
||||
@@ -123,8 +125,7 @@ void scan_files() {
|
||||
const uint8_t retries = 3;
|
||||
flash_write_data_to_file(file_retries_pin1, &retries, sizeof(uint8_t));
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
printf("FATAL ERROR: Retries PIN1 not found in memory!\r\n");
|
||||
}
|
||||
file_retries_sopin = search_by_fid(0x108A, NULL, SPECIFY_EF);
|
||||
@@ -134,8 +135,7 @@ void scan_files() {
|
||||
const uint8_t retries = 15;
|
||||
flash_write_data_to_file(file_retries_sopin, &retries, sizeof(uint8_t));
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
printf("FATAL ERROR: Retries SOPIN not found in memory!\r\n");
|
||||
}
|
||||
file_t *tf = NULL;
|
||||
@@ -147,8 +147,7 @@ void scan_files() {
|
||||
const uint8_t retries = 3;
|
||||
flash_write_data_to_file(tf, &retries, sizeof(uint8_t));
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
printf("FATAL ERROR: Max Retries PIN1 not found in memory!\r\n");
|
||||
}
|
||||
tf = search_by_fid(0x1089, NULL, SPECIFY_EF);
|
||||
@@ -158,14 +157,14 @@ void scan_files() {
|
||||
const uint8_t retries = 15;
|
||||
flash_write_data_to_file(tf, &retries, sizeof(uint8_t));
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
printf("FATAL ERROR: Retries SOPIN not found in memory!\r\n");
|
||||
}
|
||||
low_flash_available();
|
||||
}
|
||||
|
||||
void scan_all() {
|
||||
void scan_all()
|
||||
{
|
||||
scan_flash();
|
||||
scan_files();
|
||||
}
|
||||
@@ -175,30 +174,40 @@ int puk_store_entries = 0;
|
||||
PUK *current_puk = NULL;
|
||||
uint8_t puk_status[MAX_PUK];
|
||||
|
||||
int add_cert_puk_store(const uint8_t *data, size_t data_len, bool copy) {
|
||||
if (data == NULL || data_len == 0)
|
||||
int add_cert_puk_store(const uint8_t *data, size_t data_len, bool copy)
|
||||
{
|
||||
if (data == NULL || data_len == 0) {
|
||||
return CCID_ERR_NULL_PARAM;
|
||||
if (puk_store_entries == MAX_PUK_STORE_ENTRIES)
|
||||
}
|
||||
if (puk_store_entries == MAX_PUK_STORE_ENTRIES) {
|
||||
return CCID_ERR_MEMORY_FATAL;
|
||||
}
|
||||
|
||||
puk_store[puk_store_entries].copied = copy;
|
||||
if (copy == true) {
|
||||
uint8_t *tmp = (uint8_t *)calloc(data_len, sizeof(uint8_t));
|
||||
uint8_t *tmp = (uint8_t *) calloc(data_len, sizeof(uint8_t));
|
||||
memcpy(tmp, data, data_len);
|
||||
puk_store[puk_store_entries].cvcert = tmp;
|
||||
}
|
||||
else
|
||||
} else {
|
||||
puk_store[puk_store_entries].cvcert = data;
|
||||
}
|
||||
puk_store[puk_store_entries].cvcert_len = data_len;
|
||||
puk_store[puk_store_entries].chr = cvc_get_chr(puk_store[puk_store_entries].cvcert, data_len, &puk_store[puk_store_entries].chr_len);
|
||||
puk_store[puk_store_entries].car = cvc_get_car(puk_store[puk_store_entries].cvcert, data_len, &puk_store[puk_store_entries].car_len);
|
||||
puk_store[puk_store_entries].puk = cvc_get_pub(puk_store[puk_store_entries].cvcert, data_len, &puk_store[puk_store_entries].puk_len);
|
||||
puk_store[puk_store_entries].chr = cvc_get_chr(puk_store[puk_store_entries].cvcert,
|
||||
data_len,
|
||||
&puk_store[puk_store_entries].chr_len);
|
||||
puk_store[puk_store_entries].car = cvc_get_car(puk_store[puk_store_entries].cvcert,
|
||||
data_len,
|
||||
&puk_store[puk_store_entries].car_len);
|
||||
puk_store[puk_store_entries].puk = cvc_get_pub(puk_store[puk_store_entries].cvcert,
|
||||
data_len,
|
||||
&puk_store[puk_store_entries].puk_len);
|
||||
|
||||
puk_store_entries++;
|
||||
return CCID_OK;
|
||||
}
|
||||
|
||||
int puk_store_select_chr(const uint8_t *chr) {
|
||||
int puk_store_select_chr(const uint8_t *chr)
|
||||
{
|
||||
for (int i = 0; i < puk_store_entries; i++) {
|
||||
if (memcmp(puk_store[i].chr, chr, puk_store[i].chr_len) == 0) {
|
||||
current_puk = &puk_store[i];
|
||||
@@ -208,48 +217,56 @@ int puk_store_select_chr(const uint8_t *chr) {
|
||||
return CCID_ERR_FILE_NOT_FOUND;
|
||||
}
|
||||
|
||||
void init_sc_hsm() {
|
||||
void init_sc_hsm()
|
||||
{
|
||||
scan_all();
|
||||
has_session_pin = has_session_sopin = false;
|
||||
isUserAuthenticated = false;
|
||||
cmd_select();
|
||||
if (puk_store_entries > 0) { /* From previous session */
|
||||
for (int i = 0; i < puk_store_entries; i++) {
|
||||
if (puk_store[i].copied == true)
|
||||
free((uint8_t *)puk_store[i].cvcert);
|
||||
if (puk_store[i].copied == true) {
|
||||
free((uint8_t *) puk_store[i].cvcert);
|
||||
}
|
||||
}
|
||||
}
|
||||
memset(puk_store, 0, sizeof(puk_store));
|
||||
puk_store_entries = 0;
|
||||
file_t *fterm = search_by_fid(EF_TERMCA, NULL, SPECIFY_EF);
|
||||
if (fterm)
|
||||
if (fterm) {
|
||||
add_cert_puk_store(file_get_data(fterm), file_get_size(fterm), false);
|
||||
}
|
||||
for (int i = 0; i < 0xfe; i++) {
|
||||
file_t *ef = search_dynamic_file((CA_CERTIFICATE_PREFIX << 8) | i);
|
||||
if (ef && file_get_size(ef) > 0)
|
||||
if (ef && file_get_size(ef) > 0) {
|
||||
add_cert_puk_store(file_get_data(ef), file_get_size(ef), false);
|
||||
}
|
||||
}
|
||||
dev_name = cvc_get_chr(file_get_data(fterm), file_get_size(fterm), &dev_name_len);
|
||||
memset(puk_status, 0, sizeof(puk_status));
|
||||
}
|
||||
|
||||
int sc_hsm_unload() {
|
||||
int sc_hsm_unload()
|
||||
{
|
||||
has_session_pin = has_session_sopin = false;
|
||||
isUserAuthenticated = false;
|
||||
sm_session_pin_len = 0;
|
||||
return CCID_OK;
|
||||
}
|
||||
|
||||
uint16_t get_device_options() {
|
||||
uint16_t get_device_options()
|
||||
{
|
||||
file_t *ef = search_by_fid(EF_DEVOPS, NULL, SPECIFY_EF);
|
||||
if (file_has_data(ef))
|
||||
if (file_has_data(ef)) {
|
||||
return (file_read_uint8(file_get_data(ef)) << 8) | file_read_uint8(file_get_data(ef)+1);
|
||||
}
|
||||
return 0x0;
|
||||
}
|
||||
|
||||
extern uint32_t board_button_read(void);
|
||||
|
||||
bool wait_button_pressed() {
|
||||
bool wait_button_pressed()
|
||||
{
|
||||
uint32_t val = EV_PRESS_BUTTON;
|
||||
#ifndef ENABLE_EMULATION
|
||||
uint16_t opts = get_device_options();
|
||||
@@ -257,14 +274,14 @@ bool wait_button_pressed() {
|
||||
queue_try_add(&card_to_usb_q, &val);
|
||||
do {
|
||||
queue_remove_blocking(&usb_to_card_q, &val);
|
||||
}
|
||||
while (val != EV_BUTTON_PRESSED && val != EV_BUTTON_TIMEOUT);
|
||||
} while (val != EV_BUTTON_PRESSED && val != EV_BUTTON_TIMEOUT);
|
||||
}
|
||||
#endif
|
||||
return val == EV_BUTTON_TIMEOUT;
|
||||
}
|
||||
|
||||
int parse_token_info(const file_t *f, int mode) {
|
||||
int parse_token_info(const file_t *f, int mode)
|
||||
{
|
||||
char *label = "SmartCard-HSM";
|
||||
char *manu = "Pol Henarejos";
|
||||
if (mode == 1) {
|
||||
@@ -273,12 +290,12 @@ int parse_token_info(const file_t *f, int mode) {
|
||||
*p++ = 0; //set later
|
||||
*p++ = 0x2; *p++ = 1; *p++ = HSM_VERSION_MAJOR;
|
||||
#ifndef ENABLE_EMULATION
|
||||
*p++ = 0x4; *p++ = 8; pico_get_unique_board_id((pico_unique_board_id_t *)p); p += 8;
|
||||
*p++ = 0x4; *p++ = 8; pico_get_unique_board_id((pico_unique_board_id_t *) p); p += 8;
|
||||
#else
|
||||
*p++ = 0x4; *p++ = 8; memset(p, 0, 8); p += 8;
|
||||
#endif
|
||||
*p++ = 0xC; *p++ = strlen(manu); strcpy((char *)p, manu); p += strlen(manu);
|
||||
*p++ = 0x80; *p++ = strlen(label); strcpy((char *)p, label); p += strlen(label);
|
||||
*p++ = 0xC; *p++ = strlen(manu); strcpy((char *) p, manu); p += strlen(manu);
|
||||
*p++ = 0x80; *p++ = strlen(label); strcpy((char *) p, label); p += strlen(label);
|
||||
*p++ = 0x3; *p++ = 2; *p++ = 4; *p++ = 0x30;
|
||||
res_APDU_size = p-res_APDU;
|
||||
res_APDU[1] = res_APDU_size-2;
|
||||
@@ -286,95 +303,113 @@ int parse_token_info(const file_t *f, int mode) {
|
||||
return 2+(2+1)+(2+8)+(2+strlen(manu))+(2+strlen(label))+(2+2);
|
||||
}
|
||||
|
||||
int pin_reset_retries(const file_t *pin, bool force) {
|
||||
if (!pin)
|
||||
int pin_reset_retries(const file_t *pin, bool force)
|
||||
{
|
||||
if (!pin) {
|
||||
return CCID_ERR_NULL_PARAM;
|
||||
}
|
||||
const file_t *max = search_by_fid(pin->fid+1, NULL, SPECIFY_EF);
|
||||
const file_t *act = search_by_fid(pin->fid+2, NULL, SPECIFY_EF);
|
||||
if (!max || !act)
|
||||
if (!max || !act) {
|
||||
return CCID_ERR_FILE_NOT_FOUND;
|
||||
}
|
||||
uint8_t retries = file_read_uint8(file_get_data(act));
|
||||
if (retries == 0 && force == false) //blocked
|
||||
if (retries == 0 && force == false) { //blocked
|
||||
return CCID_ERR_BLOCKED;
|
||||
}
|
||||
retries = file_read_uint8(file_get_data(max));
|
||||
int r = flash_write_data_to_file((file_t *)act, &retries, sizeof(retries));
|
||||
int r = flash_write_data_to_file((file_t *) act, &retries, sizeof(retries));
|
||||
low_flash_available();
|
||||
return r;
|
||||
}
|
||||
|
||||
int pin_wrong_retry(const file_t *pin) {
|
||||
if (!pin)
|
||||
int pin_wrong_retry(const file_t *pin)
|
||||
{
|
||||
if (!pin) {
|
||||
return CCID_ERR_NULL_PARAM;
|
||||
}
|
||||
const file_t *act = search_by_fid(pin->fid+2, NULL, SPECIFY_EF);
|
||||
if (!act)
|
||||
if (!act) {
|
||||
return CCID_ERR_FILE_NOT_FOUND;
|
||||
}
|
||||
uint8_t retries = file_read_uint8(file_get_data(act));
|
||||
if (retries > 0) {
|
||||
retries -= 1;
|
||||
int r = flash_write_data_to_file((file_t *)act, &retries, sizeof(retries));
|
||||
if (r != CCID_OK)
|
||||
int r = flash_write_data_to_file((file_t *) act, &retries, sizeof(retries));
|
||||
if (r != CCID_OK) {
|
||||
return r;
|
||||
}
|
||||
low_flash_available();
|
||||
if (retries == 0)
|
||||
if (retries == 0) {
|
||||
return CCID_ERR_BLOCKED;
|
||||
}
|
||||
return retries;
|
||||
}
|
||||
return CCID_ERR_BLOCKED;
|
||||
}
|
||||
|
||||
bool pka_enabled() {
|
||||
bool pka_enabled()
|
||||
{
|
||||
file_t *ef_puk = search_by_fid(EF_PUKAUT, NULL, SPECIFY_EF);
|
||||
return file_has_data(ef_puk) && file_read_uint8(file_get_data(ef_puk)) > 0;
|
||||
}
|
||||
|
||||
int check_pin(const file_t *pin, const uint8_t *data, size_t len) {
|
||||
if (!file_has_data((file_t *)pin)) {
|
||||
int check_pin(const file_t *pin, const uint8_t *data, size_t len)
|
||||
{
|
||||
if (!file_has_data((file_t *) pin)) {
|
||||
return SW_REFERENCE_NOT_FOUND();
|
||||
}
|
||||
if (pka_enabled() == false)
|
||||
if (pka_enabled() == false) {
|
||||
isUserAuthenticated = false;
|
||||
}
|
||||
has_session_pin = has_session_sopin = false;
|
||||
if (is_secured_apdu() && sm_session_pin_len > 0 && pin == file_pin1) {
|
||||
if (len == sm_session_pin_len && memcmp(data, sm_session_pin, len) != 0) {
|
||||
int retries;
|
||||
if ((retries = pin_wrong_retry(pin)) < CCID_OK)
|
||||
if ((retries = pin_wrong_retry(pin)) < CCID_OK) {
|
||||
return SW_PIN_BLOCKED();
|
||||
}
|
||||
return set_res_sw(0x63, 0xc0 | retries);
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
uint8_t dhash[32];
|
||||
double_hash_pin(data, len, dhash);
|
||||
if (sizeof(dhash) != file_get_size(pin)-1) //1 byte for pin len
|
||||
if (sizeof(dhash) != file_get_size(pin)-1) { //1 byte for pin len
|
||||
return SW_CONDITIONS_NOT_SATISFIED();
|
||||
}
|
||||
if (memcmp(file_get_data(pin)+1, dhash, sizeof(dhash)) != 0) {
|
||||
int retries;
|
||||
if ((retries = pin_wrong_retry(pin)) < CCID_OK)
|
||||
if ((retries = pin_wrong_retry(pin)) < CCID_OK) {
|
||||
return SW_PIN_BLOCKED();
|
||||
}
|
||||
return set_res_sw(0x63, 0xc0 | retries);
|
||||
}
|
||||
}
|
||||
int r = pin_reset_retries(pin, false);
|
||||
if (r == CCID_ERR_BLOCKED)
|
||||
if (r == CCID_ERR_BLOCKED) {
|
||||
return SW_PIN_BLOCKED();
|
||||
if (r != CCID_OK)
|
||||
}
|
||||
if (r != CCID_OK) {
|
||||
return SW_MEMORY_FAILURE();
|
||||
if (pka_enabled() == false)
|
||||
}
|
||||
if (pka_enabled() == false) {
|
||||
isUserAuthenticated = true;
|
||||
}
|
||||
if (pin == file_pin1) {
|
||||
hash_multi(data, len, session_pin);
|
||||
has_session_pin = true;
|
||||
}
|
||||
else if (pin == file_sopin) {
|
||||
} else if (pin == file_sopin) {
|
||||
hash_multi(data, len, session_sopin);
|
||||
has_session_sopin = true;
|
||||
}
|
||||
return SW_OK();
|
||||
}
|
||||
|
||||
const uint8_t *get_meta_tag(file_t *ef, uint16_t meta_tag, size_t *tag_len) {
|
||||
if (ef == NULL)
|
||||
const uint8_t *get_meta_tag(file_t *ef, uint16_t meta_tag, size_t *tag_len)
|
||||
{
|
||||
if (ef == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
uint8_t *meta_data = NULL;
|
||||
uint8_t meta_size = meta_find(ef->fid, &meta_data);
|
||||
if (meta_size > 0 && meta_data != NULL) {
|
||||
@@ -389,42 +424,49 @@ const uint8_t *get_meta_tag(file_t *ef, uint16_t meta_tag, size_t *tag_len) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint32_t get_key_counter(file_t *fkey) {
|
||||
uint32_t get_key_counter(file_t *fkey)
|
||||
{
|
||||
size_t tag_len = 0;
|
||||
const uint8_t *meta_tag = get_meta_tag(fkey, 0x90, &tag_len);
|
||||
if (meta_tag)
|
||||
if (meta_tag) {
|
||||
return (meta_tag[0] << 24) | (meta_tag[1] << 16) | (meta_tag[2] << 8) | meta_tag[3];
|
||||
}
|
||||
return 0xffffffff;
|
||||
}
|
||||
|
||||
bool key_has_purpose(file_t *ef, uint8_t purpose) {
|
||||
bool key_has_purpose(file_t *ef, uint8_t purpose)
|
||||
{
|
||||
size_t tag_len = 0;
|
||||
const uint8_t *meta_tag = get_meta_tag(ef, 0x91, &tag_len);
|
||||
if (meta_tag) {
|
||||
for (int i = 0; i < tag_len; i++) {
|
||||
if (meta_tag[i] == purpose)
|
||||
if (meta_tag[i] == purpose) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t decrement_key_counter(file_t *fkey) {
|
||||
if (!fkey)
|
||||
uint32_t decrement_key_counter(file_t *fkey)
|
||||
{
|
||||
if (!fkey) {
|
||||
return 0xffffff;
|
||||
}
|
||||
uint8_t *meta_data = NULL;
|
||||
uint8_t meta_size = meta_find(fkey->fid, &meta_data);
|
||||
if (meta_size > 0 && meta_data != NULL) {
|
||||
uint16_t tag = 0x0;
|
||||
uint8_t *tag_data = NULL, *p = NULL;
|
||||
size_t tag_len = 0;
|
||||
uint8_t *cmeta = (uint8_t *)calloc(1, meta_size);
|
||||
uint8_t *cmeta = (uint8_t *) calloc(1, meta_size);
|
||||
/* We cannot modify meta_data, as it comes from flash memory. It must be cpied to an aux buffer */
|
||||
memcpy(cmeta, meta_data, meta_size);
|
||||
while (walk_tlv(cmeta, meta_size, &p, &tag, &tag_len, &tag_data)) {
|
||||
if (tag == 0x90) { //ofset tag
|
||||
uint32_t val = (tag_data[0] << 24) | (tag_data[1] << 16) | (tag_data[2] << 8) | tag_data[3];
|
||||
uint32_t val =
|
||||
(tag_data[0] << 24) | (tag_data[1] << 16) | (tag_data[2] << 8) | tag_data[3];
|
||||
val--;
|
||||
tag_data[0] = (val >> 24) & 0xff;
|
||||
tag_data[1] = (val >> 16) & 0xff;
|
||||
@@ -433,8 +475,9 @@ uint32_t decrement_key_counter(file_t *fkey) {
|
||||
|
||||
int r = meta_add(fkey->fid, cmeta, meta_size);
|
||||
free(cmeta);
|
||||
if (r != 0)
|
||||
if (r != 0) {
|
||||
return 0xffffffff;
|
||||
}
|
||||
low_flash_available();
|
||||
return val;
|
||||
}
|
||||
@@ -445,50 +488,53 @@ uint32_t decrement_key_counter(file_t *fkey) {
|
||||
}
|
||||
|
||||
//Stores the private and public keys in flash
|
||||
int store_keys(void *key_ctx, int type, uint8_t key_id) {
|
||||
int store_keys(void *key_ctx, int type, uint8_t key_id)
|
||||
{
|
||||
int r, key_size = 0;
|
||||
uint8_t kdata[4096/8]; //worst case
|
||||
if (type == HSM_KEY_RSA) {
|
||||
mbedtls_rsa_context *rsa = (mbedtls_rsa_context *)key_ctx;
|
||||
mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) key_ctx;
|
||||
key_size = mbedtls_mpi_size(&rsa->P)+mbedtls_mpi_size(&rsa->Q);
|
||||
mbedtls_mpi_write_binary(&rsa->P, kdata, key_size/2);
|
||||
mbedtls_mpi_write_binary(&rsa->Q, kdata+key_size/2, key_size/2);
|
||||
}
|
||||
else if (type == HSM_KEY_EC) {
|
||||
mbedtls_ecdsa_context *ecdsa = (mbedtls_ecdsa_context *)key_ctx;
|
||||
} else if (type == HSM_KEY_EC) {
|
||||
mbedtls_ecdsa_context *ecdsa = (mbedtls_ecdsa_context *) key_ctx;
|
||||
key_size = mbedtls_mpi_size(&ecdsa->d);
|
||||
kdata[0] = ecdsa->grp.id & 0xff;
|
||||
mbedtls_mpi_write_binary(&ecdsa->d, kdata+1, key_size);
|
||||
key_size++;
|
||||
}
|
||||
else if (type & HSM_KEY_AES) {
|
||||
if (type == HSM_KEY_AES_128)
|
||||
} else if (type & HSM_KEY_AES) {
|
||||
if (type == HSM_KEY_AES_128) {
|
||||
key_size = 16;
|
||||
else if (type == HSM_KEY_AES_192)
|
||||
} else if (type == HSM_KEY_AES_192) {
|
||||
key_size = 24;
|
||||
else if (type == HSM_KEY_AES_256)
|
||||
} else if (type == HSM_KEY_AES_256) {
|
||||
key_size = 32;
|
||||
}
|
||||
memcpy(kdata, key_ctx, key_size);
|
||||
}
|
||||
else
|
||||
} else {
|
||||
return CCID_WRONG_DATA;
|
||||
}
|
||||
file_t *fpk = file_new((KEY_PREFIX << 8) | key_id);
|
||||
if (!fpk)
|
||||
if (!fpk) {
|
||||
return CCID_ERR_MEMORY_FATAL;
|
||||
}
|
||||
r = mkek_encrypt(kdata, key_size);
|
||||
if (r != CCID_OK) {
|
||||
return r;
|
||||
}
|
||||
r = flash_write_data_to_file(fpk, kdata, key_size);
|
||||
if (r != CCID_OK)
|
||||
if (r != CCID_OK) {
|
||||
return r;
|
||||
}
|
||||
low_flash_available();
|
||||
return CCID_OK;
|
||||
}
|
||||
|
||||
int find_and_store_meta_key(uint8_t key_id) {
|
||||
size_t lt[4] = { 0,0,0,0 }, meta_size = 0;
|
||||
uint8_t *pt[4] = { NULL,NULL,NULL,NULL };
|
||||
int find_and_store_meta_key(uint8_t key_id)
|
||||
{
|
||||
size_t lt[4] = { 0, 0, 0, 0 }, meta_size = 0;
|
||||
uint8_t *pt[4] = { NULL, NULL, NULL, NULL };
|
||||
uint8_t t90[4] = { 0xFF, 0xFF, 0xFF, 0xFE };
|
||||
for (int t = 0; t < 4; t++) {
|
||||
uint8_t *ptt = NULL;
|
||||
@@ -508,7 +554,7 @@ int find_and_store_meta_key(uint8_t key_id) {
|
||||
}
|
||||
}
|
||||
if (meta_size) {
|
||||
uint8_t *meta = (uint8_t *)calloc(1, meta_size), *m = meta;
|
||||
uint8_t *meta = (uint8_t *) calloc(1, meta_size), *m = meta;
|
||||
for (int t = 0; t < 4; t++) {
|
||||
if (lt[t] > 0 && pt[t] != NULL) {
|
||||
*m++ = 0x90+t;
|
||||
@@ -519,15 +565,18 @@ int find_and_store_meta_key(uint8_t key_id) {
|
||||
}
|
||||
int r = meta_add((KEY_PREFIX << 8) | key_id, meta, meta_size);
|
||||
free(meta);
|
||||
if (r != 0)
|
||||
if (r != 0) {
|
||||
return CCID_EXEC_ERROR;
|
||||
}
|
||||
}
|
||||
return CCID_OK;
|
||||
}
|
||||
|
||||
int load_private_key_rsa(mbedtls_rsa_context *ctx, file_t *fkey) {
|
||||
if (wait_button_pressed() == true) //timeout
|
||||
int load_private_key_rsa(mbedtls_rsa_context *ctx, file_t *fkey)
|
||||
{
|
||||
if (wait_button_pressed() == true) { //timeout
|
||||
return CCID_VERIFICATION_FAILED;
|
||||
}
|
||||
|
||||
int key_size = file_get_size(fkey);
|
||||
uint8_t kdata[4096/8];
|
||||
@@ -568,9 +617,11 @@ int load_private_key_rsa(mbedtls_rsa_context *ctx, file_t *fkey) {
|
||||
return CCID_OK;
|
||||
}
|
||||
|
||||
int load_private_key_ecdsa(mbedtls_ecdsa_context *ctx, file_t *fkey) {
|
||||
if (wait_button_pressed() == true) //timeout
|
||||
int load_private_key_ecdsa(mbedtls_ecdsa_context *ctx, file_t *fkey)
|
||||
{
|
||||
if (wait_button_pressed() == true) { //timeout
|
||||
return CCID_VERIFICATION_FAILED;
|
||||
}
|
||||
|
||||
int key_size = file_get_size(fkey);
|
||||
uint8_t kdata[67]; //Worst case, 521 bit + 1byte
|
||||
@@ -611,8 +662,8 @@ int load_private_key_ecdsa(mbedtls_ecdsa_context *ctx, file_t *fkey) {
|
||||
#define INS_EXTERNAL_AUTHENTICATE 0x82
|
||||
#define INS_CHALLENGE 0x84
|
||||
#define INS_GENERAL_AUTHENTICATE 0x86
|
||||
#define INS_SELECT_FILE 0xA4
|
||||
#define INS_READ_BINARY 0xB0
|
||||
#define INS_SELECT_FILE 0xA4
|
||||
#define INS_READ_BINARY 0xB0
|
||||
#define INS_READ_BINARY_ODD 0xB1
|
||||
#define INS_UPDATE_EF 0xD7
|
||||
#define INS_DELETE_FILE 0xE4
|
||||
@@ -645,13 +696,15 @@ static const cmd_t cmds[] = {
|
||||
{ INS_PUK_AUTH, cmd_puk_auth },
|
||||
{ INS_PSO, cmd_pso },
|
||||
{ INS_EXTERNAL_AUTHENTICATE, cmd_external_authenticate },
|
||||
{ 0x00, 0x0}
|
||||
{ 0x00, 0x0 }
|
||||
};
|
||||
|
||||
int sc_hsm_process_apdu() {
|
||||
int sc_hsm_process_apdu()
|
||||
{
|
||||
int r = sm_unwrap();
|
||||
if (r != CCID_OK)
|
||||
if (r != CCID_OK) {
|
||||
return SW_DATA_INVALID();
|
||||
}
|
||||
for (const cmd_t *cmd = cmds; cmd->ins != 0x00; cmd++) {
|
||||
if (cmd->ins == INS(apdu)) {
|
||||
int r = cmd->cmd_handler();
|
||||
|
||||
Reference in New Issue
Block a user