MRTD decrypt RX APDU

This commit is contained in:
Chris van Marle
2022-10-11 22:13:29 +02:00
parent eaeb887d6f
commit 374f2acb62
3 changed files with 19 additions and 46 deletions

View File

@@ -77,28 +77,9 @@ struct AIDSet AID = {
.AdditionalBiometrics = {0xA0, 0x00, 0x00, 0x02, 0x47, 0x20, 0x03}, .AdditionalBiometrics = {0xA0, 0x00, 0x00, 0x02, 0x47, 0x20, 0x03},
}; };
/*bool mrtd_send_apdu(MrtdApplication* app, uint8_t* buffer, size_t length) {
FuriHalNfcTxRxContext* tx_rx = app->tx_rx;
memcpy(tx_rx->tx_data, buffer, length); //TODO: rename to transceive?
tx_rx->tx_bits = length * 8; bool mrtd_send_apdu(MrtdApplication* app, uint8_t cla, uint8_t ins, uint8_t p1, uint8_t p2, uint8_t lc, const void* data, int16_t le, uint8_t* output) {
tx_rx->tx_rx_type = FuriHalNfcTxRxTypeDefault;
//TODO: timeout as param?
if(furi_hal_nfc_tx_rx(tx_rx, 300)) {
mrtd_trace(app);
uint16_t ret_code = mrtd_decode_response(tx_rx->rx_data, tx_rx->rx_bits / 8);
if(ret_code == 0x9000) {
return true;
} else {
FURI_LOG_E(TAG, "APDU answer is not 0x9000, but 0x%04X", ret_code);
return false;
}
}
return false;
}*/
bool mrtd_send_apdu(MrtdApplication* app, uint8_t cla, uint8_t ins, uint8_t p1, uint8_t p2, uint8_t lc, const void* data, int16_t le) {
FuriHalNfcTxRxContext* tx_rx = app->tx_rx; FuriHalNfcTxRxContext* tx_rx = app->tx_rx;
size_t idx = 0; size_t idx = 0;
@@ -133,16 +114,18 @@ bool mrtd_send_apdu(MrtdApplication* app, uint8_t cla, uint8_t ins, uint8_t p1,
mrtd_trace(app); mrtd_trace(app);
uint16_t ret_code = mrtd_decode_response(tx_rx->rx_data, tx_rx->rx_bits / 8); uint16_t ret_code = mrtd_decode_response(tx_rx->rx_data, tx_rx->rx_bits / 8);
if(app->secure_messaging && ret_code == 0x9000) {
app->ssc_long++;
mrtd_bac_decrypt_verify_sm(tx_rx->rx_data, tx_rx->rx_bits / 8 - 2,
app->ksenc, app->ksmac, app->ssc_long, output, &ret_code);
}
//TODO: handle other return codes? //TODO: handle other return codes?
if(ret_code == 0x9000) { if(ret_code == 0x9000) {
if(!app->secure_messaging && le > 0) {
if(app->secure_messaging) { // Secure Messaging sets output while decrypting
//TODO: decrypt and verify memcpy(output, tx_rx->rx_data, le);
app->ssc_long++;
mrtd_bac_decrypt_verify
} }
return true; return true;
} else { } else {
FURI_LOG_I(TAG, "APDU answer is not 0x9000, but 0x%04X", ret_code); FURI_LOG_I(TAG, "APDU answer is not 0x9000, but 0x%04X", ret_code);
@@ -168,7 +151,7 @@ bool mrtd_send_apdu(MrtdApplication* app, uint8_t cla, uint8_t ins, uint8_t p1,
bool mrtd_select_app(MrtdApplication* app, AIDValue aid) { bool mrtd_select_app(MrtdApplication* app, AIDValue aid) {
FURI_LOG_D(TAG, "Send select App: %02X %02X %02X %02X %02X %02X %02X", FURI_LOG_D(TAG, "Send select App: %02X %02X %02X %02X %02X %02X %02X",
aid[0], aid[1], aid[2], aid[3], aid[4], aid[5], aid[6]); aid[0], aid[1], aid[2], aid[3], aid[4], aid[5], aid[6]);
if(!mrtd_send_apdu(app, 0x00, 0xA4, 0x04, 0x0C, 0x07, aid, -1)) { if(!mrtd_send_apdu(app, 0x00, 0xA4, 0x04, 0x0C, 0x07, aid, -1, NULL)) {
FURI_LOG_W(TAG, "Failed select App"); FURI_LOG_W(TAG, "Failed select App");
return false; return false;
} }
@@ -177,14 +160,11 @@ bool mrtd_select_app(MrtdApplication* app, AIDValue aid) {
bool mrtd_get_challenge(MrtdApplication* app, uint8_t challenge[8]) { bool mrtd_get_challenge(MrtdApplication* app, uint8_t challenge[8]) {
FURI_LOG_D(TAG, "Send Get Challenge"); FURI_LOG_D(TAG, "Send Get Challenge");
if(!mrtd_send_apdu(app, 0x00, 0x84, 0x00, 0x00, 0x00, NULL, 0x08)) { if(!mrtd_send_apdu(app, 0x00, 0x84, 0x00, 0x00, 0x00, NULL, 0x08, challenge)) {
FURI_LOG_W(TAG, "Failed get challenge"); FURI_LOG_W(TAG, "Failed get challenge");
return false; return false;
} }
FuriHalNfcTxRxContext* tx_rx = app->tx_rx;
memcpy(challenge, tx_rx->rx_data, 8);
return true; return true;
} }
@@ -193,21 +173,18 @@ bool mrtd_external_authenticate(MrtdApplication* app, uint8_t* cmd_data, size_t
furi_assert(out_size >= 0x28); furi_assert(out_size >= 0x28);
FURI_LOG_D(TAG, "Send External Authenticate"); FURI_LOG_D(TAG, "Send External Authenticate");
if(!mrtd_send_apdu(app, 0x00, 0x82, 0x00, 0x00, cmd_size, cmd_data, 0x28)) { if(!mrtd_send_apdu(app, 0x00, 0x82, 0x00, 0x00, cmd_size, cmd_data, 0x28, out_data)) {
FURI_LOG_W(TAG, "Failed External Authenticate"); FURI_LOG_W(TAG, "Failed External Authenticate");
return false; return false;
} }
FuriHalNfcTxRxContext* tx_rx = app->tx_rx;
memcpy(out_data, tx_rx->rx_data, 0x28);
return true; return true;
} }
bool mrtd_select_file(MrtdApplication* app, EFFile file) { bool mrtd_select_file(MrtdApplication* app, EFFile file) {
uint8_t data[] = {file.file_id >> 8, file.file_id & 0xff}; uint8_t data[] = {file.file_id >> 8, file.file_id & 0xff};
FURI_LOG_D(TAG, "Send select EF: 0x%04X", file.file_id); FURI_LOG_D(TAG, "Send select EF: 0x%04X", file.file_id);
if(!mrtd_send_apdu(app, 0x00, 0xA4, 0x02, 0x0C, 0x02, data, -1)) { if(!mrtd_send_apdu(app, 0x00, 0xA4, 0x02, 0x0C, 0x02, data, -1, NULL)) {
FURI_LOG_E(TAG, "Failed select EF 0x%04X", file.file_id); FURI_LOG_E(TAG, "Failed select EF 0x%04X", file.file_id);
return false; return false;
} }
@@ -221,12 +198,12 @@ size_t mrtd_read_binary(MrtdApplication* app, uint8_t* buffer, size_t bufsize, s
UNUSED(bufsize); UNUSED(bufsize);
// 00 B0 offst - // 00 B0 offst -
FURI_LOG_D(TAG, "Read binary, offset: %d", offset); FURI_LOG_D(TAG, "Read binary, offset: %d", offset);
if(!mrtd_send_apdu(app, 0x00, 0xB0, offset>>8, offset&0xff, 0x00, NULL, 0)) { //TODO: limit reading/buffer fill to max bufsize
if(!mrtd_send_apdu(app, 0x00, 0xB0, offset>>8, offset&0xff, 0x00, NULL, 0, buffer)) {
FURI_LOG_E(TAG, "Failed to read"); FURI_LOG_E(TAG, "Failed to read");
return 0; return 0;
} }
//TODO: copy data to buffer
//TODO: return read amount //TODO: return read amount
return 0; return 0;

View File

@@ -146,12 +146,6 @@ bool mrtd_bac_encrypt(const uint8_t* data, size_t data_length, uint8_t* key, uin
bool mrtd_bac_decrypt(const uint8_t* data, size_t data_length, uint8_t* key, uint8_t* output) { bool mrtd_bac_decrypt(const uint8_t* data, size_t data_length, uint8_t* key, uint8_t* output) {
uint8_t IV[8] = "\x00\x00\x00\x00\x00\x00\x00\x00"; uint8_t IV[8] = "\x00\x00\x00\x00\x00\x00\x00\x00";
printf("Decrypt: ");
for(uint8_t i=0; i<data_length; ++i) {
printf("%02X ", data[i]);
}
printf("\n");
mbedtls_des3_context ctx; mbedtls_des3_context ctx;
mbedtls_des3_init(&ctx); mbedtls_des3_init(&ctx);
mbedtls_des3_set2key_dec(&ctx, key); mbedtls_des3_set2key_dec(&ctx, key);

View File

@@ -71,6 +71,8 @@ bool mrtd_bac_decrypt(const uint8_t* data, size_t data_length, uint8_t* key, uin
bool mrtd_bac_decrypt_verify(const uint8_t* data, size_t data_length, uint8_t* key_enc, uint8_t* key_mac, uint8_t* output); bool mrtd_bac_decrypt_verify(const uint8_t* data, size_t data_length, uint8_t* key_enc, uint8_t* key_mac, uint8_t* output);
bool mrtd_bac_decrypt_verify_sm(const uint8_t* data, size_t data_length, uint8_t* key_enc, uint8_t* key_mac, uint64_t ssc, uint8_t* output, uint16_t* ret_code);
#include <machine/_endian.h> #include <machine/_endian.h>
#define htonll(x) ((((uint64_t)__htonl(x)) << 32) + __htonl((x) >> 32)) #define htonll(x) ((((uint64_t)__htonl(x)) << 32) + __htonl((x) >> 32))