From 08469f940af422e07da60e03fbe7bd4f9dff3c62 Mon Sep 17 00:00:00 2001 From: Bjoern Kerler Date: Fri, 10 Apr 2020 22:52:16 +0200 Subject: [PATCH] Replace MIX and OLD Commands --- armsrc/appmain.c | 2 +- armsrc/mifaredesfire.c | 88 ++++++++++++++++++++++++++++-------------- armsrc/mifaredesfire.h | 2 +- client/cmdhfmfdes.c | 43 +++++++++++---------- 4 files changed, 82 insertions(+), 53 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 15eb40f26..b44dbc5c5 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1287,7 +1287,7 @@ static void PacketReceived(PacketCommandNG *packet) { break; } case CMD_HF_DESFIRE_COMMAND: { - MifareSendCommand(packet->oldarg[0], packet->oldarg[1], packet->data.asBytes); + MifareSendCommand(packet->data.asBytes); break; } case CMD_HF_MIFARE_NACK_DETECT: { diff --git a/armsrc/mifaredesfire.c b/armsrc/mifaredesfire.c index 815c301ac..eddff857a 100644 --- a/armsrc/mifaredesfire.c +++ b/armsrc/mifaredesfire.c @@ -52,29 +52,33 @@ bool InitDesfireCard() { return true; } -void MifareSendCommand(uint8_t arg0, uint8_t arg1, uint8_t *datain) { +void MifareSendCommand(uint8_t *datain) { + struct p { + uint8_t flags; + uint8_t datalen; + uint8_t datain[FRAME_PAYLOAD_SIZE]; + } PACKED; + struct p *payload = (struct p *) datain; - uint8_t flags = arg0; - size_t datalen = arg1; uint8_t resp[RECEIVE_SIZE]; memset(resp, 0, sizeof(resp)); if (DBGLEVEL >= DBG_EXTENDED) { - Dbprintf(" flags : %02X", flags); - Dbprintf(" len : %02X", datalen); - print_result(" RX : ", datain, datalen); + Dbprintf(" flags : %02X", payload->flags); + Dbprintf(" len : %02X", payload->datalen); + print_result(" RX : ", payload->datain, payload->datalen); } - if (flags & CLEARTRACE) + if (payload->flags & CLEARTRACE) clear_trace(); - if (flags & INIT) { + if (payload->flags & INIT) { if (!InitDesfireCard()) { return; } } - int len = DesfireAPDU(datain, datalen, resp); + int len = DesfireAPDU(payload->datain, payload->datalen, resp); if (DBGLEVEL >= DBG_EXTENDED) print_result("RESP <--: ", resp, len); @@ -83,10 +87,21 @@ void MifareSendCommand(uint8_t arg0, uint8_t arg1, uint8_t *datain) { return; } - if (flags & DISCONNECT) + if (payload->flags & DISCONNECT) OnSuccess(); - reply_mix(CMD_ACK, 1, len, 0, resp, len); + //reply_mix(CMD_ACK, 1, len, 0, resp, len); + LED_B_ON(); + struct r { + uint8_t len; + uint8_t data[RECEIVE_SIZE]; + } PACKED; + + struct r rpayload; + rpayload.len=len; + memcpy(rpayload.data,resp,rpayload.len); + reply_ng(CMD_HF_DESFIRE_COMMAND, PM3_SUCCESS, (uint8_t *)&rpayload, sizeof(payload)); + LED_B_OFF(); } void MifareDesfireGetInformation() { @@ -202,13 +217,11 @@ typedef enum { void MifareDES_Auth1(uint8_t *datain) { int len = 0; struct p { - uint8_t isOK; uint8_t mode; uint8_t algo; uint8_t keyno; uint8_t key[24]; uint8_t keylen; - uint8_t sessionkey[24]; } PACKED; struct p *payload = (struct p *) datain; @@ -275,13 +288,6 @@ void MifareDES_Auth1(uint8_t *datain) { if (payload->algo==MFDES_ALGO_AES) { mbedtls_aes_init(&ctx); - if (mbedtls_aes_setkey_dec(&ctx, key->data, 128) != 0) { - if (DBGLEVEL >= DBG_EXTENDED) { - DbpString("mbedtls_aes_setkey_dec failed"); - } - OnErrorNG(CMD_HF_DESFIRE_AUTH1,7); - return; - } Desfire_aes_key_new(keybytes, key); } else if (payload->algo == MFDES_ALGO_3DES) { @@ -342,8 +348,16 @@ void MifareDES_Auth1(uint8_t *datain) { } // Part 3 - if (payload->algo==MFDES_ALGO_AES) + if (payload->algo==MFDES_ALGO_AES) { + if (mbedtls_aes_setkey_dec(&ctx, key->data, 128) != 0) { + if (DBGLEVEL >= DBG_EXTENDED) { + DbpString("mbedtls_aes_setkey_dec failed"); + } + OnErrorNG(CMD_HF_DESFIRE_AUTH1,7); + return; + } mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_DECRYPT, 16, IV, encRndB, RndB); + } else if (payload->algo == MFDES_ALGO_3DES) tdes_dec(&RndB, &encRndB, key->data); else if (payload->algo == MFDES_ALGO_DES) @@ -353,7 +367,6 @@ void MifareDES_Auth1(uint8_t *datain) { memcpy(rotRndB, RndB, payload->keylen); rol(rotRndB, payload->keylen); - //memcpy(RndA, decRndA, payload->keylen); uint8_t encRndA[16] = {0x00}; // - Encrypt our response @@ -434,10 +447,8 @@ void MifareDES_Auth1(uint8_t *datain) { struct desfire_key sessionKey = {0}; desfirekey_t skey = &sessionKey; Desfire_session_key_new(RndA, RndB, key, skey); - memset(payload->sessionkey,0x0,24); - memcpy(payload->sessionkey,skey->data,payload->keylen); - print_result("SESSION : ", skey->data, payload->keylen); - print_result("SESSION : ", payload->sessionkey, payload->keylen); + if (DBGLEVEL >= DBG_EXTENDED) + print_result("SESSIONKEY : ", skey->data, payload->keylen); if (payload->mode != MFDES_AUTH_PICC) { memcpy(encRndA, resp + 1, payload->keylen); @@ -453,12 +464,21 @@ void MifareDES_Auth1(uint8_t *datain) { des_dec(&encRndA, &encRndA, key->data); } else if (payload->mode==MFDES_AUTH_AES) { - mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_DECRYPT, 16, IV, encRndA, encRndA); + if (mbedtls_aes_setkey_dec(&ctx, key->data, 128) != 0) { + if (DBGLEVEL >= DBG_EXTENDED) { + DbpString("mbedtls_aes_setkey_dec failed"); + } + OnErrorNG(CMD_HF_DESFIRE_AUTH1,7); + return; + } + mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_DECRYPT, 16, IV, encRndA, encRndA); } rol(RndA, payload->keylen); - print_result("RndA : ", RndA, payload->keylen); - print_result("encRndA : ", encRndA, payload->keylen); + if (DBGLEVEL >= DBG_EXTENDED) { + print_result("RndA : ", RndA, payload->keylen); + print_result("encRndA : ", encRndA, payload->keylen); + } for (int x = 0; x < payload->keylen; x++) { if (RndA[x] != encRndA[x]) { DbpString("Authentication failed. Cannot verify Session Key."); @@ -563,7 +583,15 @@ void MifareDES_Auth1(uint8_t *datain) { //reply_mix(CMD_ACK, 1, len, 0, resp, len); LED_B_ON(); - reply_ng(CMD_HF_DESFIRE_AUTH1, PM3_SUCCESS, (uint8_t *)payload, sizeof(payload)); + struct r { + uint8_t sessionkeylen; + uint8_t sessionkey[24]; + } PACKED; + + struct r rpayload; + rpayload.sessionkeylen=payload->keylen; + memcpy(rpayload.sessionkey,skey->data,rpayload.sessionkeylen); + reply_ng(CMD_HF_DESFIRE_AUTH1, PM3_SUCCESS, (uint8_t *)&rpayload, sizeof(payload)); LED_B_OFF(); } diff --git a/armsrc/mifaredesfire.h b/armsrc/mifaredesfire.h index ae4b135c5..1e19ec49f 100644 --- a/armsrc/mifaredesfire.h +++ b/armsrc/mifaredesfire.h @@ -14,7 +14,7 @@ #include "common.h" bool InitDesfireCard(); -void MifareSendCommand(uint8_t arg0, uint8_t arg1, uint8_t *datain); +void MifareSendCommand(uint8_t *datain); void MifareDesfireGetInformation(); void MifareDES_Auth1(uint8_t *datain); void ReaderMifareDES(uint32_t param, uint32_t param2, uint8_t *datain); diff --git a/client/cmdhfmfdes.c b/client/cmdhfmfdes.c index da56766f6..b23d78ec3 100644 --- a/client/cmdhfmfdes.c +++ b/client/cmdhfmfdes.c @@ -853,20 +853,17 @@ static int CmdHF14ADesFormatPICC(const char *Cmd) { int res = get_desfire_select_application(aid); if (res != PM3_SUCCESS) return res; struct { - uint8_t isOK; uint8_t mode; uint8_t algo; uint8_t keyno; uint8_t key[24]; uint8_t keylen; - uint8_t sessionkey[24]; } PACKED payload; payload.keylen=keylen; memcpy(payload.key,key,keylen); payload.mode=MFDES_AUTH_PICC; payload.algo=MFDES_ALGO_DES; payload.keyno=0; - //SendCommandOLD(CMD_HF_DESFIRE_AUTH1, 2, 1, 0, data, keylen + 1); SendCommandNG(CMD_HF_DESFIRE_AUTH1,(uint8_t*)&payload,sizeof(payload)); PacketResponseNG resp; @@ -878,14 +875,26 @@ static int CmdHF14ADesFormatPICC(const char *Cmd) { uint8_t isOK = (resp.status==PM3_SUCCESS); if (isOK) { - uint8_t rdata[] = {0xFC}; // 0xFC - SendCommandMIX(CMD_HF_DESFIRE_COMMAND, NONE, sizeof(rdata), 0, rdata, sizeof(rdata)); - if (!WaitForResponseTimeout(CMD_ACK, &resp, 3000)) { + struct { + uint8_t flags; + uint8_t datalen; + uint8_t datain[FRAME_PAYLOAD_SIZE]; + } PACKED payload; + payload.datain[0]=0xFC; + payload.flags=NONE; + payload.datalen=1; + SendCommandNG(CMD_HF_DESFIRE_COMMAND,(uint8_t*)&payload,sizeof(payload)); + if (!WaitForResponseTimeout(CMD_HF_DESFIRE_COMMAND, &resp, 3000)) { PrintAndLogEx(WARNING, "Client reset command execute timeout"); DropField(); return PM3_ETIMEOUT; } - if (resp.oldarg[0] & 0xFF) { + if (resp.status==PM3_SUCCESS) { + /*struct r { + uint8_t len; + uint8_t data[RECEIVE_SIZE]; + } PACKED; + struct r *rpayload = (struct r *)&resp.data.asBytes;*/ PrintAndLogEx(INFO, "Card successfully reset"); return PM3_SUCCESS; } @@ -1407,7 +1416,6 @@ static int CmdHF14ADesAuth(const char *Cmd) { // 2 = 3DES 16 // 3 = 3K 3DES 24 // 4 = AES 16 - //SetAPDULogging(true); uint8_t keylength = 8; CLIParserInit("hf mfdes auth", @@ -1443,14 +1451,12 @@ static int CmdHF14ADesAuth(const char *Cmd) { if ((keylen < 8) || (keylen > 24)) { PrintAndLogEx(ERR, "Specified key must have 16 bytes length."); - //SetAPDULogging(false); return PM3_EINVARG; } // AID if (aidlength != 3) { PrintAndLogEx(WARNING, "aid must include %d HEX symbols", 3); - //SetAPDULogging(false); return PM3_EINVARG; } @@ -1458,27 +1464,23 @@ static int CmdHF14ADesAuth(const char *Cmd) { case 1: if (cmdAuthAlgo != 1 && cmdAuthAlgo != 2) { PrintAndLogEx(NORMAL, "Crypto algo not valid for the auth mode"); - //SetAPDULogging(false); return PM3_EINVARG; } break; case 2: if (cmdAuthAlgo != 1 && cmdAuthAlgo != 2 && cmdAuthAlgo != 3) { PrintAndLogEx(NORMAL, "Crypto algo not valid for the auth mode"); - //SetAPDULogging(false); return PM3_EINVARG; } break; case 3: if (cmdAuthAlgo != 4) { PrintAndLogEx(NORMAL, "Crypto algo not valid for the auth mode"); - //SetAPDULogging(false); return PM3_EINVARG; } break; default: PrintAndLogEx(WARNING, "Wrong Auth mode (%d) -> (1=normal, 2=iso, 3=aes)", cmdAuthMode); - //SetAPDULogging(false); return PM3_EINVARG; } @@ -1520,25 +1522,19 @@ static int CmdHF14ADesAuth(const char *Cmd) { } struct { - uint8_t isOK; uint8_t mode; uint8_t algo; uint8_t keyno; uint8_t key[24]; uint8_t keylen; - uint8_t sessionkey[24]; } PACKED payload; payload.keylen=keylength; memcpy(payload.key,key,keylength); payload.mode=cmdAuthMode; payload.algo=cmdAuthAlgo; payload.keyno=cmdKeyNo; - //SendCommandOLD(CMD_HF_DESFIRE_AUTH1, 2, 1, 0, data, keylen + 1); SendCommandNG(CMD_HF_DESFIRE_AUTH1,(uint8_t*)&payload,sizeof(payload)); - //uint8_t data[25] = {keylength}; // max length: 1 + 24 (3k3DES) - //memcpy(data + 1, key, keylength); - //SendCommandOLD(CMD_HF_DESFIRE_AUTH1, cmdAuthMode, cmdAuthAlgo, cmdKeyNo, data, keylength + 1); PacketResponseNG resp; if (!WaitForResponseTimeout(CMD_HF_DESFIRE_AUTH1, &resp, 3000)) { @@ -1549,8 +1545,13 @@ static int CmdHF14ADesAuth(const char *Cmd) { uint8_t isOK = (resp.status == PM3_SUCCESS); if (isOK) { - uint8_t *session_key = payload.sessionkey; + struct r { + uint8_t sessionkeylen; + uint8_t sessionkey[24]; + } PACKED; + struct r *rpayload = (struct r *)&resp.data.asBytes; + uint8_t *session_key = rpayload->sessionkey; PrintAndLogEx(SUCCESS, " Key : " _GREEN_("%s"), sprint_hex(key, keylength)); PrintAndLogEx(SUCCESS, " SESSION : " _GREEN_("%s"), sprint_hex(session_key, keylength)); PrintAndLogEx(INFO, "-------------------------------------------------------------");