diff --git a/client/src/cmdhfmfdes.c b/client/src/cmdhfmfdes.c index a1e1cdd47..a210c3e8e 100644 --- a/client/src/cmdhfmfdes.c +++ b/client/src/cmdhfmfdes.c @@ -4658,8 +4658,8 @@ static int DesfileReadFileAndPrint(DesfireContext *dctx, uint8_t fnum, int filet // MF2DLHX0.pdf, 10.3.2.1 Transaction MAC Counter, page 41 uint32_t actTMC = MemLeToUint2byte(&resp[0]); uint32_t sessTMC = MemLeToUint2byte(&resp[2]); - PrintAndLogEx(SUCCESS, "Session tr counter : %d (0x%08x)", sessTMC, sessTMC); - PrintAndLogEx(SUCCESS, "Actual tr counter : %d (0x%08x)", actTMC, actTMC); + PrintAndLogEx(SUCCESS, "Session tr counter : %d (0x%04x)", sessTMC, sessTMC); + PrintAndLogEx(SUCCESS, "Actual tr counter : %d (0x%04x)", actTMC, actTMC); } PrintAndLogEx(SUCCESS, "Transaction MAC : %s", sprint_hex(&resp[4], 8)); } @@ -4853,7 +4853,8 @@ static int CmdHF14ADesWriteData(const char *Cmd) { "hf mfdes write --aid 123456 --fid 01 --type record --offset 000000 -d 11223344 -> write record to record file. use default channel settings from `default` command\n" "hf mfdes write --appisoid 1234 --fileisoid 1000 --type data -c iso -d 01020304 -> write data to std/backup file via iso commandset\n" "hf mfdes write --appisoid 1234 --fileisoid 2000 --type record -c iso -d 01020304 -> send record to record file via iso commandset\n" - "hf mfdes write --aid 123456 --fid 01 -d 01020304 --readerid 010203 -> write data to file with CommitReaderID command before write and CommitTransaction after write"); + "hf mfdes write --aid 123456 --fid 01 -d 01020304 --readerid 010203 -> write data to file with CommitReaderID command before write and CommitTransaction after write\n" + "hf mfdes write --appisoid df01 --fid 04 -d 01020304 --trkey 00112233445566778899aabbccddeeff --readerid 5532 -t aes -s lrp -> advanced CommitReaderID via lrp channel sample"); void *argtable[] = { arg_param_begin, @@ -5166,7 +5167,16 @@ static int CmdHF14ADesWriteData(const char *Cmd) { PrintAndLogEx(INFO, _GREEN_("Commit result:")); uint32_t cnt = MemLeToUint4byte(&resp[0]); transactionCounter = cnt; - PrintAndLogEx(SUCCESS, "Transaction counter: %d (0x%08x)", cnt, cnt); + if (dctx.secureChannel != DACLRP) { + PrintAndLogEx(SUCCESS, "Transaction counter: %d (0x%08x)", cnt, cnt); + } else { + // For composing TMC the two subparts are concatenated as follows: actTMC || sesTMC. Both subparts are represented LSB first. + // MF2DLHX0.pdf, 10.3.2.1 Transaction MAC Counter, page 41 + uint32_t actTMC = MemLeToUint2byte(&resp[0]); + uint32_t sessTMC = MemLeToUint2byte(&resp[2]); + PrintAndLogEx(SUCCESS, "Session tr counter : %d (0x%04x)", sessTMC, sessTMC); + PrintAndLogEx(SUCCESS, "Actual tr counter : %d (0x%04x)", actTMC, actTMC); + } PrintAndLogEx(SUCCESS, "Transaction MAC : %s", sprint_hex(&resp[4], 8)); } } diff --git a/client/src/mifare/desfirecrypto.c b/client/src/mifare/desfirecrypto.c index f3c332213..be0e84b06 100644 --- a/client/src/mifare/desfirecrypto.c +++ b/client/src/mifare/desfirecrypto.c @@ -671,10 +671,16 @@ void DesfireGenTransSessionKeyEV2(uint8_t *key, uint32_t trCntr, uint8_t *uid, b // page 43 void DesfireGenTransSessionKeyLRP(uint8_t *key, uint32_t trCntr, uint8_t *uid, bool forMAC, uint8_t *sessionkey) { uint8_t data[CRYPTO_AES_BLOCK_SIZE] = {0}; + + // SV1 = 00h||01h||00h||80h||(actTMC+1)||(sesTMC+1)||UID||5Ah + // SV2 = 00h||01h||00h||80h||(actTMC+1)||(sesTMC+1)||UID||A5h + // SesTMMACKey = MACLRP (AppTransactionMACKey; SV1) + // SesTMENCKey = MACLRP (AppTransactionMACKey; SV2) data[1] = 0x01; data[3] = 0x80; - Uint4byteToMemLe(&data[4], trCntr + 0x00010001); + // we thought that CommitReaderID is the first command in the transaction (actTMC == 0 !!!) + Uint4byteToMemLe(&data[4], (trCntr & 0xffff) + 0x00010001); memcpy(&data[8], uid, 7); if (forMAC) { data[15] = 0x5a; @@ -683,23 +689,21 @@ void DesfireGenTransSessionKeyLRP(uint8_t *key, uint32_t trCntr, uint8_t *uid, b } LRPContext lctx = {0}; - LRPSetKey(&lctx, key, 0, true); + LRPSetKey(&lctx, key, 0, false); LRPCMAC(&lctx, data, sizeof(data), sessionkey); } void DesfireDecodePrevReaderID(DesfireContext *ctx, uint8_t *key, uint32_t trCntr, uint8_t *encPrevReaderID, uint8_t *prevReaderID) { - uint8_t sessionkey[16] = {0}; + uint8_t sessionkey[CRYPTO_AES128_KEY_SIZE] = {0}; uint8_t uid[12] = {0}; memcpy(uid, ctx->uid, MAX(ctx->uidlen, 7)); if (ctx->secureChannel == DACEV2) { DesfireGenTransSessionKeyEV2(key, trCntr, uid, false, sessionkey); - - aes_decode(NULL, sessionkey, encPrevReaderID, prevReaderID, CRYPTO_AES_BLOCK_SIZE); } else if (ctx->secureChannel == DACLRP) { DesfireGenTransSessionKeyLRP(key, trCntr, uid, false, sessionkey); - } + aes_decode(NULL, sessionkey, encPrevReaderID, prevReaderID, CRYPTO_AES128_KEY_SIZE); } int DesfireLRPCalcCMAC(DesfireContext *ctx, uint8_t cmd, uint8_t *data, size_t datalen, uint8_t *mac) { diff --git a/client/src/mifare/desfiresecurechan.c b/client/src/mifare/desfiresecurechan.c index 37da5f394..760d2b479 100644 --- a/client/src/mifare/desfiresecurechan.c +++ b/client/src/mifare/desfiresecurechan.c @@ -81,7 +81,6 @@ static const AllowedChannelModesS AllowedChannelModes[] = { {MFDES_FORMAT_PICC, DACd40, DCCNative, DCMMACed}, {MFDES_GET_FILE_IDS, DACd40, DCCNative, DCMMACed}, {MFDES_GET_ISOFILE_IDS, DACd40, DCCNative, DCMMACed}, - {MFDES_COMMIT_READER_ID, DACd40, DCCNative, DCMMACed}, {MFDES_ABORT_TRANSACTION, DACd40, DCCNative, DCMMACed}, {MFDES_GET_UID, DACd40, DCCNative, DCMEncrypted}, @@ -161,6 +160,7 @@ static const AllowedChannelModesS AllowedChannelModes[] = { {MFDES_CLEAR_RECORD_FILE, DACLRP, DCCNative, DCMMACed}, {MFDES_COMMIT_TRANSACTION, DACLRP, DCCNative, DCMMACed}, {MFDES_ABORT_TRANSACTION, DACLRP, DCCNative, DCMMACed}, + {MFDES_COMMIT_READER_ID, DACLRP, DCCNative, DCMMACed}, {MFDES_GET_UID, DACLRP, DCCNative, DCMEncrypted}, {MFDES_CHANGE_FILE_SETTINGS, DACLRP, DCCNative, DCMEncrypted},