mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-21 13:53:55 -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,7 +674,7 @@ static int DesfireExchangeISONative(bool activate_field, DesfireContext_t *ctx,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (respcode) {
|
if (respcode) {
|
||||||
*respcode = 0xff;
|
*respcode = 0xFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t sw = 0;
|
uint16_t sw = 0;
|
||||||
|
@ -698,10 +698,11 @@ static int DesfireExchangeISONative(bool activate_field, DesfireContext_t *ctx,
|
||||||
// tx chaining
|
// tx chaining
|
||||||
size_t sentdatalen = 0;
|
size_t sentdatalen = 0;
|
||||||
while (datalen >= sentdatalen) {
|
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;
|
apdu.Lc = DESFIRE_TX_FRAME_MAX_LEN;
|
||||||
else
|
} else {
|
||||||
apdu.Lc = datalen - sentdatalen;
|
apdu.Lc = datalen - sentdatalen;
|
||||||
|
}
|
||||||
|
|
||||||
apdu.data = &data[sentdatalen];
|
apdu.data = &data[sentdatalen];
|
||||||
|
|
||||||
|
@ -725,8 +726,8 @@ static int DesfireExchangeISONative(bool activate_field, DesfireContext_t *ctx,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (respcode != NULL && ((sw & 0xff00) == 0x9100)) {
|
if (respcode != NULL && ((sw & 0xFF00) == 0x9100)) {
|
||||||
*respcode = sw & 0xff;
|
*respcode = sw & 0xFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resp) {
|
if (resp) {
|
||||||
|
@ -759,6 +760,8 @@ static int DesfireExchangeISONative(bool activate_field, DesfireContext_t *ctx,
|
||||||
apdu.P2 = 0;
|
apdu.P2 = 0;
|
||||||
apdu.data = NULL;
|
apdu.data = NULL;
|
||||||
|
|
||||||
|
buflen = 0;
|
||||||
|
|
||||||
res = DESFIRESendApdu(false, apdu, buf, DESFIRE_BUFFER_SIZE, &buflen, &sw);
|
res = DESFIRESendApdu(false, apdu, buf, DESFIRE_BUFFER_SIZE, &buflen, &sw);
|
||||||
if (res != PM3_SUCCESS) {
|
if (res != PM3_SUCCESS) {
|
||||||
PrintAndLogEx(DEBUG, "error DESFIRESendApdu %s", DesfireGetErrorString(res, &sw));
|
PrintAndLogEx(DEBUG, "error DESFIRESendApdu %s", DesfireGetErrorString(res, &sw));
|
||||||
|
@ -766,8 +769,8 @@ static int DesfireExchangeISONative(bool activate_field, DesfireContext_t *ctx,
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (respcode != NULL && ((sw & 0xff00) == 0x9100)) {
|
if (respcode != NULL && ((sw & 0xFF00) == 0x9100)) {
|
||||||
*respcode = sw & 0xff;
|
*respcode = sw & 0xFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resp != NULL) {
|
if (resp != NULL) {
|
||||||
|
@ -776,9 +779,10 @@ static int DesfireExchangeISONative(bool activate_field, DesfireContext_t *ctx,
|
||||||
memcpy(&resp[i * splitbysize + 1], buf, buflen);
|
memcpy(&resp[i * splitbysize + 1], buf, buflen);
|
||||||
i += 1;
|
i += 1;
|
||||||
} else {
|
} else {
|
||||||
memcpy(&resp[pos], buf, buflen);
|
memcpy(resp + (pos), buf, buflen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pos += buflen;
|
pos += buflen;
|
||||||
|
|
||||||
if (sw != DESFIRE_GET_ISO_STATUS(MFDES_ADDITIONAL_FRAME)) {
|
if (sw != DESFIRE_GET_ISO_STATUS(MFDES_ADDITIONAL_FRAME)) {
|
||||||
|
@ -786,6 +790,7 @@ static int DesfireExchangeISONative(bool activate_field, DesfireContext_t *ctx,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (resplen) {
|
if (resplen) {
|
||||||
*resplen = (splitbysize) ? i : pos;
|
*resplen = (splitbysize) ? i : pos;
|
||||||
}
|
}
|
||||||
|
@ -866,13 +871,14 @@ int DesfireExchangeEx(bool activate_field, DesfireContext_t *ctx, uint8_t cmd, u
|
||||||
case DCCNativeISO:
|
case DCCNativeISO:
|
||||||
DesfireSecureChannelEncode(ctx, cmd, data, datalen, databuf, &databuflen);
|
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);
|
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);
|
res = DesfireExchangeISONative(activate_field, ctx, cmd, databuf, databuflen, respcode, databuf, &databuflen, enable_chaining, splitbysize);
|
||||||
|
}
|
||||||
|
|
||||||
if (splitbysize) {
|
if (splitbysize) {
|
||||||
uint8_t sdata[250 * 5] = {0};
|
uint8_t sdata[DESFIRE_BUFFER_SIZE] = {0};
|
||||||
size_t sdatalen = 0;
|
size_t sdatalen = 0;
|
||||||
DesfireJoinBlockToBytes(databuf, databuflen, splitbysize, sdata, &sdatalen);
|
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) {
|
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;
|
*resplen = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t respcode = 0xFF;
|
||||||
|
|
||||||
uint8_t respcode = 0xff;
|
|
||||||
uint8_t *xresp = calloc(DESFIRE_BUFFER_SIZE, 1);
|
uint8_t *xresp = calloc(DESFIRE_BUFFER_SIZE, 1);
|
||||||
if (xresp == NULL)
|
if (xresp == NULL) {
|
||||||
return PM3_EMALLOC;
|
return PM3_EMALLOC;
|
||||||
|
}
|
||||||
|
|
||||||
size_t xresplen = 0;
|
size_t xresplen = 0;
|
||||||
int res = DesfireExchangeEx(false, dctx, cmd, data, datalen, &respcode, xresp, &xresplen, true, splitbysize);
|
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);
|
free(xresp);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (respcode != MFDES_S_OPERATION_OK) {
|
if (respcode != MFDES_S_OPERATION_OK) {
|
||||||
free(xresp);
|
free(xresp);
|
||||||
return PM3_EAPDU_FAIL;
|
return PM3_EAPDU_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (checklength >= 0 && xresplen != checklength) {
|
if (checklength >= 0 && xresplen != checklength) {
|
||||||
free(xresp);
|
free(xresp);
|
||||||
return PM3_EAPDU_FAIL;
|
return PM3_EAPDU_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resplen)
|
if (resplen) {
|
||||||
*resplen = xresplen;
|
*resplen = xresplen;
|
||||||
if (resp)
|
}
|
||||||
|
|
||||||
|
if (resp) {
|
||||||
memcpy(resp, xresp, (splitbysize == 0) ? xresplen : xresplen * splitbysize);
|
memcpy(resp, xresp, (splitbysize == 0) ? xresplen : xresplen * splitbysize);
|
||||||
|
}
|
||||||
|
|
||||||
free(xresp);
|
free(xresp);
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
|
@ -1996,13 +2010,16 @@ int DesfireReadSignature(DesfireContext_t *dctx, uint8_t sid, uint8_t *resp, siz
|
||||||
uint8_t respcode = 0xff;
|
uint8_t respcode = 0xff;
|
||||||
|
|
||||||
int res = DesfireExchange(dctx, MFDES_READSIG, &sid, 1, &respcode, xresp, &xresplen);
|
int res = DesfireExchange(dctx, MFDES_READSIG, &sid, 1, &respcode, xresp, &xresplen);
|
||||||
if (res != PM3_SUCCESS)
|
if (res != PM3_SUCCESS) {
|
||||||
return res;
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
if (respcode != 0x90)
|
if (respcode != 0x90) {
|
||||||
return PM3_EAPDU_FAIL;
|
return PM3_EAPDU_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(resp, xresp, xresplen);
|
memcpy(resp, xresp, xresplen);
|
||||||
|
|
||||||
*resplen = xresplen;
|
*resplen = xresplen;
|
||||||
|
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
|
@ -2172,7 +2189,6 @@ int DesfireReadFile(DesfireContext_t *dctx, uint8_t fnum, uint32_t offset, uint3
|
||||||
data[0] = fnum;
|
data[0] = fnum;
|
||||||
Uint3byteToMemLe(&data[1], offset);
|
Uint3byteToMemLe(&data[1], offset);
|
||||||
Uint3byteToMemLe(&data[4], len);
|
Uint3byteToMemLe(&data[4], len);
|
||||||
|
|
||||||
return DesfireCommand(dctx, (dctx->isoChaining) ? MFDES_READ_DATA2 : MFDES_READ_DATA, data, 7, resp, resplen, -1);
|
return DesfireCommand(dctx, (dctx->isoChaining) ? MFDES_READ_DATA2 : MFDES_READ_DATA, data, 7, resp, resplen, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include "crc16.h" // crc16 ccitt
|
#include "crc16.h" // crc16 ccitt
|
||||||
#include "crc32.h"
|
#include "crc32.h"
|
||||||
#include "commonutil.h"
|
#include "commonutil.h"
|
||||||
|
#include "desfirecore.h" // DESFIRE_BUFFER_SIZE
|
||||||
|
|
||||||
void DesfireClearContext(DesfireContext_t *ctx) {
|
void DesfireClearContext(DesfireContext_t *ctx) {
|
||||||
ctx->keyNum = 0;
|
ctx->keyNum = 0;
|
||||||
|
@ -148,22 +149,29 @@ size_t DesfireSearchCRCPos(uint8_t *data, size_t datalen, uint8_t respcode, uint
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t crcdata[1024] = {0};
|
uint8_t crcdata[DESFIRE_BUFFER_SIZE] = {0};
|
||||||
size_t crcposfound = 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)
|
// 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++) {
|
for (int i = 0; i < crclen + 2; i++) {
|
||||||
if (crcpos - i == 0)
|
|
||||||
|
if (crcpos - i == 0) {
|
||||||
break;
|
break;
|
||||||
if (crcpos - i + crclen > datalen)
|
}
|
||||||
|
|
||||||
|
if (crcpos - i + crclen > datalen) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(crcdata, data, crcpos - i);
|
memcpy(crcdata, data, crcpos - i);
|
||||||
crcdata[crcpos - i] = respcode;
|
crcdata[crcpos - i] = respcode;
|
||||||
|
|
||||||
bool res;
|
bool res;
|
||||||
if (crclen == 4)
|
if (crclen == 4) {
|
||||||
res = desfire_crc32_check(crcdata, crcpos - i + 1, &data[crcpos - i]);
|
res = desfire_crc32_check(crcdata, crcpos - i + 1, &data[crcpos - i]);
|
||||||
else
|
} else {
|
||||||
res = iso14443a_crc_check(data, crcpos - i, &data[crcpos - i]);
|
res = iso14443a_crc_check(data, crcpos - i, &data[crcpos - i]);
|
||||||
|
}
|
||||||
|
|
||||||
if (res) {
|
if (res) {
|
||||||
crcposfound = crcpos - i;
|
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) {
|
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};
|
uint8_t xiv[DESFIRE_MAX_CRYPTO_BLOCK_SIZE] = {0};
|
||||||
|
|
||||||
if (ctx->secureChannel == DACd40) {
|
if (ctx->secureChannel == DACd40) {
|
||||||
|
@ -287,15 +296,17 @@ void DesfireCryptoEncDecEx(DesfireContext_t *ctx, DesfireCryptoOpKeyType key_typ
|
||||||
else
|
else
|
||||||
memcpy(iv, xiv, block_size);
|
memcpy(iv, xiv, block_size);
|
||||||
|
|
||||||
if (dstdata)
|
if (dstdata) {
|
||||||
memcpy(dstdata, data, srcdatalen);
|
memcpy(dstdata, data, srcdatalen);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DesfireCryptoEncDec(DesfireContext_t *ctx, DesfireCryptoOpKeyType key_type, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, bool encode) {
|
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 dir_to_send = encode;
|
||||||
bool xencode = encode;
|
bool xencode = encode;
|
||||||
if (ctx->secureChannel == DACd40)
|
if (ctx->secureChannel == DACd40) {
|
||||||
xencode = false;
|
xencode = false;
|
||||||
|
}
|
||||||
|
|
||||||
DesfireCryptoEncDecEx(ctx, key_type, srcdata, srcdatalen, dstdata, dir_to_send, xencode, NULL);
|
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) {
|
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);
|
int kbs = desfire_get_key_block_length(ctx->keyType);
|
||||||
if (kbs == 0)
|
if (kbs == 0) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t buffer[padded_data_length(MAX(minlen, len) + 1, kbs)];
|
uint8_t buffer[padded_data_length(MAX(minlen, len) + 1, kbs)];
|
||||||
memset(buffer, 0, sizeof(buffer));
|
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);
|
DesfireCryptoEncDec(ctx, key_type, buffer, len, NULL, true);
|
||||||
|
|
||||||
if (cmac != NULL)
|
if (cmac != NULL) {
|
||||||
memcpy(cmac, ctx->IV, kbs);
|
memcpy(cmac, ctx->IV, kbs);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DesfireCryptoCMAC(DesfireContext_t *ctx, uint8_t *data, size_t len, uint8_t *cmac) {
|
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;
|
return;
|
||||||
|
|
||||||
int kbs = desfire_get_key_block_length(ctx->keyType); // 8 or 16
|
int kbs = desfire_get_key_block_length(ctx->keyType); // 8 or 16
|
||||||
if (kbs == 0)
|
if (kbs == 0) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t cmac[DESFIRE_MAX_CRYPTO_BLOCK_SIZE * 3] = {0};
|
uint8_t cmac[DESFIRE_MAX_CRYPTO_BLOCK_SIZE * 3] = {0};
|
||||||
uint8_t buffer[DESFIRE_MAX_CRYPTO_BLOCK_SIZE * 3] = {0};
|
uint8_t buffer[DESFIRE_MAX_CRYPTO_BLOCK_SIZE * 3] = {0};
|
||||||
|
|
||||||
if (ctx->keyType == T_AES) {
|
if (ctx->keyType == T_AES) {
|
||||||
// AES uses 16 byte IV
|
// AES uses 16 byte IV
|
||||||
if (kbs < CRYPTO_AES_BLOCK_SIZE)
|
if (kbs < CRYPTO_AES_BLOCK_SIZE) {
|
||||||
kbs = CRYPTO_AES_BLOCK_SIZE;
|
kbs = CRYPTO_AES_BLOCK_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
buffer[0] = 0x01;
|
buffer[0] = 0x01;
|
||||||
memcpy(&buffer[1], data, len);
|
memcpy(&buffer[1], data, len);
|
||||||
|
@ -429,8 +444,9 @@ void DesfireDESKeySetVersion(uint8_t *key, DesfireCryptoAlgorithm keytype, uint8
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// clear version
|
// 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;
|
key[n] &= 0xFE;
|
||||||
|
}
|
||||||
|
|
||||||
// set version
|
// set version
|
||||||
for (int n = 0; n < 8; n++) {
|
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 DesfireDESKeyGetVersion(const uint8_t *key) {
|
||||||
uint8_t version = 0;
|
uint8_t version = 0;
|
||||||
for (int n = 0; n < 8; n++)
|
for (int n = 0; n < 8; n++) {
|
||||||
version |= ((key[n] & 1) << (7 - n));
|
version |= ((key[n] & 1) << (7 - n));
|
||||||
|
}
|
||||||
|
|
||||||
return version;
|
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) {
|
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;
|
size_t mdatalen = 0;
|
||||||
|
|
||||||
mdata[0] = cmd;
|
mdata[0] = cmd;
|
||||||
Uint2byteToMemLe(&mdata[1], ctx->cmdCntr);
|
Uint2byteToMemLe(&mdata[1], ctx->cmdCntr);
|
||||||
memcpy(&mdata[3], ctx->TI, 4);
|
memcpy(&mdata[3], ctx->TI, 4);
|
||||||
if (data != NULL && datalen > 0)
|
if (data != NULL && datalen > 0) {
|
||||||
memcpy(&mdata[7], data, datalen);
|
memcpy(&mdata[7], data, datalen);
|
||||||
|
}
|
||||||
|
|
||||||
mdatalen = 1 + 2 + 4 + datalen;
|
mdatalen = 1 + 2 + 4 + datalen;
|
||||||
|
|
||||||
return aes_cmac8(NULL, ctx->sessionKeyMAC, mdata, mac, mdatalen);
|
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) {
|
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;
|
size_t mdatalen = 0;
|
||||||
|
|
||||||
mdata[0] = cmd;
|
mdata[0] = cmd;
|
||||||
Uint2byteToMemLe(&mdata[1], ctx->cmdCntr);
|
Uint2byteToMemLe(&mdata[1], ctx->cmdCntr);
|
||||||
|
|
||||||
memcpy(&mdata[3], ctx->TI, 4);
|
memcpy(&mdata[3], ctx->TI, 4);
|
||||||
if (data != NULL && datalen > 0)
|
|
||||||
|
if (data != NULL && datalen > 0) {
|
||||||
memcpy(&mdata[7], data, datalen);
|
memcpy(&mdata[7], data, datalen);
|
||||||
|
}
|
||||||
|
|
||||||
mdatalen = 1 + 2 + 4 + datalen;
|
mdatalen = 1 + 2 + 4 + datalen;
|
||||||
|
|
||||||
LRPContext_t lctx = {0};
|
LRPContext_t lctx = {0};
|
||||||
|
|
|
@ -49,9 +49,11 @@ static const uint8_t CommandsCanUseAnyChannel[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool CommandCanUseAnyChannel(uint8_t cmd) {
|
static bool CommandCanUseAnyChannel(uint8_t cmd) {
|
||||||
for (int i = 0; i < ARRAYLEN(CommandsCanUseAnyChannel); i++)
|
for (int i = 0; i < ARRAYLEN(CommandsCanUseAnyChannel); i++) {
|
||||||
if (CommandsCanUseAnyChannel[i] == cmd)
|
if (CommandsCanUseAnyChannel[i] == cmd) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,10 +209,11 @@ static const CmdHeaderLengths_t CmdHeaderLengths[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static uint8_t DesfireGetCmdHeaderLen(uint8_t cmd) {
|
static uint8_t DesfireGetCmdHeaderLen(uint8_t cmd) {
|
||||||
for (int i = 0; i < ARRAYLEN(CmdHeaderLengths); i++)
|
for (int i = 0; i < ARRAYLEN(CmdHeaderLengths); i++) {
|
||||||
if (CmdHeaderLengths[i].cmd == cmd)
|
if (CmdHeaderLengths[i].cmd == cmd) {
|
||||||
return CmdHeaderLengths[i].len;
|
return CmdHeaderLengths[i].len;
|
||||||
|
}
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -228,12 +231,15 @@ static const uint8_t EV1D40TransmitMAC[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool DesfireEV1D40TransmitMAC(DesfireContext_t *ctx, uint8_t cmd) {
|
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;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < ARRAYLEN(EV1D40TransmitMAC); i++)
|
for (int i = 0; i < ARRAYLEN(EV1D40TransmitMAC); i++) {
|
||||||
if (EV1D40TransmitMAC[i] == cmd)
|
if (EV1D40TransmitMAC[i] == cmd) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -247,12 +253,15 @@ static const uint8_t D40ReceiveMAC[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool DesfireEV1D40ReceiveMAC(DesfireContext_t *ctx, uint8_t cmd) {
|
static bool DesfireEV1D40ReceiveMAC(DesfireContext_t *ctx, uint8_t cmd) {
|
||||||
if (ctx->secureChannel != DACd40)
|
if (ctx->secureChannel != DACd40) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < ARRAYLEN(D40ReceiveMAC); i++)
|
for (int i = 0; i < ARRAYLEN(D40ReceiveMAC); i++) {
|
||||||
if (D40ReceiveMAC[i] == cmd)
|
if (D40ReceiveMAC[i] == cmd) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -269,10 +278,11 @@ static const uint8_t ISOChannelValidCmd[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool DesfireISOChannelValidCmd(uint8_t cmd) {
|
static bool DesfireISOChannelValidCmd(uint8_t cmd) {
|
||||||
for (int i = 0; i < ARRAYLEN(ISOChannelValidCmd); i++)
|
for (int i = 0; i < ARRAYLEN(ISOChannelValidCmd); i++) {
|
||||||
if (ISOChannelValidCmd[i] == cmd)
|
if (ISOChannelValidCmd[i] == cmd) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
return false;
|
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) {
|
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));
|
uint8_t *data = calloc(DESFIRE_BUFFER_SIZE, sizeof(uint8_t));
|
||||||
if (data == NULL)
|
if (data == NULL) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(dstdata, srcdata, srcdatalen);
|
memcpy(dstdata, srcdata, srcdatalen);
|
||||||
*dstdatalen = srcdatalen;
|
*dstdatalen = srcdatalen;
|
||||||
|
|
||||||
uint8_t hdrlen = DesfireGetCmdHeaderLen(cmd);
|
uint8_t hdrlen = DesfireGetCmdHeaderLen(cmd);
|
||||||
if (srcdatalen < hdrlen)
|
if (srcdatalen < hdrlen) {
|
||||||
hdrlen = srcdatalen;
|
hdrlen = srcdatalen;
|
||||||
|
}
|
||||||
|
|
||||||
size_t rlen;
|
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) {
|
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));
|
uint8_t *data = calloc(DESFIRE_BUFFER_SIZE, sizeof(uint8_t));
|
||||||
if (data == NULL)
|
if (data == NULL) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// if comm mode = plain --> response with MAC
|
// if comm mode = plain --> response with MAC
|
||||||
// if request is not zero length --> response MAC
|
// if request is not zero length --> response MAC
|
||||||
if (ctx->commMode == DCMPlain || ctx->commMode == DCMMACed || (ctx->commMode == DCMEncrypted && !ctx->lastRequestZeroLen)) {
|
if (ctx->commMode == DCMPlain || ctx->commMode == DCMMACed || (ctx->commMode == DCMEncrypted && !ctx->lastRequestZeroLen)) {
|
||||||
|
|
||||||
if (srcdatalen < DesfireGetMACLength(ctx)) {
|
if (srcdatalen < DesfireGetMACLength(ctx)) {
|
||||||
memcpy(dstdata, srcdata, srcdatalen);
|
memcpy(dstdata, srcdata, srcdatalen);
|
||||||
*dstdatalen = srcdatalen;
|
*dstdatalen = srcdatalen;
|
||||||
|
@ -596,6 +610,7 @@ static void DesfireSecureChannelDecodeEV1(DesfireContext_t *ctx, uint8_t *srcdat
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(dstdata, srcdata, srcdatalen - DesfireGetMACLength(ctx));
|
memcpy(dstdata, srcdata, srcdatalen - DesfireGetMACLength(ctx));
|
||||||
|
|
||||||
*dstdatalen = srcdatalen - DesfireGetMACLength(ctx);
|
*dstdatalen = srcdatalen - DesfireGetMACLength(ctx);
|
||||||
|
|
||||||
memcpy(data, srcdata, *dstdatalen);
|
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};
|
uint8_t cmac[DESFIRE_MAX_CRYPTO_BLOCK_SIZE] = {0};
|
||||||
DesfireCryptoCMAC(ctx, data, *dstdatalen + 1, cmac);
|
DesfireCryptoCMAC(ctx, data, *dstdatalen + 1, cmac);
|
||||||
|
|
||||||
if (memcmp(&srcdata[*dstdatalen], cmac, DesfireGetMACLength(ctx)) != 0) {
|
if (memcmp(&srcdata[*dstdatalen], cmac, DesfireGetMACLength(ctx)) != 0) {
|
||||||
|
|
||||||
PrintAndLogEx(WARNING, "Received MAC is not match with calculated");
|
PrintAndLogEx(WARNING, "Received MAC is not match with calculated");
|
||||||
PrintAndLogEx(INFO, " received MAC: %s", sprint_hex(&srcdata[*dstdatalen], DesfireGetMACLength(ctx)));
|
PrintAndLogEx(INFO, " received MAC: %s", sprint_hex(&srcdata[*dstdatalen], DesfireGetMACLength(ctx)));
|
||||||
PrintAndLogEx(INFO, " calculated MAC: %s", sprint_hex(cmac, DesfireGetMACLength(ctx)));
|
PrintAndLogEx(INFO, " calculated MAC: %s", sprint_hex(cmac, DesfireGetMACLength(ctx)));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (GetAPDULogging())
|
|
||||||
|
if (GetAPDULogging()) {
|
||||||
PrintAndLogEx(INFO, "Received MAC OK");
|
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)) {
|
if (srcdatalen < desfire_get_key_block_length(ctx->keyType)) {
|
||||||
memcpy(dstdata, srcdata, srcdatalen);
|
memcpy(dstdata, srcdata, srcdatalen);
|
||||||
*dstdatalen = srcdatalen;
|
*dstdatalen = srcdatalen;
|
||||||
|
@ -620,7 +642,7 @@ static void DesfireSecureChannelDecodeEV1(DesfireContext_t *ctx, uint8_t *srcdat
|
||||||
}
|
}
|
||||||
|
|
||||||
DesfireCryptoEncDec(ctx, DCOSessionKeyEnc, srcdata, srcdatalen, dstdata, false);
|
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);
|
size_t puredatalen = DesfireSearchCRCPos(dstdata, srcdatalen, respcode, 4);
|
||||||
if (puredatalen != 0) {
|
if (puredatalen != 0) {
|
||||||
|
|
|
@ -53,11 +53,7 @@ static bool TestCRC16(void) {
|
||||||
len = DesfireSearchCRCPos(data, 1, 0x00, 2);
|
len = DesfireSearchCRCPos(data, 1, 0x00, 2);
|
||||||
res = res && (len == 0);
|
res = res && (len == 0);
|
||||||
|
|
||||||
if (res)
|
PrintAndLogEx(INFO, "CRC16............. ( %s )", (res) ? _GREEN_("ok") : _RED_("fail"));
|
||||||
PrintAndLogEx(INFO, "CRC16............. " _GREEN_("ok"));
|
|
||||||
else
|
|
||||||
PrintAndLogEx(ERR, "CRC16............. " _RED_("fail"));
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,11 +76,7 @@ static bool TestCRC32(void) {
|
||||||
len = DesfireSearchCRCPos(data, 2, 0x00, 4);
|
len = DesfireSearchCRCPos(data, 2, 0x00, 4);
|
||||||
res = res && (len == 0);
|
res = res && (len == 0);
|
||||||
|
|
||||||
if (res)
|
PrintAndLogEx(INFO, "CRC32............. ( %s )", (res) ? _GREEN_("ok") : _RED_("fail"));
|
||||||
PrintAndLogEx(INFO, "CRC32............. " _GREEN_("ok"));
|
|
||||||
else
|
|
||||||
PrintAndLogEx(ERR, "CRC32............. " _RED_("fail"));
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,11 +123,7 @@ static bool TestCMACSubkeys(void) {
|
||||||
res = res && (memcmp(sk1, sk1_3tdea, sizeof(sk1_3tdea)) == 0);
|
res = res && (memcmp(sk1, sk1_3tdea, sizeof(sk1_3tdea)) == 0);
|
||||||
res = res && (memcmp(sk2, sk2_3tdea, sizeof(sk2_3tdea)) == 0);
|
res = res && (memcmp(sk2, sk2_3tdea, sizeof(sk2_3tdea)) == 0);
|
||||||
|
|
||||||
if (res)
|
PrintAndLogEx(INFO, "CMAC subkeys...... ( %s )", (res) ? _GREEN_("ok") : _RED_("fail"));
|
||||||
PrintAndLogEx(INFO, "CMAC subkeys...... " _GREEN_("ok"));
|
|
||||||
else
|
|
||||||
PrintAndLogEx(ERR, "CMAC subkeys...... " _RED_("fail"));
|
|
||||||
|
|
||||||
return res;
|
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};
|
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);
|
res = res && (memcmp(dctx.key, dkey, sizeof(dkey)) == 0);
|
||||||
|
|
||||||
if (res)
|
PrintAndLogEx(INFO, "An10922 AES....... ( %s )", (res) ? _GREEN_("ok") : _RED_("fail"));
|
||||||
PrintAndLogEx(INFO, "An10922 AES....... " _GREEN_("ok"));
|
|
||||||
else
|
|
||||||
PrintAndLogEx(ERR, "An10922 AES....... " _RED_("fail"));
|
|
||||||
|
|
||||||
return res;
|
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};
|
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);
|
res = res && (memcmp(dctx.key, dkey, sizeof(dkey)) == 0);
|
||||||
|
|
||||||
if (res)
|
PrintAndLogEx(INFO, "An10922 2TDEA..... ( %s )", (res) ? _GREEN_("ok") : _RED_("fail"));
|
||||||
PrintAndLogEx(INFO, "An10922 2TDEA..... " _GREEN_("ok"));
|
|
||||||
else
|
|
||||||
PrintAndLogEx(ERR, "An10922 2TDEA..... " _RED_("fail"));
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,11 +181,7 @@ static bool TestAn10922KDF3TDEA(void) {
|
||||||
};
|
};
|
||||||
res = res && (memcmp(dctx.key, dkey, sizeof(dkey)) == 0);
|
res = res && (memcmp(dctx.key, dkey, sizeof(dkey)) == 0);
|
||||||
|
|
||||||
if (res)
|
PrintAndLogEx(INFO, "An10922 3TDEA..... ( %s )", (res) ? _GREEN_("ok") : _RED_("fail"));
|
||||||
PrintAndLogEx(INFO, "An10922 3TDEA..... " _GREEN_("ok"));
|
|
||||||
else
|
|
||||||
PrintAndLogEx(ERR, "An10922 3TDEA..... " _RED_("fail"));
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,11 +221,7 @@ static bool TestCMAC3TDEA(void) {
|
||||||
DesfireCryptoCMAC(&dctx, CMACData, 32, cmac);
|
DesfireCryptoCMAC(&dctx, CMACData, 32, cmac);
|
||||||
res = res && (memcmp(cmac, cmac4, sizeof(cmac1)) == 0);
|
res = res && (memcmp(cmac, cmac4, sizeof(cmac1)) == 0);
|
||||||
|
|
||||||
if (res)
|
PrintAndLogEx(INFO, "CMAC 3TDEA........ ( %s )", (res) ? _GREEN_("ok") : _RED_("fail"));
|
||||||
PrintAndLogEx(INFO, "CMAC 3TDEA........ " _GREEN_("ok"));
|
|
||||||
else
|
|
||||||
PrintAndLogEx(ERR, "CMAC 3TDEA........ " _RED_("fail"));
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -289,11 +261,7 @@ static bool TestCMAC2TDEA(void) {
|
||||||
DesfireCryptoCMAC(&dctx, CMACData, 32, cmac);
|
DesfireCryptoCMAC(&dctx, CMACData, 32, cmac);
|
||||||
res = res && (memcmp(cmac, cmac4, sizeof(cmac1)) == 0);
|
res = res && (memcmp(cmac, cmac4, sizeof(cmac1)) == 0);
|
||||||
|
|
||||||
if (res)
|
PrintAndLogEx(INFO, "CMAC 2TDEA........ ( %s )", (res) ? _GREEN_("ok") : _RED_("fail"));
|
||||||
PrintAndLogEx(INFO, "CMAC 2TDEA........ " _GREEN_("ok"));
|
|
||||||
else
|
|
||||||
PrintAndLogEx(ERR, "CMAC 2TDEA........ " _RED_("fail"));
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -329,11 +297,7 @@ static bool TestCMACDES(void) {
|
||||||
DesfireCryptoCMAC(&dctx, CMACData, 32, cmac);
|
DesfireCryptoCMAC(&dctx, CMACData, 32, cmac);
|
||||||
res = res && (memcmp(cmac, cmac4, sizeof(cmac1)) == 0);
|
res = res && (memcmp(cmac, cmac4, sizeof(cmac1)) == 0);
|
||||||
|
|
||||||
if (res)
|
PrintAndLogEx(INFO, "CMAC DES.......... ( %s )", (res) ? _GREEN_("ok") : _RED_("fail"));
|
||||||
PrintAndLogEx(INFO, "CMAC DES.......... " _GREEN_("ok"));
|
|
||||||
else
|
|
||||||
PrintAndLogEx(ERR, "CMAC DES.......... " _RED_("fail"));
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -356,11 +320,7 @@ static bool TestEV2SessionKeys(void) {
|
||||||
DesfireGenSessionKeyEV2(key, rnda, rndb, false, sessionkey);
|
DesfireGenSessionKeyEV2(key, rnda, rndb, false, sessionkey);
|
||||||
res = res && (memcmp(sessionkey, sessionkeymac, sizeof(sessionkeymac)) == 0);
|
res = res && (memcmp(sessionkey, sessionkeymac, sizeof(sessionkeymac)) == 0);
|
||||||
|
|
||||||
if (res)
|
PrintAndLogEx(INFO, "EV2 session keys.. ( %s )", (res) ? _GREEN_("ok") : _RED_("fail"));
|
||||||
PrintAndLogEx(INFO, "EV2 session keys.. " _GREEN_("ok"));
|
|
||||||
else
|
|
||||||
PrintAndLogEx(ERR, "EV2 session keys.. " _RED_("fail"));
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -392,11 +352,7 @@ static bool TestEV2IVEncode(void) {
|
||||||
DesfireEV2FillIV(&ctx, true, iv);
|
DesfireEV2FillIV(&ctx, true, iv);
|
||||||
res = res && (memcmp(iv, ivres2, sizeof(ivres2)) == 0);
|
res = res && (memcmp(iv, ivres2, sizeof(ivres2)) == 0);
|
||||||
|
|
||||||
if (res)
|
PrintAndLogEx(INFO, "EV2 IV calc....... ( %s )", (res) ? _GREEN_("ok") : _RED_("fail"));
|
||||||
PrintAndLogEx(INFO, "EV2 IV calc....... " _GREEN_("ok"));
|
|
||||||
else
|
|
||||||
PrintAndLogEx(ERR, "EV2 IV calc....... " _RED_("fail"));
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -452,17 +408,12 @@ static bool TestEV2MAC(void) {
|
||||||
DesfireEV2CalcCMAC(&ctx, rc, cmddata4, sizeof(cmddata4), mac);
|
DesfireEV2CalcCMAC(&ctx, rc, cmddata4, sizeof(cmddata4), mac);
|
||||||
res = res && (memcmp(mac, macres4, sizeof(macres4)) == 0);
|
res = res && (memcmp(mac, macres4, sizeof(macres4)) == 0);
|
||||||
|
|
||||||
if (res)
|
PrintAndLogEx(INFO, "EV2 MAC calc...... ( %s )", (res) ? _GREEN_("ok") : _RED_("fail"));
|
||||||
PrintAndLogEx(INFO, "EV2 MAC calc...... " _GREEN_("ok"));
|
|
||||||
else
|
|
||||||
PrintAndLogEx(ERR, "EV2 MAC calc...... " _RED_("fail"));
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool TestTransSessionKeys(void) {
|
static bool TestTransSessionKeys(void) {
|
||||||
bool res = true;
|
bool res = true;
|
||||||
|
|
||||||
uint8_t key[] = {0x66, 0xA8, 0xCB, 0x93, 0x26, 0x9D, 0xC9, 0xBC, 0x28, 0x85, 0xB7, 0xA9, 0x1B, 0x9C, 0x69, 0x7B};
|
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};
|
uint8_t uid[] = {0x04, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06};
|
||||||
uint32_t trCntr = 8;
|
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};
|
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);
|
res = res && (memcmp(sessionkey, keyenc, sizeof(keyenc)) == 0);
|
||||||
|
|
||||||
if (res)
|
PrintAndLogEx(INFO, "Trans session key. ( %s )", (res) ? _GREEN_("ok") : _RED_("fail"));
|
||||||
PrintAndLogEx(INFO, "Trans session key. " _GREEN_("ok"));
|
|
||||||
else
|
|
||||||
PrintAndLogEx(ERR, "Trans session key. " _RED_("fail"));
|
|
||||||
|
|
||||||
return res;
|
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};
|
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);
|
res = res && (memcmp(ctx.plaintexts[15], pt15, sizeof(pt15)) == 0);
|
||||||
|
|
||||||
if (res)
|
PrintAndLogEx(INFO, "LRP plaintexts.... ( %s )", (res) ? _GREEN_("ok") : _RED_("fail"));
|
||||||
PrintAndLogEx(INFO, "LRP plaintexts.... " _GREEN_("ok"));
|
|
||||||
else
|
|
||||||
PrintAndLogEx(ERR, "LRP plaintexts.... " _RED_("fail"));
|
|
||||||
|
|
||||||
return res;
|
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};
|
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);
|
res = res && (memcmp(ctx.updatedKeys[2], key2, sizeof(key2)) == 0);
|
||||||
|
|
||||||
if (res)
|
PrintAndLogEx(INFO, "LRP updated keys.. ( %s )", (res) ? _GREEN_("ok") : _RED_("fail"));
|
||||||
PrintAndLogEx(INFO, "LRP updated keys.. " _GREEN_("ok"));
|
|
||||||
else
|
|
||||||
PrintAndLogEx(ERR, "LRP updated keys.. " _RED_("fail"));
|
|
||||||
|
|
||||||
return res;
|
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};
|
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);
|
res = res && (memcmp(y, y5, sizeof(y5)) == 0);
|
||||||
|
|
||||||
if (res)
|
PrintAndLogEx(INFO, "LRP eval.......... ( %s )", (res) ? _GREEN_("ok") : _RED_("fail"));
|
||||||
PrintAndLogEx(INFO, "LRP eval.......... " _GREEN_("ok"));
|
|
||||||
else
|
|
||||||
PrintAndLogEx(ERR, "LRP eval.......... " _RED_("fail"));
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -618,11 +553,7 @@ static bool TestLRPIncCounter(void) {
|
||||||
uint8_t ctrr4[] = {0x00};
|
uint8_t ctrr4[] = {0x00};
|
||||||
res = res && (memcmp(ctr4, ctrr4, sizeof(ctrr4)) == 0);
|
res = res && (memcmp(ctr4, ctrr4, sizeof(ctrr4)) == 0);
|
||||||
|
|
||||||
if (res)
|
PrintAndLogEx(INFO, "LRP inc counter... ( %s )", (res) ? _GREEN_("ok") : _RED_("fail"));
|
||||||
PrintAndLogEx(INFO, "LRP inc counter... " _GREEN_("ok"));
|
|
||||||
else
|
|
||||||
PrintAndLogEx(ERR, "LRP inc counter... " _RED_("fail"));
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -686,11 +617,7 @@ static bool TestLRPEncode(void) {
|
||||||
res = res && (resplen == sizeof(res5));
|
res = res && (resplen == sizeof(res5));
|
||||||
res = res && (memcmp(resp, res5, sizeof(res5)) == 0);
|
res = res && (memcmp(resp, res5, sizeof(res5)) == 0);
|
||||||
|
|
||||||
if (res)
|
PrintAndLogEx(INFO, "LRP encode........ ( %s )", (res) ? _GREEN_("ok") : _RED_("fail"));
|
||||||
PrintAndLogEx(INFO, "LRP encode........ " _GREEN_("ok"));
|
|
||||||
else
|
|
||||||
PrintAndLogEx(ERR, "LRP encode........ " _RED_("fail"));
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -753,11 +680,7 @@ static bool TestLRPDecode(void) {
|
||||||
res = res && (resplen == sizeof(res5));
|
res = res && (resplen == sizeof(res5));
|
||||||
res = res && (memcmp(resp, res5, sizeof(res5)) == 0);
|
res = res && (memcmp(resp, res5, sizeof(res5)) == 0);
|
||||||
|
|
||||||
if (res)
|
PrintAndLogEx(INFO, "LRP decode........ ( %s )", (res) ? _GREEN_("ok") : _RED_("fail"));
|
||||||
PrintAndLogEx(INFO, "LRP decode........ " _GREEN_("ok"));
|
|
||||||
else
|
|
||||||
PrintAndLogEx(ERR, "LRP decode........ " _RED_("fail"));
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -793,11 +716,7 @@ static bool TestLRPSubkeys(void) {
|
||||||
res = res && (memcmp(sk1, sk1r3, sizeof(sk1r3)) == 0);
|
res = res && (memcmp(sk1, sk1r3, sizeof(sk1r3)) == 0);
|
||||||
res = res && (memcmp(sk2, sk2r3, sizeof(sk2r3)) == 0);
|
res = res && (memcmp(sk2, sk2r3, sizeof(sk2r3)) == 0);
|
||||||
|
|
||||||
if (res)
|
PrintAndLogEx(INFO, "LRP subkeys....... ( %s )", (res) ? _GREEN_("ok") : _RED_("fail"));
|
||||||
PrintAndLogEx(INFO, "LRP subkeys....... " _GREEN_("ok"));
|
|
||||||
else
|
|
||||||
PrintAndLogEx(ERR, "LRP subkeys....... " _RED_("fail"));
|
|
||||||
|
|
||||||
return res;
|
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};
|
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);
|
res = res && (memcmp(cmac, cmacres6, sizeof(cmacres6)) == 0);
|
||||||
|
|
||||||
if (res)
|
PrintAndLogEx(INFO, "LRP CMAC.......... ( %s )", (res) ? _GREEN_("ok") : _RED_("fail"));
|
||||||
PrintAndLogEx(INFO, "LRP CMAC.......... " _GREEN_("ok"));
|
|
||||||
else
|
|
||||||
PrintAndLogEx(ERR, "LRP CMAC.......... " _RED_("fail"));
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -877,11 +792,7 @@ static bool TestLRPSessionKeys(void) {
|
||||||
DesfireGenSessionKeyLRP(key, rnda, rndb, true, sessionkey);
|
DesfireGenSessionKeyLRP(key, rnda, rndb, true, sessionkey);
|
||||||
res = res && (memcmp(sessionkey, sessionkeyres, sizeof(sessionkeyres)) == 0);
|
res = res && (memcmp(sessionkey, sessionkeyres, sizeof(sessionkeyres)) == 0);
|
||||||
|
|
||||||
if (res)
|
PrintAndLogEx(INFO, "LRP session keys.. ( %s )", (res) ? _GREEN_("ok") : _RED_("fail"));
|
||||||
PrintAndLogEx(INFO, "LRP session keys.. " _GREEN_("ok"));
|
|
||||||
else
|
|
||||||
PrintAndLogEx(ERR, "LRP session keys.. " _RED_("fail"));
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -914,11 +825,7 @@ bool DesfireTest(bool verbose) {
|
||||||
res = res && TestLRPSessionKeys();
|
res = res && TestLRPSessionKeys();
|
||||||
|
|
||||||
PrintAndLogEx(INFO, "---------------------------");
|
PrintAndLogEx(INFO, "---------------------------");
|
||||||
if (res)
|
PrintAndLogEx(SUCCESS, "Tests ( %s )", (res) ? _GREEN_("ok") : _RED_("fail"));
|
||||||
PrintAndLogEx(SUCCESS, " Tests [ %s ]", _GREEN_("ok"));
|
|
||||||
else
|
|
||||||
PrintAndLogEx(FAILED, " Tests [ %s ]", _RED_("fail"));
|
|
||||||
|
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue