From b5e420c11b7fd4322bcfcb27e0e578421999d1af Mon Sep 17 00:00:00 2001 From: Chris van Marle Date: Tue, 11 Oct 2022 22:13:31 +0200 Subject: [PATCH] MRTD handle BAC decrypt+unpad --- lib/nfc/protocols/mrtd.c | 43 ++++++++++++++++++-------------- lib/nfc/protocols/mrtd.h | 1 + lib/nfc/protocols/mrtd_helpers.c | 24 ++++++++++++++++-- 3 files changed, 47 insertions(+), 21 deletions(-) diff --git a/lib/nfc/protocols/mrtd.c b/lib/nfc/protocols/mrtd.c index 61ab50865..6b6f328d4 100644 --- a/lib/nfc/protocols/mrtd.c +++ b/lib/nfc/protocols/mrtd.c @@ -15,6 +15,8 @@ //- PACE (CONDITIONAL) //- BAC (CONDITIONAL) +//TODO: idea - generalize ISO7816 reading. List available apps + static void hexdump(FuriLogLevel level, char* prefix, void* data, size_t length) { if(furi_log_get_level() >= level) { printf("%s ", prefix); @@ -50,24 +52,24 @@ struct EFFormat EF = { .DIR = {.file_id = 0x2F00, .short_id = 0x1E }, .CardAccess = {.file_id = 0x011C, .short_id = 0x1C }, .CardSecurity = {.file_id = 0x011D, .short_id = 0x1D }, - .COM = {.file_id = 0x011E, .short_id = 0x1E }, - .SOD = {.file_id = 0X011D, .short_id = 0X1D }, - .DG1 = {.file_id = 0X0101, .short_id = 0X01 }, - .DG2 = {.file_id = 0X0102, .short_id = 0X02 }, - .DG3 = {.file_id = 0X0103, .short_id = 0X03 }, - .DG4 = {.file_id = 0X0104, .short_id = 0X04 }, - .DG5 = {.file_id = 0X0105, .short_id = 0X05 }, - .DG6 = {.file_id = 0X0106, .short_id = 0X06 }, - .DG7 = {.file_id = 0X0107, .short_id = 0X07 }, - .DG8 = {.file_id = 0X0108, .short_id = 0X08 }, - .DG9 = {.file_id = 0X0109, .short_id = 0X09 }, - .DG10 = {.file_id = 0X010A, .short_id = 0X0A }, - .DG11 = {.file_id = 0X010B, .short_id = 0X0B }, - .DG12 = {.file_id = 0X010C, .short_id = 0X0C }, - .DG13 = {.file_id = 0X010D, .short_id = 0X0D }, - .DG14 = {.file_id = 0X010E, .short_id = 0X0E }, - .DG15 = {.file_id = 0X010F, .short_id = 0X0F }, - .DG16 = {.file_id = 0X0110, .short_id = 0X10 }, + .COM = {.file_id = 0x011E, .short_id = 0x1E, .tag = 0x60 }, + .SOD = {.file_id = 0X011D, .short_id = 0X1D, .tag = 0x77 }, + .DG1 = {.file_id = 0X0101, .short_id = 0X01, .tag = 0x61 }, + .DG2 = {.file_id = 0X0102, .short_id = 0X02, .tag = 0x75 }, + .DG3 = {.file_id = 0X0103, .short_id = 0X03, .tag = 0x63 }, + .DG4 = {.file_id = 0X0104, .short_id = 0X04, .tag = 0x76 }, + .DG5 = {.file_id = 0X0105, .short_id = 0X05, .tag = 0x65 }, + .DG6 = {.file_id = 0X0106, .short_id = 0X06, .tag = 0x66 }, + .DG7 = {.file_id = 0X0107, .short_id = 0X07, .tag = 0x67 }, + .DG8 = {.file_id = 0X0108, .short_id = 0X08, .tag = 0x68 }, + .DG9 = {.file_id = 0X0109, .short_id = 0X09, .tag = 0x69 }, + .DG10 = {.file_id = 0X010A, .short_id = 0X0A, .tag = 0x6a }, + .DG11 = {.file_id = 0X010B, .short_id = 0X0B, .tag = 0x6b }, + .DG12 = {.file_id = 0X010C, .short_id = 0X0C, .tag = 0x6c }, + .DG13 = {.file_id = 0X010D, .short_id = 0X0D, .tag = 0x6d }, + .DG14 = {.file_id = 0X010E, .short_id = 0X0E, .tag = 0x6e }, + .DG15 = {.file_id = 0X010F, .short_id = 0X0F, .tag = 0x6f }, + .DG16 = {.file_id = 0X0110, .short_id = 0X10, .tag = 0x70 }, }; struct AIDSet AID = { @@ -198,8 +200,11 @@ size_t mrtd_read_binary(MrtdApplication* app, uint8_t* buffer, size_t bufsize, s UNUSED(bufsize); // 00 B0 offst - FURI_LOG_D(TAG, "Read binary, offset: %d", offset); + //TODO: read first 4 bytes, determine length, iterate through file //TODO: limit reading/buffer fill to max bufsize - if(!mrtd_send_apdu(app, 0x00, 0xB0, offset>>8, offset&0xff, 0x00, NULL, 0, buffer)) { + + int16_t max_read = 0; // 0 = 'everything', -1 = 'nothing' + if(!mrtd_send_apdu(app, 0x00, 0xB0, offset>>8, offset&0xff, 0x00, NULL, max_read, buffer)) { FURI_LOG_E(TAG, "Failed to read"); return 0; } diff --git a/lib/nfc/protocols/mrtd.h b/lib/nfc/protocols/mrtd.h index f207fd97f..eeef9ca4f 100644 --- a/lib/nfc/protocols/mrtd.h +++ b/lib/nfc/protocols/mrtd.h @@ -50,6 +50,7 @@ typedef struct { typedef struct { const uint8_t short_id; const uint16_t file_id; + const uint8_t tag; } EFFile; struct EFFormat { diff --git a/lib/nfc/protocols/mrtd_helpers.c b/lib/nfc/protocols/mrtd_helpers.c index 39a9029fd..9923555fd 100644 --- a/lib/nfc/protocols/mrtd_helpers.c +++ b/lib/nfc/protocols/mrtd_helpers.c @@ -177,14 +177,34 @@ bool mrtd_bac_decrypt_verify_sm(const uint8_t* data, size_t data_length, uint8_t // Message: [DO'85 or DO'87] || [DO'99] || DO'8E // Lengths: Var 1+1+2=4 1+1+8=10 - printf("ret_code: %02X %02X\n", data[data_length - 10 - 2], data[data_length - 10 - 2 + 1]); *ret_code = data[data_length - 10 - 2] <<8 | data[data_length - 10 - 1]; //ntohs(data + data_length - 10 - 2); - printf("set to: %04X\n", *ret_code); if(data[0] == 0x87) { uint8_t do87_length = data[1] - 1; mrtd_bac_decrypt(data + 3, do87_length, key_enc, output); + printf("Decrypted: "); for(uint8_t i=0; i=0; --padidx) { + if(output[padidx] == 0x00) { + continue; + } else if(output[padidx] == 0x80) { + break; + } else { + printf("Invalid padding\r\n"); + return false; + } + } + printf(" "); + for(int i=0; i