fixing buffer overflow when reading large files

This commit is contained in:
iceman1001 2024-04-22 09:17:58 +02:00
commit 365454bb3c
4 changed files with 145 additions and 177 deletions

View file

@ -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);
}

View file

@ -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};

View file

@ -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) {

View file

@ -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;
}