Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sync mifare and nfc-utils #91

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 8 additions & 21 deletions src/mfcuk.c
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,6 @@ static inline uint64_t bswap_64(uint64_t x)
#endif

#include <string.h>
#include <err.h>
#include <errno.h>

#include "xgetopt.h"
Expand All @@ -192,18 +191,10 @@ static inline uint64_t bswap_64(uint64_t x)
#include "mfcuk_utils.h"
#include "mfcuk_finger.h"
#include "mfcuk.h"
#include "nfc-utils.h"

#define MAX_FRAME_LEN 264

#ifdef DEBUG
# warning Debug mode is enabled
# define WARN(...) fprintf(stderr, "%s %d: ", __FILE__, __LINE__ ); warnx (" WARNING: " __VA_ARGS__ )
# define ERR(...) fprintf(stderr, "%s %d: ", __FILE__, __LINE__ ); warnx (" ERROR " __VA_ARGS__ )
#else
# define WARN(...) warnx ("WARNING: " __VA_ARGS__ )
# define ERR(...) warnx ("ERROR: " __VA_ARGS__ )
#endif

static uint32_t bswap_32_pu8(uint8_t *pu8)
{
// TODO: This function need to be tested on both endianness machine types
Expand Down Expand Up @@ -745,7 +736,7 @@ static void print_mifare_classic_tag_actions(const char *title, mifare_classic_t
return;
}

bTagType = tag->amb->mbm.btUnknown;
bTagType = tag->amb->mbm.btSAK;

if (!IS_MIFARE_CLASSIC_1K(bTagType) && !IS_MIFARE_CLASSIC_4K(bTagType)) {
return;
Expand All @@ -759,7 +750,7 @@ static void print_mifare_classic_tag_actions(const char *title, mifare_classic_t
printf("Sector\t| Key A\t|ACTS | RESL\t| Key B\t|ACTS | RESL\n");
printf("---------------------------------------------------------------------\n");

if (IS_MIFARE_CLASSIC_1K(tag->amb->mbm.btUnknown)) {
if (IS_MIFARE_CLASSIC_1K(tag->amb->mbm.btSAK)) {
max_blocks = MIFARE_CLASSIC_1K_MAX_BLOCKS;
} else {
max_blocks = MIFARE_CLASSIC_4K_MAX_BLOCKS;
Expand Down Expand Up @@ -949,15 +940,11 @@ int main(int argc, char *argv[])
memset(&tag_recover_verify, 0, sizeof(tag_recover_verify));

tag_recover_verify.type = MIFARE_CLASSIC_4K;
tag_recover_verify.tag_basic.amb[0].mbm.btUnknown = MIFARE_CLASSIC_4K;
tag_recover_verify.tag_basic.amb[0].mbm.btSAK = MIFARE_CLASSIC_4K;

// "Sort-of" initializing the entries
memset((void *)arrSpoofEntries, 0, sizeof(arrSpoofEntries));

// MAIN ( broken-brain (: ) logic of the tool
// ---------------------------------------
clear_screen();

print_identification();

if (argc < 2) {
Expand Down Expand Up @@ -1039,7 +1026,7 @@ int main(int argc, char *argv[])
WARN("non-supported tag type value (%s)", optarg);
} else {
tag_recover_verify.type = i;
tag_recover_verify.tag_basic.amb[0].mbm.btUnknown = i;
tag_recover_verify.tag_basic.amb[0].mbm.btSAK = i;
bfOpts[ch] = true;
}
break;
Expand Down Expand Up @@ -1423,7 +1410,7 @@ int main(int argc, char *argv[])
ptr_trailer_dump = (mifare_classic_block_trailer *)((char *)(&dump_loaded_tag.tag_basic) + (0 * MIFARE_CLASSIC_BYTES_PER_BLOCK));

memcpy(ptr_trailer, ptr_trailer_dump, sizeof(*ptr_trailer));
tag_recover_verify.type = tag_recover_verify.tag_basic.amb[0].mbm.btUnknown;
tag_recover_verify.type = tag_recover_verify.tag_basic.amb[0].mbm.btSAK;
tag_recover_verify.uid = bswap_32_pu8(tag_recover_verify.tag_basic.amb[0].mbm.abtUID);
}
}
Expand Down Expand Up @@ -1460,12 +1447,12 @@ int main(int argc, char *argv[])

// Tag on the reader type
tag_on_reader.type = ti.nti.nai.btSak;
tag_on_reader.tag_basic.amb[0].mbm.btUnknown = ti.nti.nai.btSak;
tag_on_reader.tag_basic.amb[0].mbm.btSAK = ti.nti.nai.btSak;

// No command line tag type specified, take it from the tag on the reader
if (!bfOpts['M']) {
tag_recover_verify.type = ti.nti.nai.btSak;
tag_recover_verify.tag_basic.amb[0].mbm.btUnknown = ti.nti.nai.btSak;
tag_recover_verify.tag_basic.amb[0].mbm.btSAK = ti.nti.nai.btSak;
}

// Tag on the reader UID
Expand Down
15 changes: 8 additions & 7 deletions src/mfcuk_finger.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
*/

#include "mfcuk_finger.h"
#include "nfc-utils.h"

mfcuk_finger_tmpl_entry mfcuk_finger_db[] = {
{ "./data/tmpls_fingerprints/mfcuk_tmpl_skgt.mfd", "Sofia SKGT", mfcuk_finger_default_comparator, mfcuk_finger_skgt_decoder, NULL },
Expand All @@ -49,12 +50,12 @@ int mfcuk_finger_db_entries = sizeof(mfcuk_finger_db) / sizeof(mfcuk_finger_db[0
int mfcuk_finger_default_decoder(mifare_classic_tag *dump)
{
if (!dump) {
fprintf(stderr, "ERROR: cannot decode a NULL pointer :)\n");
ERR("Cannot decode a NULL pointer");
return 0;
}

printf("UID:\t%02x%02x%02x%02x\n", dump->amb[0].mbm.abtUID[0], dump->amb[0].mbm.abtUID[1], dump->amb[0].mbm.abtUID[2], dump->amb[0].mbm.abtUID[3]);
printf("TYPE:\t%02x\n", dump->amb[0].mbm.btUnknown);
printf("TYPE:\t%02x\n", dump->amb[0].mbm.btSAK);

return 1;
}
Expand All @@ -63,7 +64,7 @@ int mfcuk_finger_default_decoder(mifare_classic_tag *dump)
int mfcuk_finger_skgt_decoder(mifare_classic_tag *dump)
{
if (!dump) {
fprintf(stderr, "ERROR: cannot decode a NULL pointer :)\n");
ERR("Cannot decode a NULL pointer");
return 0;
}

Expand Down Expand Up @@ -131,27 +132,27 @@ int mfcuk_finger_load(void)
fp = fopen(mfcuk_finger_db[i].tmpl_filename, "rb");

if (!fp) {
fprintf(stderr, "WARN: cannot open template file '%s'\n", mfcuk_finger_db[i].tmpl_filename);
WARN("Cannot open template file '%s'", mfcuk_finger_db[i].tmpl_filename);
continue;
}

// If not read exactly 1 record, something is wrong
if ((result = fread((void *)(&mask), sizeof(mask), 1, fp)) != 1) {
fprintf(stderr, "WARN: cannot read MASK from template file '%s'\n", mfcuk_finger_db[i].tmpl_filename);
WARN("Cannot read MASK from template file '%s'", mfcuk_finger_db[i].tmpl_filename);
fclose(fp);
continue;
}

// If not read exactly 1 record, something is wrong
if ((result = fread((void *)(&values), sizeof(values), 1, fp)) != 1) {
fprintf(stderr, "WARN: cannot read VALUES template file '%s'\n", mfcuk_finger_db[i].tmpl_filename);
WARN("Cannot read VALUES template file '%s'", mfcuk_finger_db[i].tmpl_filename);
fclose(fp);
continue;
}

if (mfcuk_finger_db[i].tmpl_data == NULL) {
if ((tmpl_new = (mfcuk_finger_template *) malloc(sizeof(mfcuk_finger_template))) == NULL) {
fprintf(stderr, "WARN: cannot allocate memory to template record %d\n", i);
WARN("Cannot allocate memory to template record %d", i);
fclose(fp);
continue;
}
Expand Down
4 changes: 2 additions & 2 deletions src/mfcuk_mifare.c
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,7 @@ void print_mifare_classic_tag_keys(const char *title, mifare_classic_tag *tag)
return;
}

bTagType = tag->amb->mbm.btUnknown;
bTagType = tag->amb->mbm.btSAK;

if (!IS_MIFARE_CLASSIC_1K(bTagType) && !IS_MIFARE_CLASSIC_4K(bTagType)) {
return;
Expand All @@ -395,7 +395,7 @@ void print_mifare_classic_tag_keys(const char *title, mifare_classic_tag *tag)
printf("Sector\t| Key A\t| AC bits\t| Key B\n");
printf("-------------------------------------------------------\n");

if (IS_MIFARE_CLASSIC_1K(tag->amb->mbm.btUnknown)) {
if (IS_MIFARE_CLASSIC_1K(tag->amb->mbm.btSAK)) {
max_blocks = MIFARE_CLASSIC_1K_MAX_BLOCKS;
} else {
max_blocks = MIFARE_CLASSIC_4K_MAX_BLOCKS;
Expand Down
6 changes: 3 additions & 3 deletions src/mfcuk_mifare.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,9 @@
#define IS_MIFARE_CLASSIC_4K(ats_sak) ( ((ats_sak) == MIFARE_CLASSIC_4K) || ((ats_sak) == MIFARE_CLASSIC_4K_SKGT) )
#define IS_MIFARE_DESFIRE(ats_sak) ( ((ats_sak) == MIFARE_DESFIRE) )

#define IS_MIFARE_CLASSIC_1K_TAG(tag) IS_MIFARE_CLASSIC_1K(tag->amb[0].mbm.btUnknown)
#define IS_MIFARE_CLASSIC_4K_TAG(tag) IS_MIFARE_CLASSIC_4K(tag->amb[0].mbm.btUnknown)
#define IS_MIFARE_DESFIRE_TAG(tag) IS_MIFARE_DESFIRE(tag->amb[0].mbm.btUnknown)
#define IS_MIFARE_CLASSIC_1K_TAG(tag) IS_MIFARE_CLASSIC_1K(tag->amb[0].mbm.btSAK)
#define IS_MIFARE_CLASSIC_4K_TAG(tag) IS_MIFARE_CLASSIC_4K(tag->amb[0].mbm.btSAK)
#define IS_MIFARE_DESFIRE_TAG(tag) IS_MIFARE_DESFIRE(tag->amb[0].mbm.btSAK)

#define MIFARE_CLASSIC_BYTES_PER_BLOCK 16 // Common for Mifare Classic 1K and Mifare Classic 4K
#define MIFARE_CLASSIC_INVALID_BLOCK 0xFFFFFFFF
Expand Down
10 changes: 0 additions & 10 deletions src/mfcuk_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,13 +95,3 @@ void sleepmillis(unsigned int millis)
usleep(millis * 1000);
#endif
}

void clear_screen()
{
#ifdef WIN32 // On Windows, use "cls" command
system("cls");
#else // Otherwise fall back to TTY control characters
printf("\033[1;1H\033[J");
#endif
}

9 changes: 0 additions & 9 deletions src/mfcuk_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,14 +81,5 @@ unsigned char hex2bin(unsigned char h, unsigned char l);
*/
void sleepmillis(unsigned int millis);

/**
* @fn void clear_screen(void);
* @brief Clears output console
*
* Wrapper for system-dependant clear screen function.
* Resets output console, clearing text and resetting character pointer.
*/
void clear_screen(void);

#endif // _MFCUK_UTILS_H_

30 changes: 18 additions & 12 deletions src/mifare.c
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
/*-
* Public platform independent Near Field Communication (NFC) library examples
* Free/Libre Near Field Communication (NFC) library
*
* Copyright (C) 2009 Roel Verdult
* Copyright (C) 2010 Romain Tartière
* Copyright (C) 2010, 2011 Romuald Conty
* Libnfc historical contributors:
* Copyright (C) 2009 Roel Verdult
* Copyright (C) 2009-2013 Romuald Conty
* Copyright (C) 2010-2012 Romain Tartière
* Copyright (C) 2010-2013 Philippe Teuwen
* Copyright (C) 2012-2013 Ludovic Rousseau
* See AUTHORS file for a more comprehensive list of contributors.
* Additional contributors of this file:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
Expand Down Expand Up @@ -47,7 +52,7 @@
* @note There are three different types of information (Authenticate, Data and Value).
*
* First an authentication must take place using Key A or B. It requires a 48 bit Key (6 bytes) and the UID.
* They are both used to initialize the internal cipher-state of the PN53X chip (http://libnfc.org/hardware/pn53x-chip).
* They are both used to initialize the internal cipher-state of the PN53X chip.
* After a successful authentication it will be possible to execute other commands (e.g. Read/Write).
* The MIFARE Classic Specification (http://www.nxp.com/acrobat/other/identification/M001053_MF1ICS50_rev5_3.pdf) explains more about this process.
*/
Expand All @@ -63,34 +68,33 @@ nfc_initiator_mifare_cmd(nfc_device *pnd, const mifare_cmd mc, const uint8_t ui8
abtCmd[1] = ui8Block; // The block address (1K=0x00..0x39, 4K=0x00..0xff)

switch (mc) {
// Read and store command have no parameter
// Read and store command have no parameter
case MC_READ:
case MC_STORE:
szParamLen = 0;
break;

// Authenticate command
// Authenticate command
case MC_AUTH_A:
case MC_AUTH_B:
szParamLen = sizeof(struct mifare_param_auth);
break;

// Data command
// Data command
case MC_WRITE:
szParamLen = sizeof(struct mifare_param_data);
break;

// Value command
// Value command
case MC_DECREMENT:
case MC_INCREMENT:
case MC_TRANSFER:
szParamLen = sizeof(struct mifare_param_value);
break;

// Please fix your code, you never should reach this statement
// Please fix your code, you never should reach this statement
default:
return false;
break;
}

// When available, copy the parameter bytes
Expand Down Expand Up @@ -126,7 +130,9 @@ nfc_initiator_mifare_cmd(nfc_device *pnd, const mifare_cmd mc, const uint8_t ui8

// When we have executed a read command, copy the received bytes into the param
if (mc == MC_READ) {
if (res == 16) {

//Check the length of response data, with PCSC reader, there have 2 bytes for SW value
if (res == 16 || res == (16 + 2)) {
memcpy(pmp->mpd.abtData, abtRx, 16);
} else {
return false;
Expand Down
51 changes: 20 additions & 31 deletions src/mifare.h
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
/*-
* Public platform independent Near Field Communication (NFC) library examples
* Free/Libre Near Field Communication (NFC) library
*
* Copyright (C) 2009 Roel Verdult
* Copyright (C) 2010 Romain Tartière
* Copyright (C) 2010, 2011 Romuald Conty
* Libnfc historical contributors:
* Copyright (C) 2009 Roel Verdult
* Copyright (C) 2009-2013 Romuald Conty
* Copyright (C) 2010-2012 Romain Tartière
* Copyright (C) 2010-2013 Philippe Teuwen
* Copyright (C) 2012-2013 Ludovic Rousseau
* See AUTHORS file for a more comprehensive list of contributors.
* Additional contributors of this file:
* Copyright (C) 2017-2018 Adam Laurie
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
Expand Down Expand Up @@ -67,10 +73,17 @@ struct mifare_param_value {
uint8_t abtValue[4];
};

struct mifare_param_trailer {
uint8_t abtKeyA[6];
uint8_t abtAccessBits[4];
uint8_t abtKeyB[6];
};

typedef union {
struct mifare_param_auth mpa;
struct mifare_param_data mpd;
struct mifare_param_value mpv;
struct mifare_param_trailer mpt;
} mifare_param;

// Reset struct alignment to default
Expand All @@ -83,11 +96,11 @@ bool nfc_initiator_mifare_cmd(nfc_device *pnd, const mifare_cmd mc, const uin

// MIFARE Classic
typedef struct {
uint8_t abtUID[4];
uint8_t abtUID[4]; // beware for 7bytes UID it goes over next fields
uint8_t btBCC;
uint8_t btUnknown;
uint8_t btSAK; // beware it's not always exactly SAK
uint8_t abtATQA[2];
uint8_t abtUnknown[8];
uint8_t abtManufacturer[8];
} mifare_classic_block_manufacturer;

typedef struct {
Expand All @@ -110,30 +123,6 @@ typedef struct {
mifare_classic_block amb[256];
} mifare_classic_tag;

// MIFARE Ultralight
typedef struct {
uint8_t sn0[3];
uint8_t btBCC0;
uint8_t sn1[4];
uint8_t btBCC1;
uint8_t internal;
uint8_t lock[2];
uint8_t otp[4];
} mifareul_block_manufacturer;

typedef struct {
uint8_t abtData[16];
} mifareul_block_data;

typedef union {
mifareul_block_manufacturer mbm;
mifareul_block_data mbd;
} mifareul_block;

typedef struct {
mifareul_block amb[4];
} mifareul_tag;

// Reset struct alignment to default
# pragma pack()

Expand Down
Loading