Add device public key recovery and upload attestation certification.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
parent
015fb61759
commit
7dc7be0909
1 changed files with 74 additions and 28 deletions
102
src/rescue.c
102
src/rescue.c
|
|
@ -75,39 +75,85 @@ int rescue_unload() {
|
|||
}
|
||||
|
||||
int cmd_keydev_sign() {
|
||||
if (apdu.nc == 0) {
|
||||
return SW_WRONG_LENGTH();
|
||||
}
|
||||
uint8_t hash[32];
|
||||
mbedtls_sha256(apdu.data, 16, hash, false);
|
||||
if (!otp_key_2) {
|
||||
return SW_INS_NOT_SUPPORTED();
|
||||
}
|
||||
mbedtls_ecdsa_context ecdsa;
|
||||
mbedtls_ecdsa_init(&ecdsa);
|
||||
int ret = mbedtls_ecp_read_key(MBEDTLS_ECP_DP_SECP256K1, &ecdsa, otp_key_2, 32);
|
||||
if (ret != 0) {
|
||||
mbedtls_ecdsa_free(&ecdsa);
|
||||
return SW_EXEC_ERROR();
|
||||
}
|
||||
uint16_t key_size = 2 * (int)((mbedtls_ecp_curve_info_from_grp_id(MBEDTLS_ECP_DP_SECP256K1)->bit_size + 7) / 8);
|
||||
mbedtls_mpi r, s;
|
||||
mbedtls_mpi_init(&r);
|
||||
mbedtls_mpi_init(&s);
|
||||
uint8_t p1 = P1(apdu);
|
||||
if (p1 == 0x01) {
|
||||
if (apdu.nc != 32) {
|
||||
return SW_WRONG_LENGTH();
|
||||
}
|
||||
if (!otp_key_2) {
|
||||
return SW_INS_NOT_SUPPORTED();
|
||||
}
|
||||
mbedtls_ecdsa_context ecdsa;
|
||||
mbedtls_ecdsa_init(&ecdsa);
|
||||
int ret = mbedtls_ecp_read_key(MBEDTLS_ECP_DP_SECP256K1, &ecdsa, otp_key_2, 32);
|
||||
if (ret != 0) {
|
||||
mbedtls_ecdsa_free(&ecdsa);
|
||||
return SW_EXEC_ERROR();
|
||||
}
|
||||
uint16_t key_size = 2 * (int)((mbedtls_ecp_curve_info_from_grp_id(MBEDTLS_ECP_DP_SECP256K1)->bit_size + 7) / 8);
|
||||
mbedtls_mpi r, s;
|
||||
mbedtls_mpi_init(&r);
|
||||
mbedtls_mpi_init(&s);
|
||||
|
||||
ret = mbedtls_ecdsa_sign(&ecdsa.MBEDTLS_PRIVATE(grp), &r, &s, &ecdsa.MBEDTLS_PRIVATE(d), hash, sizeof(hash), random_gen, NULL);
|
||||
if (ret != 0) {
|
||||
ret = mbedtls_ecdsa_sign(&ecdsa.MBEDTLS_PRIVATE(grp), &r, &s, &ecdsa.MBEDTLS_PRIVATE(d), apdu.data, apdu.nc, random_gen, NULL);
|
||||
if (ret != 0) {
|
||||
mbedtls_ecdsa_free(&ecdsa);
|
||||
mbedtls_mpi_free(&r);
|
||||
mbedtls_mpi_free(&s);
|
||||
return SW_EXEC_ERROR();
|
||||
}
|
||||
|
||||
mbedtls_mpi_write_binary(&r, res_APDU, key_size / 2); res_APDU_size = key_size / 2;
|
||||
mbedtls_mpi_write_binary(&s, res_APDU + res_APDU_size, key_size / 2); res_APDU_size += key_size / 2;
|
||||
mbedtls_ecdsa_free(&ecdsa);
|
||||
mbedtls_mpi_free(&r);
|
||||
mbedtls_mpi_free(&s);
|
||||
return SW_EXEC_ERROR();
|
||||
}
|
||||
|
||||
mbedtls_mpi_write_binary(&r, res_APDU, key_size / 2); res_APDU_size = key_size / 2;
|
||||
mbedtls_mpi_write_binary(&s, res_APDU + res_APDU_size, key_size / 2); res_APDU_size += key_size / 2;
|
||||
mbedtls_ecdsa_free(&ecdsa);
|
||||
mbedtls_mpi_free(&r);
|
||||
mbedtls_mpi_free(&s);
|
||||
else if (p1 == 0x02) {
|
||||
// Return public key
|
||||
if (!otp_key_2) {
|
||||
return SW_INS_NOT_SUPPORTED();
|
||||
}
|
||||
if (apdu.nc != 0) {
|
||||
return SW_WRONG_LENGTH();
|
||||
}
|
||||
mbedtls_ecp_keypair ecp;
|
||||
mbedtls_ecp_keypair_init(&ecp);
|
||||
int ret = mbedtls_ecp_read_key(MBEDTLS_ECP_DP_SECP256K1, &ecp, otp_key_2, 32);
|
||||
if (ret != 0) {
|
||||
mbedtls_ecp_keypair_free(&ecp);
|
||||
return SW_EXEC_ERROR();
|
||||
}
|
||||
ret = mbedtls_ecp_mul(&ecp.MBEDTLS_PRIVATE(grp), &ecp.MBEDTLS_PRIVATE(Q), &ecp.MBEDTLS_PRIVATE(d), &ecp.MBEDTLS_PRIVATE(grp).G, random_gen, NULL);
|
||||
if (ret != 0) {
|
||||
mbedtls_ecp_keypair_free(&ecp);
|
||||
return SW_EXEC_ERROR();
|
||||
}
|
||||
size_t olen = 0;
|
||||
ret = mbedtls_ecp_point_write_binary(&ecp.MBEDTLS_PRIVATE(grp), &ecp.MBEDTLS_PRIVATE(Q), MBEDTLS_ECP_PF_UNCOMPRESSED, &olen, res_APDU, 4096);
|
||||
if (ret != 0) {
|
||||
mbedtls_ecp_keypair_free(&ecp);
|
||||
return SW_EXEC_ERROR();
|
||||
}
|
||||
res_APDU_size = (uint16_t)olen;
|
||||
mbedtls_ecp_keypair_free(&ecp);
|
||||
}
|
||||
else if (p1 == 0x03) {
|
||||
// Upload device attestation certificate
|
||||
if (apdu.nc == 0) {
|
||||
return SW_WRONG_LENGTH();
|
||||
}
|
||||
file_t *ef_devcert = file_new(0x2F02); // EF_DEVCERT
|
||||
if (!ef_devcert) {
|
||||
return SW_FILE_NOT_FOUND();
|
||||
}
|
||||
file_put_data(ef_devcert, apdu.data, (uint16_t)apdu.nc);
|
||||
res_APDU_size = 0;
|
||||
low_flash_available();
|
||||
}
|
||||
else {
|
||||
return SW_INCORRECT_P1P2();
|
||||
}
|
||||
return SW_OK();
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue