mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-21 05:43:48 -07:00
fix #2384 the use of free() is completely wrong as we use bigbuff allocations. Converted the old style to new and removed the dynamic allocation.
This commit is contained in:
parent
2b276cae1a
commit
498af46fbf
1 changed files with 67 additions and 44 deletions
|
@ -543,30 +543,35 @@ void *mifare_cryto_preprocess_data(desfiretag_t tag, void *data, size_t *nbytes,
|
|||
|
||||
void *mifare_cryto_postprocess_data(desfiretag_t tag, void *data, size_t *nbytes, int communication_settings) {
|
||||
void *res = data;
|
||||
void *edata = NULL;
|
||||
uint8_t first_cmac_byte = 0x00;
|
||||
|
||||
desfirekey_t key = DESFIRE(tag)->session_key;
|
||||
|
||||
if (!key)
|
||||
if (!key) {
|
||||
return data;
|
||||
}
|
||||
|
||||
// Return directly if we just have a status code.
|
||||
if (1 == *nbytes)
|
||||
if (1 == *nbytes) {
|
||||
return res;
|
||||
}
|
||||
|
||||
switch (communication_settings & MDCM_MASK) {
|
||||
case MDCM_PLAIN:
|
||||
case MDCM_PLAIN: {
|
||||
|
||||
if (AS_LEGACY == DESFIRE(tag)->authentication_scheme)
|
||||
if (AS_LEGACY == DESFIRE(tag)->authentication_scheme) {
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
/* pass through */
|
||||
case MDCM_MACED:
|
||||
case MDCM_MACED: {
|
||||
switch (DESFIRE(tag)->authentication_scheme) {
|
||||
case AS_LEGACY:
|
||||
if (communication_settings & MAC_VERIFY) {
|
||||
case AS_LEGACY: {
|
||||
|
||||
if ((communication_settings & MAC_VERIFY) == MAC_VERIFY) {
|
||||
|
||||
*nbytes -= key_macing_length(key);
|
||||
|
||||
if (*nbytes == 0) {
|
||||
*nbytes = -1;
|
||||
res = NULL;
|
||||
|
@ -577,18 +582,17 @@ void *mifare_cryto_postprocess_data(desfiretag_t tag, void *data, size_t *nbytes
|
|||
}
|
||||
|
||||
size_t edl = enciphered_data_length(tag, *nbytes - 1, communication_settings);
|
||||
edata = BigBuf_malloc(edl);
|
||||
|
||||
uint8_t edata[edl];
|
||||
memset(edata, 0, sizeof(edata));
|
||||
memcpy(edata, data, *nbytes - 1);
|
||||
memset((uint8_t *)edata + *nbytes - 1, 0, edl - *nbytes + 1);
|
||||
|
||||
mifare_cypher_blocks_chained(tag, NULL, NULL, edata, edl, MCD_SEND, MCO_ENCYPHER);
|
||||
|
||||
if (0 != memcmp((uint8_t *)data + *nbytes - 1, (uint8_t *)edata + edl - 8, 4)) {
|
||||
if (0 != memcmp((uint8_t *)data + *nbytes - 1, edata + edl - 8, 4)) {
|
||||
#ifdef WITH_DEBUG
|
||||
Dbprintf("MACing not verified");
|
||||
hexdump((uint8_t *)data + *nbytes - 1, key_macing_length(key), "Expect ", 0);
|
||||
hexdump((uint8_t *)edata + edl - 8, key_macing_length(key), "Actual ", 0);
|
||||
hexdump(edata + edl - 8, key_macing_length(key), "Actual ", 0);
|
||||
#endif
|
||||
DESFIRE(tag)->last_pcd_error = CRYPTO_ERROR;
|
||||
*nbytes = -1;
|
||||
|
@ -596,10 +600,16 @@ void *mifare_cryto_postprocess_data(desfiretag_t tag, void *data, size_t *nbytes
|
|||
}
|
||||
}
|
||||
break;
|
||||
case AS_NEW:
|
||||
if (!(communication_settings & CMAC_COMMAND))
|
||||
}
|
||||
case AS_NEW: {
|
||||
|
||||
if ((communication_settings & CMAC_COMMAND) != CMAC_COMMAND) {
|
||||
break;
|
||||
if (communication_settings & CMAC_VERIFY) {
|
||||
}
|
||||
|
||||
int n = 0;
|
||||
|
||||
if ((communication_settings & CMAC_VERIFY) == CMAC_VERIFY) {
|
||||
if (*nbytes < 9) {
|
||||
*nbytes = -1;
|
||||
res = NULL;
|
||||
|
@ -607,13 +617,16 @@ void *mifare_cryto_postprocess_data(desfiretag_t tag, void *data, size_t *nbytes
|
|||
}
|
||||
first_cmac_byte = ((uint8_t *)data)[*nbytes - 9];
|
||||
((uint8_t *)data)[*nbytes - 9] = ((uint8_t *)data)[*nbytes - 1];
|
||||
|
||||
n = 8;
|
||||
}
|
||||
|
||||
int n = (communication_settings & CMAC_VERIFY) ? 8 : 0;
|
||||
cmac(key, DESFIRE(tag)->ivect, ((uint8_t *)data), *nbytes - n, DESFIRE(tag)->cmac);
|
||||
|
||||
if (communication_settings & CMAC_VERIFY) {
|
||||
if ((communication_settings & CMAC_VERIFY) == CMAC_VERIFY) {
|
||||
|
||||
((uint8_t *)data)[*nbytes - 9] = first_cmac_byte;
|
||||
|
||||
if (0 != memcmp(DESFIRE(tag)->cmac, (uint8_t *)data + *nbytes - 9, 8)) {
|
||||
#ifdef WITH_DEBUG
|
||||
Dbprintf("CMAC NOT verified :-(");
|
||||
|
@ -628,12 +641,11 @@ void *mifare_cryto_postprocess_data(desfiretag_t tag, void *data, size_t *nbytes
|
|||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
free(edata);
|
||||
|
||||
break;
|
||||
case MDCM_ENCIPHERED:
|
||||
}
|
||||
case MDCM_ENCIPHERED: {
|
||||
(*nbytes)--;
|
||||
bool verified = false;
|
||||
int crc_pos = 0x00;
|
||||
|
@ -670,48 +682,50 @@ void *mifare_cryto_postprocess_data(desfiretag_t tag, void *data, size_t *nbytes
|
|||
* verified, and accumulating 0's in it should not change it.
|
||||
*/
|
||||
switch (DESFIRE(tag)->authentication_scheme) {
|
||||
case AS_LEGACY:
|
||||
case AS_LEGACY: {
|
||||
crc_pos = *nbytes - 8 - 1; // The CRC can be over two blocks
|
||||
if (crc_pos < 0) {
|
||||
/* Single block */
|
||||
crc_pos = 0;
|
||||
crc_pos = 0; // Single block
|
||||
}
|
||||
break;
|
||||
case AS_NEW:
|
||||
}
|
||||
case AS_NEW: {
|
||||
/* Move status between payload and CRC */
|
||||
res = DESFIRE(tag)->crypto_buffer;
|
||||
memcpy(res, data, *nbytes);
|
||||
|
||||
crc_pos = (*nbytes) - 16 - 3;
|
||||
if (crc_pos < 0) {
|
||||
/* Single block */
|
||||
crc_pos = 0;
|
||||
crc_pos = 0; // Single block
|
||||
}
|
||||
|
||||
memcpy((uint8_t *)res + crc_pos + 1, (uint8_t *)res + crc_pos, *nbytes - crc_pos);
|
||||
((uint8_t *)res)[crc_pos] = 0x00;
|
||||
crc_pos++;
|
||||
*nbytes += 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
uint16_t crc_16 = 0x00;
|
||||
uint32_t crc = 0x00;
|
||||
|
||||
switch (DESFIRE(tag)->authentication_scheme) {
|
||||
case AS_LEGACY:
|
||||
case AS_LEGACY: {
|
||||
AddCrc14A((uint8_t *)res, end_crc_pos);
|
||||
end_crc_pos = crc_pos + 2;
|
||||
//
|
||||
|
||||
|
||||
crc = crc_16;
|
||||
break;
|
||||
case AS_NEW:
|
||||
}
|
||||
case AS_NEW: {
|
||||
end_crc_pos = crc_pos + 4;
|
||||
crc32_ex(res, end_crc_pos, (uint8_t *)&crc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!crc) {
|
||||
|
||||
if (crc == 0) {
|
||||
verified = true;
|
||||
for (int n = end_crc_pos; n < *nbytes - 1; n++) {
|
||||
uint8_t byte = ((uint8_t *)res)[n];
|
||||
|
@ -719,31 +733,40 @@ void *mifare_cryto_postprocess_data(desfiretag_t tag, void *data, size_t *nbytes
|
|||
verified = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (verified) {
|
||||
|
||||
*nbytes = crc_pos;
|
||||
|
||||
switch (DESFIRE(tag)->authentication_scheme) {
|
||||
case AS_LEGACY:
|
||||
case AS_LEGACY: {
|
||||
((uint8_t *)data)[(*nbytes)++] = 0x00;
|
||||
break;
|
||||
case AS_NEW:
|
||||
}
|
||||
case AS_NEW: {
|
||||
/* The status byte was already before the CRC */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
switch (DESFIRE(tag)->authentication_scheme) {
|
||||
case AS_LEGACY:
|
||||
case AS_LEGACY: {
|
||||
break;
|
||||
case AS_NEW:
|
||||
}
|
||||
case AS_NEW: {
|
||||
x = ((uint8_t *)res)[crc_pos - 1];
|
||||
((uint8_t *)res)[crc_pos - 1] = ((uint8_t *)res)[crc_pos];
|
||||
((uint8_t *)res)[crc_pos] = x;
|
||||
break;
|
||||
}
|
||||
}
|
||||
crc_pos++;
|
||||
}
|
||||
} while (!verified && (end_crc_pos < *nbytes));
|
||||
|
||||
if (!verified) {
|
||||
} while (verified == false && (end_crc_pos < *nbytes));
|
||||
|
||||
if (verified == false) {
|
||||
#ifdef WITH_DEBUG
|
||||
/* FIXME In some configurations, the file is transmitted PLAIN */
|
||||
Dbprintf("CRC not verified in decyphered stream");
|
||||
|
@ -752,14 +775,14 @@ void *mifare_cryto_postprocess_data(desfiretag_t tag, void *data, size_t *nbytes
|
|||
*nbytes = -1;
|
||||
res = NULL;
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
}
|
||||
default: {
|
||||
Dbprintf("Unknown communication settings");
|
||||
*nbytes = -1;
|
||||
res = NULL;
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue