From d6c0f45e8ccfc010bad2f79f82b4ee7cd53eaad8 Mon Sep 17 00:00:00 2001 From: Yang Kun <91833768+ikspress@users.noreply.github.com> Date: Tue, 9 Jul 2024 00:56:24 +0800 Subject: [PATCH] Sync mifare and nfc-utils --- src/mfcuk.c | 29 ++++++++------------------ src/mfcuk_finger.c | 15 +++++++------- src/mfcuk_mifare.c | 4 ++-- src/mfcuk_mifare.h | 6 +++--- src/mfcuk_utils.c | 10 --------- src/mfcuk_utils.h | 9 -------- src/mifare.c | 30 ++++++++++++++++----------- src/mifare.h | 51 ++++++++++++++++++---------------------------- src/nfc-utils.c | 24 ++-------------------- src/nfc-utils.h | 8 +++----- 10 files changed, 64 insertions(+), 122 deletions(-) diff --git a/src/mfcuk.c b/src/mfcuk.c index ec4cf0e..2370420 100644 --- a/src/mfcuk.c +++ b/src/mfcuk.c @@ -171,7 +171,6 @@ static inline uint64_t bswap_64(uint64_t x) #endif #include -#include #include #include "xgetopt.h" @@ -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 @@ -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; @@ -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; @@ -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) { @@ -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; @@ -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); } } @@ -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 diff --git a/src/mfcuk_finger.c b/src/mfcuk_finger.c index c54a29a..5d92980 100644 --- a/src/mfcuk_finger.c +++ b/src/mfcuk_finger.c @@ -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 }, @@ -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; } @@ -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; } @@ -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; } diff --git a/src/mfcuk_mifare.c b/src/mfcuk_mifare.c index 8c84dcb..6e970cd 100644 --- a/src/mfcuk_mifare.c +++ b/src/mfcuk_mifare.c @@ -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; @@ -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; diff --git a/src/mfcuk_mifare.h b/src/mfcuk_mifare.h index 6a7975c..4729a8a 100644 --- a/src/mfcuk_mifare.h +++ b/src/mfcuk_mifare.h @@ -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 diff --git a/src/mfcuk_utils.c b/src/mfcuk_utils.c index 4d8f2e6..973eef4 100644 --- a/src/mfcuk_utils.c +++ b/src/mfcuk_utils.c @@ -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 -} - diff --git a/src/mfcuk_utils.h b/src/mfcuk_utils.h index 73195b6..e90322f 100644 --- a/src/mfcuk_utils.h +++ b/src/mfcuk_utils.h @@ -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_ diff --git a/src/mifare.c b/src/mifare.c index 6c84724..c28198f 100644 --- a/src/mifare.c +++ b/src/mifare.c @@ -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: @@ -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. */ @@ -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 @@ -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; diff --git a/src/mifare.h b/src/mifare.h index fb90fea..17fed34 100644 --- a/src/mifare.h +++ b/src/mifare.h @@ -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: @@ -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 @@ -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 { @@ -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() diff --git a/src/nfc-utils.c b/src/nfc-utils.c index 5c0a264..ee876ae 100644 --- a/src/nfc-utils.c +++ b/src/nfc-utils.c @@ -7,6 +7,7 @@ * 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 @@ -36,8 +37,6 @@ * @file nfc-utils.c * @brief Provide some examples shared functions like print, parity calculation, options parsing. */ -#include -#include #include "nfc-utils.h" @@ -45,17 +44,7 @@ uint8_t oddparity(const uint8_t bt) { // cf http://graphics.stanford.edu/~seander/bithacks.html#ParityParallel - return (0x9669 >> ((bt ^(bt >> 4)) & 0xF)) & 1; -} - -void -oddparity_bytes_ts(const uint8_t *pbtData, const size_t szLen, uint8_t *pbtPar) -{ - size_t szByteNr; - // Calculate the parity bits for the command - for (szByteNr = 0; szByteNr < szLen; szByteNr++) { - pbtPar[szByteNr] = oddparity(pbtData[szByteNr]); - } + return (0x9669 >> ((bt ^ (bt >> 4)) & 0xF)) & 1; } void @@ -117,12 +106,3 @@ print_hex_par(const uint8_t *pbtData, const size_t szBits, const uint8_t *pbtDat } printf("\n"); } - -void -print_nfc_target(const nfc_target *pnt, bool verbose) -{ - char *s; - str_nfc_target(&s, pnt, verbose); - printf("%s", s); - nfc_free(s); -} diff --git a/src/nfc-utils.h b/src/nfc-utils.h index 8c52d4c..3298835 100644 --- a/src/nfc-utils.h +++ b/src/nfc-utils.h @@ -7,6 +7,7 @@ * 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 @@ -41,8 +42,9 @@ #ifndef _EXAMPLES_NFC_UTILS_H_ # define _EXAMPLES_NFC_UTILS_H_ +# include +# include # include -# include # include /** @@ -92,12 +94,8 @@ #endif uint8_t oddparity(const uint8_t bt); -void oddparity_bytes_ts(const uint8_t *pbtData, const size_t szLen, uint8_t *pbtPar); - void print_hex(const uint8_t *pbtData, const size_t szLen); void print_hex_bits(const uint8_t *pbtData, const size_t szBits); void print_hex_par(const uint8_t *pbtData, const size_t szBits, const uint8_t *pbtDataPar); -void print_nfc_target(const nfc_target *pnt, bool verbose); - #endif