d40/encoded channel works

This commit is contained in:
merlokk 2021-07-28 14:18:53 +03:00
commit b1f819e208
2 changed files with 44 additions and 43 deletions

View file

@ -6363,13 +6363,14 @@ static int CmdHF14ADesReadData(const char *Cmd) {
break; break;
} }
} }
DesfireSetCommMode(&dctx, fsettings.commMode);
if (verbose) if (verbose)
PrintAndLogEx(INFO, "Got file type: %s. Option: %s. comm mode: %s", PrintAndLogEx(INFO, "Got file type: %s. Option: %s. comm mode: %s",
GetDesfireFileType(fsettings.fileType), GetDesfireFileType(fsettings.fileType),
CLIGetOptionListStr(DesfireReadFileTypeOpts, op), CLIGetOptionListStr(DesfireReadFileTypeOpts, op),
CLIGetOptionListStr(DesfireCommunicationModeOpts, fsettings.commMode)); CLIGetOptionListStr(DesfireCommunicationModeOpts, fsettings.commMode));
DesfireSetCommMode(&dctx, fsettings.commMode);
} else { } else {
PrintAndLogEx(WARNING, "GetFileSettings error. Can't get file type."); PrintAndLogEx(WARNING, "GetFileSettings error. Can't get file type.");
} }
@ -6408,6 +6409,7 @@ static int CmdHF14ADesReadData(const char *Cmd) {
} }
if (op == RFTRecord) { if (op == RFTRecord) {
resplen = 0;
if (reclen == 0) { if (reclen == 0) {
res = DesfireReadRecords(&dctx, fnum, offset, 1, resp, &resplen); res = DesfireReadRecords(&dctx, fnum, offset, 1, resp, &resplen);
if (res != PM3_SUCCESS) { if (res != PM3_SUCCESS) {
@ -6421,12 +6423,15 @@ static int CmdHF14ADesReadData(const char *Cmd) {
if (verbose) if (verbose)
PrintAndLogEx(INFO, "Record length %zu", reclen); PrintAndLogEx(INFO, "Record length %zu", reclen);
// if we got one record via the DesfireReadRecords before -- we not need to get it 2nd time
if (length != 1 || resplen == 0) {
res = DesfireReadRecords(&dctx, fnum, offset, length, resp, &resplen); res = DesfireReadRecords(&dctx, fnum, offset, length, resp, &resplen);
if (res != PM3_SUCCESS) { if (res != PM3_SUCCESS) {
PrintAndLogEx(ERR, "Desfire ReadRecords command " _RED_("error") ". Result: %d", res); PrintAndLogEx(ERR, "Desfire ReadRecords command " _RED_("error") ". Result: %d", res);
DropField(); DropField();
return PM3_ESOFT; return PM3_ESOFT;
} }
}
if (resplen > 0) { if (resplen > 0) {
size_t reccount = resplen / reclen; size_t reccount = resplen / reclen;

View file

@ -148,14 +148,9 @@ static void DesfireSecureChannelEncodeD40(DesfireContext *ctx, uint8_t cmd, uint
size_t rlen = 0; size_t rlen = 0;
uint8_t hdrlen = DesfireGetCmdHeaderLen(cmd); uint8_t hdrlen = DesfireGetCmdHeaderLen(cmd);
switch (ctx->commMode) { if (ctx->commMode == DCMMACed || (ctx->commMode == DCMEncrypted && srcdatalen <= hdrlen)) {
case DCMPlain:
memcpy(dstdata, srcdata, srcdatalen);
*dstdatalen = srcdatalen;
break;
case DCMMACed:
if (srcdatalen == 0) if (srcdatalen == 0)
break; return;
rlen = srcdatalen + DesfireGetMACLength(ctx); rlen = srcdatalen + DesfireGetMACLength(ctx);
memcpy(data, srcdata, srcdatalen); memcpy(data, srcdata, srcdatalen);
@ -163,20 +158,18 @@ static void DesfireSecureChannelEncodeD40(DesfireContext *ctx, uint8_t cmd, uint
memcpy(dstdata, srcdata, srcdatalen); memcpy(dstdata, srcdata, srcdatalen);
memcpy(&dstdata[srcdatalen], ctx->IV, 4); memcpy(&dstdata[srcdatalen], ctx->IV, 4);
*dstdatalen = rlen; *dstdatalen = rlen;
break; } else if (ctx->commMode == DCMEncrypted) {
case DCMEncrypted:
if (srcdatalen == 0 || srcdatalen <= hdrlen) if (srcdatalen == 0 || srcdatalen <= hdrlen)
break; return;
rlen = padded_data_length(srcdatalen + 2, desfire_get_key_block_length(ctx->keyType)); // 2 - crc16 rlen = padded_data_length(srcdatalen + 2, desfire_get_key_block_length(ctx->keyType)); // 2 - crc16
memcpy(data, srcdata, srcdatalen); memcpy(data, srcdata, srcdatalen);
compute_crc(CRC_14443_A, data, srcdatalen, &data[srcdatalen], &data[srcdatalen + 1]); compute_crc(CRC_14443_A, data, srcdatalen, &data[srcdatalen], &data[srcdatalen + 1]);
DesfireCryptoEncDec(ctx, true, data, rlen, dstdata, true); DesfireCryptoEncDec(ctx, true, data, rlen, dstdata, true);
*dstdatalen = rlen; *dstdatalen = rlen;
break; } if (ctx->commMode == DCMEncryptedPlain) {
case DCMEncryptedPlain:
if (srcdatalen == 0 || srcdatalen <= hdrlen) if (srcdatalen == 0 || srcdatalen <= hdrlen)
break; return;
rlen = padded_data_length(srcdatalen - hdrlen, desfire_get_key_block_length(ctx->keyType)) + hdrlen; rlen = padded_data_length(srcdatalen - hdrlen, desfire_get_key_block_length(ctx->keyType)) + hdrlen;
memcpy(data, srcdata, srcdatalen); memcpy(data, srcdata, srcdatalen);
@ -184,9 +177,9 @@ static void DesfireSecureChannelEncodeD40(DesfireContext *ctx, uint8_t cmd, uint
DesfireCryptoEncDec(ctx, true, &data[hdrlen], rlen - hdrlen, &dstdata[hdrlen], true); DesfireCryptoEncDec(ctx, true, &data[hdrlen], rlen - hdrlen, &dstdata[hdrlen], true);
*dstdatalen = rlen; *dstdatalen = rlen;
ctx->commMode = DCMEncrypted; ctx->commMode = DCMEncrypted;
break; } else {
case DCMNone: memcpy(dstdata, srcdata, srcdatalen);
; *dstdatalen = srcdatalen;
} }
} }
@ -261,6 +254,9 @@ static void DesfireSecureChannelDecodeD40(DesfireContext *ctx, uint8_t *srcdata,
switch (ctx->commMode) { switch (ctx->commMode) {
case DCMMACed: case DCMMACed:
//if (srcdatalen > 4)
// *dstdatalen = srcdatalen - 4;
// TODO check MAC!!!
break; break;
case DCMEncrypted: case DCMEncrypted: