Refactoring initialize command to support no dkek, random dkek, dkek shares and key domains.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
@@ -680,7 +680,7 @@ static int cmd_initialize() {
|
|||||||
if (apdu.cmd_apdu_data_len > 0) {
|
if (apdu.cmd_apdu_data_len > 0) {
|
||||||
initialize_flash(true);
|
initialize_flash(true);
|
||||||
scan_all();
|
scan_all();
|
||||||
uint8_t tag = 0x0, *tag_data = NULL, *p = NULL, kds = 1, dkeks = 0;
|
uint8_t tag = 0x0, *tag_data = NULL, *p = NULL, *kds = NULL, *dkeks = NULL;
|
||||||
size_t tag_len = 0;
|
size_t tag_len = 0;
|
||||||
while (walk_tlv(apdu.cmd_apdu_data, apdu.cmd_apdu_data_len, &p, &tag, &tag_len, &tag_data)) {
|
while (walk_tlv(apdu.cmd_apdu_data, apdu.cmd_apdu_data_len, &p, &tag, &tag_len, &tag_data)) {
|
||||||
if (tag == 0x80) { //options
|
if (tag == 0x80) { //options
|
||||||
@@ -717,52 +717,54 @@ static int cmd_initialize() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (tag == 0x92) {
|
else if (tag == 0x92) {
|
||||||
dkeks = *tag_data;
|
dkeks = tag_data;
|
||||||
file_t *tf = file_new(EF_DKEK);
|
file_t *tf = file_new(EF_DKEK);
|
||||||
if (!tf)
|
if (!tf)
|
||||||
return SW_MEMORY_FAILURE();
|
return SW_MEMORY_FAILURE();
|
||||||
flash_write_data_to_file(tf, NULL, 0);
|
flash_write_data_to_file(tf, NULL, 0);
|
||||||
low_flash_available();
|
|
||||||
}
|
}
|
||||||
else if (tag == 0x97) {
|
else if (tag == 0x97) {
|
||||||
kds = MIN(*tag_data,16);
|
kds = tag_data;
|
||||||
for (int i = 0; i < kds; i++) {
|
for (int i = 0; i < MIN(*kds,MAX_KEY_DOMAINS); i++) {
|
||||||
file_t *tf = file_new(EF_DKEK+i);
|
file_t *tf = file_new(EF_DKEK+i);
|
||||||
if (!tf)
|
if (!tf)
|
||||||
return SW_MEMORY_FAILURE();
|
return SW_MEMORY_FAILURE();
|
||||||
flash_write_data_to_file(tf, NULL, 0);
|
flash_write_data_to_file(tf, NULL, 0);
|
||||||
}
|
}
|
||||||
low_flash_available();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (kds < 1)
|
|
||||||
return SW_WRONG_DATA();
|
|
||||||
uint8_t t[MAX_KEY_DOMAINS*2];
|
|
||||||
memset(t, 0, 2*kds);
|
|
||||||
file_t *tf = search_by_fid(EF_KEY_DOMAIN, NULL, SPECIFY_EF);
|
|
||||||
if (!tf)
|
|
||||||
return SW_EXEC_ERROR();
|
|
||||||
if (dkeks > 0)
|
|
||||||
t[0] = dkeks;
|
|
||||||
if (flash_write_data_to_file(tf, t, 2*kds) != CCID_OK)
|
|
||||||
return SW_EXEC_ERROR();
|
|
||||||
if (dkeks == 0) {
|
|
||||||
//At least, the first DKEK shall exist
|
//At least, the first DKEK shall exist
|
||||||
|
file_t *tf_kd = search_by_fid(EF_KEY_DOMAIN, NULL, SPECIFY_EF);
|
||||||
|
if (!tf_kd)
|
||||||
|
return SW_EXEC_ERROR();
|
||||||
file_t *tf = search_dynamic_file(EF_DKEK);
|
file_t *tf = search_dynamic_file(EF_DKEK);
|
||||||
if (!tf) {
|
if (!tf) {
|
||||||
file_t *tf = file_new(EF_DKEK);
|
file_t *tf = file_new(EF_DKEK);
|
||||||
if (!tf)
|
if (!tf)
|
||||||
return SW_MEMORY_FAILURE();
|
return SW_MEMORY_FAILURE();
|
||||||
flash_write_data_to_file(tf, NULL, 0);
|
|
||||||
low_flash_available();
|
|
||||||
}
|
}
|
||||||
for (int kd = 0; kd < kds; kd++) {
|
uint8_t t[DKEK_SIZE];
|
||||||
int r = save_dkek_key(kd, random_bytes_get(32));
|
memset(t, 0, sizeof(t));
|
||||||
|
flash_write_data_to_file(tf, t, sizeof(t));
|
||||||
|
if (dkeks) {
|
||||||
|
if (*dkeks > 0) {
|
||||||
|
uint16_t d = *dkeks;
|
||||||
|
if (flash_write_data_to_file(tf_kd, (const uint8_t *)&d, sizeof(d)) != CCID_OK)
|
||||||
|
return SW_EXEC_ERROR();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
int r = save_dkek_key(0, random_bytes_get(32));
|
||||||
if (r != CCID_OK)
|
if (r != CCID_OK)
|
||||||
return SW_EXEC_ERROR();
|
return SW_EXEC_ERROR();
|
||||||
t[2*kd] = 1;
|
uint16_t d = 0x0101;
|
||||||
|
if (flash_write_data_to_file(tf_kd, (const uint8_t *)&d, sizeof(d)) != CCID_OK)
|
||||||
|
return SW_EXEC_ERROR();
|
||||||
}
|
}
|
||||||
if (flash_write_data_to_file(tf, t, 2*kds) != CCID_OK)
|
}
|
||||||
|
if (kds) {
|
||||||
|
uint8_t t[MAX_KEY_DOMAINS*2], k = MIN(*kds,MAX_KEY_DOMAINS);
|
||||||
|
memset(t, 0, 2*k);
|
||||||
|
if (flash_write_data_to_file(tf_kd, t, 2*k) != CCID_OK)
|
||||||
return SW_EXEC_ERROR();
|
return SW_EXEC_ERROR();
|
||||||
}
|
}
|
||||||
low_flash_available();
|
low_flash_available();
|
||||||
@@ -790,10 +792,12 @@ static int cmd_key_domain() {
|
|||||||
if (p1 == 0x0) { //dkek import
|
if (p1 == 0x0) { //dkek import
|
||||||
if (p2 > MAX_KEY_DOMAINS)
|
if (p2 > MAX_KEY_DOMAINS)
|
||||||
return SW_WRONG_P1P2();
|
return SW_WRONG_P1P2();
|
||||||
file_t *tf = search_by_fid(EF_KEY_DOMAIN, NULL, SPECIFY_EF);
|
file_t *tf_kd = search_by_fid(EF_KEY_DOMAIN, NULL, SPECIFY_EF);
|
||||||
if (!tf)
|
if (!tf_kd)
|
||||||
return SW_EXEC_ERROR();
|
return SW_EXEC_ERROR();
|
||||||
uint8_t *kdata = file_get_data(tf), dkeks = *(kdata+2*p2), current_dkeks = *(kdata+2*p2+1);
|
if (file_get_size(tf_kd) == 0)
|
||||||
|
return SW_WRONG_P1P2();
|
||||||
|
uint8_t *kdata = file_get_data(tf_kd), dkeks = kdata ? *(kdata+2*p2) : 0, current_dkeks = kdata ? *(kdata+2*p2+1) : 0;
|
||||||
if (apdu.cmd_apdu_data_len > 0) {
|
if (apdu.cmd_apdu_data_len > 0) {
|
||||||
file_t *tf = file_new(EF_DKEK+p2);
|
file_t *tf = file_new(EF_DKEK+p2);
|
||||||
if (!tf)
|
if (!tf)
|
||||||
@@ -805,13 +809,16 @@ static int cmd_key_domain() {
|
|||||||
if (save_dkek_key(p2, NULL) != CCID_OK)
|
if (save_dkek_key(p2, NULL) != CCID_OK)
|
||||||
return SW_FILE_NOT_FOUND();
|
return SW_FILE_NOT_FOUND();
|
||||||
}
|
}
|
||||||
|
uint8_t t[2] = { dkeks, current_dkeks };
|
||||||
|
if (flash_write_data_to_file(tf_kd, t, sizeof(t)) != CCID_OK)
|
||||||
|
return SW_EXEC_ERROR();
|
||||||
low_flash_available();
|
low_flash_available();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
file_t *tf = search_dynamic_file(EF_DKEK+p2);
|
file_t *tf = search_dynamic_file(EF_DKEK+p2);
|
||||||
if (!tf)
|
if (!tf)
|
||||||
return SW_INCORRECT_P1P2();
|
return SW_INCORRECT_P1P2();
|
||||||
if (current_dkeks == 0)
|
if (current_dkeks == 0 && file_get_size(tf_kd) > 2)
|
||||||
return SW_REFERENCE_NOT_FOUND();
|
return SW_REFERENCE_NOT_FOUND();
|
||||||
}
|
}
|
||||||
memset(res_APDU,0,10);
|
memset(res_APDU,0,10);
|
||||||
|
|||||||
Reference in New Issue
Block a user