channel d40/encode works

This commit is contained in:
merlokk 2021-07-11 18:14:27 +03:00
commit d8a8c015bc
3 changed files with 24 additions and 12 deletions

View file

@ -5029,6 +5029,8 @@ static int CmdDesGetSessionParameters(CLIParserContext *ctx, DesfireContext *dct
int commmode = defaultCommMode;
int commset = defaultCommSet;
int secchann = defaultSecureChannel;
if (securechannel)
secchann = *securechannel;
if (keynoid) {
keynum = arg_get_int_def(ctx, keynoid, keynum);
@ -5079,6 +5081,7 @@ static int CmdDesGetSessionParameters(CLIParserContext *ctx, DesfireContext *dct
}
if (schannid) {
if (CLIGetOptionList(arg_get_str(ctx, schannid), DesfireSecureChannelOpts, &secchann))
return PM3_ESOFT;
}
@ -5187,7 +5190,7 @@ static int CmdHF14ADesChKeySettings(const char *Cmd) {
bool verbose = arg_get_lit(ctx, 2);
DesfireContext dctx;
int securechann = DCMPlain;
int securechann = DCMEncrypted;
uint32_t appid = 0x000000;
int res = CmdDesGetSessionParameters(ctx, &dctx, 3, 4, 5, 6, 7, 8, 9, 10, 11, &securechann, &appid);
if (res) {

View file

@ -215,8 +215,11 @@ void DesfireCryptoEncDecEx(DesfireContext *ctx, bool use_session_key, uint8_t *s
uint8_t data[1024] = {0};
uint8_t xiv[DESFIRE_MAX_CRYPTO_BLOCK_SIZE] = {0};
if (ctx->secureChannel == DACd40)
bool xencode = encode;
if (ctx->secureChannel == DACd40) {
memset(ctx->IV, 0, DESFIRE_MAX_CRYPTO_BLOCK_SIZE);
xencode = false;
}
size_t block_size = desfire_get_key_block_length(ctx->keyType);
@ -228,9 +231,9 @@ void DesfireCryptoEncDecEx(DesfireContext *ctx, bool use_session_key, uint8_t *s
size_t offset = 0;
while (offset < srcdatalen) {
if (use_session_key)
DesfireCryptoEncDecSingleBlock(ctx->sessionKeyMAC, ctx->keyType, srcdata + offset, data + offset, xiv, encode, encode);
DesfireCryptoEncDecSingleBlock(ctx->sessionKeyMAC, ctx->keyType, srcdata + offset, data + offset, xiv, encode, xencode);
else
DesfireCryptoEncDecSingleBlock(ctx->key, ctx->keyType, srcdata + offset, data + offset, xiv, encode, encode);
DesfireCryptoEncDecSingleBlock(ctx->key, ctx->keyType, srcdata + offset, data + offset, xiv, encode, xencode);
offset += block_size;
}

View file

@ -46,6 +46,7 @@ AllowedChannelModesS AllowedChannelModes[] = {
{MFDES_COMMIT_READER_ID, DACd40, DCCNative, DCMMACed},
{MFDES_GET_UID, DACd40, DCCNative, DCMEncrypted},
{MFDES_CHANGE_KEY_SETTINGS, DACd40, DCCNative, DCMEncrypted},
{MFDES_READ_DATA, DACd40, DCCNative, DCMEncrypted},
{MFDES_WRITE_DATA, DACd40, DCCNative, DCMEncrypted},
@ -56,6 +57,7 @@ AllowedChannelModesS AllowedChannelModes[] = {
{MFDES_GET_KEY_SETTINGS, DACEV1, DCCNative, DCMMACed},
{MFDES_GET_UID, DACEV1, DCCNative, DCMEncrypted},
{MFDES_CHANGE_KEY_SETTINGS, DACEV1, DCCNative, DCMEncrypted},
};
static void DesfireSecureChannelEncodeD40(DesfireContext *ctx, uint8_t cmd, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, size_t *dstdatalen) {
@ -74,10 +76,9 @@ static void DesfireSecureChannelEncodeD40(DesfireContext *ctx, uint8_t cmd, uint
if (srcdatalen == 0)
break;
rlen = padded_data_length(srcdatalen, desfire_get_key_block_length(ctx->keyType));
rlen = srcdatalen + DesfireGetMACLength(ctx);
memcpy(data, srcdata, srcdatalen);
memset(ctx->IV, 0, sizeof(ctx->IV));
DesfireCryptoEncDec(ctx, true, data, rlen, NULL, true);
DesfireCryptoEncDec(ctx, true, data, srcdatalen, NULL, true);
memcpy(dstdata, srcdata, srcdatalen);
memcpy(&dstdata[srcdatalen], ctx->IV, 4);
*dstdatalen = rlen;
@ -89,7 +90,6 @@ static void DesfireSecureChannelEncodeD40(DesfireContext *ctx, uint8_t cmd, uint
rlen = padded_data_length(srcdatalen + 2, desfire_get_key_block_length(ctx->keyType)); // 2 - crc16
memcpy(data, srcdata, srcdatalen);
compute_crc(CRC_14443_A, data, srcdatalen, &data[srcdatalen], &data[srcdatalen + 1]);
memset(ctx->IV, 0, sizeof(ctx->IV));
DesfireCryptoEncDec(ctx, true, data, rlen, dstdata, true);
*dstdatalen = rlen;
break;
@ -100,7 +100,8 @@ static void DesfireSecureChannelEncodeD40(DesfireContext *ctx, uint8_t cmd, uint
static void DesfireSecureChannelEncodeEV1(DesfireContext *ctx, uint8_t cmd, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, size_t *dstdatalen) {
uint8_t data[1024] = {0};
size_t rlen = 0;
// we calc MAC anyway
// if encypted channel and no data - we only calc MAC
if (ctx->commMode == DCMPlain || ctx->commMode == DCMMACed || (ctx->commMode == DCMEncrypted && srcdatalen == 0)) {
@ -110,14 +111,19 @@ static void DesfireSecureChannelEncodeEV1(DesfireContext *ctx, uint8_t cmd, uint
DesfireCryptoCMAC(ctx, data, srcdatalen + 1, cmac);
memcpy(dstdata, srcdata, srcdatalen);
*dstdatalen = srcdatalen;
if (srcdatalen != 0 && ctx->commMode == DCMMACed) {
memcpy(&dstdata[srcdatalen], cmac, DesfireGetMACLength(ctx));
*dstdatalen = srcdatalen + DesfireGetMACLength(ctx);
}
} else if (ctx->commMode == DCMEncrypted) {
rlen = padded_data_length(srcdatalen + 4, desfire_get_key_block_length(ctx->keyType));
memcpy(data, srcdata, srcdatalen);
desfire_crc32_append(data, srcdatalen);
PrintAndLogEx(INFO, "decoded[%d]: %s", rlen, sprint_hex(data, rlen));
DesfireCryptoEncDec(ctx, true, data, rlen, dstdata, true);
*dstdatalen = rlen;
} else {
memcpy(dstdata, srcdata, srcdatalen);
*dstdatalen = srcdatalen;