mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-19 21:03:48 -07:00
Fix DES authentification and format picc
This commit is contained in:
parent
3eee351f4f
commit
5adc8e876a
4 changed files with 967 additions and 548 deletions
File diff suppressed because it is too large
Load diff
|
@ -28,6 +28,7 @@
|
||||||
#include "desfire_crypto.h"
|
#include "desfire_crypto.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <util.h>
|
||||||
#include "commonutil.h"
|
#include "commonutil.h"
|
||||||
#include "mbedtls/aes.h"
|
#include "mbedtls/aes.h"
|
||||||
#include "mbedtls/des.h"
|
#include "mbedtls/des.h"
|
||||||
|
@ -406,6 +407,8 @@ void *mifare_cryto_preprocess_data(desfiretag_t tag, void *data, size_t *nbytes,
|
||||||
|
|
||||||
/* pass through */
|
/* pass through */
|
||||||
case MDCM_MACED:
|
case MDCM_MACED:
|
||||||
|
communication_settings|=NO_CRC;
|
||||||
|
|
||||||
switch (DESFIRE(tag)->authentication_scheme) {
|
switch (DESFIRE(tag)->authentication_scheme) {
|
||||||
case AS_LEGACY:
|
case AS_LEGACY:
|
||||||
if (!(communication_settings & MAC_COMMAND))
|
if (!(communication_settings & MAC_COMMAND))
|
||||||
|
@ -508,6 +511,9 @@ 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 *mifare_cryto_postprocess_data(desfiretag_t tag, void *data, size_t *nbytes, int communication_settings) {
|
||||||
void *res = data;
|
void *res = data;
|
||||||
void *edata = NULL;
|
void *edata = NULL;
|
||||||
|
tag->crypto_buffer_size=*nbytes*2;
|
||||||
|
tag->crypto_buffer=(uint8_t*)malloc(tag->crypto_buffer_size);
|
||||||
|
|
||||||
uint8_t first_cmac_byte = 0x00;
|
uint8_t first_cmac_byte = 0x00;
|
||||||
|
|
||||||
desfirekey_t key = DESFIRE(tag)->session_key;
|
desfirekey_t key = DESFIRE(tag)->session_key;
|
||||||
|
@ -527,6 +533,7 @@ void *mifare_cryto_postprocess_data(desfiretag_t tag, void *data, size_t *nbytes
|
||||||
|
|
||||||
/* pass through */
|
/* pass through */
|
||||||
case MDCM_MACED:
|
case MDCM_MACED:
|
||||||
|
communication_settings|=NO_CRC;
|
||||||
switch (DESFIRE(tag)->authentication_scheme) {
|
switch (DESFIRE(tag)->authentication_scheme) {
|
||||||
case AS_LEGACY:
|
case AS_LEGACY:
|
||||||
if (communication_settings & MAC_VERIFY) {
|
if (communication_settings & MAC_VERIFY) {
|
||||||
|
@ -540,18 +547,20 @@ void *mifare_cryto_postprocess_data(desfiretag_t tag, void *data, size_t *nbytes
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t edl = enciphered_data_length(tag, *nbytes - 1, communication_settings);
|
size_t edl = enciphered_data_length(tag, *nbytes, communication_settings);
|
||||||
edata = malloc(edl);
|
edata = malloc(edl);
|
||||||
|
|
||||||
memcpy(edata, data, *nbytes - 1);
|
memcpy(edata, data, *nbytes);
|
||||||
memset((uint8_t *)edata + *nbytes - 1, 0, edl - *nbytes + 1);
|
memset((uint8_t *)edata + *nbytes , 0, edl - *nbytes);
|
||||||
|
|
||||||
mifare_cypher_blocks_chained(tag, NULL, NULL, edata, edl, MCD_SEND, MCO_ENCYPHER);
|
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, (uint8_t *)edata + edl - 8, 4)) {
|
||||||
|
PrintAndLogEx(NORMAL, "Expected MAC %s", sprint_hex(data+*nbytes, key_macing_length(key)));
|
||||||
|
PrintAndLogEx(NORMAL, "Actual MAC %s", sprint_hex(edata + edl - 8, key_macing_length(key)));
|
||||||
#ifdef WITH_DEBUG
|
#ifdef WITH_DEBUG
|
||||||
Dbprintf("MACing not verified");
|
Dbprintf("MACing not verified");
|
||||||
hexdump((uint8_t *)data + *nbytes - 1, key_macing_length(key), "Expect ", 0);
|
hexdump((uint8_t *)data + *nbytes, key_macing_length(key), "Expect ", 0);
|
||||||
hexdump((uint8_t *)edata + edl - 8, key_macing_length(key), "Actual ", 0);
|
hexdump((uint8_t *)edata + edl - 8, key_macing_length(key), "Actual ", 0);
|
||||||
#endif
|
#endif
|
||||||
DESFIRE(tag)->last_pcd_error = CRYPTO_ERROR;
|
DESFIRE(tag)->last_pcd_error = CRYPTO_ERROR;
|
||||||
|
@ -644,17 +653,19 @@ void *mifare_cryto_postprocess_data(desfiretag_t tag, void *data, size_t *nbytes
|
||||||
case AS_NEW:
|
case AS_NEW:
|
||||||
/* Move status between payload and CRC */
|
/* Move status between payload and CRC */
|
||||||
res = DESFIRE(tag)->crypto_buffer;
|
res = DESFIRE(tag)->crypto_buffer;
|
||||||
memcpy(res, data, *nbytes);
|
if (res!=NULL) {
|
||||||
|
memcpy(res, data, *nbytes);
|
||||||
|
|
||||||
crc_pos = (*nbytes) - 16 - 3;
|
crc_pos = (*nbytes) - 16 - 3;
|
||||||
if (crc_pos < 0) {
|
if (crc_pos < 0) {
|
||||||
/* Single block */
|
/* Single block */
|
||||||
crc_pos = 0;
|
crc_pos = 0;
|
||||||
|
}
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -725,6 +736,9 @@ void *mifare_cryto_postprocess_data(desfiretag_t tag, void *data, size_t *nbytes
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
free(tag->crypto_buffer);
|
||||||
|
tag->crypto_buffer_size=0;
|
||||||
|
tag->crypto_buffer=NULL;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -854,3 +868,45 @@ void mifare_cypher_blocks_chained(desfiretag_t tag, desfirekey_t key, uint8_t *i
|
||||||
offset += block_size;
|
offset += block_size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define CRC32_PRESET 0xFFFFFFFF
|
||||||
|
|
||||||
|
static void
|
||||||
|
desfire_crc32_byte(uint32_t *crc, const uint8_t value)
|
||||||
|
{
|
||||||
|
/* x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 1 */
|
||||||
|
const uint32_t poly = 0xEDB88320;
|
||||||
|
|
||||||
|
*crc ^= value;
|
||||||
|
for (int current_bit = 7; current_bit >= 0; current_bit--) {
|
||||||
|
int bit_out = (*crc) & 0x00000001;
|
||||||
|
*crc >>= 1;
|
||||||
|
if (bit_out)
|
||||||
|
*crc ^= poly;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void desfire_crc32(const uint8_t *data, const size_t len, uint8_t *crc)
|
||||||
|
{
|
||||||
|
uint32_t desfire_crc = CRC32_PRESET;
|
||||||
|
for (size_t i = 0; i < len; i++) {
|
||||||
|
desfire_crc32_byte(&desfire_crc, data[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
*((uint32_t *)(crc)) = htole32(desfire_crc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void desfire_crc32_append(uint8_t *data, const size_t len)
|
||||||
|
{
|
||||||
|
desfire_crc32(data, len, data + len);
|
||||||
|
}
|
||||||
|
|
||||||
|
void iso14443a_crc_append(uint8_t* data, size_t len)
|
||||||
|
{
|
||||||
|
return compute_crc(CRC_14443_A, data, len, data+len, data+len+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void iso14443a_crc(uint8_t* data, size_t len, uint8_t* pbtCrc)
|
||||||
|
{
|
||||||
|
return compute_crc(CRC_14443_A, data, len, pbtCrc, pbtCrc+1);
|
||||||
|
}
|
|
@ -129,4 +129,8 @@ size_t enciphered_data_length(const desfiretag_t tag, const size_t nbytes, int c
|
||||||
void cmac_generate_subkeys(desfirekey_t key);
|
void cmac_generate_subkeys(desfirekey_t key);
|
||||||
void cmac(const desfirekey_t key, uint8_t *ivect, const uint8_t *data, size_t len, uint8_t *cmac);
|
void cmac(const desfirekey_t key, uint8_t *ivect, const uint8_t *data, size_t len, uint8_t *cmac);
|
||||||
|
|
||||||
#endif
|
void desfire_crc32(const uint8_t *data, const size_t len, uint8_t *crc);
|
||||||
|
void desfire_crc32_append(uint8_t *data, const size_t len);
|
||||||
|
void iso14443a_crc_append(uint8_t* data, size_t len);
|
||||||
|
void iso14443a_crc(uint8_t* data, size_t len, uint8_t* pbtCrc);
|
||||||
|
#endif
|
|
@ -359,6 +359,7 @@ ISO 7816-4 Basic interindustry commands. For command APDU's.
|
||||||
#define MFDES_READSIG 0x3C
|
#define MFDES_READSIG 0x3C
|
||||||
#define MFDES_WRITE_DATA 0x3D
|
#define MFDES_WRITE_DATA 0x3D
|
||||||
#define MFDES_GET_KEY_SETTINGS 0x45
|
#define MFDES_GET_KEY_SETTINGS 0x45
|
||||||
|
#define MFDES_GET_UID 0x51
|
||||||
#define MFDES_CHANGE_KEY_SETTINGS 0x54
|
#define MFDES_CHANGE_KEY_SETTINGS 0x54
|
||||||
#define MFDES_SELECT_APPLICATION 0x5A
|
#define MFDES_SELECT_APPLICATION 0x5A
|
||||||
#define MFDES_CHANGE_FILE_SETTINGS 0x5F
|
#define MFDES_CHANGE_FILE_SETTINGS 0x5F
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue