Addded fast crc32 checksum for DKEK storage.
It is for checking the integrity of the DKEK and thus, the scret keys, as they are encrypted with DKEK. Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
@@ -32,6 +32,19 @@
|
|||||||
extern bool has_session_pin;
|
extern bool has_session_pin;
|
||||||
extern uint8_t session_pin[32];
|
extern uint8_t session_pin[32];
|
||||||
|
|
||||||
|
#define POLY 0xedb88320
|
||||||
|
|
||||||
|
uint32_t crc32c(const uint8_t *buf, size_t len)
|
||||||
|
{
|
||||||
|
uint32_t crc = ~0;
|
||||||
|
while (len--) {
|
||||||
|
crc ^= *buf++;
|
||||||
|
for (int k = 0; k < 8; k++)
|
||||||
|
crc = (crc >> 1) ^ (POLY & (0 - (crc & 1)));
|
||||||
|
}
|
||||||
|
return ~crc;
|
||||||
|
}
|
||||||
|
|
||||||
int load_dkek(uint8_t id, uint8_t *dkek) {
|
int load_dkek(uint8_t id, uint8_t *dkek) {
|
||||||
if (has_session_pin == false)
|
if (has_session_pin == false)
|
||||||
return CCID_NO_LOGIN;
|
return CCID_NO_LOGIN;
|
||||||
@@ -39,9 +52,11 @@ int load_dkek(uint8_t id, uint8_t *dkek) {
|
|||||||
if (!tf)
|
if (!tf)
|
||||||
return CCID_ERR_FILE_NOT_FOUND;
|
return CCID_ERR_FILE_NOT_FOUND;
|
||||||
memcpy(dkek, file_get_data(tf), DKEK_SIZE);
|
memcpy(dkek, file_get_data(tf), DKEK_SIZE);
|
||||||
int ret = aes_decrypt_cfb_256(session_pin, DKEK_IV(dkek), DKEK_KEY(dkek), DKEK_KEY_SIZE);
|
int ret = aes_decrypt_cfb_256(session_pin, DKEK_IV(dkek), DKEK_KEY(dkek), DKEK_KEY_SIZE+DKEK_KEY_CS_SIZE);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
return CCID_EXEC_ERROR;
|
return CCID_EXEC_ERROR;
|
||||||
|
if (crc32c(DKEK_KEY(dkek), DKEK_KEY_SIZE) != *(uint32_t*)DKEK_CHECKSUM(dkek))
|
||||||
|
return CCID_WRONG_DKEK;
|
||||||
return CCID_OK;
|
return CCID_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,7 +68,8 @@ int store_dkek_key(uint8_t id, uint8_t *dkek) {
|
|||||||
file_t *tf = search_dynamic_file(EF_DKEK+id);
|
file_t *tf = search_dynamic_file(EF_DKEK+id);
|
||||||
if (!tf)
|
if (!tf)
|
||||||
return CCID_ERR_FILE_NOT_FOUND;
|
return CCID_ERR_FILE_NOT_FOUND;
|
||||||
aes_encrypt_cfb_256(session_pin, DKEK_IV(dkek), DKEK_KEY(dkek), DKEK_KEY_SIZE);
|
*(uint32_t*)DKEK_CHECKSUM(dkek) = crc32c(DKEK_KEY(dkek), DKEK_KEY_SIZE);
|
||||||
|
aes_encrypt_cfb_256(session_pin, DKEK_IV(dkek), DKEK_KEY(dkek), DKEK_KEY_SIZE+DKEK_KEY_CS_SIZE);
|
||||||
flash_write_data_to_file(tf, dkek, DKEK_SIZE);
|
flash_write_data_to_file(tf, dkek, DKEK_SIZE);
|
||||||
low_flash_available();
|
low_flash_available();
|
||||||
release_dkek(dkek);
|
release_dkek(dkek);
|
||||||
|
|||||||
@@ -37,8 +37,10 @@ extern int dkek_decode_key(uint8_t, void *key_ctx, const uint8_t *in, size_t in_
|
|||||||
|
|
||||||
#define DKEK_IV_SIZE (IV_SIZE)
|
#define DKEK_IV_SIZE (IV_SIZE)
|
||||||
#define DKEK_KEY_SIZE (32)
|
#define DKEK_KEY_SIZE (32)
|
||||||
#define DKEK_SIZE (DKEK_IV_SIZE+DKEK_KEY_SIZE)
|
#define DKEK_KEY_CS_SIZE (4)
|
||||||
|
#define DKEK_SIZE (DKEK_IV_SIZE+DKEK_KEY_SIZE+DKEK_KEY_CS_SIZE)
|
||||||
#define DKEK_KEY(p) (p+DKEK_IV_SIZE)
|
#define DKEK_KEY(p) (p+DKEK_IV_SIZE)
|
||||||
#define DKEK_IV(p) (p)
|
#define DKEK_IV(p) (p)
|
||||||
|
#define DKEK_CHECKSUM(p) (p+DKEK_IV_SIZE+DKEK_KEY_SIZE)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -695,7 +695,8 @@ static int cmd_initialize() {
|
|||||||
}
|
}
|
||||||
uint8_t t[DKEK_SIZE];
|
uint8_t t[DKEK_SIZE];
|
||||||
memset(t, 0, sizeof(t));
|
memset(t, 0, sizeof(t));
|
||||||
flash_write_data_to_file(tf, t, sizeof(t));
|
if (store_dkek_key(0, t) != CCID_OK)
|
||||||
|
return SW_EXEC_ERROR();
|
||||||
if (dkeks) {
|
if (dkeks) {
|
||||||
if (*dkeks > 0) {
|
if (*dkeks > 0) {
|
||||||
uint16_t d = *dkeks;
|
uint16_t d = *dkeks;
|
||||||
@@ -817,12 +818,10 @@ static int cmd_key_domain() {
|
|||||||
}
|
}
|
||||||
if (flash_write_data_to_file(tf_kd, t, tf_kd_size) != CCID_OK)
|
if (flash_write_data_to_file(tf_kd, t, tf_kd_size) != CCID_OK)
|
||||||
return SW_EXEC_ERROR();
|
return SW_EXEC_ERROR();
|
||||||
file_t *tf = file_new(EF_DKEK+p2);
|
|
||||||
if (!tf)
|
|
||||||
return SW_MEMORY_FAILURE();
|
|
||||||
uint8_t dk[DKEK_SIZE];
|
uint8_t dk[DKEK_SIZE];
|
||||||
memset(dk, 0, sizeof(dk));
|
memset(dk, 0, sizeof(dk));
|
||||||
flash_write_data_to_file(tf, dk, sizeof(dk));
|
if (store_dkek_key(p2, dk) != CCID_OK)
|
||||||
|
return SW_EXEC_ERROR();
|
||||||
low_flash_available();
|
low_flash_available();
|
||||||
return SW_OK();
|
return SW_OK();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user