From 905c55de2bbe642412b47ed4e92344096c817fac Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 10 Mar 2017 09:48:36 +0100 Subject: [PATCH] ADD: `analyse nuid` - generates NUID 4byte from a UID 7byte. Mifare Classic Ev1 has this option as a activation sequences. This NUID is also used for authenticate (cuid), not the block0 data. ref: http://www.gorferay.com/mifare-and-handling-of-uids/ --- client/cmdanalyse.c | 68 +++++++++++++++++++++++++++++++++++++++++--- client/cmdanalyse.h | 7 +++-- common/iso14443crc.c | 2 +- common/iso14443crc.h | 1 + 4 files changed, 71 insertions(+), 7 deletions(-) diff --git a/client/cmdanalyse.c b/client/cmdanalyse.c index a8deb67f..a7004293 100644 --- a/client/cmdanalyse.c +++ b/client/cmdanalyse.c @@ -22,7 +22,7 @@ int usage_analyse_lcr(void) { PrintAndLog(" bytes to calc missing XOR in a LCR"); PrintAndLog(""); PrintAndLog("Samples:"); - PrintAndLog(" analyse lcr 04008064BA"); + PrintAndLog(" analyse lcr 04008064BA"); PrintAndLog("expected output: Target (BA) requires final LRC XOR byte value: 5A"); return 0; } @@ -38,7 +38,7 @@ int usage_analyse_checksum(void) { PrintAndLog(" m bit mask to limit the outpuyt"); PrintAndLog(""); PrintAndLog("Samples:"); - PrintAndLog(" analyse chksum b 137AF00A0A0D m FF"); + PrintAndLog(" analyse chksum b 137AF00A0A0D m FF"); PrintAndLog("expected output: 0x61"); return 0; } @@ -51,7 +51,7 @@ int usage_analyse_crc(void){ PrintAndLog(" bytes to calc crc"); PrintAndLog(""); PrintAndLog("Samples:"); - PrintAndLog(" analyse crc 137AF00A0A0D"); + PrintAndLog(" analyse crc 137AF00A0A0D"); return 0; } int usage_analyse_hid(void){ @@ -65,7 +65,19 @@ int usage_analyse_hid(void){ PrintAndLog(" input bytes"); PrintAndLog(""); PrintAndLog("Samples:"); - PrintAndLog(" analyse hid r 0123456789abcdef"); + PrintAndLog(" analyse hid r 0123456789abcdef"); + return 0; +} +int usage_analyse_nuid(void){ + PrintAndLog("Generate 4byte NUID from 7byte UID"); + PrintAndLog(""); + PrintAndLog("Usage: analyse hid [h] "); + PrintAndLog("Options:"); + PrintAndLog(" h This help"); + PrintAndLog(" input bytes (14 hexsymbols)"); + PrintAndLog(""); + PrintAndLog("Samples:"); + PrintAndLog(" analyse nuid 11223344556677"); return 0; } @@ -521,6 +533,53 @@ int CmdAnalyseHid(const char *Cmd){ return 0; } +void generate4bNUID(uint8_t *uid, uint8_t *nuid){ + uint16_t crc; + uint8_t first, second; + + ComputeCrc14443(CRC_14443_A, uid, 3, &first, &second); + nuid[0] |= (second & 0xE0) | 0xF; + nuid[1] = first; + + crc = first; + crc |= second << 8; + + UpdateCrc14443(uid[3], &crc); + UpdateCrc14443(uid[4], &crc); + UpdateCrc14443(uid[5], &crc); + UpdateCrc14443(uid[6], &crc); + + nuid[2] = (crc >> 8) & 0xFF ; + nuid[3] = crc & 0xFF; +} + +int CmdAnalyseNuid(const char *Cmd){ + uint8_t nuid[4] = {0}; + uint8_t uid[7] = {0}; + int len = 0; + char cmdp = param_getchar(Cmd, 0); + if (strlen(Cmd) == 0|| cmdp == 'h' || cmdp == 'H') return usage_analyse_nuid(); + + /* selftest UID 040D681AB52281 -> NUID 8F430FEF */ + if (cmdp == 't' || cmdp == 'T') { + memcpy(uid, "\x04\x0d\x68\x1a\xb5\x22\x81", 7); + generate4bNUID(uid, nuid); + if ( 0 == memcmp(nuid, "\x8f\x43\x0f\xef", 4)) + printf("Selftest OK\n"); + else + printf("Selftest Failed\n"); + return 0; + } + + param_gethex_ex(Cmd, 0, uid, &len); + if ( len%2 || len != 14) return usage_analyse_nuid(); + + generate4bNUID(uid, nuid); + + printf("UID | %s \n", sprint_hex(uid, 7)); + printf("NUID | %s \n", sprint_hex(nuid, 4)); + return 0; +} static command_t CommandTable[] = { {"help", CmdHelp, 1, "This help"}, {"lcr", CmdAnalyseLCR, 1, "Generate final byte for XOR LRC"}, @@ -531,6 +590,7 @@ static command_t CommandTable[] = { {"lfsr", CmdAnalyseLfsr, 1, "LFSR tests"}, {"a", CmdAnalyseA, 1, "num bits test"}, {"hid", CmdAnalyseHid, 1, "Permute function from 'heart of darkness' paper"}, + {"nuid", CmdAnalyseNuid, 1, "create NUID from 7byte UID"}, {NULL, NULL, 0, NULL} }; diff --git a/client/cmdanalyse.h b/client/cmdanalyse.h index 70e472cd..adef8ce1 100644 --- a/client/cmdanalyse.h +++ b/client/cmdanalyse.h @@ -18,15 +18,17 @@ #include "ui.h" // PrintAndLog #include "util.h" #include "crc.h" -#include "../common/iso15693tools.h" +#include "iso15693tools.h" // +#include "iso14443crc.h" // crc 14a #include "tea.h" -#include "../include/legic_prng.h" +#include "legic_prng.h" #include "loclass/elite_crack.h" int usage_analyse_lcr(void); int usage_analyse_checksum(void); int usage_analyse_crc(void); int usage_analyse_hid(void); +int usage_analyse_nuid(void); int CmdAnalyse(const char *Cmd); int CmdAnalyseLCR(const char *Cmd); @@ -36,4 +38,5 @@ int CmdAnalyseCRC(const char *Cmd); int CmdAnalyseTEASelfTest(const char *Cmd); int CmdAnalyseLfsr(const char *Cmd); int CmdAnalyseHid(const char *Cmd); +int CmdAnalyseNuid(const char *Cmd); #endif diff --git a/common/iso14443crc.c b/common/iso14443crc.c index a6def1a9..d07a2871 100644 --- a/common/iso14443crc.c +++ b/common/iso14443crc.c @@ -8,7 +8,7 @@ #include "iso14443crc.h" -static unsigned short UpdateCrc14443(unsigned char ch, unsigned short *lpwCrc) +unsigned short UpdateCrc14443(unsigned char ch, unsigned short *lpwCrc) { ch = (ch ^ (unsigned char) ((*lpwCrc) & 0x00FF)); ch = (ch ^ (ch << 4)); diff --git a/common/iso14443crc.h b/common/iso14443crc.h index 4b1fb7e8..9373d951 100644 --- a/common/iso14443crc.h +++ b/common/iso14443crc.h @@ -18,6 +18,7 @@ #define CRC_14443_B 0xFFFF /* ISO/IEC 13239 (formerly ISO/IEC 3309) */ #define CRC_ICLASS 0xE012 /* ICLASS PREFIX */ +unsigned short UpdateCrc14443(unsigned char ch, unsigned short *lpwCrc); void ComputeCrc14443(int CrcType, const unsigned char *Data, int Length, unsigned char *TransmitFirst, -- 2.39.2