Switching to new style.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
274
src/hsm/kek.c
274
src/hsm/kek.c
@@ -39,8 +39,7 @@ bool has_mkek_mask = false;
|
||||
|
||||
#define POLY 0xedb88320
|
||||
|
||||
uint32_t crc32c(const uint8_t *buf, size_t len)
|
||||
{
|
||||
uint32_t crc32c(const uint8_t *buf, size_t len) {
|
||||
uint32_t crc = ~0;
|
||||
while (len--) {
|
||||
crc ^= *buf++;
|
||||
@@ -51,8 +50,7 @@ uint32_t crc32c(const uint8_t *buf, size_t len)
|
||||
return ~crc;
|
||||
}
|
||||
|
||||
int load_mkek(uint8_t *mkek)
|
||||
{
|
||||
int load_mkek(uint8_t *mkek) {
|
||||
if (has_session_pin == false && has_session_sopin == false) {
|
||||
return CCID_NO_LOGIN;
|
||||
}
|
||||
@@ -81,7 +79,7 @@ int load_mkek(uint8_t *mkek)
|
||||
}
|
||||
}
|
||||
int ret =
|
||||
aes_decrypt_cfb_256(pin, MKEK_IV(mkek), MKEK_KEY(mkek), MKEK_KEY_SIZE+MKEK_KEY_CS_SIZE);
|
||||
aes_decrypt_cfb_256(pin, MKEK_IV(mkek), MKEK_KEY(mkek), MKEK_KEY_SIZE + MKEK_KEY_CS_SIZE);
|
||||
if (ret != 0) {
|
||||
return CCID_EXEC_ERROR;
|
||||
}
|
||||
@@ -93,8 +91,7 @@ int load_mkek(uint8_t *mkek)
|
||||
|
||||
mse_t mse = { .init = false };
|
||||
|
||||
int mse_decrypt_ct(uint8_t *data, size_t len)
|
||||
{
|
||||
int mse_decrypt_ct(uint8_t *data, size_t len) {
|
||||
mbedtls_chachapoly_context chatx;
|
||||
mbedtls_chachapoly_init(&chatx);
|
||||
mbedtls_chachapoly_setkey(&chatx, mse.key_enc + 12);
|
||||
@@ -110,9 +107,8 @@ int mse_decrypt_ct(uint8_t *data, size_t len)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int load_dkek(uint8_t id, uint8_t *dkek)
|
||||
{
|
||||
file_t *tf = search_dynamic_file(EF_DKEK+id);
|
||||
int load_dkek(uint8_t id, uint8_t *dkek) {
|
||||
file_t *tf = search_dynamic_file(EF_DKEK + id);
|
||||
if (!tf) {
|
||||
return CCID_ERR_FILE_NOT_FOUND;
|
||||
}
|
||||
@@ -120,21 +116,20 @@ int load_dkek(uint8_t id, uint8_t *dkek)
|
||||
return mkek_decrypt(dkek, DKEK_KEY_SIZE);
|
||||
}
|
||||
|
||||
void release_mkek(uint8_t *mkek)
|
||||
{
|
||||
void release_mkek(uint8_t *mkek) {
|
||||
mbedtls_platform_zeroize(mkek, MKEK_SIZE);
|
||||
}
|
||||
|
||||
int store_mkek(const uint8_t *mkek)
|
||||
{
|
||||
int store_mkek(const uint8_t *mkek) {
|
||||
if (has_session_pin == false && has_session_sopin == false) {
|
||||
return CCID_NO_LOGIN;
|
||||
}
|
||||
uint8_t tmp_mkek[MKEK_SIZE];
|
||||
if (mkek == NULL) {
|
||||
const uint8_t *rd = random_bytes_get(MKEK_IV_SIZE+MKEK_KEY_SIZE);
|
||||
memcpy(tmp_mkek, rd, MKEK_IV_SIZE+MKEK_KEY_SIZE);
|
||||
} else {
|
||||
const uint8_t *rd = random_bytes_get(MKEK_IV_SIZE + MKEK_KEY_SIZE);
|
||||
memcpy(tmp_mkek, rd, MKEK_IV_SIZE + MKEK_KEY_SIZE);
|
||||
}
|
||||
else {
|
||||
memcpy(tmp_mkek, mkek, MKEK_SIZE);
|
||||
}
|
||||
*(uint32_t *) MKEK_CHECKSUM(tmp_mkek) = crc32c(MKEK_KEY(tmp_mkek), MKEK_KEY_SIZE);
|
||||
@@ -150,7 +145,7 @@ int store_mkek(const uint8_t *mkek)
|
||||
aes_encrypt_cfb_256(session_pin,
|
||||
MKEK_IV(tmp_mkek_pin),
|
||||
MKEK_KEY(tmp_mkek_pin),
|
||||
MKEK_KEY_SIZE+MKEK_KEY_CS_SIZE);
|
||||
MKEK_KEY_SIZE + MKEK_KEY_CS_SIZE);
|
||||
flash_write_data_to_file(tf, tmp_mkek_pin, MKEK_SIZE);
|
||||
release_mkek(tmp_mkek_pin);
|
||||
}
|
||||
@@ -175,9 +170,8 @@ int store_mkek(const uint8_t *mkek)
|
||||
return CCID_OK;
|
||||
}
|
||||
|
||||
int store_dkek_key(uint8_t id, uint8_t *dkek)
|
||||
{
|
||||
file_t *tf = search_dynamic_file(EF_DKEK+id);
|
||||
int store_dkek_key(uint8_t id, uint8_t *dkek) {
|
||||
file_t *tf = search_dynamic_file(EF_DKEK + id);
|
||||
if (!tf) {
|
||||
return CCID_ERR_FILE_NOT_FOUND;
|
||||
}
|
||||
@@ -190,25 +184,24 @@ int store_dkek_key(uint8_t id, uint8_t *dkek)
|
||||
return CCID_OK;
|
||||
}
|
||||
|
||||
int save_dkek_key(uint8_t id, const uint8_t *key)
|
||||
{
|
||||
int save_dkek_key(uint8_t id, const uint8_t *key) {
|
||||
uint8_t dkek[DKEK_KEY_SIZE];
|
||||
if (!key) {
|
||||
file_t *tf = search_dynamic_file(EF_DKEK+id);
|
||||
file_t *tf = search_dynamic_file(EF_DKEK + id);
|
||||
if (!tf) {
|
||||
return CCID_ERR_FILE_NOT_FOUND;
|
||||
}
|
||||
memcpy(dkek, file_get_data(tf), DKEK_KEY_SIZE);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
memcpy(dkek, key, DKEK_KEY_SIZE);
|
||||
}
|
||||
return store_dkek_key(id, dkek);
|
||||
}
|
||||
|
||||
int import_dkek_share(uint8_t id, const uint8_t *share)
|
||||
{
|
||||
int import_dkek_share(uint8_t id, const uint8_t *share) {
|
||||
uint8_t tmp_dkek[DKEK_KEY_SIZE];
|
||||
file_t *tf = search_dynamic_file(EF_DKEK+id);
|
||||
file_t *tf = search_dynamic_file(EF_DKEK + id);
|
||||
if (!tf) {
|
||||
return CCID_ERR_FILE_NOT_FOUND;
|
||||
}
|
||||
@@ -224,8 +217,7 @@ int import_dkek_share(uint8_t id, const uint8_t *share)
|
||||
return CCID_OK;
|
||||
}
|
||||
|
||||
int dkek_kcv(uint8_t id, uint8_t *kcv) //kcv 8 bytes
|
||||
{
|
||||
int dkek_kcv(uint8_t id, uint8_t *kcv) { //kcv 8 bytes
|
||||
uint8_t hsh[32], dkek[DKEK_KEY_SIZE];
|
||||
memset(kcv, 0, 8);
|
||||
memset(hsh, 0, sizeof(hsh));
|
||||
@@ -239,38 +231,35 @@ int dkek_kcv(uint8_t id, uint8_t *kcv) //kcv 8 bytes
|
||||
return CCID_OK;
|
||||
}
|
||||
|
||||
int dkek_kenc(uint8_t id, uint8_t *kenc) //kenc 32 bytes
|
||||
{
|
||||
uint8_t dkek[DKEK_KEY_SIZE+4];
|
||||
int dkek_kenc(uint8_t id, uint8_t *kenc) { //kenc 32 bytes
|
||||
uint8_t dkek[DKEK_KEY_SIZE + 4];
|
||||
memset(kenc, 0, 32);
|
||||
int r = load_dkek(id, dkek);
|
||||
if (r != CCID_OK) {
|
||||
return r;
|
||||
}
|
||||
memcpy(dkek+DKEK_KEY_SIZE, "\x0\x0\x0\x1", 4);
|
||||
memcpy(dkek + DKEK_KEY_SIZE, "\x0\x0\x0\x1", 4);
|
||||
hash256(dkek, sizeof(dkek), kenc);
|
||||
mbedtls_platform_zeroize(dkek, sizeof(dkek));
|
||||
return CCID_OK;
|
||||
}
|
||||
|
||||
int dkek_kmac(uint8_t id, uint8_t *kmac) //kmac 32 bytes
|
||||
{
|
||||
uint8_t dkek[DKEK_KEY_SIZE+4];
|
||||
int dkek_kmac(uint8_t id, uint8_t *kmac) { //kmac 32 bytes
|
||||
uint8_t dkek[DKEK_KEY_SIZE + 4];
|
||||
memset(kmac, 0, 32);
|
||||
int r = load_dkek(id, dkek);
|
||||
if (r != CCID_OK) {
|
||||
return r;
|
||||
}
|
||||
memcpy(dkek+DKEK_KEY_SIZE, "\x0\x0\x0\x2", 4);
|
||||
hash256(dkek, DKEK_KEY_SIZE+4, kmac);
|
||||
memcpy(dkek + DKEK_KEY_SIZE, "\x0\x0\x0\x2", 4);
|
||||
hash256(dkek, DKEK_KEY_SIZE + 4, kmac);
|
||||
mbedtls_platform_zeroize(dkek, sizeof(dkek));
|
||||
return CCID_OK;
|
||||
}
|
||||
|
||||
int mkek_encrypt(uint8_t *data, size_t len)
|
||||
{
|
||||
int mkek_encrypt(uint8_t *data, size_t len) {
|
||||
int r;
|
||||
uint8_t mkek[MKEK_SIZE+4];
|
||||
uint8_t mkek[MKEK_SIZE + 4];
|
||||
if ((r = load_mkek(mkek)) != CCID_OK) {
|
||||
return r;
|
||||
}
|
||||
@@ -279,10 +268,9 @@ int mkek_encrypt(uint8_t *data, size_t len)
|
||||
return r;
|
||||
}
|
||||
|
||||
int mkek_decrypt(uint8_t *data, size_t len)
|
||||
{
|
||||
int mkek_decrypt(uint8_t *data, size_t len) {
|
||||
int r;
|
||||
uint8_t mkek[MKEK_SIZE+4];
|
||||
uint8_t mkek[MKEK_SIZE + 4];
|
||||
if ((r = load_mkek(mkek)) != CCID_OK) {
|
||||
return r;
|
||||
}
|
||||
@@ -297,13 +285,12 @@ int dkek_encode_key(uint8_t id,
|
||||
uint8_t *out,
|
||||
size_t *out_len,
|
||||
const uint8_t *allowed,
|
||||
size_t allowed_len)
|
||||
{
|
||||
size_t allowed_len) {
|
||||
if (!(key_type & HSM_KEY_RSA) && !(key_type & HSM_KEY_EC) && !(key_type & HSM_KEY_AES)) {
|
||||
return CCID_WRONG_DATA;
|
||||
}
|
||||
|
||||
uint8_t kb[8+2*4+2*4096/8+3+13]; //worst case: RSA-4096 (plus, 13 bytes padding)
|
||||
uint8_t kb[8 + 2 * 4 + 2 * 4096 / 8 + 3 + 13]; //worst case: RSA-4096 (plus, 13 bytes padding)
|
||||
memset(kb, 0, sizeof(kb));
|
||||
int kb_len = 0, r = 0;
|
||||
uint8_t *algo = NULL;
|
||||
@@ -332,80 +319,87 @@ int dkek_encode_key(uint8_t id,
|
||||
if (key_type & HSM_KEY_AES) {
|
||||
if (key_type & HSM_KEY_AES_128) {
|
||||
kb_len = 16;
|
||||
} else if (key_type & HSM_KEY_AES_192) {
|
||||
}
|
||||
else if (key_type & HSM_KEY_AES_192) {
|
||||
kb_len = 24;
|
||||
} else if (key_type & HSM_KEY_AES_256) {
|
||||
}
|
||||
else if (key_type & HSM_KEY_AES_256) {
|
||||
kb_len = 32;
|
||||
}
|
||||
|
||||
if (kb_len != 16 && kb_len != 24 && kb_len != 32) {
|
||||
return CCID_WRONG_DATA;
|
||||
}
|
||||
if (*out_len < 8+1+10+6+4+(2+32+14)+16) {
|
||||
if (*out_len < 8 + 1 + 10 + 6 + 4 + (2 + 32 + 14) + 16) {
|
||||
return CCID_WRONG_LENGTH;
|
||||
}
|
||||
|
||||
put_uint16_t(kb_len, kb+8);
|
||||
memcpy(kb+10, key_ctx, kb_len);
|
||||
put_uint16_t(kb_len, kb + 8);
|
||||
memcpy(kb + 10, key_ctx, kb_len);
|
||||
kb_len += 2;
|
||||
|
||||
algo = (uint8_t *) "\x00\x08\x60\x86\x48\x01\x65\x03\x04\x01"; //2.16.840.1.101.3.4.1 (2+8)
|
||||
algo_len = 10;
|
||||
} else if (key_type & HSM_KEY_RSA) {
|
||||
if (*out_len < 8+1+12+6+(8+2*4+2*4096/8+3+13)+16) { //13 bytes pading
|
||||
}
|
||||
else if (key_type & HSM_KEY_RSA) {
|
||||
if (*out_len < 8 + 1 + 12 + 6 + (8 + 2 * 4 + 2 * 4096 / 8 + 3 + 13) + 16) { //13 bytes pading
|
||||
return CCID_WRONG_LENGTH;
|
||||
}
|
||||
mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) key_ctx;
|
||||
kb_len = 0;
|
||||
put_uint16_t(mbedtls_rsa_get_len(rsa)*8, kb+8+kb_len); kb_len += 2;
|
||||
put_uint16_t(mbedtls_rsa_get_len(rsa) * 8, kb + 8 + kb_len); kb_len += 2;
|
||||
|
||||
put_uint16_t(mbedtls_mpi_size(&rsa->D), kb+8+kb_len); kb_len += 2;
|
||||
mbedtls_mpi_write_binary(&rsa->D, kb+8+kb_len, mbedtls_mpi_size(&rsa->D));
|
||||
put_uint16_t(mbedtls_mpi_size(&rsa->D), kb + 8 + kb_len); kb_len += 2;
|
||||
mbedtls_mpi_write_binary(&rsa->D, kb + 8 + kb_len, mbedtls_mpi_size(&rsa->D));
|
||||
kb_len += mbedtls_mpi_size(&rsa->D);
|
||||
put_uint16_t(mbedtls_mpi_size(&rsa->N), kb+8+kb_len); kb_len += 2;
|
||||
mbedtls_mpi_write_binary(&rsa->N, kb+8+kb_len, mbedtls_mpi_size(&rsa->N));
|
||||
put_uint16_t(mbedtls_mpi_size(&rsa->N), kb + 8 + kb_len); kb_len += 2;
|
||||
mbedtls_mpi_write_binary(&rsa->N, kb + 8 + kb_len, mbedtls_mpi_size(&rsa->N));
|
||||
kb_len += mbedtls_mpi_size(&rsa->N);
|
||||
put_uint16_t(mbedtls_mpi_size(&rsa->E), kb+8+kb_len); kb_len += 2;
|
||||
mbedtls_mpi_write_binary(&rsa->E, kb+8+kb_len, mbedtls_mpi_size(&rsa->E));
|
||||
put_uint16_t(mbedtls_mpi_size(&rsa->E), kb + 8 + kb_len); kb_len += 2;
|
||||
mbedtls_mpi_write_binary(&rsa->E, kb + 8 + kb_len, mbedtls_mpi_size(&rsa->E));
|
||||
kb_len += mbedtls_mpi_size(&rsa->E);
|
||||
|
||||
algo = (uint8_t *) "\x00\x0A\x04\x00\x7F\x00\x07\x02\x02\x02\x01\x02";
|
||||
algo_len = 12;
|
||||
} else if (key_type & HSM_KEY_EC) {
|
||||
if (*out_len < 8+1+12+6+(8+2*8+9*66+2+4)+16) { //4 bytes pading
|
||||
}
|
||||
else if (key_type & HSM_KEY_EC) {
|
||||
if (*out_len < 8 + 1 + 12 + 6 + (8 + 2 * 8 + 9 * 66 + 2 + 4) + 16) { //4 bytes pading
|
||||
return CCID_WRONG_LENGTH;
|
||||
}
|
||||
mbedtls_ecdsa_context *ecdsa = (mbedtls_ecdsa_context *) key_ctx;
|
||||
kb_len = 0;
|
||||
put_uint16_t(mbedtls_mpi_size(&ecdsa->grp.P)*8, kb+8+kb_len); kb_len += 2;
|
||||
put_uint16_t(mbedtls_mpi_size(&ecdsa->grp.A), kb+8+kb_len); kb_len += 2;
|
||||
mbedtls_mpi_write_binary(&ecdsa->grp.A, kb+8+kb_len, mbedtls_mpi_size(&ecdsa->grp.A));
|
||||
put_uint16_t(mbedtls_mpi_size(&ecdsa->grp.P) * 8, kb + 8 + kb_len); kb_len += 2;
|
||||
put_uint16_t(mbedtls_mpi_size(&ecdsa->grp.A), kb + 8 + kb_len); kb_len += 2;
|
||||
mbedtls_mpi_write_binary(&ecdsa->grp.A, kb + 8 + kb_len, mbedtls_mpi_size(&ecdsa->grp.A));
|
||||
kb_len += mbedtls_mpi_size(&ecdsa->grp.A);
|
||||
put_uint16_t(mbedtls_mpi_size(&ecdsa->grp.B), kb+8+kb_len); kb_len += 2;
|
||||
mbedtls_mpi_write_binary(&ecdsa->grp.B, kb+8+kb_len, mbedtls_mpi_size(&ecdsa->grp.B));
|
||||
put_uint16_t(mbedtls_mpi_size(&ecdsa->grp.B), kb + 8 + kb_len); kb_len += 2;
|
||||
mbedtls_mpi_write_binary(&ecdsa->grp.B, kb + 8 + kb_len, mbedtls_mpi_size(&ecdsa->grp.B));
|
||||
kb_len += mbedtls_mpi_size(&ecdsa->grp.B);
|
||||
put_uint16_t(mbedtls_mpi_size(&ecdsa->grp.P), kb+8+kb_len); kb_len += 2;
|
||||
mbedtls_mpi_write_binary(&ecdsa->grp.P, kb+8+kb_len, mbedtls_mpi_size(&ecdsa->grp.P));
|
||||
put_uint16_t(mbedtls_mpi_size(&ecdsa->grp.P), kb + 8 + kb_len); kb_len += 2;
|
||||
mbedtls_mpi_write_binary(&ecdsa->grp.P, kb + 8 + kb_len, mbedtls_mpi_size(&ecdsa->grp.P));
|
||||
kb_len += mbedtls_mpi_size(&ecdsa->grp.P);
|
||||
put_uint16_t(mbedtls_mpi_size(&ecdsa->grp.N), kb+8+kb_len); kb_len += 2;
|
||||
mbedtls_mpi_write_binary(&ecdsa->grp.N, kb+8+kb_len, mbedtls_mpi_size(&ecdsa->grp.N));
|
||||
put_uint16_t(mbedtls_mpi_size(&ecdsa->grp.N), kb + 8 + kb_len); kb_len += 2;
|
||||
mbedtls_mpi_write_binary(&ecdsa->grp.N, kb + 8 + kb_len, mbedtls_mpi_size(&ecdsa->grp.N));
|
||||
kb_len += mbedtls_mpi_size(&ecdsa->grp.N);
|
||||
put_uint16_t(1+mbedtls_mpi_size(&ecdsa->grp.G.X)+mbedtls_mpi_size(&ecdsa->grp.G.Y),
|
||||
kb+8+kb_len); kb_len += 2;
|
||||
kb[8+kb_len++] = 0x4;
|
||||
mbedtls_mpi_write_binary(&ecdsa->grp.G.X, kb+8+kb_len, mbedtls_mpi_size(&ecdsa->grp.G.X));
|
||||
put_uint16_t(1 + mbedtls_mpi_size(&ecdsa->grp.G.X) + mbedtls_mpi_size(&ecdsa->grp.G.Y),
|
||||
kb + 8 + kb_len); kb_len += 2;
|
||||
kb[8 + kb_len++] = 0x4;
|
||||
mbedtls_mpi_write_binary(&ecdsa->grp.G.X, kb + 8 + kb_len,
|
||||
mbedtls_mpi_size(&ecdsa->grp.G.X));
|
||||
kb_len += mbedtls_mpi_size(&ecdsa->grp.G.X);
|
||||
mbedtls_mpi_write_binary(&ecdsa->grp.G.Y, kb+8+kb_len, mbedtls_mpi_size(&ecdsa->grp.G.Y));
|
||||
mbedtls_mpi_write_binary(&ecdsa->grp.G.Y, kb + 8 + kb_len,
|
||||
mbedtls_mpi_size(&ecdsa->grp.G.Y));
|
||||
kb_len += mbedtls_mpi_size(&ecdsa->grp.G.Y);
|
||||
put_uint16_t(mbedtls_mpi_size(&ecdsa->d), kb+8+kb_len); kb_len += 2;
|
||||
mbedtls_mpi_write_binary(&ecdsa->d, kb+8+kb_len, mbedtls_mpi_size(&ecdsa->d));
|
||||
put_uint16_t(mbedtls_mpi_size(&ecdsa->d), kb + 8 + kb_len); kb_len += 2;
|
||||
mbedtls_mpi_write_binary(&ecdsa->d, kb + 8 + kb_len, mbedtls_mpi_size(&ecdsa->d));
|
||||
kb_len += mbedtls_mpi_size(&ecdsa->d);
|
||||
put_uint16_t(1+mbedtls_mpi_size(&ecdsa->Q.X)+mbedtls_mpi_size(&ecdsa->Q.Y), kb+8+kb_len);
|
||||
put_uint16_t(1 + mbedtls_mpi_size(&ecdsa->Q.X) + mbedtls_mpi_size(&ecdsa->Q.Y),
|
||||
kb + 8 + kb_len);
|
||||
kb_len += 2;
|
||||
kb[8+kb_len++] = 0x4;
|
||||
mbedtls_mpi_write_binary(&ecdsa->Q.X, kb+8+kb_len, mbedtls_mpi_size(&ecdsa->Q.X));
|
||||
kb[8 + kb_len++] = 0x4;
|
||||
mbedtls_mpi_write_binary(&ecdsa->Q.X, kb + 8 + kb_len, mbedtls_mpi_size(&ecdsa->Q.X));
|
||||
kb_len += mbedtls_mpi_size(&ecdsa->Q.X);
|
||||
mbedtls_mpi_write_binary(&ecdsa->Q.Y, kb+8+kb_len, mbedtls_mpi_size(&ecdsa->Q.Y));
|
||||
mbedtls_mpi_write_binary(&ecdsa->Q.Y, kb + 8 + kb_len, mbedtls_mpi_size(&ecdsa->Q.Y));
|
||||
kb_len += mbedtls_mpi_size(&ecdsa->Q.Y);
|
||||
|
||||
algo = (uint8_t *) "\x00\x0A\x04\x00\x7F\x00\x07\x02\x02\x02\x02\x03";
|
||||
@@ -414,30 +408,34 @@ int dkek_encode_key(uint8_t id,
|
||||
memset(out, 0, *out_len);
|
||||
*out_len = 0;
|
||||
|
||||
memcpy(out+*out_len, kcv, 8);
|
||||
memcpy(out + *out_len, kcv, 8);
|
||||
*out_len += 8;
|
||||
|
||||
if (key_type & HSM_KEY_AES) {
|
||||
out[*out_len] = 15;
|
||||
} else if (key_type & HSM_KEY_RSA) {
|
||||
}
|
||||
else if (key_type & HSM_KEY_RSA) {
|
||||
out[*out_len] = 5;
|
||||
} else if (key_type & HSM_KEY_EC) {
|
||||
}
|
||||
else if (key_type & HSM_KEY_EC) {
|
||||
out[*out_len] = 12;
|
||||
}
|
||||
*out_len += 1;
|
||||
|
||||
if (algo) {
|
||||
memcpy(out+*out_len, algo, algo_len);
|
||||
memcpy(out + *out_len, algo, algo_len);
|
||||
*out_len += algo_len;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
*out_len += 2;
|
||||
}
|
||||
|
||||
if (allowed && allowed_len > 0) {
|
||||
put_uint16_t(allowed_len, out+*out_len); *out_len += 2;
|
||||
memcpy(out+*out_len, allowed, allowed_len);
|
||||
put_uint16_t(allowed_len, out + *out_len); *out_len += 2;
|
||||
memcpy(out + *out_len, allowed, allowed_len);
|
||||
*out_len += allowed_len;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
*out_len += 2;
|
||||
}
|
||||
//add 4 zeros
|
||||
@@ -445,9 +443,9 @@ int dkek_encode_key(uint8_t id,
|
||||
|
||||
memcpy(kb, random_bytes_get(8), 8);
|
||||
kb_len += 8; //8 random bytes
|
||||
int kb_len_pad = ((int) (kb_len/16))*16;
|
||||
int kb_len_pad = ((int) (kb_len / 16)) * 16;
|
||||
if (kb_len % 16 > 0) {
|
||||
kb_len_pad = ((int) (kb_len/16)+1)*16;
|
||||
kb_len_pad = ((int) (kb_len / 16) + 1) * 16;
|
||||
}
|
||||
//key already copied at kb+10
|
||||
if (kb_len < kb_len_pad) {
|
||||
@@ -458,7 +456,7 @@ int dkek_encode_key(uint8_t id,
|
||||
return r;
|
||||
}
|
||||
|
||||
memcpy(out+*out_len, kb, kb_len_pad);
|
||||
memcpy(out + *out_len, kb, kb_len_pad);
|
||||
*out_len += kb_len_pad;
|
||||
|
||||
r = mbedtls_cipher_cmac(mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_256_ECB),
|
||||
@@ -466,7 +464,7 @@ int dkek_encode_key(uint8_t id,
|
||||
256,
|
||||
out,
|
||||
*out_len,
|
||||
out+*out_len);
|
||||
out + *out_len);
|
||||
|
||||
*out_len += 16;
|
||||
if (r != 0) {
|
||||
@@ -475,13 +473,14 @@ int dkek_encode_key(uint8_t id,
|
||||
return CCID_OK;
|
||||
}
|
||||
|
||||
int dkek_type_key(const uint8_t *in)
|
||||
{
|
||||
int dkek_type_key(const uint8_t *in) {
|
||||
if (in[8] == 5 || in[8] == 6) {
|
||||
return HSM_KEY_RSA;
|
||||
} else if (in[8] == 12) {
|
||||
}
|
||||
else if (in[8] == 12) {
|
||||
return HSM_KEY_EC;
|
||||
} else if (in[8] == 15) {
|
||||
}
|
||||
else if (in[8] == 15) {
|
||||
return HSM_KEY_AES;
|
||||
}
|
||||
return 0x0;
|
||||
@@ -493,8 +492,7 @@ int dkek_decode_key(uint8_t id,
|
||||
size_t in_len,
|
||||
int *key_size_out,
|
||||
uint8_t **allowed,
|
||||
size_t *allowed_len)
|
||||
{
|
||||
size_t *allowed_len) {
|
||||
uint8_t kcv[8];
|
||||
int r = 0;
|
||||
memset(kcv, 0, sizeof(kcv));
|
||||
@@ -526,12 +524,12 @@ int dkek_decode_key(uint8_t id,
|
||||
kmac,
|
||||
256,
|
||||
in,
|
||||
in_len-16,
|
||||
in_len - 16,
|
||||
signature);
|
||||
if (r != 0) {
|
||||
return CCID_WRONG_SIGNATURE;
|
||||
}
|
||||
if (memcmp(signature, in+in_len-16, 16) != 0) {
|
||||
if (memcmp(signature, in + in_len - 16, 16) != 0) {
|
||||
return CCID_WRONG_SIGNATURE;
|
||||
}
|
||||
|
||||
@@ -541,16 +539,16 @@ int dkek_decode_key(uint8_t id,
|
||||
}
|
||||
|
||||
if ((key_type == 5 || key_type == 6) &&
|
||||
memcmp(in+9, "\x00\x0A\x04\x00\x7F\x00\x07\x02\x02\x02\x01\x02", 12) != 0) {
|
||||
memcmp(in + 9, "\x00\x0A\x04\x00\x7F\x00\x07\x02\x02\x02\x01\x02", 12) != 0) {
|
||||
return CCID_WRONG_DATA;
|
||||
}
|
||||
|
||||
if (key_type == 12 &&
|
||||
memcmp(in+9, "\x00\x0A\x04\x00\x7F\x00\x07\x02\x02\x02\x02\x03", 12) != 0) {
|
||||
memcmp(in + 9, "\x00\x0A\x04\x00\x7F\x00\x07\x02\x02\x02\x02\x03", 12) != 0) {
|
||||
return CCID_WRONG_DATA;
|
||||
}
|
||||
|
||||
if (key_type == 15 && memcmp(in+9, "\x00\x08\x60\x86\x48\x01\x65\x03\x04\x01", 10) != 0) {
|
||||
if (key_type == 15 && memcmp(in + 9, "\x00\x08\x60\x86\x48\x01\x65\x03\x04\x01", 10) != 0) {
|
||||
return CCID_WRONG_DATA;
|
||||
}
|
||||
|
||||
@@ -558,29 +556,29 @@ int dkek_decode_key(uint8_t id,
|
||||
|
||||
//OID
|
||||
size_t len = get_uint16_t(in, ofs);
|
||||
ofs += len+2;
|
||||
ofs += len + 2;
|
||||
|
||||
//Allowed algorithms
|
||||
len = get_uint16_t(in, ofs);
|
||||
*allowed = (uint8_t *) (in+ofs+2);
|
||||
*allowed = (uint8_t *) (in + ofs + 2);
|
||||
*allowed_len = len;
|
||||
ofs += len+2;
|
||||
ofs += len + 2;
|
||||
|
||||
//Access conditions
|
||||
len = get_uint16_t(in, ofs);
|
||||
ofs += len+2;
|
||||
ofs += len + 2;
|
||||
|
||||
//Key OID
|
||||
len = get_uint16_t(in, ofs);
|
||||
ofs += len+2;
|
||||
ofs += len + 2;
|
||||
|
||||
if ((in_len-16-ofs) % 16 != 0) {
|
||||
if ((in_len - 16 - ofs) % 16 != 0) {
|
||||
return CCID_WRONG_PADDING;
|
||||
}
|
||||
uint8_t kb[8+2*4+2*4096/8+3+13]; //worst case: RSA-4096 (plus, 13 bytes padding)
|
||||
uint8_t kb[8 + 2 * 4 + 2 * 4096 / 8 + 3 + 13]; //worst case: RSA-4096 (plus, 13 bytes padding)
|
||||
memset(kb, 0, sizeof(kb));
|
||||
memcpy(kb, in+ofs, in_len-16-ofs);
|
||||
r = aes_decrypt(kenc, NULL, 256, HSM_AES_MODE_CBC, kb, in_len-16-ofs);
|
||||
memcpy(kb, in + ofs, in_len - 16 - ofs);
|
||||
r = aes_decrypt(kenc, NULL, 256, HSM_AES_MODE_CBC, kb, in_len - 16 - ofs);
|
||||
if (r != CCID_OK) {
|
||||
return r;
|
||||
}
|
||||
@@ -595,47 +593,48 @@ int dkek_decode_key(uint8_t id,
|
||||
mbedtls_rsa_init(rsa);
|
||||
if (key_type == 5) {
|
||||
len = get_uint16_t(kb, ofs); ofs += 2;
|
||||
r = mbedtls_mpi_read_binary(&rsa->D, kb+ofs, len); ofs += len;
|
||||
r = mbedtls_mpi_read_binary(&rsa->D, kb + ofs, len); ofs += len;
|
||||
if (r != 0) {
|
||||
mbedtls_rsa_free(rsa);
|
||||
return CCID_WRONG_DATA;
|
||||
}
|
||||
|
||||
len = get_uint16_t(kb, ofs); ofs += 2;
|
||||
r = mbedtls_mpi_read_binary(&rsa->N, kb+ofs, len); ofs += len;
|
||||
r = mbedtls_mpi_read_binary(&rsa->N, kb + ofs, len); ofs += len;
|
||||
if (r != 0) {
|
||||
mbedtls_rsa_free(rsa);
|
||||
return CCID_WRONG_DATA;
|
||||
}
|
||||
} else if (key_type == 6) {
|
||||
}
|
||||
else if (key_type == 6) {
|
||||
//DP-1
|
||||
len = get_uint16_t(kb, ofs); ofs += len+2;
|
||||
len = get_uint16_t(kb, ofs); ofs += len + 2;
|
||||
|
||||
//DQ-1
|
||||
len = get_uint16_t(kb, ofs); ofs += len+2;
|
||||
len = get_uint16_t(kb, ofs); ofs += len + 2;
|
||||
|
||||
len = get_uint16_t(kb, ofs); ofs += 2;
|
||||
r = mbedtls_mpi_read_binary(&rsa->P, kb+ofs, len); ofs += len;
|
||||
r = mbedtls_mpi_read_binary(&rsa->P, kb + ofs, len); ofs += len;
|
||||
if (r != 0) {
|
||||
mbedtls_rsa_free(rsa);
|
||||
return CCID_WRONG_DATA;
|
||||
}
|
||||
|
||||
//PQ
|
||||
len = get_uint16_t(kb, ofs); ofs += len+2;
|
||||
len = get_uint16_t(kb, ofs); ofs += len + 2;
|
||||
|
||||
len = get_uint16_t(kb, ofs); ofs += 2;
|
||||
r = mbedtls_mpi_read_binary(&rsa->Q, kb+ofs, len); ofs += len;
|
||||
r = mbedtls_mpi_read_binary(&rsa->Q, kb + ofs, len); ofs += len;
|
||||
if (r != 0) {
|
||||
mbedtls_rsa_free(rsa);
|
||||
return CCID_WRONG_DATA;
|
||||
}
|
||||
//N
|
||||
len = get_uint16_t(kb, ofs); ofs += len+2;
|
||||
len = get_uint16_t(kb, ofs); ofs += len + 2;
|
||||
}
|
||||
|
||||
len = get_uint16_t(kb, ofs); ofs += 2;
|
||||
r = mbedtls_mpi_read_binary(&rsa->E, kb+ofs, len); ofs += len;
|
||||
r = mbedtls_mpi_read_binary(&rsa->E, kb + ofs, len); ofs += len;
|
||||
if (r != 0) {
|
||||
mbedtls_rsa_free(rsa);
|
||||
return CCID_WRONG_DATA;
|
||||
@@ -647,7 +646,8 @@ int dkek_decode_key(uint8_t id,
|
||||
mbedtls_rsa_free(rsa);
|
||||
return CCID_EXEC_ERROR;
|
||||
}
|
||||
} else if (key_type == 6) {
|
||||
}
|
||||
else if (key_type == 6) {
|
||||
r = mbedtls_rsa_import(rsa, NULL, &rsa->P, &rsa->Q, NULL, &rsa->E);
|
||||
if (r != 0) {
|
||||
mbedtls_rsa_free(rsa);
|
||||
@@ -665,19 +665,20 @@ int dkek_decode_key(uint8_t id,
|
||||
mbedtls_rsa_free(rsa);
|
||||
return CCID_EXEC_ERROR;
|
||||
}
|
||||
} else if (key_type == 12) {
|
||||
}
|
||||
else if (key_type == 12) {
|
||||
mbedtls_ecdsa_context *ecdsa = (mbedtls_ecdsa_context *) key_ctx;
|
||||
mbedtls_ecdsa_init(ecdsa);
|
||||
|
||||
//A
|
||||
len = get_uint16_t(kb, ofs); ofs += len+2;
|
||||
len = get_uint16_t(kb, ofs); ofs += len + 2;
|
||||
|
||||
//B
|
||||
len = get_uint16_t(kb, ofs); ofs += len+2;
|
||||
len = get_uint16_t(kb, ofs); ofs += len + 2;
|
||||
|
||||
//P
|
||||
len = get_uint16_t(kb, ofs); ofs += 2;
|
||||
mbedtls_ecp_group_id ec_id = ec_get_curve_from_prime(kb+ofs, len);
|
||||
mbedtls_ecp_group_id ec_id = ec_get_curve_from_prime(kb + ofs, len);
|
||||
if (ec_id == MBEDTLS_ECP_DP_NONE) {
|
||||
mbedtls_ecdsa_free(ecdsa);
|
||||
return CCID_WRONG_DATA;
|
||||
@@ -685,14 +686,14 @@ int dkek_decode_key(uint8_t id,
|
||||
ofs += len;
|
||||
|
||||
//N
|
||||
len = get_uint16_t(kb, ofs); ofs += len+2;
|
||||
len = get_uint16_t(kb, ofs); ofs += len + 2;
|
||||
|
||||
//G
|
||||
len = get_uint16_t(kb, ofs); ofs += len+2;
|
||||
len = get_uint16_t(kb, ofs); ofs += len + 2;
|
||||
|
||||
//d
|
||||
len = get_uint16_t(kb, ofs); ofs += 2;
|
||||
r = mbedtls_ecp_read_key(ec_id, ecdsa, kb+ofs, len);
|
||||
r = mbedtls_ecp_read_key(ec_id, ecdsa, kb + ofs, len);
|
||||
if (r != 0) {
|
||||
mbedtls_ecdsa_free(ecdsa);
|
||||
return CCID_EXEC_ERROR;
|
||||
@@ -711,8 +712,9 @@ int dkek_decode_key(uint8_t id,
|
||||
mbedtls_ecdsa_free(ecdsa);
|
||||
return CCID_EXEC_ERROR;
|
||||
}
|
||||
} else if (key_type == 15) {
|
||||
memcpy(key_ctx, kb+ofs, key_size);
|
||||
}
|
||||
else if (key_type == 15) {
|
||||
memcpy(key_ctx, kb + ofs, key_size);
|
||||
}
|
||||
return CCID_OK;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user