From d7aa4feae80034810697672eb22a4a49a91e7140 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Fri, 6 Aug 2021 19:46:49 +0300 Subject: [PATCH] iso select rework --- client/src/mifare/desfirecore.c | 93 ++++++++++++++++++++++++++++++++- client/src/mifare/desfirecore.h | 14 +++++ 2 files changed, 105 insertions(+), 2 deletions(-) diff --git a/client/src/mifare/desfirecore.c b/client/src/mifare/desfirecore.c index 17a7e0197..54b486642 100644 --- a/client/src/mifare/desfirecore.c +++ b/client/src/mifare/desfirecore.c @@ -263,6 +263,10 @@ const char *DesfireAuthErrorToStr(int error) { return "Can't select application."; case 201: return "Authentication retured no error but channel not authenticated."; + case 202: + return "Can't select application by ISO ID."; + case 203: + return "Can't select file by ISO ID."; case 301: return "ISO Get challenge error."; case 302: @@ -886,6 +890,62 @@ int DesfireSelectAndAuthenticate(DesfireContext *dctx, DesfireSecureChannel secu return DesfireSelectAndAuthenticateEx(dctx, secureChannel, aid, false, verbose); } +int DesfireSelectAndAuthenticateISO(DesfireContext *dctx, DesfireSecureChannel secureChannel, bool useaid, uint32_t aid, uint16_t isoappid, uint16_t isofileid, bool noauth, bool verbose) { + if (verbose) + DesfirePrintContext(dctx); + + int res = 0; + if (useaid) { + dctx->cmdSet = DCCNativeISO; + if (verbose) + PrintAndLogEx(INFO, "Select via " _CYAN_("native iso wrapping") " interface"); + + res = DesfireSelectAIDHex(dctx, aid, false, 0); + if (res != PM3_SUCCESS) { + PrintAndLogEx(ERR, "Desfire select " _RED_("error") "."); + return 200; + } + if (verbose) + PrintAndLogEx(INFO, "App %06x via native iso channel is " _GREEN_("selected"), aid); + + dctx->cmdSet = DCCISO; + } else { + res = DesfireSelectEx(dctx, true, ISWIsoID, isoappid, NULL); + if (res != PM3_SUCCESS) { + PrintAndLogEx(ERR, "Desfire iso application select " _RED_("error") "."); + return 202; + } + if (verbose) + PrintAndLogEx(INFO, "Application iso id %04x is " _GREEN_("selected"), isoappid); + + res = DesfireSelectEx(dctx, false, ISWIsoID, isofileid, NULL); + if (res != PM3_SUCCESS) { + PrintAndLogEx(ERR, "Desfire iso file select " _RED_("error") "."); + return 203; + } + + if (verbose) + PrintAndLogEx(INFO, "Application iso id %04x file iso id %04x is " _GREEN_("selected"), isoappid, isofileid); + } + + if (!noauth) { + res = DesfireAuthenticate(dctx, secureChannel, verbose); + if (res != PM3_SUCCESS) { + PrintAndLogEx(ERR, "Desfire authenticate " _RED_("error") ". Result: [%d] %s", res, DesfireAuthErrorToStr(res)); + return res; + } + + if (DesfireIsAuthenticated(dctx)) { + if (verbose) + PrintAndLogEx(INFO, "Desfire " _GREEN_("authenticated")); + } else { + return 201; + } + } + + return PM3_SUCCESS; +} + static int DesfireAuthenticateEV1(DesfireContext *dctx, DesfireSecureChannel secureChannel, bool verbose) { // 3 different way to authenticate AUTH (CRC16) , AUTH_ISO (CRC32) , AUTH_AES (CRC32) // 4 different crypto arg1 DES, 3DES, 3K3DES, AES @@ -2566,11 +2626,11 @@ int DesfireSetConfiguration(DesfireContext *dctx, uint8_t paramid, uint8_t *para return res; } -int DesfireISOSelect(DesfireContext *dctx, DesfireISOSelectControl cntr, uint8_t *data, uint8_t datalen, uint8_t *resp, size_t *resplen) { +int DesfireISOSelectEx(DesfireContext *dctx, bool fieldon, DesfireISOSelectControl cntr, uint8_t *data, uint8_t datalen, uint8_t *resp, size_t *resplen) { uint8_t xresp[250] = {0}; size_t xresplen = 0; uint16_t sw = 0; - int res = DesfireExchangeISO(true, dctx, (sAPDU) {0x00, ISO7816_SELECT_FILE, cntr, ((resp == NULL) ? 0x0C : 0x00), datalen, data}, APDU_INCLUDE_LE_00, xresp, &xresplen, &sw); + int res = DesfireExchangeISO(fieldon, dctx, (sAPDU) {0x00, ISO7816_SELECT_FILE, cntr, ((resp == NULL) ? 0x0C : 0x00), datalen, data}, APDU_INCLUDE_LE_00, xresp, &xresplen, &sw); if (res == PM3_SUCCESS && sw != 0x9000) return PM3_ESOFT; @@ -2585,6 +2645,10 @@ int DesfireISOSelect(DesfireContext *dctx, DesfireISOSelectControl cntr, uint8_t return res; } +int DesfireISOSelect(DesfireContext *dctx, DesfireISOSelectControl cntr, uint8_t *data, uint8_t datalen, uint8_t *resp, size_t *resplen) { + return DesfireISOSelectEx(dctx, true, cntr, data, datalen, resp, resplen); +} + int DesfireISOSelectDF(DesfireContext *dctx, char *dfname, uint8_t *resp, size_t *resplen) { return DesfireISOSelect(dctx, ISSDFName, (uint8_t *)dfname, strnlen(dfname, 16), resp, resplen); } @@ -2685,3 +2749,28 @@ int DesfireISOAppendRecord(DesfireContext *dctx, uint8_t fileid, uint8_t *data, return res; } + +int DesfireSelectEx(DesfireContext *ctx, bool fieldon, DesfireISOSelectWay way, uint32_t id, char *dfname) { + uint8_t resp[250] = {0}; + size_t resplen = 0; + + if (way == ISWMF || (way == ISWDFName && dfname == NULL)) { + return DesfireISOSelect(ctx, ISSMFDFEF, NULL, 0, resp, &resplen); + } else if (way == ISW6bAID) { + if (fieldon) + return DesfireSelectAIDHex(ctx, id, false, 0); + else + return DesfireSelectAIDHexNoFieldOn(ctx, id); + } else if (way == ISWIsoID) { + uint8_t data[2] = {0}; + Uint2byteToMemBe(data, id); + return DesfireISOSelectEx(ctx, fieldon, ISSMFDFEF, data, 2, resp, &resplen); + } else if (way == ISWDFName) { + return DesfireISOSelect(ctx, ISSMFDFEF, NULL, 0, resp, &resplen); + } + return PM3_ESOFT; +} + +int DesfireSelect(DesfireContext *ctx, DesfireISOSelectWay way, uint32_t id, char *dfname) { + return DesfireSelectEx(ctx, true, way, id, dfname); +} diff --git a/client/src/mifare/desfirecore.h b/client/src/mifare/desfirecore.h index 83af91767..a03e489eb 100644 --- a/client/src/mifare/desfirecore.h +++ b/client/src/mifare/desfirecore.h @@ -30,6 +30,14 @@ enum DesfireISOSelectControlEnum { }; typedef enum DesfireISOSelectControlEnum DesfireISOSelectControl; +enum DesfireISOSelectWayEnum { + ISW6bAID, + ISWMF, + ISWIsoID, + ISWDFName +}; +typedef enum DesfireISOSelectWayEnum DesfireISOSelectWay; + typedef struct { const uint8_t id; const char *text; @@ -160,9 +168,13 @@ int DesfireSelectAIDHex(DesfireContext *ctx, uint32_t aid1, bool select_two, uin int DesfireSelectAIDHexNoFieldOn(DesfireContext *ctx, uint32_t aid); void DesfirePrintAIDFunctions(uint32_t appid); +int DesfireSelectEx(DesfireContext *ctx, bool fieldon, DesfireISOSelectWay way, uint32_t id, char *dfname); +int DesfireSelect(DesfireContext *ctx, DesfireISOSelectWay way, uint32_t id, char *dfname); + const char *DesfireAuthErrorToStr(int error); int DesfireSelectAndAuthenticate(DesfireContext *dctx, DesfireSecureChannel secureChannel, uint32_t aid, bool verbose); int DesfireSelectAndAuthenticateEx(DesfireContext *dctx, DesfireSecureChannel secureChannel, uint32_t aid, bool noauth, bool verbose); +int DesfireSelectAndAuthenticateISO(DesfireContext *dctx, DesfireSecureChannel secureChannel, bool useaid, uint32_t aid, uint16_t isoappid, uint16_t isofileid, bool noauth, bool verbose); int DesfireAuthenticate(DesfireContext *dctx, DesfireSecureChannel secureChannel, bool verbose); void DesfireCheckAuthCommands(uint32_t appAID, char *dfname, uint8_t keyNum, AuthCommandsChk *authCmdCheck); void DesfireCheckAuthCommandsPrint(AuthCommandsChk *authCmdCheck); @@ -230,6 +242,8 @@ int DesfireUpdateRecord(DesfireContext *dctx, uint8_t fnum, uint32_t recnum, uin int DesfireISOSelectDF(DesfireContext *dctx, char *dfname, uint8_t *resp, size_t *resplen); int DesfireISOSelect(DesfireContext *dctx, DesfireISOSelectControl cntr, uint8_t *data, uint8_t datalen, uint8_t *resp, size_t *resplen); +int DesfireISOSelectFile(DesfireContext *dctx, char *appdfname, uint16_t appid, uint16_t fileid); +int DesfireISOSelectEx(DesfireContext *dctx, bool fieldon, DesfireISOSelectControl cntr, uint8_t *data, uint8_t datalen, uint8_t *resp, size_t *resplen); int DesfireISOGetChallenge(DesfireContext *dctx, DesfireCryptoAlgorythm keytype, uint8_t *resp, size_t *resplen); int DesfireISOExternalAuth(DesfireContext *dctx, bool app_level, uint8_t keynum, DesfireCryptoAlgorythm keytype, uint8_t *data); int DesfireISOInternalAuth(DesfireContext *dctx, bool app_level, uint8_t keynum, DesfireCryptoAlgorythm keytype, uint8_t *data, uint8_t *resp, size_t *resplen);