Merge pull request #787 from bkerler/DesAuth

Mifare Des authentification fixes
This commit is contained in:
Iceman 2020-06-13 18:26:23 +02:00 committed by GitHub
commit e0eaff453f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 1026 additions and 646 deletions

View file

@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file.
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
## [unreleased][unreleased] ## [unreleased][unreleased]
- Fix `hf mfdes` authentification issues, DES working (@bkerler)
- Add Android cross-compilation to client cmake (@dxl, @doegox) - Add Android cross-compilation to client cmake (@dxl, @doegox)
- Fix `emv scan` - now saves in current folder and uses unique names (@iceman1001) - Fix `emv scan` - now saves in current folder and uses unique names (@iceman1001)
- Fix pm3.sh - parse COM ports larger than one digit (@doegox) - Fix pm3.sh - parse COM ports larger than one digit (@doegox)

File diff suppressed because it is too large Load diff

View file

@ -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 "aes.h" #include "aes.h"
#include "des.h" #include "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,22 @@ 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)) {
#ifdef WITH_DEBUG
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)));
#endif
#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,6 +655,7 @@ 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;
if (res != NULL) {
memcpy(res, data, *nbytes); memcpy(res, data, *nbytes);
crc_pos = (*nbytes) - 16 - 3; crc_pos = (*nbytes) - 16 - 3;
@ -655,6 +667,7 @@ void *mifare_cryto_postprocess_data(desfiretag_t tag, void *data, size_t *nbytes
((uint8_t *) res)[crc_pos] = 0x00; ((uint8_t *) res)[crc_pos] = 0x00;
crc_pos++; crc_pos++;
*nbytes += 1; *nbytes += 1;
}
break; break;
} }
@ -725,6 +738,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;
} }
@ -864,3 +880,19 @@ void mifare_cypher_blocks_chained(desfiretag_t tag, desfirekey_t key, uint8_t *i
offset += block_size; offset += block_size;
} }
} }
void desfire_crc32(const uint8_t *data, const size_t len, uint8_t *crc) {
crc32_ex(data,len,crc);
}
void desfire_crc32_append(uint8_t *data, const size_t len) {
crc32_ex(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);
}

View file

@ -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);
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 #endif

View file

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