From d3d9b675446a942a4bc9eb5acc868f0600adf5fe Mon Sep 17 00:00:00 2001 From: Chris van Marle Date: Tue, 11 Oct 2022 22:13:38 +0200 Subject: [PATCH] MRTD remove some logs. Read DG1, try DG2 --- lib/nfc/nfc_worker.c | 26 +++------------------ lib/nfc/protocols/mrtd.c | 49 +++++++++++++++++----------------------- test_mrtd_helpers.c | 30 ++++++++++++++++-------- 3 files changed, 45 insertions(+), 60 deletions(-) diff --git a/lib/nfc/nfc_worker.c b/lib/nfc/nfc_worker.c index 44ee06e19..7efdda5da 100644 --- a/lib/nfc/nfc_worker.c +++ b/lib/nfc/nfc_worker.c @@ -280,34 +280,14 @@ static bool nfc_worker_read_mrtd(NfcWorker* nfc_worker, FuriHalNfcTxRxContext* t // Read passport if(!furi_hal_nfc_detect(&nfc_worker->dev_data->nfc_data, 300)) break; - if(!mrtd_select_app(mrtd_app, AID.eMRTDApplication)) break; + //TODO: if(!mrtd_select_app(mrtd_app, AID.eMRTDApplication)) break; - mrtd_test(mrtd_app, mrtd_data); + mrtd_test(mrtd_app, mrtd_data); // Some EFs are only available before Select App + //TODO: try select eMRTDApp first, but when PACE, read CardAccess first! //TODO: read general informatie //TODO: after auth scene, do auth (BAC / PACE) - /* - // Copy data - // TODO Set EmvData to reader or like in mifare ultralight! - result->number_len = emv_app.card_number_len; - memcpy(result->number, emv_app.card_number, result->number_len); - result->aid_len = emv_app.aid_len; - memcpy(result->aid, emv_app.aid, result->aid_len); - if(emv_app.name_found) { - memcpy(result->name, emv_app.name, sizeof(emv_app.name)); - } - if(emv_app.exp_month) { - result->exp_mon = emv_app.exp_month; - result->exp_year = emv_app.exp_year; - } - if(emv_app.country_code) { - result->country_code = emv_app.country_code; - } - if(emv_app.currency_code) { - result->currency_code = emv_app.currency_code; - } - */ read_success = true; } while(false); diff --git a/lib/nfc/protocols/mrtd.c b/lib/nfc/protocols/mrtd.c index c68d9b7c6..1e57c0639 100644 --- a/lib/nfc/protocols/mrtd.c +++ b/lib/nfc/protocols/mrtd.c @@ -55,16 +55,11 @@ bool mrtd_send_apdu(MrtdApplication* app, uint8_t cla, uint8_t ins, uint8_t p1, FuriHalNfcTxRxContext* tx_rx = app->tx_rx; size_t idx = 0; - FURI_LOG_D(TAG, "Send APDU, lc: %d, le: %d", lc, le); + FURI_LOG_T(TAG, "Send APDU, lc: %d, le: %d", lc, le); if(app->secure_messaging) { - FURI_LOG_D(TAG, "Protect APDU"); - app->ssc_long++; idx = mrtd_protect_apdu(cla, ins, p1, p2, lc, data, le, app->ksenc, app->ksmac, app->ssc_long, tx_rx->tx_data); - - FURI_LOG_D(TAG, "Protect APDU - done"); - } else { tx_rx->tx_data[idx++] = cla; tx_rx->tx_data[idx++] = ins; @@ -83,11 +78,9 @@ bool mrtd_send_apdu(MrtdApplication* app, uint8_t cla, uint8_t ins, uint8_t p1, tx_rx->tx_bits = idx * 8; tx_rx->tx_rx_type = FuriHalNfcTxRxTypeDefault; - FURI_LOG_D(TAG, "Sending..."); //TODO: timeout as param? if(furi_hal_nfc_tx_rx(tx_rx, 300)) { mrtd_trace(app); - FURI_LOG_D(TAG, "Sending - done"); uint16_t ret_code = mrtd_decode_response(tx_rx->rx_data, tx_rx->rx_bits / 8); if(app->secure_messaging && ret_code == 0x9000) { @@ -182,11 +175,12 @@ size_t mrtd_read_binary(MrtdApplication* app, uint8_t* buffer, size_t bufsize, s //TODO: test with max_read = bufsize (value !0, > file size) int16_t max_read = 0; // 0 = 'everything', -1 = 'nothing', >0 = amount of bytes - size_t buf_written; + size_t buf_written = 0; if(!mrtd_send_apdu(app, 0x00, 0xB0, offset>>8, offset&0xff, 0x00, NULL, max_read, buffer, &buf_written)) { FURI_LOG_E(TAG, "Failed to read"); return 0; } + FURI_LOG_D(TAG, "buf_written: %d\n", buf_written); return buf_written; } @@ -194,16 +188,21 @@ size_t mrtd_read_binary(MrtdApplication* app, uint8_t* buffer, size_t bufsize, s //TODO: use short id to read, because it's mandatory for eMRTD //TODO: check for support of extended length in EF.ATR/INFO, see ISO7816-4 -void mrtd_read_dump(MrtdApplication* app, EFFile file, const char* descr) { - FURI_LOG_D(TAG, "Read and dump %s:", descr); +void mrtd_read_dump(MrtdApplication* app, EFFile file) { + FURI_LOG_D(TAG, "Read and dump %s:", file.name); if(!mrtd_select_file(app, file)) { return; } + uint8_t data[2048]; size_t read = 0; + size_t offset = 0; do { - read = mrtd_read_binary(app, data + read, sizeof(data) - read, read); + read = mrtd_read_binary(app, data, sizeof(data), offset); + offset += read; + + hexdump(FuriLogLevelDebug, "Data:", data, read); } while(read > 0); } @@ -322,24 +321,15 @@ bool mrtd_read_parse_file(MrtdApplication* app, MrtdData* mrtd_data, EFFile file //TODO: remove testing function void mrtd_test(MrtdApplication* app, MrtdData* mrtd_data) { - //FuriHalNfcTxRxContext* tx_rx = app->tx_rx; - FURI_LOG_D(TAG, "Mrtd Test"); - mrtd_read_dump(app, EF.ATR, "EF.ATR"); - mrtd_read_dump(app, EF.COM, "EF.COM"); - mrtd_read_dump(app, EF.DIR, "EF.DIR"); - mrtd_read_dump(app, EF.CardAccess, "EF.CardAccess"); - mrtd_read_dump(app, EF.CardSecurity, "EF.CardSecurity"); + mrtd_read_dump(app, EF.ATR); + mrtd_read_dump(app, EF.COM); + mrtd_read_dump(app, EF.DIR); + mrtd_read_dump(app, EF.CardAccess); + mrtd_read_dump(app, EF.CardSecurity); mrtd_select_app(app, AID.eMRTDApplication); - //TODO: remove details - /* - mrtd_data->auth.birth_date = (MrtdDate){.year=69, .month=8, .day=6}; - mrtd_data->auth.expiry_date = (MrtdDate){.year=94, .month=6, .day=23}; - memcpy(mrtd_data->auth.doc_number, "L898902C<", 9); - */ - MrtdAuthMethod method = mrtd_data->auth.method; mrtd_data->auth_success = false; FURI_LOG_D(TAG, "Auth method: %d", method); @@ -362,7 +352,10 @@ void mrtd_test(MrtdApplication* app, MrtdData* mrtd_data) { } mrtd_read_parse_file(app, mrtd_data, EF.COM); - mrtd_read_parse_file(app, mrtd_data, EF.DIR); + //mrtd_read_parse_file(app, mrtd_data, EF.DIR); + + mrtd_read_dump(app, EF.DG1); + mrtd_read_dump(app, EF.DG2); } MrtdApplication* mrtd_alloc_init(FuriHalNfcTxRxContext* tx_rx) { @@ -449,7 +442,7 @@ bool mrtd_bac(MrtdApplication* app, MrtdAuthData* auth) { uint8_t kseed[16]; for(uint8_t i=0; i<16; ++i) { kseed[i] = k_ifd[i] ^ kic[i]; - printf("seed %2d = %02X ^ %02X = %02X\r\n", i, k_ifd[i], kic[i], kseed[i]); + //printf("seed %2d = %02X ^ %02X = %02X\r\n", i, k_ifd[i], kic[i], kseed[i]); } hexdump(FuriLogLevelDebug, "kseed:", kseed, 16); diff --git a/test_mrtd_helpers.c b/test_mrtd_helpers.c index 2449bb2a2..e0a41aa86 100644 --- a/test_mrtd_helpers.c +++ b/test_mrtd_helpers.c @@ -450,7 +450,6 @@ int main(int argc, char** argv) { // Verify working against mrtdreader - /* printf("=====================================\n\n"); //TODO: set auth data @@ -468,9 +467,9 @@ int main(int argc, char** argv) { uint8_t buffer[32]; // RND.IC || RND.IFD || KIC //TODO: set challenge rx - mrtd_bac_decrypt_verify((uint8_t*)"\x3F\xD4\x6B\xA9\xFF\x29\x4B\xF6\x77\x4E\x8F\x1E\xEC\xAE\x2E\x67\xDB\xE7\x70\x53\xB3\xAD\x9C\xDC\xED\x6E\xED\xD6\x04\x2E\xB7\x6B\x74\xDE\x2A\xFB\x4B\xC0\xF7\x24", 40, kenc, kmac, buffer); + mrtd_bac_decrypt_verify((uint8_t*)"\x11\x0e\x51\x83\xbe\x78\x94\xcf\x43\x40\x8e\xea\xfe\x99\x54\xbb\x17\x97\x27\x65\xf8\xb4\x51\xa4\x94\x0d\xb2\x5b\xad\x1b\xe3\x64\x16\x53\x2a\xff\xad\xee\x29\xcf", 40, kenc, kmac, buffer); //TODO: set kifd - uint8_t *kifd = "\x9F\x10\x40\xEA\x7F\xAE\xF8\xC3\x09\x6E\xAE\x07\x66\x95\x3F\xDC"; + uint8_t *kifd = (uint8_t*)"\xe0\x01\xf4\x4c\x09\xb1\xb3\x16\x63\xab\x3a\x11\x8d\xa3\x17\xcc"; printf("buffer: "); print_hex(buffer, 32); printf("\n"); // 8F763C0B1CDF9F9D|0983F7C136155248|7A705FD193C6A6328C42264A3804002C @@ -492,16 +491,29 @@ int main(int argc, char** argv) { printf("ks_enc: "); print_hex(ks_enc, 16); printf("\n"); printf("ks_mac: "); print_hex(ks_mac, 16); printf("\n"); - printf("rnd_ic: "); print_hex(rnd_ic, 16); printf("\n"); - printf("rnd_ifd: "); print_hex(rnd_ifd, 16); printf("\n"); - uint64_t ssc = mrtd_ssc_from_data(rnd_ic, rnd_ifd); - printf("ssc: %016lx", ssc); + printf("rnd_ic: "); print_hex(rnd_ic, 8); printf("\n"); + printf("rnd_ifd: "); print_hex(rnd_ifd, 8); printf("\n"); + ssc = mrtd_ssc_from_data(rnd_ic, rnd_ifd); + printf("ssc: %016lx\n", ssc); ssc++; + ssc+=6; + + //test_mrtd_protect_ + //TODO: set challenge TX for verification - test_mrtd_protect_apdu(0x00, 0xA4, 0x02, 0x0C, 0x02, "\x01\x1e", -1, ks_enc, ks_mac, ssc, - (uint8_t*)"\x0C\xA4\x02\x0C\x15\x87\x09\x01\xC5\x4E\x76\x3A\xD1\x89\xF0\xFA\x8E\x08\x1F\x03\xC2\xB6\xCE\x8A\xE1\x53\x00", 27); + test_mrtd_protect_apdu(0x00, 0xA4, 0x02, 0x0C, 0x02, "\x01\x01", -1, ks_enc, ks_mac, ssc, + (uint8_t*)"\x0c\xa4\x02\x0c\x15\x87\x09\x01\xc8\xcc\x50\x6f\x50\xae\x10\xc7\x8e\x08\xaf\xec\x2e\x03\x90\x26\x8f\xa5\x00", 27); + + /* + uint8_t* select_ef_com = "\x0C\xA4\x02\x0C\x15\x87\x09\x01\xE2\x94\xA2\x9A\xF3\x73\xFD\x20\x8E\x08\x7E\x3B\xA9\xAA\x7C\xB9\x07\x0C\x00"; + uint8_t* select_ef_dg1 = "\x0C\xA4\x02\x0C\x15\x87\x09\x01\x9C\xD7\x89\x94\x97\x05\xB8\xF3\x8E\x08\x6C\xA2\xC1\x48\xA7\x47\xBA\x96\x00"; + uint8_t buffer2[256]; + + mrtd_bac_decrypt(select_ef_dg1 + 8, 8, ks_enc, buffer2); + printf("Decrypted: "); + print_hex(buffer2, 8); */ return 0;