mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2026-08-29 07:38:21 +00:00
Added support for older card (EF2011)
This commit is contained in:
+120
-53
@@ -9,10 +9,28 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define HRT_NEW_AID 0xEF2014
|
||||
#define HRT_OLD_AID 0xEF2011
|
||||
#define HRT_APPLICATION_INFO_FILE_ID 0x08
|
||||
#define HRT_APPLICATION_INFO_LEN 11
|
||||
#define HRT_NEW_AID 0xEF2014
|
||||
#define HRT_OLD_AID 0xEF2011
|
||||
#define HRT_CONTROL_INFO_FILE_ID 0x00
|
||||
#define HRT_PERIOD_PASS_FILE_ID 0x01
|
||||
#define HRT_STORED_VALUE_FILE_ID 0x02
|
||||
#define HRT_ETICKET_FILE_ID 0x03
|
||||
#define HRT_HISTORY_FILE_ID 0x04
|
||||
#define HRT_APPLICATION_INFO_FILE_ID 0x08
|
||||
#define HRT_APPLICATION_INFO_LEN 11
|
||||
#define HRT_CONTROL_INFO_LEN 6
|
||||
#define HRT_CONTROL_INFO_V2_LEN 10
|
||||
#define HRT_PERIOD_PASS_LEN 32
|
||||
#define HRT_PERIOD_PASS_V2_LEN 35
|
||||
#define HRT_STORED_VALUE_LEN 12
|
||||
#define HRT_STORED_VALUE_V2_LEN 13
|
||||
#define HRT_ETICKET_LEN 26
|
||||
#define HRT_ETICKET_V2_LEN 45
|
||||
|
||||
typedef struct {
|
||||
uint32_t aid;
|
||||
int version;
|
||||
} hrt_application_t;
|
||||
|
||||
typedef enum {
|
||||
HRT_AREA_TYPE_CITY = 0,
|
||||
@@ -122,13 +140,25 @@ static bool hrt_format_card_number(const char *card_number, char *out, size_t ou
|
||||
return written > 0 && (size_t)written < out_len;
|
||||
}
|
||||
|
||||
static bool hrt_aid_list_contains(const uint8_t *aidbuf, size_t aidbuflen) {
|
||||
static bool hrt_get_application_from_aid_list(const uint8_t *aidbuf, size_t aidbuflen, hrt_application_t *application) {
|
||||
if (aidbuf == NULL || aidbuflen < 3) return false;
|
||||
|
||||
for (size_t i = 0; i + 2 < aidbuflen; i += 3) {
|
||||
// TODO: Also add HRT_OLD_AID check. Currently it is not
|
||||
// checked since parsing the older cards is not yet implemented.
|
||||
if (DesfireAIDByteToUint(&aidbuf[i]) == HRT_NEW_AID) {
|
||||
uint32_t aid = DesfireAIDByteToUint(&aidbuf[i]);
|
||||
|
||||
if (aid == HRT_OLD_AID) {
|
||||
if (application != NULL) {
|
||||
application->aid = HRT_OLD_AID;
|
||||
application->version = 1;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (aid == HRT_NEW_AID) {
|
||||
if (application != NULL) {
|
||||
application->aid = HRT_NEW_AID;
|
||||
application->version = 2;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -136,6 +166,22 @@ static bool hrt_aid_list_contains(const uint8_t *aidbuf, size_t aidbuflen) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static size_t hrt_control_info_len(int version) {
|
||||
return version == 2 ? HRT_CONTROL_INFO_V2_LEN : HRT_CONTROL_INFO_LEN;
|
||||
}
|
||||
|
||||
static size_t hrt_period_pass_len(int version) {
|
||||
return version == 2 ? HRT_PERIOD_PASS_V2_LEN : HRT_PERIOD_PASS_LEN;
|
||||
}
|
||||
|
||||
static size_t hrt_stored_value_len(int version) {
|
||||
return version == 2 ? HRT_STORED_VALUE_V2_LEN : HRT_STORED_VALUE_LEN;
|
||||
}
|
||||
|
||||
static size_t hrt_eticket_len(int version) {
|
||||
return version == 2 ? HRT_ETICKET_V2_LEN : HRT_ETICKET_LEN;
|
||||
}
|
||||
|
||||
static bool hrt_read_and_parse_application_info(DesfireContext_t *dctx, hrt_travel_card_t *card) {
|
||||
if (dctx == NULL || card == NULL) return false;
|
||||
|
||||
@@ -367,24 +413,75 @@ static void hrt_print_card(const hrt_travel_card_t *card) {
|
||||
hrt_print_history(card);
|
||||
}
|
||||
|
||||
static bool hrt_select_application(DesfireContext_t *dctx, const hrt_application_t *application) {
|
||||
if (dctx == NULL || application == NULL) return false;
|
||||
|
||||
return DesfireSelectAIDHex(dctx, application->aid, false, 0) == PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static bool hrt_read_card(DesfireContext_t *dctx, const hrt_application_t *application, hrt_travel_card_t *card) {
|
||||
if (dctx == NULL || application == NULL || card == NULL) return false;
|
||||
|
||||
uint8_t buf[APDU_RES_LEN] = {0};
|
||||
size_t len = 0;
|
||||
|
||||
hrt_travelcard_init_empty(card, application->version);
|
||||
|
||||
// File 0x08: Application info
|
||||
if (hrt_read_and_parse_application_info(dctx, card) == false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// File 0x00: Control info
|
||||
len = 0;
|
||||
if (DesfireReadFile(dctx, HRT_CONTROL_INFO_FILE_ID, 0, hrt_control_info_len(application->version), buf, &len) == PM3_SUCCESS) {
|
||||
hrt_travelcard_set_control_info(card, buf, len);
|
||||
}
|
||||
|
||||
// File 0x01: Period pass
|
||||
len = 0;
|
||||
if (DesfireReadFile(dctx, HRT_PERIOD_PASS_FILE_ID, 0, hrt_period_pass_len(application->version), buf, &len) == PM3_SUCCESS) {
|
||||
hrt_travelcard_set_period_pass(card, buf, len);
|
||||
}
|
||||
|
||||
// File 0x02: Stored value
|
||||
len = 0;
|
||||
if (DesfireReadFile(dctx, HRT_STORED_VALUE_FILE_ID, 0, hrt_stored_value_len(application->version), buf, &len) == PM3_SUCCESS) {
|
||||
hrt_travelcard_set_stored_value(card, buf, len);
|
||||
}
|
||||
|
||||
// File 0x03: eTicket
|
||||
len = 0;
|
||||
if (DesfireReadFile(dctx, HRT_ETICKET_FILE_ID, 0, hrt_eticket_len(application->version), buf, &len) == PM3_SUCCESS) {
|
||||
hrt_travelcard_set_eticket(card, buf, len);
|
||||
}
|
||||
|
||||
// File 0x04: History records
|
||||
len = 0;
|
||||
if (DesfireReadRecords(dctx, HRT_HISTORY_FILE_ID, 0, 0, buf, &len) == PM3_SUCCESS) {
|
||||
hrt_travelcard_set_history(card, buf, len);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool is_valid_hrt_card(DesfireContext_t *dctx, const uint8_t *aidbuf, size_t aidbuflen) {
|
||||
if (dctx == NULL) return false;
|
||||
|
||||
if (hrt_aid_list_contains(aidbuf, aidbuflen) == false) {
|
||||
hrt_application_t application = {0};
|
||||
if (hrt_get_application_from_aid_list(aidbuf, aidbuflen, &application) == false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
DesfireSetCommMode(dctx, DCMPlain);
|
||||
DesfireSetCommandSet(dctx, DCCNative);
|
||||
|
||||
// TODO: Add support for older travelcard (AID EF2011)
|
||||
|
||||
if (DesfireSelectAIDHex(dctx, HRT_NEW_AID, false, 0) != PM3_SUCCESS) {
|
||||
if (hrt_select_application(dctx, &application) == false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
hrt_travel_card_t card;
|
||||
hrt_travelcard_init_empty(&card, 2);
|
||||
hrt_travelcard_init_empty(&card, application.version);
|
||||
|
||||
bool is_valid = hrt_read_and_parse_application_info(dctx, &card);
|
||||
|
||||
@@ -398,50 +495,20 @@ bool hrt_parser_parse(DesfireContext_t *dctx) {
|
||||
DesfireSetCommMode(dctx, DCMPlain);
|
||||
DesfireSetCommandSet(dctx, DCCNative);
|
||||
|
||||
// TODO: Add support for older travelcard (AID EF2011)
|
||||
hrt_application_t applications[] = {
|
||||
{HRT_OLD_AID, 1},
|
||||
{HRT_NEW_AID, 2},
|
||||
};
|
||||
|
||||
if (DesfireSelectAIDHex(dctx, HRT_NEW_AID, false, 0) == PM3_SUCCESS) {
|
||||
uint8_t buf[APDU_RES_LEN] = {0};
|
||||
size_t len = 0;
|
||||
for (size_t i = 0; i < ARRAYLEN(applications); i++) {
|
||||
if (hrt_select_application(dctx, &applications[i]) == false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
hrt_travel_card_t card;
|
||||
hrt_travelcard_init_empty(&card, 2);
|
||||
|
||||
// File 0x08: Application info (11 bytes)
|
||||
// Check that application info parses before reading other files
|
||||
if (hrt_read_and_parse_application_info(dctx, &card) == false) {
|
||||
if (hrt_read_card(dctx, &applications[i], &card) == false) {
|
||||
hrt_travelcard_free(&card);
|
||||
return false;
|
||||
}
|
||||
|
||||
// File 0x00: Control info (10 bytes)
|
||||
len = 0;
|
||||
if (DesfireReadFile(dctx, 0x00, 0, 10, buf, &len) == PM3_SUCCESS) {
|
||||
hrt_travelcard_set_control_info(&card, buf, len);
|
||||
}
|
||||
|
||||
// File 0x01: Period pass (35 bytes)
|
||||
len = 0;
|
||||
if (DesfireReadFile(dctx, 0x01, 0, 35, buf, &len) == PM3_SUCCESS) {
|
||||
hrt_travelcard_set_period_pass(&card, buf, len);
|
||||
}
|
||||
|
||||
// File 0x02: Stored value (13 bytes)
|
||||
len = 0;
|
||||
if (DesfireReadFile(dctx, 0x02, 0, 13, buf, &len) == PM3_SUCCESS) {
|
||||
hrt_travelcard_set_stored_value(&card, buf, len);
|
||||
}
|
||||
|
||||
// File 0x03: eTicket (45 bytes)
|
||||
len = 0;
|
||||
if (DesfireReadFile(dctx, 0x03, 0, 45, buf, &len) == PM3_SUCCESS) {
|
||||
hrt_travelcard_set_eticket(&card, buf, len);
|
||||
}
|
||||
|
||||
// File 0x04: History records (all)
|
||||
len = 0;
|
||||
if (DesfireReadRecords(dctx, 0x04, 0, 0, buf, &len) == PM3_SUCCESS) {
|
||||
hrt_travelcard_set_history(&card, buf, len);
|
||||
continue;
|
||||
}
|
||||
|
||||
hrt_print_card(&card);
|
||||
|
||||
Reference in New Issue
Block a user