mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-21 05:43:48 -07:00
fixing buffer overflow when reading large files
This commit is contained in:
parent
d1e921171b
commit
365454bb3c
4 changed files with 145 additions and 177 deletions
|
@ -674,11 +674,11 @@ static int DesfireExchangeISONative(bool activate_field, DesfireContext_t *ctx,
|
|||
}
|
||||
|
||||
if (respcode) {
|
||||
*respcode = 0xff;
|
||||
*respcode = 0xFF;
|
||||
}
|
||||
|
||||
uint16_t sw = 0;
|
||||
uint8_t *buf = calloc(DESFIRE_BUFFER_SIZE, 1);
|
||||
uint8_t *buf = calloc(DESFIRE_BUFFER_SIZE, 1);
|
||||
if (buf == NULL) {
|
||||
return PM3_EMALLOC;
|
||||
}
|
||||
|
@ -698,10 +698,11 @@ static int DesfireExchangeISONative(bool activate_field, DesfireContext_t *ctx,
|
|||
// tx chaining
|
||||
size_t sentdatalen = 0;
|
||||
while (datalen >= sentdatalen) {
|
||||
if (datalen - sentdatalen > DESFIRE_TX_FRAME_MAX_LEN)
|
||||
if (datalen - sentdatalen > DESFIRE_TX_FRAME_MAX_LEN) {
|
||||
apdu.Lc = DESFIRE_TX_FRAME_MAX_LEN;
|
||||
else
|
||||
} else {
|
||||
apdu.Lc = datalen - sentdatalen;
|
||||
}
|
||||
|
||||
apdu.data = &data[sentdatalen];
|
||||
|
||||
|
@ -725,8 +726,8 @@ static int DesfireExchangeISONative(bool activate_field, DesfireContext_t *ctx,
|
|||
}
|
||||
}
|
||||
|
||||
if (respcode != NULL && ((sw & 0xff00) == 0x9100)) {
|
||||
*respcode = sw & 0xff;
|
||||
if (respcode != NULL && ((sw & 0xFF00) == 0x9100)) {
|
||||
*respcode = sw & 0xFF;
|
||||
}
|
||||
|
||||
if (resp) {
|
||||
|
@ -741,7 +742,7 @@ static int DesfireExchangeISONative(bool activate_field, DesfireContext_t *ctx,
|
|||
pos += buflen;
|
||||
if (enable_chaining == false) {
|
||||
if (sw == DESFIRE_GET_ISO_STATUS(MFDES_S_OPERATION_OK) ||
|
||||
sw == DESFIRE_GET_ISO_STATUS(MFDES_ADDITIONAL_FRAME)) {
|
||||
sw == DESFIRE_GET_ISO_STATUS(MFDES_ADDITIONAL_FRAME)) {
|
||||
|
||||
if (resplen) {
|
||||
*resplen = pos;
|
||||
|
@ -759,6 +760,8 @@ static int DesfireExchangeISONative(bool activate_field, DesfireContext_t *ctx,
|
|||
apdu.P2 = 0;
|
||||
apdu.data = NULL;
|
||||
|
||||
buflen = 0;
|
||||
|
||||
res = DESFIRESendApdu(false, apdu, buf, DESFIRE_BUFFER_SIZE, &buflen, &sw);
|
||||
if (res != PM3_SUCCESS) {
|
||||
PrintAndLogEx(DEBUG, "error DESFIRESendApdu %s", DesfireGetErrorString(res, &sw));
|
||||
|
@ -766,8 +769,8 @@ static int DesfireExchangeISONative(bool activate_field, DesfireContext_t *ctx,
|
|||
return res;
|
||||
}
|
||||
|
||||
if (respcode != NULL && ((sw & 0xff00) == 0x9100)) {
|
||||
*respcode = sw & 0xff;
|
||||
if (respcode != NULL && ((sw & 0xFF00) == 0x9100)) {
|
||||
*respcode = sw & 0xFF;
|
||||
}
|
||||
|
||||
if (resp != NULL) {
|
||||
|
@ -776,9 +779,10 @@ static int DesfireExchangeISONative(bool activate_field, DesfireContext_t *ctx,
|
|||
memcpy(&resp[i * splitbysize + 1], buf, buflen);
|
||||
i += 1;
|
||||
} else {
|
||||
memcpy(&resp[pos], buf, buflen);
|
||||
memcpy(resp + (pos), buf, buflen);
|
||||
}
|
||||
}
|
||||
|
||||
pos += buflen;
|
||||
|
||||
if (sw != DESFIRE_GET_ISO_STATUS(MFDES_ADDITIONAL_FRAME)) {
|
||||
|
@ -786,6 +790,7 @@ static int DesfireExchangeISONative(bool activate_field, DesfireContext_t *ctx,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
if (resplen) {
|
||||
*resplen = (splitbysize) ? i : pos;
|
||||
}
|
||||
|
@ -854,7 +859,7 @@ int DesfireExchangeEx(bool activate_field, DesfireContext_t *ctx, uint8_t cmd, u
|
|||
DesfirePrintContext(ctx);
|
||||
}
|
||||
|
||||
uint8_t *databuf = calloc(DESFIRE_BUFFER_SIZE, 1);
|
||||
uint8_t *databuf = calloc(DESFIRE_BUFFER_SIZE, 1);
|
||||
if (databuf == NULL) {
|
||||
return PM3_EMALLOC;
|
||||
}
|
||||
|
@ -866,13 +871,14 @@ int DesfireExchangeEx(bool activate_field, DesfireContext_t *ctx, uint8_t cmd, u
|
|||
case DCCNativeISO:
|
||||
DesfireSecureChannelEncode(ctx, cmd, data, datalen, databuf, &databuflen);
|
||||
|
||||
if (ctx->cmdSet == DCCNative)
|
||||
if (ctx->cmdSet == DCCNative) {
|
||||
res = DesfireExchangeNative(activate_field, ctx, cmd, databuf, databuflen, respcode, databuf, &databuflen, enable_chaining, splitbysize);
|
||||
else
|
||||
} else {
|
||||
res = DesfireExchangeISONative(activate_field, ctx, cmd, databuf, databuflen, respcode, databuf, &databuflen, enable_chaining, splitbysize);
|
||||
}
|
||||
|
||||
if (splitbysize) {
|
||||
uint8_t sdata[250 * 5] = {0};
|
||||
uint8_t sdata[DESFIRE_BUFFER_SIZE] = {0};
|
||||
size_t sdatalen = 0;
|
||||
DesfireJoinBlockToBytes(databuf, databuflen, splitbysize, sdata, &sdatalen);
|
||||
|
||||
|
@ -1924,13 +1930,16 @@ void DesfirePrintAppList(DesfireContext_t *dctx, PICCInfo_t *PICCInfo, AppListS
|
|||
}
|
||||
|
||||
static int DesfireCommandEx(DesfireContext_t *dctx, uint8_t cmd, uint8_t *data, size_t datalen, uint8_t *resp, size_t *resplen, int checklength, size_t splitbysize) {
|
||||
if (resplen)
|
||||
if (resplen) {
|
||||
*resplen = 0;
|
||||
}
|
||||
|
||||
uint8_t respcode = 0xFF;
|
||||
|
||||
uint8_t respcode = 0xff;
|
||||
uint8_t *xresp = calloc(DESFIRE_BUFFER_SIZE, 1);
|
||||
if (xresp == NULL)
|
||||
if (xresp == NULL) {
|
||||
return PM3_EMALLOC;
|
||||
}
|
||||
|
||||
size_t xresplen = 0;
|
||||
int res = DesfireExchangeEx(false, dctx, cmd, data, datalen, &respcode, xresp, &xresplen, true, splitbysize);
|
||||
|
@ -1938,19 +1947,24 @@ static int DesfireCommandEx(DesfireContext_t *dctx, uint8_t cmd, uint8_t *data,
|
|||
free(xresp);
|
||||
return res;
|
||||
}
|
||||
|
||||
if (respcode != MFDES_S_OPERATION_OK) {
|
||||
free(xresp);
|
||||
return PM3_EAPDU_FAIL;
|
||||
}
|
||||
|
||||
if (checklength >= 0 && xresplen != checklength) {
|
||||
free(xresp);
|
||||
return PM3_EAPDU_FAIL;
|
||||
}
|
||||
|
||||
if (resplen)
|
||||
if (resplen) {
|
||||
*resplen = xresplen;
|
||||
if (resp)
|
||||
}
|
||||
|
||||
if (resp) {
|
||||
memcpy(resp, xresp, (splitbysize == 0) ? xresplen : xresplen * splitbysize);
|
||||
}
|
||||
|
||||
free(xresp);
|
||||
return PM3_SUCCESS;
|
||||
|
@ -1996,13 +2010,16 @@ int DesfireReadSignature(DesfireContext_t *dctx, uint8_t sid, uint8_t *resp, siz
|
|||
uint8_t respcode = 0xff;
|
||||
|
||||
int res = DesfireExchange(dctx, MFDES_READSIG, &sid, 1, &respcode, xresp, &xresplen);
|
||||
if (res != PM3_SUCCESS)
|
||||
if (res != PM3_SUCCESS) {
|
||||
return res;
|
||||
}
|
||||
|
||||
if (respcode != 0x90)
|
||||
if (respcode != 0x90) {
|
||||
return PM3_EAPDU_FAIL;
|
||||
}
|
||||
|
||||
memcpy(resp, xresp, xresplen);
|
||||
|
||||
*resplen = xresplen;
|
||||
|
||||
return PM3_SUCCESS;
|
||||
|
@ -2172,7 +2189,6 @@ int DesfireReadFile(DesfireContext_t *dctx, uint8_t fnum, uint32_t offset, uint3
|
|||
data[0] = fnum;
|
||||
Uint3byteToMemLe(&data[1], offset);
|
||||
Uint3byteToMemLe(&data[4], len);
|
||||
|
||||
return DesfireCommand(dctx, (dctx->isoChaining) ? MFDES_READ_DATA2 : MFDES_READ_DATA, data, 7, resp, resplen, -1);
|
||||
}
|
||||
|
||||
|
|
|
@ -26,9 +26,10 @@
|
|||
#include "des.h"
|
||||
#include <mbedtls/cmac.h>
|
||||
#include "crc.h"
|
||||
#include "crc16.h" // crc16 ccitt
|
||||
#include "crc16.h" // crc16 ccitt
|
||||
#include "crc32.h"
|
||||
#include "commonutil.h"
|
||||
#include "desfirecore.h" // DESFIRE_BUFFER_SIZE
|
||||
|
||||
void DesfireClearContext(DesfireContext_t *ctx) {
|
||||
ctx->keyNum = 0;
|
||||
|
@ -148,22 +149,29 @@ size_t DesfireSearchCRCPos(uint8_t *data, size_t datalen, uint8_t respcode, uint
|
|||
return 0;
|
||||
}
|
||||
|
||||
uint8_t crcdata[1024] = {0};
|
||||
uint8_t crcdata[DESFIRE_BUFFER_SIZE] = {0};
|
||||
size_t crcposfound = 0;
|
||||
// crc may be 00..00 and at the end of file may be padding 0x80. so we search from last zero to crclen + 2 (one for crc=0 and one for padding 0x80)
|
||||
for (int i = 0; i < crclen + 2; i++) {
|
||||
if (crcpos - i == 0)
|
||||
|
||||
if (crcpos - i == 0) {
|
||||
break;
|
||||
if (crcpos - i + crclen > datalen)
|
||||
}
|
||||
|
||||
if (crcpos - i + crclen > datalen) {
|
||||
continue;
|
||||
}
|
||||
|
||||
memcpy(crcdata, data, crcpos - i);
|
||||
crcdata[crcpos - i] = respcode;
|
||||
|
||||
bool res;
|
||||
if (crclen == 4)
|
||||
if (crclen == 4) {
|
||||
res = desfire_crc32_check(crcdata, crcpos - i + 1, &data[crcpos - i]);
|
||||
else
|
||||
} else {
|
||||
res = iso14443a_crc_check(data, crcpos - i, &data[crcpos - i]);
|
||||
}
|
||||
|
||||
if (res) {
|
||||
crcposfound = crcpos - i;
|
||||
}
|
||||
|
@ -252,7 +260,8 @@ static void DesfireCryptoEncDecSingleBlock(uint8_t *key, DesfireCryptoAlgorithm
|
|||
}
|
||||
|
||||
void DesfireCryptoEncDecEx(DesfireContext_t *ctx, DesfireCryptoOpKeyType key_type, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, bool dir_to_send, bool encode, uint8_t *iv) {
|
||||
uint8_t data[1024] = {0};
|
||||
|
||||
uint8_t data[DESFIRE_BUFFER_SIZE] = {0};
|
||||
uint8_t xiv[DESFIRE_MAX_CRYPTO_BLOCK_SIZE] = {0};
|
||||
|
||||
if (ctx->secureChannel == DACd40) {
|
||||
|
@ -287,15 +296,17 @@ void DesfireCryptoEncDecEx(DesfireContext_t *ctx, DesfireCryptoOpKeyType key_typ
|
|||
else
|
||||
memcpy(iv, xiv, block_size);
|
||||
|
||||
if (dstdata)
|
||||
if (dstdata) {
|
||||
memcpy(dstdata, data, srcdatalen);
|
||||
}
|
||||
}
|
||||
|
||||
void DesfireCryptoEncDec(DesfireContext_t *ctx, DesfireCryptoOpKeyType key_type, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, bool encode) {
|
||||
bool dir_to_send = encode;
|
||||
bool xencode = encode;
|
||||
if (ctx->secureChannel == DACd40)
|
||||
if (ctx->secureChannel == DACd40) {
|
||||
xencode = false;
|
||||
}
|
||||
|
||||
DesfireCryptoEncDecEx(ctx, key_type, srcdata, srcdatalen, dstdata, dir_to_send, xencode, NULL);
|
||||
}
|
||||
|
@ -333,8 +344,9 @@ void DesfireCMACGenerateSubkeys(DesfireContext_t *ctx, DesfireCryptoOpKeyType ke
|
|||
|
||||
void DesfireCryptoCMACEx(DesfireContext_t *ctx, DesfireCryptoOpKeyType key_type, uint8_t *data, size_t len, size_t minlen, uint8_t *cmac) {
|
||||
int kbs = desfire_get_key_block_length(ctx->keyType);
|
||||
if (kbs == 0)
|
||||
if (kbs == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t buffer[padded_data_length(MAX(minlen, len) + 1, kbs)];
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
|
@ -357,8 +369,9 @@ void DesfireCryptoCMACEx(DesfireContext_t *ctx, DesfireCryptoOpKeyType key_type,
|
|||
|
||||
DesfireCryptoEncDec(ctx, key_type, buffer, len, NULL, true);
|
||||
|
||||
if (cmac != NULL)
|
||||
if (cmac != NULL) {
|
||||
memcpy(cmac, ctx->IV, kbs);
|
||||
}
|
||||
}
|
||||
|
||||
void DesfireCryptoCMAC(DesfireContext_t *ctx, uint8_t *data, size_t len, uint8_t *cmac) {
|
||||
|
@ -371,16 +384,18 @@ void MifareKdfAn10922(DesfireContext_t *ctx, DesfireCryptoOpKeyType key_type, co
|
|||
return;
|
||||
|
||||
int kbs = desfire_get_key_block_length(ctx->keyType); // 8 or 16
|
||||
if (kbs == 0)
|
||||
if (kbs == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t cmac[DESFIRE_MAX_CRYPTO_BLOCK_SIZE * 3] = {0};
|
||||
uint8_t buffer[DESFIRE_MAX_CRYPTO_BLOCK_SIZE * 3] = {0};
|
||||
|
||||
if (ctx->keyType == T_AES) {
|
||||
// AES uses 16 byte IV
|
||||
if (kbs < CRYPTO_AES_BLOCK_SIZE)
|
||||
if (kbs < CRYPTO_AES_BLOCK_SIZE) {
|
||||
kbs = CRYPTO_AES_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
buffer[0] = 0x01;
|
||||
memcpy(&buffer[1], data, len);
|
||||
|
@ -429,8 +444,9 @@ void DesfireDESKeySetVersion(uint8_t *key, DesfireCryptoAlgorithm keytype, uint8
|
|||
return;
|
||||
|
||||
// clear version
|
||||
for (int n = 0; n < desfire_get_key_length(keytype); n++)
|
||||
for (int n = 0; n < desfire_get_key_length(keytype); n++) {
|
||||
key[n] &= 0xFE;
|
||||
}
|
||||
|
||||
// set version
|
||||
for (int n = 0; n < 8; n++) {
|
||||
|
@ -451,8 +467,9 @@ void DesfireDESKeySetVersion(uint8_t *key, DesfireCryptoAlgorithm keytype, uint8
|
|||
|
||||
uint8_t DesfireDESKeyGetVersion(const uint8_t *key) {
|
||||
uint8_t version = 0;
|
||||
for (int n = 0; n < 8; n++)
|
||||
for (int n = 0; n < 8; n++) {
|
||||
version |= ((key[n] & 1) << (7 - n));
|
||||
}
|
||||
|
||||
return version;
|
||||
}
|
||||
|
@ -644,14 +661,16 @@ void DesfireEV2FillIV(DesfireContext_t *ctx, bool ivforcommand, uint8_t *iv) {
|
|||
}
|
||||
|
||||
int DesfireEV2CalcCMAC(DesfireContext_t *ctx, uint8_t cmd, uint8_t *data, size_t datalen, uint8_t *mac) {
|
||||
uint8_t mdata[1050] = {0};
|
||||
uint8_t mdata[DESFIRE_BUFFER_SIZE] = {0};
|
||||
size_t mdatalen = 0;
|
||||
|
||||
mdata[0] = cmd;
|
||||
Uint2byteToMemLe(&mdata[1], ctx->cmdCntr);
|
||||
memcpy(&mdata[3], ctx->TI, 4);
|
||||
if (data != NULL && datalen > 0)
|
||||
if (data != NULL && datalen > 0) {
|
||||
memcpy(&mdata[7], data, datalen);
|
||||
}
|
||||
|
||||
mdatalen = 1 + 2 + 4 + datalen;
|
||||
|
||||
return aes_cmac8(NULL, ctx->sessionKeyMAC, mdata, mac, mdatalen);
|
||||
|
@ -717,14 +736,18 @@ void DesfireDecodePrevReaderID(DesfireContext_t *ctx, uint8_t *key, uint32_t trC
|
|||
}
|
||||
|
||||
int DesfireLRPCalcCMAC(DesfireContext_t *ctx, uint8_t cmd, uint8_t *data, size_t datalen, uint8_t *mac) {
|
||||
uint8_t mdata[1050] = {0};
|
||||
uint8_t mdata[DESFIRE_BUFFER_SIZE] = {0};
|
||||
size_t mdatalen = 0;
|
||||
|
||||
mdata[0] = cmd;
|
||||
Uint2byteToMemLe(&mdata[1], ctx->cmdCntr);
|
||||
|
||||
memcpy(&mdata[3], ctx->TI, 4);
|
||||
if (data != NULL && datalen > 0)
|
||||
|
||||
if (data != NULL && datalen > 0) {
|
||||
memcpy(&mdata[7], data, datalen);
|
||||
}
|
||||
|
||||
mdatalen = 1 + 2 + 4 + datalen;
|
||||
|
||||
LRPContext_t lctx = {0};
|
||||
|
|
|
@ -49,9 +49,11 @@ static const uint8_t CommandsCanUseAnyChannel[] = {
|
|||
};
|
||||
|
||||
static bool CommandCanUseAnyChannel(uint8_t cmd) {
|
||||
for (int i = 0; i < ARRAYLEN(CommandsCanUseAnyChannel); i++)
|
||||
if (CommandsCanUseAnyChannel[i] == cmd)
|
||||
for (int i = 0; i < ARRAYLEN(CommandsCanUseAnyChannel); i++) {
|
||||
if (CommandsCanUseAnyChannel[i] == cmd) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -207,10 +209,11 @@ static const CmdHeaderLengths_t CmdHeaderLengths[] = {
|
|||
};
|
||||
|
||||
static uint8_t DesfireGetCmdHeaderLen(uint8_t cmd) {
|
||||
for (int i = 0; i < ARRAYLEN(CmdHeaderLengths); i++)
|
||||
if (CmdHeaderLengths[i].cmd == cmd)
|
||||
for (int i = 0; i < ARRAYLEN(CmdHeaderLengths); i++) {
|
||||
if (CmdHeaderLengths[i].cmd == cmd) {
|
||||
return CmdHeaderLengths[i].len;
|
||||
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -228,12 +231,15 @@ static const uint8_t EV1D40TransmitMAC[] = {
|
|||
};
|
||||
|
||||
static bool DesfireEV1D40TransmitMAC(DesfireContext_t *ctx, uint8_t cmd) {
|
||||
if (ctx->secureChannel != DACd40 && ctx->secureChannel != DACEV1)
|
||||
if (ctx->secureChannel != DACd40 && ctx->secureChannel != DACEV1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (int i = 0; i < ARRAYLEN(EV1D40TransmitMAC); i++)
|
||||
if (EV1D40TransmitMAC[i] == cmd)
|
||||
for (int i = 0; i < ARRAYLEN(EV1D40TransmitMAC); i++) {
|
||||
if (EV1D40TransmitMAC[i] == cmd) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -247,12 +253,15 @@ static const uint8_t D40ReceiveMAC[] = {
|
|||
};
|
||||
|
||||
static bool DesfireEV1D40ReceiveMAC(DesfireContext_t *ctx, uint8_t cmd) {
|
||||
if (ctx->secureChannel != DACd40)
|
||||
if (ctx->secureChannel != DACd40) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (int i = 0; i < ARRAYLEN(D40ReceiveMAC); i++)
|
||||
if (D40ReceiveMAC[i] == cmd)
|
||||
for (int i = 0; i < ARRAYLEN(D40ReceiveMAC); i++) {
|
||||
if (D40ReceiveMAC[i] == cmd) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -269,10 +278,11 @@ static const uint8_t ISOChannelValidCmd[] = {
|
|||
};
|
||||
|
||||
static bool DesfireISOChannelValidCmd(uint8_t cmd) {
|
||||
for (int i = 0; i < ARRAYLEN(ISOChannelValidCmd); i++)
|
||||
if (ISOChannelValidCmd[i] == cmd)
|
||||
for (int i = 0; i < ARRAYLEN(ISOChannelValidCmd); i++) {
|
||||
if (ISOChannelValidCmd[i] == cmd) {
|
||||
return true;
|
||||
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -349,15 +359,17 @@ static void DesfireSecureChannelEncodeD40(DesfireContext_t *ctx, uint8_t cmd, ui
|
|||
static void DesfireSecureChannelEncodeEV1(DesfireContext_t *ctx, uint8_t cmd, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, size_t *dstdatalen) {
|
||||
|
||||
uint8_t *data = calloc(DESFIRE_BUFFER_SIZE, sizeof(uint8_t));
|
||||
if (data == NULL)
|
||||
if (data == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(dstdata, srcdata, srcdatalen);
|
||||
*dstdatalen = srcdatalen;
|
||||
|
||||
uint8_t hdrlen = DesfireGetCmdHeaderLen(cmd);
|
||||
if (srcdatalen < hdrlen)
|
||||
if (srcdatalen < hdrlen) {
|
||||
hdrlen = srcdatalen;
|
||||
}
|
||||
|
||||
size_t rlen;
|
||||
|
||||
|
@ -582,12 +594,14 @@ static void DesfireSecureChannelDecodeD40(DesfireContext_t *ctx, uint8_t *srcdat
|
|||
static void DesfireSecureChannelDecodeEV1(DesfireContext_t *ctx, uint8_t *srcdata, size_t srcdatalen, uint8_t respcode, uint8_t *dstdata, size_t *dstdatalen) {
|
||||
|
||||
uint8_t *data = calloc(DESFIRE_BUFFER_SIZE, sizeof(uint8_t));
|
||||
if (data == NULL)
|
||||
if (data == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
// if comm mode = plain --> response with MAC
|
||||
// if request is not zero length --> response MAC
|
||||
if (ctx->commMode == DCMPlain || ctx->commMode == DCMMACed || (ctx->commMode == DCMEncrypted && !ctx->lastRequestZeroLen)) {
|
||||
|
||||
if (srcdatalen < DesfireGetMACLength(ctx)) {
|
||||
memcpy(dstdata, srcdata, srcdatalen);
|
||||
*dstdatalen = srcdatalen;
|
||||
|
@ -596,6 +610,7 @@ static void DesfireSecureChannelDecodeEV1(DesfireContext_t *ctx, uint8_t *srcdat
|
|||
}
|
||||
|
||||
memcpy(dstdata, srcdata, srcdatalen - DesfireGetMACLength(ctx));
|
||||
|
||||
*dstdatalen = srcdatalen - DesfireGetMACLength(ctx);
|
||||
|
||||
memcpy(data, srcdata, *dstdatalen);
|
||||
|
@ -603,15 +618,22 @@ static void DesfireSecureChannelDecodeEV1(DesfireContext_t *ctx, uint8_t *srcdat
|
|||
|
||||
uint8_t cmac[DESFIRE_MAX_CRYPTO_BLOCK_SIZE] = {0};
|
||||
DesfireCryptoCMAC(ctx, data, *dstdatalen + 1, cmac);
|
||||
|
||||
if (memcmp(&srcdata[*dstdatalen], cmac, DesfireGetMACLength(ctx)) != 0) {
|
||||
|
||||
PrintAndLogEx(WARNING, "Received MAC is not match with calculated");
|
||||
PrintAndLogEx(INFO, " received MAC: %s", sprint_hex(&srcdata[*dstdatalen], DesfireGetMACLength(ctx)));
|
||||
PrintAndLogEx(INFO, " calculated MAC: %s", sprint_hex(cmac, DesfireGetMACLength(ctx)));
|
||||
|
||||
} else {
|
||||
if (GetAPDULogging())
|
||||
|
||||
if (GetAPDULogging()) {
|
||||
PrintAndLogEx(INFO, "Received MAC OK");
|
||||
}
|
||||
}
|
||||
} else if (ctx->commMode == DCMEncrypted || ctx->commMode == DCMEncryptedWithPadding) {
|
||||
|
||||
} else if (ctx->commMode == DCMEncrypted || ctx->commMode == DCMEncryptedWithPadding) {
|
||||
|
||||
if (srcdatalen < desfire_get_key_block_length(ctx->keyType)) {
|
||||
memcpy(dstdata, srcdata, srcdatalen);
|
||||
*dstdatalen = srcdatalen;
|
||||
|
@ -620,7 +642,7 @@ static void DesfireSecureChannelDecodeEV1(DesfireContext_t *ctx, uint8_t *srcdat
|
|||
}
|
||||
|
||||
DesfireCryptoEncDec(ctx, DCOSessionKeyEnc, srcdata, srcdatalen, dstdata, false);
|
||||
//PrintAndLogEx(INFO, "decoded[%d]: %s", srcdatalen, sprint_hex(dstdata, srcdatalen));
|
||||
// PrintAndLogEx(INFO, "decoded[%d]: %s", srcdatalen, sprint_hex(dstdata, srcdatalen));
|
||||
|
||||
size_t puredatalen = DesfireSearchCRCPos(dstdata, srcdatalen, respcode, 4);
|
||||
if (puredatalen != 0) {
|
||||
|
|
|
@ -53,11 +53,7 @@ static bool TestCRC16(void) {
|
|||
len = DesfireSearchCRCPos(data, 1, 0x00, 2);
|
||||
res = res && (len == 0);
|
||||
|
||||
if (res)
|
||||
PrintAndLogEx(INFO, "CRC16............. " _GREEN_("ok"));
|
||||
else
|
||||
PrintAndLogEx(ERR, "CRC16............. " _RED_("fail"));
|
||||
|
||||
PrintAndLogEx(INFO, "CRC16............. ( %s )", (res) ? _GREEN_("ok") : _RED_("fail"));
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -80,11 +76,7 @@ static bool TestCRC32(void) {
|
|||
len = DesfireSearchCRCPos(data, 2, 0x00, 4);
|
||||
res = res && (len == 0);
|
||||
|
||||
if (res)
|
||||
PrintAndLogEx(INFO, "CRC32............. " _GREEN_("ok"));
|
||||
else
|
||||
PrintAndLogEx(ERR, "CRC32............. " _RED_("fail"));
|
||||
|
||||
PrintAndLogEx(INFO, "CRC32............. ( %s )", (res) ? _GREEN_("ok") : _RED_("fail"));
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -131,11 +123,7 @@ static bool TestCMACSubkeys(void) {
|
|||
res = res && (memcmp(sk1, sk1_3tdea, sizeof(sk1_3tdea)) == 0);
|
||||
res = res && (memcmp(sk2, sk2_3tdea, sizeof(sk2_3tdea)) == 0);
|
||||
|
||||
if (res)
|
||||
PrintAndLogEx(INFO, "CMAC subkeys...... " _GREEN_("ok"));
|
||||
else
|
||||
PrintAndLogEx(ERR, "CMAC subkeys...... " _RED_("fail"));
|
||||
|
||||
PrintAndLogEx(INFO, "CMAC subkeys...... ( %s )", (res) ? _GREEN_("ok") : _RED_("fail"));
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -155,11 +143,7 @@ static bool TestAn10922KDFAES(void) {
|
|||
uint8_t dkey[] = {0xA8, 0xDD, 0x63, 0xA3, 0xB8, 0x9D, 0x54, 0xB3, 0x7C, 0xA8, 0x02, 0x47, 0x3F, 0xDA, 0x91, 0x75};
|
||||
res = res && (memcmp(dctx.key, dkey, sizeof(dkey)) == 0);
|
||||
|
||||
if (res)
|
||||
PrintAndLogEx(INFO, "An10922 AES....... " _GREEN_("ok"));
|
||||
else
|
||||
PrintAndLogEx(ERR, "An10922 AES....... " _RED_("fail"));
|
||||
|
||||
PrintAndLogEx(INFO, "An10922 AES....... ( %s )", (res) ? _GREEN_("ok") : _RED_("fail"));
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -177,11 +161,7 @@ static bool TestAn10922KDF2TDEA(void) {
|
|||
uint8_t dkey[] = {0x16, 0xF8, 0x59, 0x7C, 0x9E, 0x89, 0x10, 0xC8, 0x6B, 0x96, 0x48, 0xD0, 0x06, 0x10, 0x7D, 0xD7};
|
||||
res = res && (memcmp(dctx.key, dkey, sizeof(dkey)) == 0);
|
||||
|
||||
if (res)
|
||||
PrintAndLogEx(INFO, "An10922 2TDEA..... " _GREEN_("ok"));
|
||||
else
|
||||
PrintAndLogEx(ERR, "An10922 2TDEA..... " _RED_("fail"));
|
||||
|
||||
PrintAndLogEx(INFO, "An10922 2TDEA..... ( %s )", (res) ? _GREEN_("ok") : _RED_("fail"));
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -201,11 +181,7 @@ static bool TestAn10922KDF3TDEA(void) {
|
|||
};
|
||||
res = res && (memcmp(dctx.key, dkey, sizeof(dkey)) == 0);
|
||||
|
||||
if (res)
|
||||
PrintAndLogEx(INFO, "An10922 3TDEA..... " _GREEN_("ok"));
|
||||
else
|
||||
PrintAndLogEx(ERR, "An10922 3TDEA..... " _RED_("fail"));
|
||||
|
||||
PrintAndLogEx(INFO, "An10922 3TDEA..... ( %s )", (res) ? _GREEN_("ok") : _RED_("fail"));
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -245,11 +221,7 @@ static bool TestCMAC3TDEA(void) {
|
|||
DesfireCryptoCMAC(&dctx, CMACData, 32, cmac);
|
||||
res = res && (memcmp(cmac, cmac4, sizeof(cmac1)) == 0);
|
||||
|
||||
if (res)
|
||||
PrintAndLogEx(INFO, "CMAC 3TDEA........ " _GREEN_("ok"));
|
||||
else
|
||||
PrintAndLogEx(ERR, "CMAC 3TDEA........ " _RED_("fail"));
|
||||
|
||||
PrintAndLogEx(INFO, "CMAC 3TDEA........ ( %s )", (res) ? _GREEN_("ok") : _RED_("fail"));
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -289,11 +261,7 @@ static bool TestCMAC2TDEA(void) {
|
|||
DesfireCryptoCMAC(&dctx, CMACData, 32, cmac);
|
||||
res = res && (memcmp(cmac, cmac4, sizeof(cmac1)) == 0);
|
||||
|
||||
if (res)
|
||||
PrintAndLogEx(INFO, "CMAC 2TDEA........ " _GREEN_("ok"));
|
||||
else
|
||||
PrintAndLogEx(ERR, "CMAC 2TDEA........ " _RED_("fail"));
|
||||
|
||||
PrintAndLogEx(INFO, "CMAC 2TDEA........ ( %s )", (res) ? _GREEN_("ok") : _RED_("fail"));
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -329,11 +297,7 @@ static bool TestCMACDES(void) {
|
|||
DesfireCryptoCMAC(&dctx, CMACData, 32, cmac);
|
||||
res = res && (memcmp(cmac, cmac4, sizeof(cmac1)) == 0);
|
||||
|
||||
if (res)
|
||||
PrintAndLogEx(INFO, "CMAC DES.......... " _GREEN_("ok"));
|
||||
else
|
||||
PrintAndLogEx(ERR, "CMAC DES.......... " _RED_("fail"));
|
||||
|
||||
PrintAndLogEx(INFO, "CMAC DES.......... ( %s )", (res) ? _GREEN_("ok") : _RED_("fail"));
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -356,11 +320,7 @@ static bool TestEV2SessionKeys(void) {
|
|||
DesfireGenSessionKeyEV2(key, rnda, rndb, false, sessionkey);
|
||||
res = res && (memcmp(sessionkey, sessionkeymac, sizeof(sessionkeymac)) == 0);
|
||||
|
||||
if (res)
|
||||
PrintAndLogEx(INFO, "EV2 session keys.. " _GREEN_("ok"));
|
||||
else
|
||||
PrintAndLogEx(ERR, "EV2 session keys.. " _RED_("fail"));
|
||||
|
||||
PrintAndLogEx(INFO, "EV2 session keys.. ( %s )", (res) ? _GREEN_("ok") : _RED_("fail"));
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -392,11 +352,7 @@ static bool TestEV2IVEncode(void) {
|
|||
DesfireEV2FillIV(&ctx, true, iv);
|
||||
res = res && (memcmp(iv, ivres2, sizeof(ivres2)) == 0);
|
||||
|
||||
if (res)
|
||||
PrintAndLogEx(INFO, "EV2 IV calc....... " _GREEN_("ok"));
|
||||
else
|
||||
PrintAndLogEx(ERR, "EV2 IV calc....... " _RED_("fail"));
|
||||
|
||||
PrintAndLogEx(INFO, "EV2 IV calc....... ( %s )", (res) ? _GREEN_("ok") : _RED_("fail"));
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -452,17 +408,12 @@ static bool TestEV2MAC(void) {
|
|||
DesfireEV2CalcCMAC(&ctx, rc, cmddata4, sizeof(cmddata4), mac);
|
||||
res = res && (memcmp(mac, macres4, sizeof(macres4)) == 0);
|
||||
|
||||
if (res)
|
||||
PrintAndLogEx(INFO, "EV2 MAC calc...... " _GREEN_("ok"));
|
||||
else
|
||||
PrintAndLogEx(ERR, "EV2 MAC calc...... " _RED_("fail"));
|
||||
|
||||
PrintAndLogEx(INFO, "EV2 MAC calc...... ( %s )", (res) ? _GREEN_("ok") : _RED_("fail"));
|
||||
return res;
|
||||
}
|
||||
|
||||
static bool TestTransSessionKeys(void) {
|
||||
bool res = true;
|
||||
|
||||
uint8_t key[] = {0x66, 0xA8, 0xCB, 0x93, 0x26, 0x9D, 0xC9, 0xBC, 0x28, 0x85, 0xB7, 0xA9, 0x1B, 0x9C, 0x69, 0x7B};
|
||||
uint8_t uid[] = {0x04, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06};
|
||||
uint32_t trCntr = 8;
|
||||
|
@ -476,11 +427,7 @@ static bool TestTransSessionKeys(void) {
|
|||
uint8_t keyenc[] = {0x11, 0x9B, 0x90, 0x2A, 0x07, 0xB1, 0x8A, 0x86, 0x5B, 0x8E, 0x1B, 0x00, 0x60, 0x59, 0x47, 0x84};
|
||||
res = res && (memcmp(sessionkey, keyenc, sizeof(keyenc)) == 0);
|
||||
|
||||
if (res)
|
||||
PrintAndLogEx(INFO, "Trans session key. " _GREEN_("ok"));
|
||||
else
|
||||
PrintAndLogEx(ERR, "Trans session key. " _RED_("fail"));
|
||||
|
||||
PrintAndLogEx(INFO, "Trans session key. ( %s )", (res) ? _GREEN_("ok") : _RED_("fail"));
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -505,11 +452,7 @@ static bool TestLRPPlaintexts(void) {
|
|||
uint8_t pt15[] = {0x71, 0xB4, 0x44, 0xAF, 0x25, 0x7A, 0x93, 0x21, 0x53, 0x11, 0xD7, 0x58, 0xDD, 0x33, 0x32, 0x47};
|
||||
res = res && (memcmp(ctx.plaintexts[15], pt15, sizeof(pt15)) == 0);
|
||||
|
||||
if (res)
|
||||
PrintAndLogEx(INFO, "LRP plaintexts.... " _GREEN_("ok"));
|
||||
else
|
||||
PrintAndLogEx(ERR, "LRP plaintexts.... " _RED_("fail"));
|
||||
|
||||
PrintAndLogEx(INFO, "LRP plaintexts.... ( %s )", (res) ? _GREEN_("ok") : _RED_("fail"));
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -531,11 +474,7 @@ static bool TestLRPUpdatedKeys(void) {
|
|||
uint8_t key2[] = {0xFE, 0x30, 0xAB, 0x50, 0x46, 0x7E, 0x61, 0x78, 0x3B, 0xFE, 0x6B, 0x5E, 0x05, 0x60, 0x16, 0x0E};
|
||||
res = res && (memcmp(ctx.updatedKeys[2], key2, sizeof(key2)) == 0);
|
||||
|
||||
if (res)
|
||||
PrintAndLogEx(INFO, "LRP updated keys.. " _GREEN_("ok"));
|
||||
else
|
||||
PrintAndLogEx(ERR, "LRP updated keys.. " _RED_("fail"));
|
||||
|
||||
PrintAndLogEx(INFO, "LRP updated keys.. ( %s )", (res) ? _GREEN_("ok") : _RED_("fail"));
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -587,11 +526,7 @@ static bool TestLRPEval(void) {
|
|||
uint8_t y5[] = {0xCF, 0x99, 0x13, 0x92, 0xF0, 0x36, 0x93, 0x50, 0xA7, 0xE2, 0x1B, 0xE5, 0x2F, 0x74, 0x88, 0x21};
|
||||
res = res && (memcmp(y, y5, sizeof(y5)) == 0);
|
||||
|
||||
if (res)
|
||||
PrintAndLogEx(INFO, "LRP eval.......... " _GREEN_("ok"));
|
||||
else
|
||||
PrintAndLogEx(ERR, "LRP eval.......... " _RED_("fail"));
|
||||
|
||||
PrintAndLogEx(INFO, "LRP eval.......... ( %s )", (res) ? _GREEN_("ok") : _RED_("fail"));
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -618,11 +553,7 @@ static bool TestLRPIncCounter(void) {
|
|||
uint8_t ctrr4[] = {0x00};
|
||||
res = res && (memcmp(ctr4, ctrr4, sizeof(ctrr4)) == 0);
|
||||
|
||||
if (res)
|
||||
PrintAndLogEx(INFO, "LRP inc counter... " _GREEN_("ok"));
|
||||
else
|
||||
PrintAndLogEx(ERR, "LRP inc counter... " _RED_("fail"));
|
||||
|
||||
PrintAndLogEx(INFO, "LRP inc counter... ( %s )", (res) ? _GREEN_("ok") : _RED_("fail"));
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -686,11 +617,7 @@ static bool TestLRPEncode(void) {
|
|||
res = res && (resplen == sizeof(res5));
|
||||
res = res && (memcmp(resp, res5, sizeof(res5)) == 0);
|
||||
|
||||
if (res)
|
||||
PrintAndLogEx(INFO, "LRP encode........ " _GREEN_("ok"));
|
||||
else
|
||||
PrintAndLogEx(ERR, "LRP encode........ " _RED_("fail"));
|
||||
|
||||
PrintAndLogEx(INFO, "LRP encode........ ( %s )", (res) ? _GREEN_("ok") : _RED_("fail"));
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -753,11 +680,7 @@ static bool TestLRPDecode(void) {
|
|||
res = res && (resplen == sizeof(res5));
|
||||
res = res && (memcmp(resp, res5, sizeof(res5)) == 0);
|
||||
|
||||
if (res)
|
||||
PrintAndLogEx(INFO, "LRP decode........ " _GREEN_("ok"));
|
||||
else
|
||||
PrintAndLogEx(ERR, "LRP decode........ " _RED_("fail"));
|
||||
|
||||
PrintAndLogEx(INFO, "LRP decode........ ( %s )", (res) ? _GREEN_("ok") : _RED_("fail"));
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -793,11 +716,7 @@ static bool TestLRPSubkeys(void) {
|
|||
res = res && (memcmp(sk1, sk1r3, sizeof(sk1r3)) == 0);
|
||||
res = res && (memcmp(sk2, sk2r3, sizeof(sk2r3)) == 0);
|
||||
|
||||
if (res)
|
||||
PrintAndLogEx(INFO, "LRP subkeys....... " _GREEN_("ok"));
|
||||
else
|
||||
PrintAndLogEx(ERR, "LRP subkeys....... " _RED_("fail"));
|
||||
|
||||
PrintAndLogEx(INFO, "LRP subkeys....... ( %s )", (res) ? _GREEN_("ok") : _RED_("fail"));
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -855,11 +774,7 @@ static bool TestLRPCMAC(void) {
|
|||
uint8_t cmacres6[] = {0x05, 0xF1, 0xCE, 0x30, 0x45, 0x1A, 0x03, 0xA6, 0xE4, 0x68, 0xB3, 0xA5, 0x90, 0x33, 0xA5, 0x54};
|
||||
res = res && (memcmp(cmac, cmacres6, sizeof(cmacres6)) == 0);
|
||||
|
||||
if (res)
|
||||
PrintAndLogEx(INFO, "LRP CMAC.......... " _GREEN_("ok"));
|
||||
else
|
||||
PrintAndLogEx(ERR, "LRP CMAC.......... " _RED_("fail"));
|
||||
|
||||
PrintAndLogEx(INFO, "LRP CMAC.......... ( %s )", (res) ? _GREEN_("ok") : _RED_("fail"));
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -877,11 +792,7 @@ static bool TestLRPSessionKeys(void) {
|
|||
DesfireGenSessionKeyLRP(key, rnda, rndb, true, sessionkey);
|
||||
res = res && (memcmp(sessionkey, sessionkeyres, sizeof(sessionkeyres)) == 0);
|
||||
|
||||
if (res)
|
||||
PrintAndLogEx(INFO, "LRP session keys.. " _GREEN_("ok"));
|
||||
else
|
||||
PrintAndLogEx(ERR, "LRP session keys.. " _RED_("fail"));
|
||||
|
||||
PrintAndLogEx(INFO, "LRP session keys.. ( %s )", (res) ? _GREEN_("ok") : _RED_("fail"));
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -914,11 +825,7 @@ bool DesfireTest(bool verbose) {
|
|||
res = res && TestLRPSessionKeys();
|
||||
|
||||
PrintAndLogEx(INFO, "---------------------------");
|
||||
if (res)
|
||||
PrintAndLogEx(SUCCESS, " Tests [ %s ]", _GREEN_("ok"));
|
||||
else
|
||||
PrintAndLogEx(FAILED, " Tests [ %s ]", _RED_("fail"));
|
||||
|
||||
PrintAndLogEx(SUCCESS, "Tests ( %s )", (res) ? _GREEN_("ok") : _RED_("fail"));
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
return res;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue