From 7dc7be090919e7638616e93f21ff4c10c1373dec Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Mon, 15 Dec 2025 14:34:04 +0100 Subject: [PATCH] Add device public key recovery and upload attestation certification. Signed-off-by: Pol Henarejos --- src/rescue.c | 102 +++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 74 insertions(+), 28 deletions(-) diff --git a/src/rescue.c b/src/rescue.c index 44174f0..acba24c 100644 --- a/src/rescue.c +++ b/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(); }