Upgrade to v5.2

Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
Pol Henarejos
2025-01-15 13:07:35 +01:00
24 changed files with 164 additions and 120 deletions

View File

@@ -50,6 +50,14 @@ uint32_t crc32c(const uint8_t *buf, size_t len) {
return ~crc;
}
void mkek_masked(uint8_t *mkek, const uint8_t *mask) {
if (mask) {
for (int i = 0; i < MKEK_KEY_SIZE; i++) {
MKEK_KEY(mkek)[i] ^= mask[i];
}
}
}
int load_mkek(uint8_t *mkek) {
if (has_session_pin == false && has_session_sopin == false) {
return PICOKEY_NO_LOGIN;
@@ -73,6 +81,10 @@ int load_mkek(uint8_t *mkek) {
return PICOKEY_EXEC_ERROR;
}
if (has_mkek_mask) {
mkek_masked(mkek, mkek_mask);
}
int ret = aes_decrypt_cfb_256(pin, MKEK_IV(mkek), MKEK_KEY(mkek), MKEK_KEY_SIZE + MKEK_KEY_CS_SIZE);
if (ret != 0) {
return PICOKEY_EXEC_ERROR;
@@ -80,11 +92,8 @@ int load_mkek(uint8_t *mkek) {
if (crc32c(MKEK_KEY(mkek), MKEK_KEY_SIZE) != *(uint32_t *) MKEK_CHECKSUM(mkek)) {
return PICOKEY_WRONG_DKEK;
}
if (has_mkek_mask || otp_key_1) {
const uint8_t *mask = otp_key_1 ? otp_key_1 : mkek_mask;
for (int i = 0; i < MKEK_KEY_SIZE; i++) {
MKEK_KEY(mkek)[i] ^= mask[i];
}
if (otp_key_1) {
mkek_masked(mkek, otp_key_1);
}
return PICOKEY_OK;
}
@@ -125,6 +134,9 @@ int store_mkek(const uint8_t *mkek) {
else {
memcpy(tmp_mkek, mkek, MKEK_SIZE);
}
if (otp_key_1) {
mkek_masked(tmp_mkek, otp_key_1);
}
*(uint32_t *) MKEK_CHECKSUM(tmp_mkek) = crc32c(MKEK_KEY(tmp_mkek), MKEK_KEY_SIZE);
if (has_session_pin) {
uint8_t tmp_mkek_pin[MKEK_SIZE];
@@ -319,7 +331,7 @@ int dkek_encode_key(uint8_t id, void *key_ctx, int key_type, uint8_t *out, uint1
return PICOKEY_WRONG_LENGTH;
}
put_uint16_t(kb_len, kb + 8);
put_uint16_t_be(kb_len, kb + 8);
memcpy(kb + 10, key_ctx, kb_len);
kb_len += 2;
@@ -332,15 +344,15 @@ int dkek_encode_key(uint8_t id, void *key_ctx, int key_type, uint8_t *out, uint1
}
mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) key_ctx;
kb_len = 0;
put_uint16_t((uint16_t)mbedtls_rsa_get_len(rsa) * 8, kb + 8 + kb_len); kb_len += 2;
kb_len += put_uint16_t_be((uint16_t)mbedtls_rsa_get_len(rsa) * 8, kb + 8 + kb_len);
put_uint16_t((uint16_t)mbedtls_mpi_size(&rsa->D), kb + 8 + kb_len); kb_len += 2;
kb_len += put_uint16_t_be((uint16_t)mbedtls_mpi_size(&rsa->D), kb + 8 + kb_len);
mbedtls_mpi_write_binary(&rsa->D, kb + 8 + kb_len, mbedtls_mpi_size(&rsa->D));
kb_len += (uint16_t)mbedtls_mpi_size(&rsa->D);
put_uint16_t((uint16_t)mbedtls_mpi_size(&rsa->N), kb + 8 + kb_len); kb_len += 2;
kb_len += put_uint16_t_be((uint16_t)mbedtls_mpi_size(&rsa->N), kb + 8 + kb_len);
mbedtls_mpi_write_binary(&rsa->N, kb + 8 + kb_len, mbedtls_mpi_size(&rsa->N));
kb_len += (uint16_t)mbedtls_mpi_size(&rsa->N);
put_uint16_t((uint16_t)mbedtls_mpi_size(&rsa->E), kb + 8 + kb_len); kb_len += 2;
kb_len += put_uint16_t_be((uint16_t)mbedtls_mpi_size(&rsa->E), kb + 8 + kb_len);
mbedtls_mpi_write_binary(&rsa->E, kb + 8 + kb_len, mbedtls_mpi_size(&rsa->E));
kb_len += (uint16_t)mbedtls_mpi_size(&rsa->E);
@@ -353,32 +365,32 @@ int dkek_encode_key(uint8_t id, void *key_ctx, int key_type, uint8_t *out, uint1
}
mbedtls_ecdsa_context *ecdsa = (mbedtls_ecdsa_context *) key_ctx;
kb_len = 0;
put_uint16_t((uint16_t)mbedtls_mpi_size(&ecdsa->grp.P) * 8, kb + 8 + kb_len); kb_len += 2;
put_uint16_t((uint16_t)mbedtls_mpi_size(&ecdsa->grp.A), kb + 8 + kb_len); kb_len += 2;
kb_len += put_uint16_t_be((uint16_t)mbedtls_mpi_size(&ecdsa->grp.P) * 8, kb + 8 + kb_len);
kb_len += put_uint16_t_be((uint16_t)mbedtls_mpi_size(&ecdsa->grp.A), kb + 8 + kb_len);
mbedtls_mpi_write_binary(&ecdsa->grp.A, kb + 8 + kb_len, mbedtls_mpi_size(&ecdsa->grp.A));
kb_len += (uint16_t)mbedtls_mpi_size(&ecdsa->grp.A);
put_uint16_t((uint16_t)mbedtls_mpi_size(&ecdsa->grp.B), kb + 8 + kb_len); kb_len += 2;
kb_len += put_uint16_t_be((uint16_t)mbedtls_mpi_size(&ecdsa->grp.B), kb + 8 + kb_len);
mbedtls_mpi_write_binary(&ecdsa->grp.B, kb + 8 + kb_len, mbedtls_mpi_size(&ecdsa->grp.B));
kb_len += (uint16_t)mbedtls_mpi_size(&ecdsa->grp.B);
put_uint16_t((uint16_t)mbedtls_mpi_size(&ecdsa->grp.P), kb + 8 + kb_len); kb_len += 2;
kb_len += put_uint16_t_be((uint16_t)mbedtls_mpi_size(&ecdsa->grp.P), kb + 8 + kb_len);
mbedtls_mpi_write_binary(&ecdsa->grp.P, kb + 8 + kb_len, mbedtls_mpi_size(&ecdsa->grp.P));
kb_len += (uint16_t)mbedtls_mpi_size(&ecdsa->grp.P);
put_uint16_t((uint16_t)mbedtls_mpi_size(&ecdsa->grp.N), kb + 8 + kb_len); kb_len += 2;
kb_len += put_uint16_t_be((uint16_t)mbedtls_mpi_size(&ecdsa->grp.N), kb + 8 + kb_len);
mbedtls_mpi_write_binary(&ecdsa->grp.N, kb + 8 + kb_len, mbedtls_mpi_size(&ecdsa->grp.N));
kb_len += (uint16_t)mbedtls_mpi_size(&ecdsa->grp.N);
size_t olen = 0;
mbedtls_ecp_point_write_binary(&ecdsa->grp, &ecdsa->grp.G, MBEDTLS_ECP_PF_UNCOMPRESSED, &olen, kb + 8 + kb_len + 2, sizeof(kb) - 8 - kb_len - 2);
put_uint16_t((uint16_t)olen, kb + 8 + kb_len);
kb_len += 2 + (uint16_t)olen;
kb_len += put_uint16_t_be((uint16_t)olen, kb + 8 + kb_len);
kb_len += (uint16_t)olen;
put_uint16_t((uint16_t)mbedtls_mpi_size(&ecdsa->d), kb + 8 + kb_len); kb_len += 2;
kb_len += put_uint16_t_be((uint16_t)mbedtls_mpi_size(&ecdsa->d), kb + 8 + kb_len);
mbedtls_mpi_write_binary(&ecdsa->d, kb + 8 + kb_len, mbedtls_mpi_size(&ecdsa->d));
kb_len += (uint16_t)mbedtls_mpi_size(&ecdsa->d);
mbedtls_ecp_point_write_binary(&ecdsa->grp, &ecdsa->Q, MBEDTLS_ECP_PF_UNCOMPRESSED, &olen, kb + 8 + kb_len + 2, sizeof(kb) - 8 - kb_len - 2);
put_uint16_t((uint16_t)olen, kb + 8 + kb_len);
kb_len += 2 + (uint16_t)olen;
kb_len += put_uint16_t_be((uint16_t)olen, kb + 8 + kb_len);
kb_len += (uint16_t)olen;
algo = (uint8_t *) "\x00\x0A\x04\x00\x7F\x00\x07\x02\x02\x02\x02\x03";
algo_len = 12;
@@ -409,7 +421,7 @@ int dkek_encode_key(uint8_t id, void *key_ctx, int key_type, uint8_t *out, uint1
}
if (allowed && allowed_len > 0) {
put_uint16_t(allowed_len, out + *out_len); *out_len += 2;
*out_len += put_uint16_t_be(allowed_len, out + *out_len);
memcpy(out + *out_len, allowed, allowed_len);
*out_len += allowed_len;
}
@@ -517,21 +529,21 @@ int dkek_decode_key(uint8_t id, void *key_ctx, const uint8_t *in, uint16_t in_le
uint16_t ofs = 9;
//OID
uint16_t len = get_uint16_t(in, ofs);
uint16_t len = get_uint16_t_be(in + ofs);
ofs += len + 2;
//Allowed algorithms
len = get_uint16_t(in, ofs);
len = get_uint16_t_be(in + ofs);
*allowed = (uint8_t *) (in + ofs + 2);
*allowed_len = len;
ofs += len + 2;
//Access conditions
len = get_uint16_t(in, ofs);
len = get_uint16_t_be(in + ofs);
ofs += len + 2;
//Key OID
len = get_uint16_t(in, ofs);
len = get_uint16_t_be(in + ofs);
ofs += len + 2;
if ((in_len - 16 - ofs) % 16 != 0) {
@@ -545,7 +557,7 @@ int dkek_decode_key(uint8_t id, void *key_ctx, const uint8_t *in, uint16_t in_le
return r;
}
int key_size = get_uint16_t(kb, 8);
int key_size = get_uint16_t_be(kb + 8);
if (key_size_out) {
*key_size_out = key_size;
}
@@ -554,14 +566,14 @@ int dkek_decode_key(uint8_t id, void *key_ctx, const uint8_t *in, uint16_t in_le
mbedtls_rsa_context *rsa = (mbedtls_rsa_context *) key_ctx;
mbedtls_rsa_init(rsa);
if (key_type == 5) {
len = get_uint16_t(kb, ofs); ofs += 2;
len = get_uint16_t_be(kb + ofs); ofs += 2;
r = mbedtls_mpi_read_binary(&rsa->D, kb + ofs, len); ofs += len;
if (r != 0) {
mbedtls_rsa_free(rsa);
return PICOKEY_WRONG_DATA;
}
len = get_uint16_t(kb, ofs); ofs += 2;
len = get_uint16_t_be(kb + ofs); ofs += 2;
r = mbedtls_mpi_read_binary(&rsa->N, kb + ofs, len); ofs += len;
if (r != 0) {
mbedtls_rsa_free(rsa);
@@ -570,12 +582,12 @@ int dkek_decode_key(uint8_t id, void *key_ctx, const uint8_t *in, uint16_t in_le
}
else if (key_type == 6) {
//DP-1
len = get_uint16_t(kb, ofs); ofs += len + 2;
len = get_uint16_t_be(kb + ofs); ofs += len + 2;
//DQ-1
len = get_uint16_t(kb, ofs); ofs += len + 2;
len = get_uint16_t_be(kb + ofs); ofs += len + 2;
len = get_uint16_t(kb, ofs); ofs += 2;
len = get_uint16_t_be(kb + ofs); ofs += 2;
r = mbedtls_mpi_read_binary(&rsa->P, kb + ofs, len); ofs += len;
if (r != 0) {
mbedtls_rsa_free(rsa);
@@ -583,19 +595,19 @@ int dkek_decode_key(uint8_t id, void *key_ctx, const uint8_t *in, uint16_t in_le
}
//PQ
len = get_uint16_t(kb, ofs); ofs += len + 2;
len = get_uint16_t_be(kb + ofs); ofs += len + 2;
len = get_uint16_t(kb, ofs); ofs += 2;
len = get_uint16_t_be(kb + ofs); ofs += 2;
r = mbedtls_mpi_read_binary(&rsa->Q, kb + ofs, len); ofs += len;
if (r != 0) {
mbedtls_rsa_free(rsa);
return PICOKEY_WRONG_DATA;
}
//N
len = get_uint16_t(kb, ofs); ofs += len + 2;
len = get_uint16_t_be(kb + ofs); ofs += len + 2;
}
len = get_uint16_t(kb, ofs); ofs += 2;
len = get_uint16_t_be(kb + ofs); ofs += 2;
r = mbedtls_mpi_read_binary(&rsa->E, kb + ofs, len); ofs += len;
if (r != 0) {
mbedtls_rsa_free(rsa);
@@ -633,13 +645,13 @@ int dkek_decode_key(uint8_t id, void *key_ctx, const uint8_t *in, uint16_t in_le
mbedtls_ecdsa_init(ecdsa);
//A
len = get_uint16_t(kb, ofs); ofs += len + 2;
len = get_uint16_t_be(kb + ofs); ofs += len + 2;
//B
len = get_uint16_t(kb, ofs); ofs += len + 2;
len = get_uint16_t_be(kb + ofs); ofs += len + 2;
//P
len = get_uint16_t(kb, ofs); ofs += 2;
len = get_uint16_t_be(kb + ofs); ofs += 2;
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);
@@ -648,10 +660,10 @@ int dkek_decode_key(uint8_t id, void *key_ctx, const uint8_t *in, uint16_t in_le
ofs += len;
//N
len = get_uint16_t(kb, ofs); ofs += len + 2;
len = get_uint16_t_be(kb + ofs); ofs += len + 2;
//G
len = get_uint16_t(kb, ofs);
len = get_uint16_t_be(kb + ofs);
if (ec_id == MBEDTLS_ECP_DP_CURVE25519 && kb[ofs + 2] != 0x09) {
ec_id = MBEDTLS_ECP_DP_ED25519;
}
@@ -661,7 +673,7 @@ int dkek_decode_key(uint8_t id, void *key_ctx, const uint8_t *in, uint16_t in_le
ofs += len + 2;
//d
len = get_uint16_t(kb, ofs); ofs += 2;
len = get_uint16_t_be(kb + ofs); ofs += 2;
r = mbedtls_ecp_read_key(ec_id, ecdsa, kb + ofs, len);
if (r != 0) {
mbedtls_ecdsa_free(ecdsa);
@@ -670,7 +682,7 @@ int dkek_decode_key(uint8_t id, void *key_ctx, const uint8_t *in, uint16_t in_le
ofs += len;
//Q
len = get_uint16_t(kb, ofs); ofs += 2;
len = get_uint16_t_be(kb + ofs); ofs += 2;
r = mbedtls_ecp_point_read_binary(&ecdsa->grp, &ecdsa->Q, kb + ofs, len);
if (r != 0) {
if (mbedtls_ecp_get_type(&ecdsa->grp) == MBEDTLS_ECP_TYPE_EDWARDS) {