]> git.zerfleddert.de Git - proxmark3-svn/blobdiff - client/cmdanalyse.c
ADD: `analyse nuid` - generates NUID 4byte from a UID 7byte. Mifare Classic Ev1...
[proxmark3-svn] / client / cmdanalyse.c
index 32309c1c229135e89479874c28a860ff4c99fa4e..a7004293679853f511be08e50fb8c0ae0085a8f2 100644 (file)
@@ -22,7 +22,7 @@ int usage_analyse_lcr(void) {
        PrintAndLog("           <bytes>    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;
 }
@@ -30,14 +30,15 @@ int usage_analyse_checksum(void) {
        PrintAndLog("The bytes will be added with eachother and than limited with the applied mask");
        PrintAndLog("Finally compute ones' complement of the least significant bytes");
        PrintAndLog("");
-       PrintAndLog("Usage:  analyse chksum [h] b <bytes> m <mask>");
+       PrintAndLog("Usage:  analyse chksum [h] [v] b <bytes> m <mask>");
        PrintAndLog("Options:");
        PrintAndLog("           h          This help");
+       PrintAndLog("           v          supress header");
        PrintAndLog("           b <bytes>  bytes to calc missing XOR in a LCR");
        PrintAndLog("           m <mask>   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;
 }
@@ -50,7 +51,7 @@ int usage_analyse_crc(void){
        PrintAndLog("           <bytes>    bytes to calc crc");
        PrintAndLog("");
        PrintAndLog("Samples:");
-       PrintAndLog("           analyse crc 137AF00A0A0D");
+       PrintAndLog("      analyse crc 137AF00A0A0D");
        return 0;
 }
 int usage_analyse_hid(void){
@@ -64,7 +65,19 @@ int usage_analyse_hid(void){
        PrintAndLog("           <bytes>    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] <bytes>");
+       PrintAndLog("Options:");
+       PrintAndLog("           h          This help");
+       PrintAndLog("           <bytes>  input bytes (14 hexsymbols)");
+       PrintAndLog("");
+       PrintAndLog("Samples:");
+       PrintAndLog("      analyse nuid 11223344556677");
        return 0;
 }
 
@@ -75,7 +88,7 @@ static uint8_t calculateLRC( uint8_t* bytes, uint8_t len) {
     return LRC;
 }
 
-static uint8_t calcSumCrumbAdd( uint8_t* bytes, uint8_t len, uint32_t mask) {
+static uint16_t calcSumCrumbAdd( uint8_t* bytes, uint8_t len, uint32_t mask) {
     uint8_t sum = 0;
     for (uint8_t i = 0; i < len; i++) {
         sum += CRUMB(bytes[i], 0);
@@ -86,10 +99,10 @@ static uint8_t calcSumCrumbAdd( uint8_t* bytes, uint8_t len, uint32_t mask) {
        sum &= mask;    
     return sum;
 }
-static uint8_t calcSumCrumbAddOnes( uint8_t* bytes, uint8_t len, uint32_t mask) {
-       return ~calcSumCrumbAdd(bytes, len, mask);
+static uint16_t calcSumCrumbAddOnes( uint8_t* bytes, uint8_t len, uint32_t mask) {
+       return (~calcSumCrumbAdd(bytes, len, mask) & mask);
 }
-static uint8_t calcSumNibbleAdd( uint8_t* bytes, uint8_t len, uint32_t mask) {
+static uint16_t calcSumNibbleAdd( uint8_t* bytes, uint8_t len, uint32_t mask) {
     uint8_t sum = 0;
     for (uint8_t i = 0; i < len; i++) {
         sum += NIBBLE_LOW(bytes[i]);
@@ -98,27 +111,37 @@ static uint8_t calcSumNibbleAdd( uint8_t* bytes, uint8_t len, uint32_t mask) {
        sum &= mask;    
     return sum;
 }
-static uint8_t calcSumNibbleAddOnes( uint8_t* bytes, uint8_t len, uint32_t mask){
-       return ~calcSumNibbleAdd(bytes, len, mask);
+static uint16_t calcSumNibbleAddOnes( uint8_t* bytes, uint8_t len, uint32_t mask){
+       return (~calcSumNibbleAdd(bytes, len, mask) & mask);
+}
+static uint16_t calcSumCrumbXor(  uint8_t* bytes, uint8_t len, uint32_t mask) {
+    uint8_t sum = 0;
+    for (uint8_t i = 0; i < len; i++) {
+        sum ^= CRUMB(bytes[i], 0);
+               sum ^= CRUMB(bytes[i], 2);
+               sum ^= CRUMB(bytes[i], 4);
+               sum ^= CRUMB(bytes[i], 6);
+       }       
+       sum &= mask;
+    return sum;
 }
-static uint8_t calcSumNibbleXor( uint8_t* bytes, uint8_t len, uint32_t mask) {
+static uint16_t calcSumNibbleXor( uint8_t* bytes, uint8_t len, uint32_t mask) {
     uint8_t sum = 0;
     for (uint8_t i = 0; i < len; i++) {
         sum ^= NIBBLE_LOW(bytes[i]);
                sum ^= NIBBLE_HIGH(bytes[i]);
        }
-       sum &= mask;    
+       sum &= mask;
     return sum;
 }
-static uint8_t calcSumByteXor( uint8_t* bytes, uint8_t len, uint32_t mask) {
+static uint16_t calcSumByteXor( uint8_t* bytes, uint8_t len, uint32_t mask) {
     uint8_t sum = 0;
     for (uint8_t i = 0; i < len; i++)
         sum ^= bytes[i];
        sum &= mask;    
     return sum;
 }
-
-static uint8_t calcSumByteAdd( uint8_t* bytes, uint8_t len, uint32_t mask) {
+static uint16_t calcSumByteAdd( uint8_t* bytes, uint8_t len, uint32_t mask) {
     uint8_t sum = 0;
     for (uint8_t i = 0; i < len; i++)
         sum += bytes[i];
@@ -126,23 +149,21 @@ static uint8_t calcSumByteAdd( uint8_t* bytes, uint8_t len, uint32_t mask) {
     return sum;
 }
 // Ones complement
-static uint8_t calcSumByteAddOnes( uint8_t* bytes, uint8_t len, uint32_t mask) {
-       return ~calcSumByteAdd(bytes, len, mask);
+static uint16_t calcSumByteAddOnes( uint8_t* bytes, uint8_t len, uint32_t mask) {
+       return (~calcSumByteAdd(bytes, len, mask) & mask);
 }
 
-
-
-static uint8_t calcSumByteSub( uint8_t* bytes, uint8_t len, uint32_t mask) {
+static uint16_t calcSumByteSub( uint8_t* bytes, uint8_t len, uint32_t mask) {
     uint8_t sum = 0;
     for (uint8_t i = 0; i < len; i++)
         sum -= bytes[i];
        sum &= mask;    
     return sum;
 }
-static uint8_t calcSumByteSubOnes( uint8_t* bytes, uint8_t len, uint32_t mask){
-       return ~calcSumByteSub(bytes, len, mask);
+static uint16_t calcSumByteSubOnes( uint8_t* bytes, uint8_t len, uint32_t mask){
+       return (~calcSumByteSub(bytes, len, mask) & mask);
 }
-static uint8_t calcSumNibbleSub( uint8_t* bytes, uint8_t len, uint32_t mask) {
+static uint16_t calcSumNibbleSub( uint8_t* bytes, uint8_t len, uint32_t mask) {
     uint8_t sum = 0;
     for (uint8_t i = 0; i < len; i++) {
         sum -= NIBBLE_LOW(bytes[i]);
@@ -151,8 +172,34 @@ static uint8_t calcSumNibbleSub( uint8_t* bytes, uint8_t len, uint32_t mask) {
        sum &= mask;    
     return sum;
 }
-static uint8_t calcSumNibbleSubOnes( uint8_t* bytes, uint8_t len, uint32_t mask) {
-       return ~calcSumNibbleSub(bytes, len, mask);
+static uint16_t calcSumNibbleSubOnes( uint8_t* bytes, uint8_t len, uint32_t mask) {
+       return (~calcSumNibbleSub(bytes, len, mask) & mask);
+}
+
+// BSD shift checksum 8bit version
+static uint16_t calcBSDchecksum8( uint8_t* bytes, uint8_t len, uint32_t mask){
+       uint16_t sum = 0;
+       for(uint8_t i = 0; i < len; i++){
+               sum = ((sum & 0xFF) >> 1) | ((sum & 0x1) << 7);   // rotate accumulator
+               sum += bytes[i];  // add next byte
+               sum &= 0xFF;  // 
+       }
+       sum &= mask;
+       return sum;
+}
+// BSD shift checksum 4bit version
+static uint16_t calcBSDchecksum4( uint8_t* bytes, uint8_t len, uint32_t mask){
+       uint16_t sum = 0;
+       for(uint8_t i = 0; i < len; i++){
+               sum = ((sum & 0xF) >> 1) | ((sum & 0x1) << 3);   // rotate accumulator
+               sum += NIBBLE_HIGH(bytes[i]);  // add high nibble
+               sum &= 0xF;  // 
+               sum = ((sum & 0xF) >> 1) | ((sum & 0x1) << 3);   // rotate accumulator
+               sum += NIBBLE_LOW(bytes[i]);  // add low nibble
+               sum &= 0xF;  // 
+       }
+       sum &= mask;
+       return sum;
 }
 
 // measuring LFSR maximum length
@@ -248,8 +295,9 @@ int CmdAnalyseCHKSUM(const char *Cmd){
        
        uint8_t data[50];
        uint8_t cmdp = 0;
-       uint32_t mask = 0xFF;
+       uint32_t mask = 0xFFFF;
        bool errors = false;
+       bool useHeader = false;
        int len = 0;
        memset(data, 0x0, sizeof(data));
        
@@ -267,6 +315,11 @@ int CmdAnalyseCHKSUM(const char *Cmd){
                        mask = param_get32ex(Cmd, cmdp+1, 0, 16);
                        cmdp += 2;
                        break;
+               case 'v':
+               case 'V':
+                       useHeader = true;
+                       cmdp++;
+                       break;
                case 'h':
                case 'H':
                        return usage_analyse_checksum();
@@ -280,25 +333,28 @@ int CmdAnalyseCHKSUM(const char *Cmd){
        //Validations
        if(errors) return usage_analyse_checksum();
        
-       PrintAndLog("\nByte Add        | 0x%X", calcSumByteAdd(data, len, mask));
-       PrintAndLog("Nibble Add      | 0x%X", calcSumNibbleAdd(data, len, mask));
-       PrintAndLog("Crumb Add       | 0x%X", calcSumCrumbAdd(data, len, mask));
-       
-       PrintAndLog("\nByte Subtract   | 0x%X", calcSumByteSub(data, len, mask));
-       PrintAndLog("Nibble Subtract | 0x%X", calcSumNibbleSub(data, len, mask));
-       
-       PrintAndLog("\nCHECKSUM - One's complement");
-       PrintAndLog("Byte Add        | 0x%X", calcSumByteAddOnes(data, len, mask));
-       PrintAndLog("Nibble Add      | 0x%X", calcSumNibbleAddOnes(data, len, mask));
-       PrintAndLog("Crumb Add       | 0x%X", calcSumCrumbAddOnes(data, len, mask));
-
-       PrintAndLog("Byte Subtract   | 0x%X", calcSumByteSubOnes(data, len, mask));
-       PrintAndLog("Nibble Subtract | 0x%X", calcSumNibbleSubOnes(data, len, mask));
-       
-       PrintAndLog("\nXOR");
-       PrintAndLog("Byte Xor   | 0x%X", calcSumByteXor(data, len, mask));
-       PrintAndLog("Nibble Xor   | 0x%X", calcSumNibbleXor(data, len, mask));
-       
+       if (useHeader) {
+               PrintAndLog("     add          | sub         | add 1's compl    | sub 1's compl   | xor");
+               PrintAndLog("byte nibble crumb | byte nibble | byte nibble cumb | byte nibble     | byte nibble cumb |  BSD       |");
+               PrintAndLog("------------------+-------------+------------------+-----------------+--------------------");
+       }
+       PrintAndLog("0x%X 0x%X   0x%X  | 0x%X 0x%X   | 0x%X 0x%X   0x%X | 0x%X 0x%X       | 0x%X 0x%X   0x%X  | 0x%X  0x%X |\n",        
+                                 calcSumByteAdd(data, len, mask)
+                               , calcSumNibbleAdd(data, len, mask)
+                               , calcSumCrumbAdd(data, len, mask)
+                               , calcSumByteSub(data, len, mask)
+                               , calcSumNibbleSub(data, len, mask)
+                               , calcSumByteAddOnes(data, len, mask)
+                               , calcSumNibbleAddOnes(data, len, mask)
+                               , calcSumCrumbAddOnes(data, len, mask)
+                               , calcSumByteSubOnes(data, len, mask)
+                               , calcSumNibbleSubOnes(data, len, mask)
+                               , calcSumByteXor(data, len, mask)
+                               , calcSumNibbleXor(data, len, mask)
+                               , calcSumCrumbXor(data, len, mask)
+                               , calcBSDchecksum8(data, len, mask)
+                               , calcBSDchecksum4(data, len, mask)
+                       );      
        return 0;
 }
 
@@ -477,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"},
@@ -487,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}
 };
 
Impressum, Datenschutz