mirror of
https://github.com/polhenarejos/pico-hsm.git
synced 2026-01-17 09:28:05 +00:00
Fix wrap/unwrap keys with specific allowed algorithms.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
parent
2e88422c86
commit
55c8a66613
3 changed files with 33 additions and 19 deletions
|
|
@ -212,7 +212,7 @@ int mkek_decrypt(uint8_t *data, size_t len) {
|
|||
return r;
|
||||
}
|
||||
|
||||
int dkek_encode_key(uint8_t id, void *key_ctx, int key_type, uint8_t *out, size_t *out_len) {
|
||||
int dkek_encode_key(uint8_t id, void *key_ctx, int key_type, uint8_t *out, size_t *out_len, const uint8_t *allowed, size_t allowed_len) {
|
||||
if (!(key_type & HSM_KEY_RSA) && !(key_type & HSM_KEY_EC) && !(key_type & HSM_KEY_AES))
|
||||
return CCID_WRONG_DATA;
|
||||
|
||||
|
|
@ -221,8 +221,6 @@ int dkek_encode_key(uint8_t id, void *key_ctx, int key_type, uint8_t *out, size_
|
|||
int kb_len = 0, r = 0;
|
||||
uint8_t *algo = NULL;
|
||||
uint8_t algo_len = 0;
|
||||
uint8_t *allowed = NULL;
|
||||
uint8_t allowed_len = 0;
|
||||
uint8_t kenc[32];
|
||||
memset(kenc, 0, sizeof(kenc));
|
||||
r = dkek_kenc(id, kenc);
|
||||
|
|
@ -260,8 +258,6 @@ int dkek_encode_key(uint8_t id, void *key_ctx, int key_type, uint8_t *out, size_
|
|||
|
||||
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;
|
||||
allowed = (uint8_t *)"\x00\x04\x10\x11\x18\x99"; //(2+4)
|
||||
allowed_len = 6;
|
||||
}
|
||||
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
|
||||
|
|
@ -329,7 +325,8 @@ int dkek_encode_key(uint8_t id, void *key_ctx, int key_type, uint8_t *out, size_
|
|||
else
|
||||
*out_len += 2;
|
||||
|
||||
if (allowed) {
|
||||
if (allowed && allowed_len > 0) {
|
||||
put_uint16_t(allowed_len, out+*out_len); *out_len += 2;
|
||||
memcpy(out+*out_len, allowed, allowed_len);
|
||||
*out_len += allowed_len;
|
||||
}
|
||||
|
|
@ -372,7 +369,7 @@ int dkek_type_key(const uint8_t *in) {
|
|||
return 0x0;
|
||||
}
|
||||
|
||||
int dkek_decode_key(uint8_t id, void *key_ctx, const uint8_t *in, size_t in_len, int *key_size_out) {
|
||||
int dkek_decode_key(uint8_t id, void *key_ctx, const uint8_t *in, size_t in_len, int *key_size_out, uint8_t **allowed, size_t *allowed_len) {
|
||||
uint8_t kcv[8];
|
||||
int r = 0;
|
||||
memset(kcv, 0, sizeof(kcv));
|
||||
|
|
@ -423,6 +420,8 @@ int dkek_decode_key(uint8_t id, void *key_ctx, const uint8_t *in, size_t in_len,
|
|||
|
||||
//Allowed algorithms
|
||||
len = get_uint16_t(in, ofs);
|
||||
*allowed = (uint8_t *)(in+ofs+2);
|
||||
*allowed_len = len;
|
||||
ofs += len+2;
|
||||
|
||||
//Access conditions
|
||||
|
|
|
|||
|
|
@ -28,9 +28,9 @@ extern int import_dkek_share(uint8_t, const uint8_t *share);
|
|||
extern int dkek_kcv(uint8_t, uint8_t *kcv);
|
||||
extern int mkek_encrypt(uint8_t *data, size_t len);
|
||||
extern int mkek_decrypt(uint8_t *data, size_t len);
|
||||
extern int dkek_encode_key(uint8_t, void *key_ctx, int key_type, uint8_t *out, size_t *out_len);
|
||||
extern int dkek_encode_key(uint8_t, void *key_ctx, int key_type, uint8_t *out, size_t *out_len, const uint8_t *, size_t);
|
||||
extern int dkek_type_key(const uint8_t *in);
|
||||
extern int dkek_decode_key(uint8_t, void *key_ctx, const uint8_t *in, size_t in_len, int *key_size_out);
|
||||
extern int dkek_decode_key(uint8_t, void *key_ctx, const uint8_t *in, size_t in_len, int *key_size_out, uint8_t **, size_t *);
|
||||
|
||||
#define MAX_DKEK_ENCODE_KEY_BUFFER (8+1+12+6+(8+2*4+2*4096/8+3+13)+16)
|
||||
|
||||
|
|
|
|||
|
|
@ -1709,6 +1709,8 @@ static int cmd_key_wrap() {
|
|||
return SW_FILE_NOT_FOUND();
|
||||
const uint8_t *dprkd = file_get_data(prkd);
|
||||
size_t wrap_len = MAX_DKEK_ENCODE_KEY_BUFFER;
|
||||
size_t tag_len = 0;
|
||||
const uint8_t *meta_tag = get_meta_tag(ef, 0x91, &tag_len);
|
||||
if (*dprkd == P15_KEYTYPE_RSA) {
|
||||
mbedtls_rsa_context ctx;
|
||||
mbedtls_rsa_init(&ctx);
|
||||
|
|
@ -1719,7 +1721,7 @@ static int cmd_key_wrap() {
|
|||
return SW_SECURE_MESSAGE_EXEC_ERROR();
|
||||
return SW_EXEC_ERROR();
|
||||
}
|
||||
r = dkek_encode_key(kdom, &ctx, HSM_KEY_RSA, res_APDU, &wrap_len);
|
||||
r = dkek_encode_key(kdom, &ctx, HSM_KEY_RSA, res_APDU, &wrap_len, meta_tag, tag_len);
|
||||
mbedtls_rsa_free(&ctx);
|
||||
}
|
||||
else if (*dprkd == P15_KEYTYPE_ECC) {
|
||||
|
|
@ -1732,7 +1734,7 @@ static int cmd_key_wrap() {
|
|||
return SW_SECURE_MESSAGE_EXEC_ERROR();
|
||||
return SW_EXEC_ERROR();
|
||||
}
|
||||
r = dkek_encode_key(kdom, &ctx, HSM_KEY_EC, res_APDU, &wrap_len);
|
||||
r = dkek_encode_key(kdom, &ctx, HSM_KEY_EC, res_APDU, &wrap_len, meta_tag, tag_len);
|
||||
mbedtls_ecdsa_free(&ctx);
|
||||
}
|
||||
else if (*dprkd == P15_KEYTYPE_AES) {
|
||||
|
|
@ -1751,7 +1753,7 @@ static int cmd_key_wrap() {
|
|||
aes_type = HSM_KEY_AES_192;
|
||||
else if (key_size == 16)
|
||||
aes_type = HSM_KEY_AES_128;
|
||||
r = dkek_encode_key(kdom, kdata, aes_type, res_APDU, &wrap_len);
|
||||
r = dkek_encode_key(kdom, kdata, aes_type, res_APDU, &wrap_len, meta_tag, tag_len);
|
||||
mbedtls_platform_zeroize(kdata, sizeof(kdata));
|
||||
}
|
||||
if (r != CCID_OK)
|
||||
|
|
@ -1767,14 +1769,15 @@ static int cmd_key_unwrap() {
|
|||
if (!isUserAuthenticated)
|
||||
return SW_SECURITY_STATUS_NOT_SATISFIED();
|
||||
int key_type = dkek_type_key(apdu.data);
|
||||
uint8_t kdom = -1;
|
||||
uint8_t kdom = -1, *allowed = NULL;
|
||||
size_t allowed_len = 0;
|
||||
if (key_type == 0x0)
|
||||
return SW_DATA_INVALID();
|
||||
if (key_type == HSM_KEY_RSA) {
|
||||
mbedtls_rsa_context ctx;
|
||||
mbedtls_rsa_init(&ctx);
|
||||
do {
|
||||
r = dkek_decode_key(++kdom, &ctx, apdu.data, apdu.nc, NULL);
|
||||
r = dkek_decode_key(++kdom, &ctx, apdu.data, apdu.nc, NULL, &allowed, &allowed_len);
|
||||
} while((r == CCID_ERR_FILE_NOT_FOUND || r == CCID_WRONG_DKEK) && kdom < MAX_KEY_DOMAINS);
|
||||
if (r != CCID_OK) {
|
||||
mbedtls_rsa_free(&ctx);
|
||||
|
|
@ -1790,7 +1793,7 @@ static int cmd_key_unwrap() {
|
|||
mbedtls_ecdsa_context ctx;
|
||||
mbedtls_ecdsa_init(&ctx);
|
||||
do {
|
||||
r = dkek_decode_key(++kdom, &ctx, apdu.data, apdu.nc, NULL);
|
||||
r = dkek_decode_key(++kdom, &ctx, apdu.data, apdu.nc, NULL, &allowed, &allowed_len);
|
||||
} while((r == CCID_ERR_FILE_NOT_FOUND || r == CCID_WRONG_DKEK) && kdom < MAX_KEY_DOMAINS);
|
||||
if (r != CCID_OK) {
|
||||
mbedtls_ecdsa_free(&ctx);
|
||||
|
|
@ -1806,7 +1809,7 @@ static int cmd_key_unwrap() {
|
|||
uint8_t aes_key[32];
|
||||
int key_size = 0, aes_type = 0;
|
||||
do {
|
||||
r = dkek_decode_key(++kdom, aes_key, apdu.data, apdu.nc, &key_size);
|
||||
r = dkek_decode_key(++kdom, aes_key, apdu.data, apdu.nc, &key_size, &allowed, &allowed_len);
|
||||
} while((r == CCID_ERR_FILE_NOT_FOUND || r == CCID_WRONG_DKEK) && kdom < MAX_KEY_DOMAINS);
|
||||
if (r != CCID_OK) {
|
||||
return SW_EXEC_ERROR();
|
||||
|
|
@ -1824,9 +1827,21 @@ static int cmd_key_unwrap() {
|
|||
return SW_EXEC_ERROR();
|
||||
}
|
||||
}
|
||||
if (kdom >= 0) {
|
||||
uint8_t meta[3] = {0x92,1,kdom};
|
||||
r = meta_add((KEY_PREFIX << 8) | key_id, meta, sizeof(meta));
|
||||
if ((allowed != NULL && allowed_len > 0) || kdom >= 0) {
|
||||
size_t meta_len = (allowed_len > 0 ? 2+allowed_len : 0) + (kdom >= 0 ? 3 : 0);
|
||||
uint8_t *meta = (uint8_t *)calloc(1,meta_len), *m = meta;
|
||||
if (allowed_len > 0) {
|
||||
*m++ = 0x91;
|
||||
*m++ = allowed_len;
|
||||
memcpy(m, allowed, allowed_len); m += allowed_len;
|
||||
}
|
||||
if (kdom >= 0) {
|
||||
*m++ = 0x92;
|
||||
*m++ = 1;
|
||||
*m++ = kdom;
|
||||
}
|
||||
r = meta_add((KEY_PREFIX << 8) | key_id, meta, meta_len);
|
||||
free(meta);
|
||||
if (r != CCID_OK)
|
||||
return r;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue