From 79d7bcbb51db25dab899b3b250f48a0ab40e30e9 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Sun, 24 May 2015 22:28:21 -0400 Subject: [PATCH 01/26] updated mfu rdbl and wrbl commands @iceman1001 s rdbl and wrbl cmd updates. dump screen output adjusted --- armsrc/appmain.c | 2 +- armsrc/apps.h | 2 +- armsrc/mifarecmd.c | 45 ++++- client/cmdhfmfu.c | 494 ++++++++++++++++++++++++--------------------- client/cmdhfmfu.h | 7 +- 5 files changed, 307 insertions(+), 243 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 96644b9a0..f8594fccb 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -845,7 +845,7 @@ void UsbPacketReceived(uint8_t *packet, int len) MifareUWriteBlock(c->arg[0], c->d.asBytes); break; case CMD_MIFAREU_WRITEBL: - MifareUWriteBlock_Special(c->arg[0], c->d.asBytes); + MifareUWriteBlock_Special(c->arg[0], c->arg[1], c->d.asBytes); break; case CMD_MIFARE_NESTED: MifareNested(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); diff --git a/armsrc/apps.h b/armsrc/apps.h index 57fb55fd3..dfd1fe523 100644 --- a/armsrc/apps.h +++ b/armsrc/apps.h @@ -171,7 +171,7 @@ void MifareUReadCard(uint8_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain) void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain); void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain); void MifareUWriteBlock(uint8_t arg0,uint8_t *datain); -void MifareUWriteBlock_Special(uint8_t arg0,uint8_t *datain); +void MifareUWriteBlock_Special(uint8_t arg0, uint8_t arg1, uint8_t *datain); void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain); void MifareChkKeys(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain); void Mifare1ksim(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain); diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 8355cd194..2a21ac486 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -16,7 +16,6 @@ #include "mifarecmd.h" #include "apps.h" #include "util.h" - #include "crc.h" // the block number for the ISO14443-4 PCB @@ -24,7 +23,6 @@ uint8_t pcb_blocknum = 0; // Deselect card by sending a s-block. the crc is precalced for speed static uint8_t deselect_cmd[] = {0xc2,0xe0,0xb4}; - //----------------------------------------------------------------------------- // Select, Authenticate, Read a MIFARE tag. // read block @@ -248,6 +246,10 @@ void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) LEDsoff(); } +// arg0 = blockNo (start) +// arg1 = Pages (number of blocks) +// arg2 = useKey +// datain = KEY bytes void MifareUReadCard(uint8_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain) { // free eventually allocated BigBuf memory @@ -335,6 +337,13 @@ void MifareUReadCard(uint8_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain) if (MF_DBGLEVEL >= MF_DBG_EXTENDED) Dbprintf("Blocks read %d", countblocks); countblocks *= 4; +/* + LED_B_ON(); + for(size_t i=0; i < countblocks; i += USB_CMD_DATA_SIZE) { + size_t len = MIN((countblocks - i),USB_CMD_DATA_SIZE); + cmd_send(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K,i,len,countblocks,dataout+i,len); + } +*/ cmd_send(CMD_ACK, 1, countblocks, BigBuf_max_traceLen(), 0, 0); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LEDsoff(); @@ -450,9 +459,17 @@ void MifareUWriteBlock(uint8_t arg0, uint8_t *datain) LEDsoff(); } -void MifareUWriteBlock_Special(uint8_t arg0, uint8_t *datain) +// Arg0 : Block to write to. +// Arg1 : 0 = use no authentication. +// 1 = use 0x1A authentication. +// 2 = use 0x1B authentication. +// datain : 4 first bytes is data to be written. +// : 4/16 next bytes is authentication key. +void MifareUWriteBlock_Special(uint8_t arg0, uint8_t arg1, uint8_t *datain) { uint8_t blockNo = arg0; + bool useKey = (arg1 == 1); //UL_C + bool usePwd = (arg1 == 2); //UL_EV1/NTAG byte_t blockdata[4] = {0x00}; memcpy(blockdata, datain,4); @@ -468,6 +485,28 @@ void MifareUWriteBlock_Special(uint8_t arg0, uint8_t *datain) return; }; + // UL-C authentication + if ( useKey ) { + uint8_t key[16] = {0x00}; + memcpy(key, datain+4, sizeof(key) ); + + if ( !mifare_ultra_auth(key) ) { + OnError(1); + return; + } + } + + // UL-EV1 / NTAG authentication + if (usePwd) { + uint8_t pwd[4] = {0x00}; + memcpy(pwd, datain+4, 4); + uint8_t pack[4] = {0,0,0,0}; + if (!mifare_ul_ev1_auth(pwd, pack)) { + OnError(1); + return; + } + } + if(mifare_ultra_special_writeblock(blockNo, blockdata)) { if (MF_DBGLEVEL >= 1) Dbprintf("Write block error"); OnError(0); diff --git a/client/cmdhfmfu.c b/client/cmdhfmfu.c index 191032984..057708cac 100644 --- a/client/cmdhfmfu.c +++ b/client/cmdhfmfu.c @@ -279,7 +279,7 @@ static int ul_print_default( uint8_t *data){ uid[6] = data[7]; PrintAndLog(" UID : %s ", sprint_hex(uid, 7)); - PrintAndLog(" UID[0] : %02X, Manufacturer: %s", uid[0], getTagInfo(uid[0]) ); + PrintAndLog(" UID[0] : %02X, %s", uid[0], getTagInfo(uid[0]) ); if ( uid[0] == 0x05 ) { uint8_t chip = (data[8] & 0xC7); // 11000111 mask, bit 3,4,5 RFU switch (chip){ @@ -839,105 +839,239 @@ int CmdHF14AMfUInfo(const char *Cmd){ } // -// Mifare Ultralight Write Single Block +// Write Single Block // int CmdHF14AMfUWrBl(const char *Cmd){ - uint8_t blockNo = -1; - bool chinese_card = FALSE; - uint8_t bldata[16] = {0x00}; + + int blockNo = -1; + bool errors = false; + bool hasAuthKey = false; + bool hasPwdKey = false; + bool swapEndian = false; + + uint8_t cmdp = 0; + uint8_t keylen = 0; + uint8_t blockdata[20] = {0x00}; + uint8_t data[16] = {0x00}; + uint8_t authenticationkey[16] = {0x00}; + uint8_t *authKeyPtr = authenticationkey; + + // starting with getting tagtype + TagTypeUL_t tagtype = GetHF14AMfU_Type(); + if (tagtype == UL_ERROR) return -1; + + while(param_getchar(Cmd, cmdp) != 0x00) + { + switch(param_getchar(Cmd, cmdp)) + { + case 'h': + case 'H': + return usage_hf_mfu_wrbl(); + case 'k': + case 'K': + // EV1/NTAG size key + keylen = param_gethex(Cmd, cmdp+1, data, 8); + if ( !keylen ) { + memcpy(authenticationkey, data, 4); + cmdp += 2; + hasPwdKey = true; + break; + } + // UL-C size key + keylen = param_gethex(Cmd, cmdp+1, data, 32); + if (!keylen){ + memcpy(authenticationkey, data, 16); + cmdp += 2; + hasAuthKey = true; + break; + } + PrintAndLog("\nERROR: Key is incorrect length\n"); + errors = true; + break; + case 'b': + case 'B': + blockNo = param_get8(Cmd, cmdp+1); + + uint8_t maxblockno = 0; + for (uint8_t idx = 0; idx < MAX_UL_TYPES; idx++){ + if (tagtype & UL_TYPES_ARRAY[idx]) + maxblockno = UL_MEMORY_ARRAY[idx]; + } + + if (blockNo < 0) { + PrintAndLog("Wrong block number"); + errors = true; + } + if (blockNo > maxblockno){ + PrintAndLog("block number too large. Max block is %u/0x%02X \n", maxblockno,maxblockno); + errors = true; + } + cmdp += 2; + break; + case 'l': + case 'L': + swapEndian = true; + cmdp++; + break; + case 'd': + case 'D': + if ( param_gethex(Cmd, cmdp+1, blockdata, 8) ) { + PrintAndLog("Block data must include 8 HEX symbols"); + errors = true; + break; + } + cmdp += 2; + break; + default: + PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = true; + break; + } + //Validations + if(errors) return usage_hf_mfu_wrbl(); + } + + if ( blockNo == -1 ) return usage_hf_mfu_wrbl(); + + // Swap endianness + if (swapEndian && hasAuthKey) authKeyPtr = SwapEndian64(authenticationkey, 16, 8); + if (swapEndian && hasPwdKey) authKeyPtr = SwapEndian64(authenticationkey, 4, 4); + + if ( blockNo <= 3) + PrintAndLog("Special Block: %0d (0x%02X) [ %s]", blockNo, blockNo, sprint_hex(blockdata, 4)); + else + PrintAndLog("Block: %0d (0x%02X) [ %s]", blockNo, blockNo, sprint_hex(blockdata, 4)); + + //Send write Block + UsbCommand c = {CMD_MIFAREU_WRITEBL, {blockNo}}; + memcpy(c.d.asBytes,blockdata,4); + + if ( hasAuthKey ) { + c.arg[1] = 1; + memcpy(c.d.asBytes+4,authKeyPtr,16); + } + else if ( hasPwdKey ) { + c.arg[1] = 2; + memcpy(c.d.asBytes+4,authKeyPtr,4); + } + + SendCommand(&c); UsbCommand resp; - - char cmdp = param_getchar(Cmd, 0); - if (strlen(Cmd) < 3 || cmdp == 'h' || cmdp == 'H') { - PrintAndLog("Usage: hf mfu wrbl [w]"); - PrintAndLog(" [block number]"); - PrintAndLog(" [block data] - (8 hex symbols)"); - PrintAndLog(" [w] - Chinese magic ultralight tag"); - PrintAndLog(""); - PrintAndLog(" sample: hf mfu wrbl 0 01020304"); - PrintAndLog(""); - return 0; - } - - blockNo = param_get8(Cmd, 0); - - if (blockNo > MAX_UL_BLOCKS){ - PrintAndLog("Error: Maximum number of blocks is 15 for Ultralight Cards!"); - return 1; - } - - if (param_gethex(Cmd, 1, bldata, 8)) { - PrintAndLog("Block data must include 8 HEX symbols"); - return 1; - } - - if (strchr(Cmd,'w') != 0 || strchr(Cmd,'W') != 0 ) { - chinese_card = TRUE; - } - - if ( blockNo <= 3) { - if (!chinese_card){ - PrintAndLog("Access Denied"); - } else { - PrintAndLog("--specialblock no:%02x", blockNo); - PrintAndLog("--data: %s", sprint_hex(bldata, 4)); - UsbCommand d = {CMD_MIFAREU_WRITEBL, {blockNo}}; - memcpy(d.d.asBytes,bldata, 4); - SendCommand(&d); - if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { - uint8_t isOK = resp.arg[0] & 0xff; - PrintAndLog("isOk:%02x", isOK); - } else { - PrintAndLog("Command execute timeout"); - } - } + if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { + uint8_t isOK = resp.arg[0] & 0xff; + PrintAndLog("isOk:%02x", isOK); } else { - PrintAndLog("--block no:%02x", blockNo); - PrintAndLog("--data: %s", sprint_hex(bldata, 4)); - UsbCommand e = {CMD_MIFAREU_WRITEBL, {blockNo}}; - memcpy(e.d.asBytes,bldata, 4); - SendCommand(&e); - if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { - uint8_t isOK = resp.arg[0] & 0xff; - PrintAndLog("isOk:%02x", isOK); - } else { - PrintAndLog("Command execute timeout"); - } + PrintAndLog("Command execute timeout"); } + return 0; } - // -// Mifare Ultralight Read Single Block +// Read Single Block // int CmdHF14AMfURdBl(const char *Cmd){ - UsbCommand resp; - uint8_t blockNo = -1; - char cmdp = param_getchar(Cmd, 0); - - if (strlen(Cmd) < 1 || cmdp == 'h' || cmdp == 'H') { - PrintAndLog("Usage: hf mfu rdbl "); - PrintAndLog(" sample: hfu mfu rdbl 0"); - return 0; + int blockNo = -1; + bool errors = false; + bool hasAuthKey = false; + bool hasPwdKey = false; + bool swapEndian = false; + uint8_t cmdp = 0; + uint8_t keylen = 0; + uint8_t data[16] = {0x00}; + uint8_t authenticationkey[16] = {0x00}; + uint8_t *authKeyPtr = authenticationkey; + + // starting with getting tagtype + TagTypeUL_t tagtype = GetHF14AMfU_Type(); + if (tagtype == UL_ERROR) return -1; + + while(param_getchar(Cmd, cmdp) != 0x00) + { + switch(param_getchar(Cmd, cmdp)) + { + case 'h': + case 'H': + return usage_hf_mfu_rdbl(); + case 'k': + case 'K': + // EV1/NTAG size key + keylen = param_gethex(Cmd, cmdp+1, data, 8); + if ( !keylen ) { + memcpy(authenticationkey, data, 4); + cmdp += 2; + hasPwdKey = true; + break; + } + // UL-C size key + keylen = param_gethex(Cmd, cmdp+1, data, 32); + if (!keylen){ + memcpy(authenticationkey, data, 16); + cmdp += 2; + hasAuthKey = true; + break; + } + PrintAndLog("\nERROR: Key is incorrect length\n"); + errors = true; + break; + case 'b': + case 'B': + blockNo = param_get8(Cmd, cmdp+1); + + uint8_t maxblockno = 0; + for (uint8_t idx = 0; idx < MAX_UL_TYPES; idx++){ + if (tagtype & UL_TYPES_ARRAY[idx]) + maxblockno = UL_MEMORY_ARRAY[idx]; + } + + if (blockNo < 0) { + PrintAndLog("Wrong block number"); + errors = true; + } + if (blockNo > maxblockno){ + PrintAndLog("block number to large. Max block is %u/0x%02X \n", maxblockno,maxblockno); + errors = true; + } + cmdp += 2; + break; + case 'l': + case 'L': + swapEndian = true; + cmdp++; + break; + default: + PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = true; + break; + } + //Validations + if(errors) return usage_hf_mfu_rdbl(); } - blockNo = param_get8(Cmd, 0); + if ( blockNo == -1 ) return usage_hf_mfu_rdbl(); - if (blockNo > MAX_UL_BLOCKS){ - PrintAndLog("Error: Maximum number of blocks is 15 for Ultralight"); - return 1; - } + // Swap endianness + if (swapEndian && hasAuthKey) authKeyPtr = SwapEndian64(authenticationkey, 16, 8); + if (swapEndian && hasPwdKey) authKeyPtr = SwapEndian64(authenticationkey, 4, 4); + //Read Block UsbCommand c = {CMD_MIFAREU_READBL, {blockNo}}; + if ( hasAuthKey ){ + c.arg[1] = 1; + memcpy(c.d.asBytes,authKeyPtr,16); + } + else if ( hasPwdKey ) { + c.arg[1] = 2; + memcpy(c.d.asBytes,authKeyPtr,4); + } + SendCommand(&c); - - + UsbCommand resp; if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { uint8_t isOK = resp.arg[0] & 0xff; if (isOK) { uint8_t *data = resp.d.asBytes; - PrintAndLog("Block: %0d (0x%02X) [ %s]", (int)blockNo, blockNo, sprint_hex(data, 4)); + PrintAndLog("Block: %0d (0x%02X) [ %s]", blockNo, blockNo, sprint_hex(data, 4)); } else { PrintAndLog("Failed reading block: (%02x)", isOK); @@ -945,7 +1079,6 @@ int CmdHF14AMfURdBl(const char *Cmd){ } else { PrintAndLog("Command execute time-out"); } - return 0; } @@ -988,6 +1121,34 @@ int usage_hf_mfu_dump(void) { return 0; } +int usage_hf_mfu_rdbl(void) { + PrintAndLog("Read a block and print. It autodetects card type.\n"); + PrintAndLog("Usage: hf mfu rdbl b k l\n"); + PrintAndLog(" Options:"); + PrintAndLog(" b : block to read"); + PrintAndLog(" k : (optional) key for authentication [UL-C 16bytes, EV1/NTAG 4bytes]"); + PrintAndLog(" l : (optional) swap entered key's endianness"); + PrintAndLog(""); + PrintAndLog(" sample : hf mfu rdbl b 0"); + PrintAndLog(" : hf mfu rdbl b 0 k 00112233445566778899AABBCCDDEEFF"); + PrintAndLog(" : hf mfu rdbl b 0 k AABBCCDDD\n"); + return 0; +} + +int usage_hf_mfu_wrbl(void) { + PrintAndLog("Write a block. It autodetects card type.\n"); + PrintAndLog("Usage: hf mfu wrbl b d k l\n"); + PrintAndLog(" Options:"); + PrintAndLog(" b : block to write"); + PrintAndLog(" d : block data - (8 hex symbols)"); + PrintAndLog(" k : (optional) key for authentication [UL-C 16bytes, EV1/NTAG 4bytes]"); + PrintAndLog(" l : (optional) swap entered key's endianness"); + PrintAndLog(""); + PrintAndLog(" sample : hf mfu wrbl b 0 d 01234567"); + PrintAndLog(" : hf mfu wrbl b 0 d 01234567 k AABBCCDDD\n"); + return 0; +} + // // Mifare Ultralight / Ultralight-C / Ultralight-EV1 // Read and Dump Card Contents, using auto detection of tag size. @@ -1079,10 +1240,10 @@ int CmdHF14AMfUDump(const char *Cmd){ TagTypeUL_t tagtype = GetHF14AMfU_Type(); if (tagtype == UL_ERROR) return -1; - if (!manualPages) + if (!manualPages) //get number of pages to read for (uint8_t idx = 0; idx < MAX_UL_TYPES; idx++) if (tagtype & UL_TYPES_ARRAY[idx]) - Pages = UL_MEMORY_ARRAY[idx]+1; + Pages = UL_MEMORY_ARRAY[idx]+1; //add one as maxblks starts at 0 ul_print_type(tagtype, 0); PrintAndLog("Reading tag memory..."); @@ -1153,9 +1314,11 @@ int CmdHF14AMfUDump(const char *Cmd){ } } + PrintAndLog("Block# | Data |lck| Ascii"); + PrintAndLog("---------------------------------"); for (i = 0; i < Pages; ++i) { if ( i < 3 ) { - PrintAndLog("Block %02x:%s ", i,sprint_hex(data + i * 4, 4)); + PrintAndLog("%02d/0x%02X | %s | | ", i, i, sprint_hex(data + i * 4, 4)); continue; } switch(i){ @@ -1202,9 +1365,10 @@ int CmdHF14AMfUDump(const char *Cmd){ case 43: tmplockbit = bit2[9]; break; //auth1 default: break; } - PrintAndLog("Block %02X:%s [%d] {%.4s}", i, sprint_hex(data + i * 4, 4), tmplockbit, data+i*4); + PrintAndLog("%02d/0x%02X | %s | %d | %.4s", i, sprint_hex(data + i * 4, 4), tmplockbit, data+i*4); } - + PrintAndLog("---------------------------------"); + // user supplied filename? if (fileNlen < 1) { // UID = data 0-1-2 4-5-6-7 (skips a beat) @@ -1369,142 +1533,6 @@ int CmdTestDES(const char * cmd) } **/ -// -// Ultralight C Read Single Block -// -int CmdHF14AMfUCRdBl(const char *Cmd) -{ - UsbCommand resp; - bool hasPwd = FALSE; - uint8_t blockNo = -1; - uint8_t key[16]; - char cmdp = param_getchar(Cmd, 0); - - if (strlen(Cmd) < 1 || cmdp == 'h' || cmdp == 'H') { - PrintAndLog("Usage: hf mfu crdbl "); - PrintAndLog(""); - PrintAndLog("sample: hf mfu crdbl 0"); - PrintAndLog(" hf mfu crdbl 0 00112233445566778899AABBCCDDEEFF"); - return 0; - } - - blockNo = param_get8(Cmd, 0); - if (blockNo < 0) { - PrintAndLog("Wrong block number"); - return 1; - } - - if (blockNo > MAX_ULC_BLOCKS ){ - PrintAndLog("Error: Maximum number of blocks is 47 for Ultralight-C"); - return 1; - } - - // key - if ( strlen(Cmd) > 3){ - if (param_gethex(Cmd, 1, key, 32)) { - PrintAndLog("Key must include %d HEX symbols", 32); - return 1; - } else { - hasPwd = TRUE; - } - } - - //Read Block - UsbCommand c = {CMD_MIFAREU_READBL, {blockNo}}; - if ( hasPwd ) { - c.arg[1] = 1; - memcpy(c.d.asBytes,key,16); - } - SendCommand(&c); - - if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { - uint8_t isOK = resp.arg[0] & 0xff; - if (isOK) { - uint8_t *data = resp.d.asBytes; - PrintAndLog("Block: %0d (0x%02X) [ %s]", (int)blockNo, blockNo, sprint_hex(data, 4)); - } - else { - PrintAndLog("Failed reading block: (%02x)", isOK); - } - } else { - PrintAndLog("Command execute time-out"); - } - return 0; -} - -// -// Mifare Ultralight C Write Single Block -// -int CmdHF14AMfUCWrBl(const char *Cmd){ - - uint8_t blockNo = -1; - bool chinese_card = FALSE; - uint8_t bldata[16] = {0x00}; - UsbCommand resp; - - char cmdp = param_getchar(Cmd, 0); - - if (strlen(Cmd) < 3 || cmdp == 'h' || cmdp == 'H') { - PrintAndLog("Usage: hf mfu cwrbl [w]"); - PrintAndLog(" [block number]"); - PrintAndLog(" [block data] - (8 hex symbols)"); - PrintAndLog(" [w] - Chinese magic ultralight tag"); - PrintAndLog(""); - PrintAndLog(" sample: hf mfu cwrbl 0 01020304"); - PrintAndLog(""); - return 0; - } - - blockNo = param_get8(Cmd, 0); - if (blockNo > MAX_ULC_BLOCKS ){ - PrintAndLog("Error: Maximum number of blocks is 47 for Ultralight-C Cards!"); - return 1; - } - - if (param_gethex(Cmd, 1, bldata, 8)) { - PrintAndLog("Block data must include 8 HEX symbols"); - return 1; - } - - if (strchr(Cmd,'w') != 0 || strchr(Cmd,'W') != 0 ) { - chinese_card = TRUE; - } - - if ( blockNo <= 3 ) { - if (!chinese_card){ - PrintAndLog("Access Denied"); - return 1; - } else { - PrintAndLog("--Special block no: 0x%02x", blockNo); - PrintAndLog("--Data: %s", sprint_hex(bldata, 4)); - UsbCommand d = {CMD_MIFAREU_WRITEBL, {blockNo}}; - memcpy(d.d.asBytes,bldata, 4); - SendCommand(&d); - if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { - uint8_t isOK = resp.arg[0] & 0xff; - PrintAndLog("isOk:%02x", isOK); - } else { - PrintAndLog("Command execute timeout"); - return 1; - } - } - } else { - PrintAndLog("--Block no : 0x%02x", blockNo); - PrintAndLog("--Data: %s", sprint_hex(bldata, 4)); - UsbCommand e = {CMD_MIFAREU_WRITEBL, {blockNo}}; - memcpy(e.d.asBytes,bldata, 4); - SendCommand(&e); - if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { - uint8_t isOK = resp.arg[0] & 0xff; - PrintAndLog("isOk : %02x", isOK); - } else { - PrintAndLog("Command execute timeout"); - return 1; - } - } - return 0; -} - // // Mifare Ultralight C - Set password // @@ -1629,10 +1657,10 @@ int CmdHF14AMfucSetUid(const char *Cmd){ } int CmdHF14AMfuGenDiverseKeys(const char *Cmd){ - + uint8_t iv[8] = { 0x00 }; uint8_t block = 0x07; - + // UL-EV1 //04 57 b6 e2 05 3f 80 UID //4a f8 4b 19 PWD @@ -1646,14 +1674,14 @@ int CmdHF14AMfuGenDiverseKeys(const char *Cmd){ uint8_t mix[8] = { 0x00 }; uint8_t divkey[8] = { 0x00 }; - + memcpy(mix, mifarekeyA, 4); - + mix[4] = mifarekeyA[4] ^ uid[0]; mix[5] = mifarekeyA[5] ^ uid[1]; mix[6] = block ^ uid[2]; mix[7] = uid[3]; - + des3_context ctx = { 0x00 }; des3_set2key_enc(&ctx, masterkey); @@ -1672,9 +1700,9 @@ int CmdHF14AMfuGenDiverseKeys(const char *Cmd){ PrintAndLog("Mifare key :\t %s", sprint_hex(mifarekeyA, sizeof(mifarekeyA))); PrintAndLog("Message :\t %s", sprint_hex(mix, sizeof(mix))); PrintAndLog("Diversified key: %s", sprint_hex(divkey+1, 6)); - + PrintAndLog("\n DES version"); - + for (int i=0; i < sizeof(mifarekeyA); ++i){ dkeyA[i] = (mifarekeyA[i] << 1) & 0xff; dkeyA[6] |= ((mifarekeyA[i] >> 7) & 1) << (i+1); @@ -1692,7 +1720,7 @@ int CmdHF14AMfuGenDiverseKeys(const char *Cmd){ memcpy(dmkey+8, dkeyB, 8); memcpy(dmkey+16, dkeyA, 8); memset(iv, 0x00, 8); - + des3_set3key_enc(&ctx, dmkey); des3_crypt_cbc(&ctx // des3_context @@ -1735,11 +1763,9 @@ static command_t CommandTable[] = {"help", CmdHelp, 1, "This help"}, {"dbg", CmdHF14AMfDbg, 0, "Set default debug mode"}, {"info", CmdHF14AMfUInfo, 0, "Tag information"}, - {"dump", CmdHF14AMfUDump, 0, "Dump Ultralight / Ultralight-C tag to binary file"}, - {"rdbl", CmdHF14AMfURdBl, 0, "Read block - Ultralight"}, - {"wrbl", CmdHF14AMfUWrBl, 0, "Write block - Ultralight"}, - {"crdbl", CmdHF14AMfUCRdBl, 0, "Read block - Ultralight C"}, - {"cwrbl", CmdHF14AMfUCWrBl, 0, "Write block - Ultralight C"}, + {"dump", CmdHF14AMfUDump, 0, "Dump Ultralight / Ultralight-C / NTAG tag to binary file"}, + {"rdbl", CmdHF14AMfURdBl, 0, "Read block"}, + {"wrbl", CmdHF14AMfUWrBl, 0, "Write block"}, {"cauth", CmdHF14AMfucAuth, 0, "Authentication - Ultralight C"}, {"setpwd", CmdHF14AMfucSetPwd, 1, "Set 3des password - Ultralight-C"}, {"setuid", CmdHF14AMfucSetUid, 1, "Set UID - MAGIC tags only"}, diff --git a/client/cmdhfmfu.h b/client/cmdhfmfu.h index 83f284031..4ec48ff9d 100644 --- a/client/cmdhfmfu.h +++ b/client/cmdhfmfu.h @@ -4,25 +4,24 @@ #ifndef CMDHFMFU_H__ #define CMDHFMFU_H__ -//standard ultralight int CmdHF14AMfUWrBl(const char *Cmd); int CmdHF14AMfURdBl(const char *Cmd); //Crypto Cards -int CmdHF14AMfUCRdBl(const char *Cmd); -int CmdHF14AMfUCRdCard(const char *Cmd); int CmdHF14AMfucAuth(const char *Cmd); //general stuff int CmdHF14AMfUDump(const char *Cmd); int CmdHF14AMfUInfo(const char *Cmd); -uint32_t GetHF14AMfU_Type(void); +uint32_t GetHF14AMfU_Type(void); int ul_print_type(uint32_t tagtype, uint8_t spacer); void ul_switch_off_field(void); int usage_hf_mfu_dump(void); int usage_hf_mfu_info(void); +int usage_hf_mfu_rdbl(void); +int usage_hf_mfu_wrbl(void); int CmdHFMFUltra(const char *Cmd); From 1d537ad65c54d8821cf228a36fc15ac6e9764f50 Mon Sep 17 00:00:00 2001 From: Pierre LALET Date: Mon, 25 May 2015 11:47:27 +0200 Subject: [PATCH 02/26] Ported hf mf esave trick for unreadable UIDs to hf mf csave Thanks: iceman1001 --- client/cmdhfmf.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 2b5a5b879..5abda060d 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -1750,10 +1750,13 @@ int CmdHF14AMfCSave(const char *Cmd) { // get filename if (mfCGetBlock(0, buf, CSETBLOCK_SINGLE_OPER)) { PrintAndLog("Cant get block: %d", 0); - return 1; + len = sprintf(fnameptr, "dump"); + fnameptr += len; + } + else { + for (j = 0; j < 7; j++, fnameptr += 2) + sprintf(fnameptr, "%02x", buf[j]); } - for (j = 0; j < 7; j++, fnameptr += 2) - sprintf(fnameptr, "%02x", buf[j]); } else { memcpy(filename, Cmd, len); fnameptr += len; From 22342f6dfe53055955e9a849ad0bedb8b3e7c83b Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Tue, 26 May 2015 10:40:23 -0400 Subject: [PATCH 03/26] Add clearCommandBuffer before SendCommand adjust output of mfu rdbl to be consistent fix output of mfu dump in case startPage was specified. (also was missing "i" in second print...) --- armsrc/mifarecmd.c | 11 +++-------- client/cmdhfmfu.c | 26 +++++++++++++++++++++----- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 2a21ac486..884da9132 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -305,7 +305,7 @@ void MifareUReadCard(uint8_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain) } for (int i = 0; i < blocks; i++){ - if ((i*4) + 4 > CARD_MEMORY_SIZE) { + if ((i*4) + 4 >= CARD_MEMORY_SIZE) { Dbprintf("Data exceeds buffer!!"); break; } @@ -337,16 +337,11 @@ void MifareUReadCard(uint8_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain) if (MF_DBGLEVEL >= MF_DBG_EXTENDED) Dbprintf("Blocks read %d", countblocks); countblocks *= 4; -/* - LED_B_ON(); - for(size_t i=0; i < countblocks; i += USB_CMD_DATA_SIZE) { - size_t len = MIN((countblocks - i),USB_CMD_DATA_SIZE); - cmd_send(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K,i,len,countblocks,dataout+i,len); - } -*/ + cmd_send(CMD_ACK, 1, countblocks, BigBuf_max_traceLen(), 0, 0); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LEDsoff(); + BigBuf_free(); } //----------------------------------------------------------------------------- diff --git a/client/cmdhfmfu.c b/client/cmdhfmfu.c index 057708cac..5d211558e 100644 --- a/client/cmdhfmfu.c +++ b/client/cmdhfmfu.c @@ -102,17 +102,20 @@ char *getUlev1CardSizeStr( uint8_t fsize ){ static void ul_switch_on_field(void) { UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT | ISO14A_NO_DISCONNECT, 0, 0}}; + clearCommandBuffer(); SendCommand(&c); } void ul_switch_off_field(void) { UsbCommand c = {CMD_READER_ISO_14443a, {0, 0, 0}}; + clearCommandBuffer(); SendCommand(&c); } static int ul_send_cmd_raw( uint8_t *cmd, uint8_t cmdlen, uint8_t *response, uint16_t responseLength ) { UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_RAW | ISO14A_NO_DISCONNECT | ISO14A_APPEND_CRC, cmdlen, 0}}; memcpy(c.d.asBytes, cmd, cmdlen); + clearCommandBuffer(); SendCommand(&c); UsbCommand resp; if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) return -1; @@ -129,6 +132,7 @@ static int ul_send_cmd_raw_crc( uint8_t *cmd, uint8_t cmdlen, uint8_t *response, c.arg[0] |= ISO14A_APPEND_CRC; memcpy(c.d.asBytes, cmd, cmdlen); + clearCommandBuffer(); SendCommand(&c); UsbCommand resp; if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) return -1; @@ -193,6 +197,7 @@ static int ulc_authentication( uint8_t *key, bool switch_off_field ){ UsbCommand c = {CMD_MIFAREUC_AUTH, {switch_off_field}}; memcpy(c.d.asBytes, key, 16); + clearCommandBuffer(); SendCommand(&c); UsbCommand resp; if ( !WaitForResponseTimeout(CMD_ACK, &resp, 1500) ) return 0; @@ -955,6 +960,7 @@ int CmdHF14AMfUWrBl(const char *Cmd){ memcpy(c.d.asBytes+4,authKeyPtr,4); } + clearCommandBuffer(); SendCommand(&c); UsbCommand resp; if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { @@ -1065,13 +1071,16 @@ int CmdHF14AMfURdBl(const char *Cmd){ memcpy(c.d.asBytes,authKeyPtr,4); } + clearCommandBuffer(); SendCommand(&c); UsbCommand resp; if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { uint8_t isOK = resp.arg[0] & 0xff; if (isOK) { uint8_t *data = resp.d.asBytes; - PrintAndLog("Block: %0d (0x%02X) [ %s]", blockNo, blockNo, sprint_hex(data, 4)); + PrintAndLog("\nBlock# | Data | Ascii"); + PrintAndLog("-----------------------------"); + PrintAndLog("%02d/0x%02X | %s| %.4s\n", blockNo, blockNo, sprint_hex(data, 4), data); } else { PrintAndLog("Failed reading block: (%02x)", isOK); @@ -1256,6 +1265,8 @@ int CmdHF14AMfUDump(const char *Cmd){ memcpy(c.d.asBytes, authKeyPtr, dataLen); } + + clearCommandBuffer(); SendCommand(&c); UsbCommand resp; if (!WaitForResponseTimeout(CMD_ACK, &resp,1500)) { @@ -1314,11 +1325,11 @@ int CmdHF14AMfUDump(const char *Cmd){ } } - PrintAndLog("Block# | Data |lck| Ascii"); + PrintAndLog("\nBlock# | Data |lck| Ascii"); PrintAndLog("---------------------------------"); for (i = 0; i < Pages; ++i) { if ( i < 3 ) { - PrintAndLog("%02d/0x%02X | %s | | ", i, i, sprint_hex(data + i * 4, 4)); + PrintAndLog("%02d/0x%02X | %s| | ", i+startPage, i+startPage, sprint_hex(data + i * 4, 4)); continue; } switch(i){ @@ -1365,10 +1376,10 @@ int CmdHF14AMfUDump(const char *Cmd){ case 43: tmplockbit = bit2[9]; break; //auth1 default: break; } - PrintAndLog("%02d/0x%02X | %s | %d | %.4s", i, sprint_hex(data + i * 4, 4), tmplockbit, data+i*4); + PrintAndLog("%02d/0x%02X | %s| %d | %.4s", i+startPage, i+startPage, sprint_hex(data + i * 4, 4), tmplockbit, data+i*4); } PrintAndLog("---------------------------------"); - + // user supplied filename? if (fileNlen < 1) { // UID = data 0-1-2 4-5-6-7 (skips a beat) @@ -1558,6 +1569,7 @@ int CmdHF14AMfucSetPwd(const char *Cmd){ UsbCommand c = {CMD_MIFAREUC_SETPWD}; memcpy( c.d.asBytes, pwd, 16); + clearCommandBuffer(); SendCommand(&c); UsbCommand resp; @@ -1606,6 +1618,7 @@ int CmdHF14AMfucSetUid(const char *Cmd){ // read block2. c.cmd = CMD_MIFAREU_READBL; c.arg[0] = 2; + clearCommandBuffer(); SendCommand(&c); if (!WaitForResponseTimeout(CMD_ACK,&resp,1500)) { PrintAndLog("Command execute timeout"); @@ -1623,6 +1636,7 @@ int CmdHF14AMfucSetUid(const char *Cmd){ c.d.asBytes[1] = uid[1]; c.d.asBytes[2] = uid[2]; c.d.asBytes[3] = 0x88 ^ uid[0] ^ uid[1] ^ uid[2]; + clearCommandBuffer(); SendCommand(&c); if (!WaitForResponseTimeout(CMD_ACK,&resp,1500)) { PrintAndLog("Command execute timeout"); @@ -1635,6 +1649,7 @@ int CmdHF14AMfucSetUid(const char *Cmd){ c.d.asBytes[1] = uid[4]; c.d.asBytes[2] = uid[5]; c.d.asBytes[3] = uid[6]; + clearCommandBuffer(); SendCommand(&c); if (!WaitForResponseTimeout(CMD_ACK,&resp,1500) ) { PrintAndLog("Command execute timeout"); @@ -1647,6 +1662,7 @@ int CmdHF14AMfucSetUid(const char *Cmd){ c.d.asBytes[1] = oldblock2[1]; c.d.asBytes[2] = oldblock2[2]; c.d.asBytes[3] = oldblock2[3]; + clearCommandBuffer(); SendCommand(&c); if (!WaitForResponseTimeout(CMD_ACK,&resp,1500) ) { PrintAndLog("Command execute timeout"); From dcbaa2b5822435a9ba6309ffc83d843c8a1ba21c Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Tue, 26 May 2015 20:31:07 -0400 Subject: [PATCH 04/26] @iceman1001 s lua script fix --- client/scripts/dumptoemul.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/scripts/dumptoemul.lua b/client/scripts/dumptoemul.lua index f9b715091..f8cc11d45 100644 --- a/client/scripts/dumptoemul.lua +++ b/client/scripts/dumptoemul.lua @@ -73,7 +73,8 @@ local function convert_to_emulform(hexdata) for i = 1, string.len(hexdata),32 do ascii = ascii ..string.sub(hexdata,i,i+31).."\n" end - return ascii + + return string.sub(ascii,1,-1) end local function main(args) From be10fe2f11db33a4f96c573dc47c47822e1a8e9d Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Wed, 27 May 2015 00:32:01 -0400 Subject: [PATCH 05/26] update changelog --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 85e7f9152..3c016c3d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac ## [Unreleased][unreleased] ### Changed +- Added ultralight/ntag tag type detection to `hf 14a read` (marshmellow) +- Improved ultralight dump command to auto detect tag type, take authentication, and dump full memory (or subset specified) of known tag types (iceman1001 / marshmellow) +- Combined ultralight read/write commands and added authentication (iceman1001) - Improved LF manchester and biphase demodulation and ask clock detection especially for reads with heavy clipping. (marshmellow) - Iclass read, `hf iclass read` now also reads tag config and prints configuration. (holiman) - *bootrom* needs to be flashed, due to new address boundaries between os and fpga, after a size optimization (piwi) @@ -13,6 +16,9 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Fixed issue #19, problems with LF T55xx commands (iceman1001, marshmellow) ### Added +- Added `hf search` - currently tests for 14443a tags, iclass tags, and 15693 tags (marshmellow) +- Added `hf mfu info` Ultralight/NTAG info command - reads tag configuration and info, allows authentication if needed (iceman1001, marshmellow) +- Added Mifare Ultralight C and Ultralight EV1/NTAG authentication. (iceman1001) - Added changelog ## [2.0.0] - 2015-03-25 From 799b2e2e9da62c96a30e9a04da911ff3cbe8cbd9 Mon Sep 17 00:00:00 2001 From: Pavel Zhovner Date: Wed, 27 May 2015 11:30:50 +0300 Subject: [PATCH 06/26] Compiling manual for MAC OS X --- COMPILING.txt | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/COMPILING.txt b/COMPILING.txt index c894f0ff0..1cc34a0fc 100644 --- a/COMPILING.txt +++ b/COMPILING.txt @@ -81,7 +81,31 @@ Download the ProxSpace environment archive and extract it to C:\ = Mac OS X = ============ -macport stuff should do ;) +Tested on OSX 10.10 Yosemite + +1 - Install Xcode and Xcode Command Line Tools + +2 - Install Homebrew and dependencies + brew install readline + brew instal libusb + +3 - Download DevKitARM for OSX + http://sourceforge.net/projects/devkitpro/files/devkitARM/devkitARM_r44/ + Unpack devkitARM_r44-osx.tar.bz2 to proxmark3 directory. + +4 - Edit proxmark3/client/Makefile adding path to readline + + LDLIBS = -L/usr/local/Cellar/readline/6.3.8/lib/ -L/opt/local/lib -L/usr/local/lib ../liblua/liblua.a -lreadline -lpthread -lm + CFLAGS = -std=c99 -I/usr/local/Cellar/readline/6.3.8/include/ -I. -I../include -I../common -I/opt/local/include -I../liblua -Wall $(COMMON_FLAGS) -g -O4 + + Replace path /usr/local/Cellar/readline/6.3.8 with your actuall readline path. See homebrew manuals. + +5 - Set Environment + + export DEVKITPRO=$HOME/proxmark3/ + export DEVKITARM=$DEVKITPRO/devkitARM + export PATH=${PATH}:${DEVKITARM}/bin + ============ = Linux = From 4973f23d3c2d2086ec694a13602b21a19726ab49 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Wed, 27 May 2015 12:24:13 -0400 Subject: [PATCH 07/26] clean up mfu device side code + add xor calc to util (prep for desfire) commented out MifareUWriteBlockCompat as it isn't used in client currently (it is a command we could support.. but why?) relabeled a few device side mfu functions to be clearer. --- armsrc/appmain.c | 8 ++--- armsrc/apps.h | 4 +-- armsrc/mifarecmd.c | 27 +++++++-------- armsrc/mifareutil.c | 84 ++++++++++++++++++++++++--------------------- armsrc/mifareutil.h | 16 +++++---- client/util.c | 13 +++++-- client/util.h | 2 ++ 7 files changed, 85 insertions(+), 69 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index f8594fccb..c226c7263 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -841,11 +841,11 @@ void UsbPacketReceived(uint8_t *packet, int len) case CMD_MIFARE_WRITEBL: MifareWriteBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); break; - case CMD_MIFAREU_WRITEBL_COMPAT: - MifareUWriteBlock(c->arg[0], c->d.asBytes); - break; + //case CMD_MIFAREU_WRITEBL_COMPAT: + //MifareUWriteBlockCompat(c->arg[0], c->d.asBytes); + //break; case CMD_MIFAREU_WRITEBL: - MifareUWriteBlock_Special(c->arg[0], c->arg[1], c->d.asBytes); + MifareUWriteBlock(c->arg[0], c->arg[1], c->d.asBytes); break; case CMD_MIFARE_NESTED: MifareNested(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); diff --git a/armsrc/apps.h b/armsrc/apps.h index dfd1fe523..6360b664b 100644 --- a/armsrc/apps.h +++ b/armsrc/apps.h @@ -170,8 +170,8 @@ void MifareUC_Auth(uint8_t arg0, uint8_t *datain); void MifareUReadCard(uint8_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain); void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain); void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain); -void MifareUWriteBlock(uint8_t arg0,uint8_t *datain); -void MifareUWriteBlock_Special(uint8_t arg0, uint8_t arg1, uint8_t *datain); +//void MifareUWriteBlockCompat(uint8_t arg0,uint8_t *datain); +void MifareUWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain); void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain); void MifareChkKeys(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain); void Mifare1ksim(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain); diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 884da9132..bf6c404af 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -254,7 +254,6 @@ void MifareUReadCard(uint8_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain) { // free eventually allocated BigBuf memory BigBuf_free(); - // clear trace clear_trace(); // params @@ -416,7 +415,8 @@ void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) LEDsoff(); } -void MifareUWriteBlock(uint8_t arg0, uint8_t *datain) +/* // Command not needed but left for future testing +void MifareUWriteBlockCompat(uint8_t arg0, uint8_t *datain) { uint8_t blockNo = arg0; byte_t blockdata[16] = {0x00}; @@ -436,7 +436,7 @@ void MifareUWriteBlock(uint8_t arg0, uint8_t *datain) return; }; - if(mifare_ultra_writeblock(blockNo, blockdata)) { + if(mifare_ultra_writeblock_compat(blockNo, blockdata)) { if (MF_DBGLEVEL >= 1) Dbprintf("Write block error"); OnError(0); return; }; @@ -453,6 +453,7 @@ void MifareUWriteBlock(uint8_t arg0, uint8_t *datain) FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LEDsoff(); } +*/ // Arg0 : Block to write to. // Arg1 : 0 = use no authentication. @@ -460,7 +461,7 @@ void MifareUWriteBlock(uint8_t arg0, uint8_t *datain) // 2 = use 0x1B authentication. // datain : 4 first bytes is data to be written. // : 4/16 next bytes is authentication key. -void MifareUWriteBlock_Special(uint8_t arg0, uint8_t arg1, uint8_t *datain) +void MifareUWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain) { uint8_t blockNo = arg0; bool useKey = (arg1 == 1); //UL_C @@ -502,7 +503,7 @@ void MifareUWriteBlock_Special(uint8_t arg0, uint8_t arg1, uint8_t *datain) } } - if(mifare_ultra_special_writeblock(blockNo, blockdata)) { + if(mifare_ultra_writeblock(blockNo, blockdata)) { if (MF_DBGLEVEL >= 1) Dbprintf("Write block error"); OnError(0); return; @@ -542,7 +543,7 @@ void MifareUSetPwd(uint8_t arg0, uint8_t *datain){ blockdata[1] = pwd[6]; blockdata[2] = pwd[5]; blockdata[3] = pwd[4]; - if(mifare_ultra_special_writeblock( 44, blockdata)) { + if(mifare_ultra_writeblock( 44, blockdata)) { if (MF_DBGLEVEL >= 1) Dbprintf("Write block error"); OnError(44); return; @@ -552,7 +553,7 @@ void MifareUSetPwd(uint8_t arg0, uint8_t *datain){ blockdata[1] = pwd[2]; blockdata[2] = pwd[1]; blockdata[3] = pwd[0]; - if(mifare_ultra_special_writeblock( 45, blockdata)) { + if(mifare_ultra_writeblock( 45, blockdata)) { if (MF_DBGLEVEL >= 1) Dbprintf("Write block error"); OnError(45); return; @@ -562,7 +563,7 @@ void MifareUSetPwd(uint8_t arg0, uint8_t *datain){ blockdata[1] = pwd[14]; blockdata[2] = pwd[13]; blockdata[3] = pwd[12]; - if(mifare_ultra_special_writeblock( 46, blockdata)) { + if(mifare_ultra_writeblock( 46, blockdata)) { if (MF_DBGLEVEL >= 1) Dbprintf("Write block error"); OnError(46); return; @@ -572,7 +573,7 @@ void MifareUSetPwd(uint8_t arg0, uint8_t *datain){ blockdata[1] = pwd[10]; blockdata[2] = pwd[9]; blockdata[3] = pwd[8]; - if(mifare_ultra_special_writeblock( 47, blockdata)) { + if(mifare_ultra_writeblock( 47, blockdata)) { if (MF_DBGLEVEL >= 1) Dbprintf("Write block error"); OnError(47); return; @@ -1265,14 +1266,12 @@ void Mifare_DES_Auth2(uint32_t arg0, uint8_t *datain){ isOK = mifare_desfire_des_auth2(cuid, key, dataout); if( isOK) { - if (MF_DBGLEVEL >= MF_DBG_EXTENDED) - Dbprintf("Authentication part2: Failed"); - //OnError(4); + if (MF_DBGLEVEL >= MF_DBG_EXTENDED) Dbprintf("Authentication part2: Failed"); + OnError(4); return; } - if (MF_DBGLEVEL >= MF_DBG_EXTENDED) - DbpString("AUTH 2 FINISHED"); + if (MF_DBGLEVEL >= MF_DBG_EXTENDED) DbpString("AUTH 2 FINISHED"); cmd_send(CMD_ACK, isOK, 0, 0, dataout, sizeof(dataout)); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); diff --git a/armsrc/mifareutil.c b/armsrc/mifareutil.c index 2f84797b9..c706e78a4 100644 --- a/armsrc/mifareutil.c +++ b/armsrc/mifareutil.c @@ -65,73 +65,74 @@ uint8_t mf_crypto1_encrypt4bit(struct Crypto1State *pcs, uint8_t data) { return bt; } -// send commands +// send 2 byte commands int mifare_sendcmd_short(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing) { return mifare_sendcmd_shortex(pcs, crypted, cmd, data, answer, answer_parity, timing); } -int mifare_sendcmd_short_special(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t* data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing) +// send X byte basic commands +int mifare_sendcmd(uint8_t cmd, uint8_t* data, uint8_t data_size, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing) { - uint8_t dcmd[8]; - dcmd[0] = cmd; - dcmd[1] = data[0]; - dcmd[2] = data[1]; - dcmd[3] = data[2]; - dcmd[4] = data[3]; - dcmd[5] = data[4]; - AppendCrc14443a(dcmd, 6); - ReaderTransmit(dcmd, sizeof(dcmd), NULL); + uint8_t dcmd[data_size+3]; + dcmd[0] = cmd; + memcpy(dcmd+1,data,data_size); + AppendCrc14443a(dcmd, data_size+1); + ReaderTransmit(dcmd, sizeof(dcmd), timing); int len = ReaderReceive(answer, answer_parity); if(!len) { - if (MF_DBGLEVEL >= 1) Dbprintf("Authentication failed. Card timeout."); - return 2; - } + if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("%02X Cmd failed. Card timeout.", cmd); + len = ReaderReceive(answer,answer_parity); + //return 0; + } return len; } +/* int mifare_sendcmd_short_mfucauth(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t *data, uint8_t *answer, uint8_t *answer_parity, uint32_t *timing) { - uint8_t dcmd[19]; + uint8_t dcmd[19]; int len; - dcmd[0] = cmd; - memcpy(dcmd+1,data,16); + dcmd[0] = cmd; + memcpy(dcmd+1,data,16); AppendCrc14443a(dcmd, 17); ReaderTransmit(dcmd, sizeof(dcmd), timing); len = ReaderReceive(answer, answer_parity); if(!len) { - if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Authentication failed. Card timeout."); - len = ReaderReceive(answer,answer_parity); - } - if(len==1) { + if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Authentication failed. Card timeout."); + len = ReaderReceive(answer,answer_parity); + } + if(len==1) { if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("NAK - Authentication failed."); return 1; - } + } return len; } int mifare_sendcmd_short_mfuev1auth(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t *data, uint8_t *answer, uint8_t *answer_parity, uint32_t *timing) { - uint8_t dcmd[7]; + uint8_t dcmd[7]; int len; - dcmd[0] = cmd; - memcpy(dcmd+1,data,4); + dcmd[0] = cmd; + memcpy(dcmd+1,data,4); AppendCrc14443a(dcmd, 5); - + ReaderTransmit(dcmd, sizeof(dcmd), timing); len = ReaderReceive(answer, answer_parity); if(!len) { - if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Authentication failed. Card timeout."); - len = ReaderReceive(answer,answer_parity); - } - if(len==1) { + if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Authentication failed. Card timeout."); + len = ReaderReceive(answer,answer_parity); + } + if(len==1) { if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("NAK - Authentication failed."); return 1; - } + } return len; } +*/ +// send 2 byte commands int mifare_sendcmd_shortex(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t *answer, uint8_t *answer_parity, uint32_t *timing) { uint8_t dcmd[4], ecmd[4]; @@ -319,7 +320,8 @@ int mifare_ul_ev1_auth(uint8_t *keybytes, uint8_t *pack){ memcpy(key, keybytes, 4); Dbprintf("EV1 Auth : %02x%02x%02x%02x", key[0], key[1], key[2], key[3]); - len = mifare_sendcmd_short_mfuev1auth(NULL, 0, 0x1B, key, resp, respPar, NULL); + len = mifare_sendcmd(0x1B, key, sizeof(key), resp, respPar, NULL); + //len = mifare_sendcmd_short_mfuev1auth(NULL, 0, 0x1B, key, resp, respPar, NULL); if (len != 4) { if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd Error: %02x %u", resp[0], len); return 0; @@ -380,8 +382,8 @@ int mifare_ultra_auth(uint8_t *keybytes){ // encrypt out, in, length, key, iv tdes_2key_enc(rnd_ab, rnd_ab, sizeof(rnd_ab), key, enc_random_b); - - len = mifare_sendcmd_short_mfucauth(NULL, 1, 0xAF, rnd_ab, resp, respPar, NULL); + //len = mifare_sendcmd_short_mfucauth(NULL, 1, 0xAF, rnd_ab, resp, respPar, NULL); + len = mifare_sendcmd(0xAF, rnd_ab, sizeof(rnd_ab), resp, respPar, NULL); if (len != 11) { if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd Error: %02x", resp[0]); return 0; @@ -425,6 +427,7 @@ int mifare_ultra_readblock(uint8_t blockNo, uint8_t *blockData) uint8_t receivedAnswer[MAX_FRAME_SIZE]; uint8_t receivedAnswerPar[MAX_PARITY_SIZE]; + len = mifare_sendcmd_short(NULL, 1, 0x30, blockNo, receivedAnswer, receivedAnswerPar, NULL); if (len == 1) { if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd Error: %02x", receivedAnswer[0]); @@ -493,7 +496,8 @@ int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t bl return 0; } -int mifare_ultra_writeblock(uint8_t blockNo, uint8_t *blockData) +/* // command not needed, but left for future testing +int mifare_ultra_writeblock_compat(uint8_t blockNo, uint8_t *blockData) { uint16_t len; uint8_t par[3] = {0}; // enough for 18 parity bits @@ -501,7 +505,6 @@ int mifare_ultra_writeblock(uint8_t blockNo, uint8_t *blockData) uint8_t receivedAnswer[MAX_FRAME_SIZE]; uint8_t receivedAnswerPar[MAX_PARITY_SIZE]; - // command MIFARE_CLASSIC_WRITEBLOCK len = mifare_sendcmd_short(NULL, true, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL); if ((len != 1) || (receivedAnswer[0] != 0x0A)) { // 0x0a - ACK @@ -524,20 +527,21 @@ int mifare_ultra_writeblock(uint8_t blockNo, uint8_t *blockData) } return 0; } +*/ -int mifare_ultra_special_writeblock(uint8_t blockNo, uint8_t *blockData) +int mifare_ultra_writeblock(uint8_t blockNo, uint8_t *blockData) { uint16_t len; - uint8_t d_block[8] = {0x00}; + uint8_t d_block[5] = {0x00}; uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE]; uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE]; // command MIFARE_CLASSIC_WRITEBLOCK d_block[0]= blockNo; memcpy(d_block+1,blockData,4); - AppendCrc14443a(d_block, 6); + //AppendCrc14443a(d_block, 6); - len = mifare_sendcmd_short_special(NULL, 1, 0xA2, d_block, receivedAnswer, receivedAnswerPar, NULL); + len = mifare_sendcmd(0xA2, d_block, sizeof(d_block), receivedAnswer, receivedAnswerPar, NULL); if (receivedAnswer[0] != 0x0A) { // 0x0a - ACK if (MF_DBGLEVEL >= MF_DBG_ERROR) diff --git a/armsrc/mifareutil.h b/armsrc/mifareutil.h index d4fcd8189..ed955cc6f 100644 --- a/armsrc/mifareutil.h +++ b/armsrc/mifareutil.h @@ -54,22 +54,24 @@ extern int MF_DBGLEVEL; //functions int mifare_sendcmd_short(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing); -int mifare_sendcmd_short_special(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t *data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing); - -int mifare_sendcmd_short_mfucauth(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t *data, uint8_t *answer, uint8_t *answer_parity, uint32_t *timing); -int mifare_sendcmd_short_mfuev1auth(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t *data, uint8_t *answer, uint8_t *answer_parity, uint32_t *timing); +int mifare_sendcmd(uint8_t cmd, uint8_t *data, uint8_t data_size, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing); +//int mifare_sendcmd_short_mfucauth(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t *data, uint8_t *answer, uint8_t *answer_parity, uint32_t *timing); +//int mifare_sendcmd_short_mfuev1auth(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t *data, uint8_t *answer, uint8_t *answer_parity, uint32_t *timing); int mifare_sendcmd_shortex(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing); +// mifare classic int mifare_classic_auth(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested); int mifare_classic_authex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested, uint32_t * ntptr, uint32_t *timing); int mifare_classic_readblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData); +int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid); +int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData); + +// Ultralight/NTAG... int mifare_ul_ev1_auth(uint8_t *key, uint8_t *pack); int mifare_ultra_auth(uint8_t *key); int mifare_ultra_readblock(uint8_t blockNo, uint8_t *blockData); -int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData); +//int mifare_ultra_writeblock_compat(uint8_t blockNo, uint8_t *blockData); int mifare_ultra_writeblock(uint8_t blockNo, uint8_t *blockData); -int mifare_ultra_special_writeblock(uint8_t blockNo, uint8_t *blockData); -int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid); int mifare_ultra_halt(); // desfire diff --git a/client/util.c b/client/util.c index cea9f7d73..1fc684b69 100644 --- a/client/util.c +++ b/client/util.c @@ -108,12 +108,12 @@ void print_hex(const uint8_t * data, const size_t len) printf("\n"); } -char * sprint_hex(const uint8_t * data, const size_t len) { +char *sprint_hex(const uint8_t *data, const size_t len) { int maxLen = ( len > 1024/3) ? 1024/3 : len; static char buf[1024]; memset(buf, 0x00, 1024); - char * tmp = buf; + char *tmp = buf; size_t i; for (i=0; i < maxLen; ++i, tmp += 3) @@ -444,3 +444,12 @@ void wiegand_add_parity(char *target, char *source, char length) target += length; *(target)= GetParity(source + length / 2, ODD, length / 2); } + +void xor(unsigned char *dst, unsigned char *src, size_t len) { + for( ; len > 0; len--,dst++,src++) + *dst ^= *src; +} + +int32_t le24toh (uint8_t data[3]) { + return (data[2] << 16) | (data[1] << 8) | data[0]; +} diff --git a/client/util.h b/client/util.h index f58f64cb4..2d2beaf42 100644 --- a/client/util.h +++ b/client/util.h @@ -63,3 +63,5 @@ void binarraytobinstring(char *target, char *source, int length); uint8_t GetParity( char *string, uint8_t type, int length); void wiegand_add_parity(char *target, char *source, char length); +void xor(unsigned char *dst, unsigned char *src, size_t len); +int32_t le24toh(uint8_t data[3]); From e35031d2b73bb4c834d6675a5df870a2de14690c Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Wed, 27 May 2015 17:21:42 -0400 Subject: [PATCH 08/26] MFU code cleanup - final ? fixed bug in debug print in MF 1k sim. --- armsrc/iso14443a.c | 4 ++-- armsrc/mifarecmd.c | 4 ++-- armsrc/mifareutil.c | 55 +++------------------------------------------ armsrc/mifareutil.h | 5 +---- 4 files changed, 8 insertions(+), 60 deletions(-) diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 64bbcbf50..cf64da2fb 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -2510,13 +2510,13 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t * || receivedCmd[0] == 0xB0) { // transfer if (receivedCmd[1] >= 16 * 4) { EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA)); - if (MF_DBGLEVEL >= 2) Dbprintf("Reader tried to operate (0x%02) on out of range block: %d (0x%02x), nacking",receivedCmd[0],receivedCmd[1],receivedCmd[1]); + if (MF_DBGLEVEL >= 2) Dbprintf("Reader tried to operate (0x%02x) on out of range block: %d (0x%02x), nacking",receivedCmd[0],receivedCmd[1],receivedCmd[1]); break; } if (receivedCmd[1] / 4 != cardAUTHSC) { EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA)); - if (MF_DBGLEVEL >= 2) Dbprintf("Reader tried to operate (0x%02) on block (0x%02x) not authenticated for (0x%02x), nacking",receivedCmd[0],receivedCmd[1],cardAUTHSC); + if (MF_DBGLEVEL >= 2) Dbprintf("Reader tried to operate (0x%02x) on block (0x%02x) not authenticated for (0x%02x), nacking",receivedCmd[0],receivedCmd[1],cardAUTHSC); break; } } diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index bf6c404af..939c90028 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -717,7 +717,7 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat LED_B_OFF(); } -// ------------------------------------------------------------------------------------------------- + // ------------------------------------------------------------------------------------------------- LED_C_ON(); @@ -746,7 +746,7 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat // nested authentication auth2_time = auth1_time + delta_time; - len = mifare_sendcmd_shortex(pcs, AUTH_NESTED, 0x60 + (targetKeyType & 0x01), targetBlockNo, receivedAnswer, par, &auth2_time); + len = mifare_sendcmd_short(pcs, AUTH_NESTED, 0x60 + (targetKeyType & 0x01), targetBlockNo, receivedAnswer, par, &auth2_time); if (len != 4) { if (MF_DBGLEVEL >= 1) Dbprintf("Nested: Auth2 error len=%d", len); continue; diff --git a/armsrc/mifareutil.c b/armsrc/mifareutil.c index c706e78a4..8ef364c25 100644 --- a/armsrc/mifareutil.c +++ b/armsrc/mifareutil.c @@ -65,12 +65,6 @@ uint8_t mf_crypto1_encrypt4bit(struct Crypto1State *pcs, uint8_t data) { return bt; } -// send 2 byte commands -int mifare_sendcmd_short(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing) -{ - return mifare_sendcmd_shortex(pcs, crypted, cmd, data, answer, answer_parity, timing); -} - // send X byte basic commands int mifare_sendcmd(uint8_t cmd, uint8_t* data, uint8_t data_size, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing) { @@ -88,52 +82,8 @@ int mifare_sendcmd(uint8_t cmd, uint8_t* data, uint8_t data_size, uint8_t* answe return len; } -/* -int mifare_sendcmd_short_mfucauth(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t *data, uint8_t *answer, uint8_t *answer_parity, uint32_t *timing) -{ - uint8_t dcmd[19]; - int len; - dcmd[0] = cmd; - memcpy(dcmd+1,data,16); - AppendCrc14443a(dcmd, 17); - - ReaderTransmit(dcmd, sizeof(dcmd), timing); - len = ReaderReceive(answer, answer_parity); - if(!len) { - if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Authentication failed. Card timeout."); - len = ReaderReceive(answer,answer_parity); - } - if(len==1) { - if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("NAK - Authentication failed."); - return 1; - } - return len; -} - -int mifare_sendcmd_short_mfuev1auth(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t *data, uint8_t *answer, uint8_t *answer_parity, uint32_t *timing) -{ - uint8_t dcmd[7]; - int len; - dcmd[0] = cmd; - memcpy(dcmd+1,data,4); - AppendCrc14443a(dcmd, 5); - - ReaderTransmit(dcmd, sizeof(dcmd), timing); - len = ReaderReceive(answer, answer_parity); - if(!len) { - if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Authentication failed. Card timeout."); - len = ReaderReceive(answer,answer_parity); - } - if(len==1) { - if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("NAK - Authentication failed."); - return 1; - } - return len; -} -*/ - // send 2 byte commands -int mifare_sendcmd_shortex(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t *answer, uint8_t *answer_parity, uint32_t *timing) +int mifare_sendcmd_short(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t *answer, uint8_t *answer_parity, uint32_t *timing) { uint8_t dcmd[4], ecmd[4]; uint16_t pos, res; @@ -319,7 +269,8 @@ int mifare_ul_ev1_auth(uint8_t *keybytes, uint8_t *pack){ uint8_t key[4] = {0x00}; memcpy(key, keybytes, 4); - Dbprintf("EV1 Auth : %02x%02x%02x%02x", key[0], key[1], key[2], key[3]); + if (MF_DBGLEVEL >= MF_DBG_EXTENDED) + Dbprintf("EV1 Auth : %02x%02x%02x%02x", key[0], key[1], key[2], key[3]); len = mifare_sendcmd(0x1B, key, sizeof(key), resp, respPar, NULL); //len = mifare_sendcmd_short_mfuev1auth(NULL, 0, 0x1B, key, resp, respPar, NULL); if (len != 4) { diff --git a/armsrc/mifareutil.h b/armsrc/mifareutil.h index ed955cc6f..85a34ef62 100644 --- a/armsrc/mifareutil.h +++ b/armsrc/mifareutil.h @@ -53,11 +53,8 @@ extern int MF_DBGLEVEL; #define cardSTATE_TO_IDLE() cardSTATE = MFEMUL_IDLE; LED_B_OFF(); LED_C_OFF(); //functions -int mifare_sendcmd_short(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing); int mifare_sendcmd(uint8_t cmd, uint8_t *data, uint8_t data_size, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing); -//int mifare_sendcmd_short_mfucauth(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t *data, uint8_t *answer, uint8_t *answer_parity, uint32_t *timing); -//int mifare_sendcmd_short_mfuev1auth(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t *data, uint8_t *answer, uint8_t *answer_parity, uint32_t *timing); -int mifare_sendcmd_shortex(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing); +int mifare_sendcmd_short(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing); // mifare classic int mifare_classic_auth(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested); From 979bba376dc9d6430b00b853a99b9dfadca4f38c Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Thu, 28 May 2015 13:23:31 -0400 Subject: [PATCH 09/26] add offset option to data printdemodbuffer easily see demod buffer's hex values at different bit offsets by using: data printdemodbuffer x o --- client/cmddata.c | 66 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 51 insertions(+), 15 deletions(-) diff --git a/client/cmddata.c b/client/cmddata.c index b9069bc19..e23b6d597 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -55,6 +55,15 @@ int CmdSetDebugMode(const char *Cmd) return 1; } +int usage_data_printdemodbuf(){ + PrintAndLog("Usage: data printdemodbuffer x o "); + PrintAndLog("Options: "); + PrintAndLog(" h This help"); + PrintAndLog(" x output in hex (omit for binary output)"); + PrintAndLog(" o enter offset in # of bits"); + return 0; +} + //by marshmellow void printDemodBuff(void) { @@ -73,23 +82,50 @@ void printDemodBuff(void) int CmdPrintDemodBuff(const char *Cmd) { - char hex; - char printBuff[512]={0x00}; - uint8_t numBits = DemodBufferLen & 0xFFFC; - sscanf(Cmd, "%c", &hex); - if (hex == 'h'){ - PrintAndLog("Usage: data printdemodbuffer [x]"); - PrintAndLog("Options: "); - PrintAndLog(" h This help"); - PrintAndLog(" x output in hex (omit for binary output)"); - return 0; + char hex[512]={0x00}; + bool hexMode = false; + bool errors = false; + uint8_t offset = 0; + char cmdp = 0; + while(param_getchar(Cmd, cmdp) != 0x00) + { + switch(param_getchar(Cmd, cmdp)) + { + case 'h': + case 'H': + return usage_data_printdemodbuf(); + case 'x': + case 'X': + hexMode = true; + cmdp++; + break; + case 'o': + case 'O': + offset = param_get8(Cmd, cmdp+1); + if (!offset) errors = true; + cmdp += 2; + break; + default: + PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = true; + break; + } + if(errors) break; } - if (hex == 'x'){ - numBits = binarraytohex(printBuff, (char *)DemodBuffer, numBits); + //Validations + if(errors) return usage_data_printdemodbuf(); + + int numBits = (DemodBufferLen-offset) & 0x7FC; //make sure we don't exceed our string + + if (hexMode){ + char *buf = DemodBuffer + offset; + numBits = binarraytohex(hex, buf, numBits); if (numBits==0) return 0; - PrintAndLog("DemodBuffer: %s",printBuff); + PrintAndLog("DemodBuffer: %s",hex); } else { - printDemodBuff(); + //setDemodBuf(DemodBuffer, DemodBufferLen-offset, offset); + char *bin = sprint_bin_break(DemodBuffer+offset,numBits,16); + PrintAndLog("DemodBuffer:\n%s",bin); } return 1; } @@ -2182,7 +2218,7 @@ static command_t CommandTable[] = {"manrawdecode", Cmdmandecoderaw, 1, "[invert] [maxErr] -- Manchester decode binary stream in DemodBuffer"}, {"norm", CmdNorm, 1, "Normalize max/min to +/-128"}, {"plot", CmdPlot, 1, "Show graph window (hit 'h' in window for keystroke help)"}, - {"printdemodbuffer",CmdPrintDemodBuff, 1, "[x] -- print the data in the DemodBuffer - 'x' for hex output"}, + {"printdemodbuffer",CmdPrintDemodBuff, 1, "[x] [o] -- print the data in the DemodBuffer - 'x' for hex output"}, {"pskindalademod", CmdIndalaDecode, 1, "[clock] [invert<0|1>] -- Demodulate an indala tag (PSK1) from GraphBuffer (args optional)"}, {"psknexwatchdemod",CmdPSKNexWatch, 1, "Demodulate a NexWatch tag (nexkey, quadrakey) (PSK1) from GraphBuffer"}, {"rawdemod", CmdRawDemod, 1, "[modulation] ... -see help (h option) -- Demodulate the data in the GraphBuffer and output binary"}, From 5b37e87a24f01af65c2d414a9393e8846a4beafe Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Thu, 28 May 2015 22:52:41 -0400 Subject: [PATCH 10/26] fix help typo --- client/cmdlft55xx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index d4b72b327..1814d4ab8 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -66,8 +66,8 @@ int usage_t55xx_write(){ PrintAndLog(" [password], OPTIONAL password 4bytes (8 hex characters)"); PrintAndLog(""); PrintAndLog("Examples:"); - PrintAndLog(" lf t55xx wd 3 11223344 - write 11223344 to block 3"); - PrintAndLog(" lf t55xx wd 3 11223344 feedbeef - write 11223344 to block 3 password feedbeef"); + PrintAndLog(" lf t55xx wr 3 11223344 - write 11223344 to block 3"); + PrintAndLog(" lf t55xx wr 3 11223344 feedbeef - write 11223344 to block 3 password feedbeef"); PrintAndLog(""); return 0; } From 185e038c7de4468e098dadf6303f72efccecaa10 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Thu, 28 May 2015 23:14:06 -0400 Subject: [PATCH 11/26] fixed further typo in lf t5 wr help also fixed offset option char to uint8_t warning in the new offset option in data printdemodbuffer --- client/cmddata.c | 2 +- client/cmdlft55xx.c | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/client/cmddata.c b/client/cmddata.c index e23b6d597..765523518 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -118,7 +118,7 @@ int CmdPrintDemodBuff(const char *Cmd) int numBits = (DemodBufferLen-offset) & 0x7FC; //make sure we don't exceed our string if (hexMode){ - char *buf = DemodBuffer + offset; + char *buf = (char *) (DemodBuffer + offset); numBits = binarraytohex(hex, buf, numBits); if (numBits==0) return 0; PrintAndLog("DemodBuffer: %s",hex); diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 1814d4ab8..b357e71c3 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -50,23 +50,23 @@ int usage_t55xx_config(){ } int usage_t55xx_read(){ PrintAndLog("Usage: lf t55xx read "); - PrintAndLog(" , block number to read. Between 0-7"); - PrintAndLog(" , OPTIONAL password (8 hex characters)"); - PrintAndLog(""); + PrintAndLog(" , block number to read. Between 0-7"); + PrintAndLog(" , OPTIONAL password (8 hex characters)"); + PrintAndLog(""); PrintAndLog("Examples:"); - PrintAndLog(" lf t55xx read 0 - read data from block 0"); + PrintAndLog(" lf t55xx read 0 - read data from block 0"); PrintAndLog(" lf t55xx read 0 feedbeef - read data from block 0 password feedbeef"); PrintAndLog(""); return 0; } int usage_t55xx_write(){ PrintAndLog("Usage: lf t55xx wr [password]"); - PrintAndLog(" , block number to read. Between 0-7"); + PrintAndLog(" , block number to write. Between 0-7"); PrintAndLog(" , 4 bytes of data to write (8 hex characters)"); - PrintAndLog(" [password], OPTIONAL password 4bytes (8 hex characters)"); - PrintAndLog(""); + PrintAndLog(" [password], OPTIONAL password 4bytes (8 hex characters)"); + PrintAndLog(""); PrintAndLog("Examples:"); - PrintAndLog(" lf t55xx wr 3 11223344 - write 11223344 to block 3"); + PrintAndLog(" lf t55xx wr 3 11223344 - write 11223344 to block 3"); PrintAndLog(" lf t55xx wr 3 11223344 feedbeef - write 11223344 to block 3 password feedbeef"); PrintAndLog(""); return 0; From 1c4c0b068131edc4bc382b767e26dae494e0d4c3 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Sat, 30 May 2015 21:51:15 -0400 Subject: [PATCH 12/26] add @Iceman1001 s sha1 scripting changes. --- client/Makefile | 1 + client/lualibs/utils.lua | 28 +- client/scripting.c | 78 ++++- client/util.c | 2 +- common/sha1.c | 665 +++++++++++++++++++++++++++++++++++++++ common/sha1.h | 213 +++++++++++++ 6 files changed, 981 insertions(+), 6 deletions(-) create mode 100644 common/sha1.c create mode 100644 common/sha1.h diff --git a/client/Makefile b/client/Makefile index 7954d1ea2..d7126da60 100644 --- a/client/Makefile +++ b/client/Makefile @@ -102,6 +102,7 @@ CMDSRCS = nonce2key/crapto1.c\ pm3_bitlib.c\ aes.c\ protocols.c\ + sha1.c\ COREOBJS = $(CORESRCS:%.c=$(OBJDIR)/%.o) diff --git a/client/lualibs/utils.lua b/client/lualibs/utils.lua index a968fde2a..592d0477d 100644 --- a/client/lualibs/utils.lua +++ b/client/lualibs/utils.lua @@ -99,6 +99,32 @@ local Utils = end return nil end, + + ------------ SHA1 hash + -- Takes a string and calculates a SHA1 hash + Sha1 = function(s) + if s == nil then return nil end + if #s == 0 then return nil end + if type(s) == 'string' then + local utils = require('utils') + --local asc = utils.ConvertHexToAscii(s) + local hash = core.sha1(s) + return hash + end + return nil + end, + -- Takes a hex string and calculates a SHA1 hash + Sha1Hex = function(s) + if s == nil then return nil end + if #s == 0 then return nil end + if type(s) == 'string' then + local utils = require('utils') + local asc = utils.ConvertHexToAscii(s) + local hash = core.sha1(asc) + return hash + end + return nil + end, -- input parameter is a string @@ -288,4 +314,4 @@ local Utils = -- end } -return Utils \ No newline at end of file +return Utils diff --git a/client/scripting.c b/client/scripting.c index 152fd9d44..6b26ec59c 100644 --- a/client/scripting.c +++ b/client/scripting.c @@ -20,6 +20,7 @@ #include "../common/iso15693tools.h" #include "../common/crc16.h" #include "../common/crc64.h" +#include "../common/sha1.h" #include "aes.h" /** * The following params expected: @@ -231,7 +232,7 @@ static int l_iso15693_crc(lua_State *L) Simple AES 128 cbc hook up to OpenSSL. params: key, input */ -static int l_aes128decrypt(lua_State *L) +static int l_aes128decrypt_cbc(lua_State *L) { //Check number of arguments int i; @@ -260,7 +261,36 @@ static int l_aes128decrypt(lua_State *L) lua_pushlstring(L,(const char *)&outdata, sizeof(outdata)); return 1;// return 1 to signal one return value } -static int l_aes128encrypt(lua_State *L) +static int l_aes128decrypt_ecb(lua_State *L) +{ + //Check number of arguments + int i; + size_t size; + const char *p_key = luaL_checklstring(L, 1, &size); + if(size != 32) return returnToLuaWithError(L,"Wrong size of key, got %d bytes, expected 32", (int) size); + + const char *p_encTxt = luaL_checklstring(L, 2, &size); + + unsigned char indata[16] = {0x00}; + unsigned char outdata[16] = {0x00}; + unsigned char aes_key[16] = {0x00}; + + // convert key to bytearray and convert input to bytearray + for (i = 0; i < 32; i += 2) { + sscanf(&p_encTxt[i], "%02x", (unsigned int *)&indata[i / 2]); + sscanf(&p_key[i], "%02x", (unsigned int *)&aes_key[i / 2]); + } + aes_context ctx; + aes_init(&ctx); + aes_setkey_dec(&ctx, aes_key, 128); + aes_crypt_ecb(&ctx, AES_DECRYPT, indata, outdata ); + + //Push decrypted array as a string + lua_pushlstring(L,(const char *)&outdata, sizeof(outdata)); + return 1;// return 1 to signal one return value +} + +static int l_aes128encrypt_cbc(lua_State *L) { //Check number of arguments int i; @@ -289,6 +319,33 @@ static int l_aes128encrypt(lua_State *L) return 1;// return 1 to signal one return value } +static int l_aes128encrypt_ecb(lua_State *L) +{ + //Check number of arguments + int i; + size_t size; + const char *p_key = luaL_checklstring(L, 1, &size); + if(size != 32) return returnToLuaWithError(L,"Wrong size of key, got %d bytes, expected 32", (int) size); + + const char *p_txt = luaL_checklstring(L, 2, &size); + + unsigned char indata[16] = {0x00}; + unsigned char outdata[16] = {0x00}; + unsigned char aes_key[16] = {0x00}; + + for (i = 0; i < 32; i += 2) { + sscanf(&p_txt[i], "%02x", (unsigned int *)&indata[i / 2]); + sscanf(&p_key[i], "%02x", (unsigned int *)&aes_key[i / 2]); + } + aes_context ctx; + aes_init(&ctx); + aes_setkey_enc(&ctx, aes_key, 128); + aes_crypt_ecb(&ctx, AES_ENCRYPT, indata, outdata ); + //Push encrypted array as a string + lua_pushlstring(L,(const char *)&outdata, sizeof(outdata)); + return 1;// return 1 to signal one return value +} + static int l_crc16(lua_State *L) { size_t size; @@ -321,6 +378,16 @@ static int l_crc64(lua_State *L) return 1; } +static int l_sha1(lua_State *L) +{ + size_t size; + const char *p_str = luaL_checklstring(L, 1, &size); + unsigned char outdata[20] = {0x00}; + sha1( (uint8_t*) p_str, size, outdata); + lua_pushlstring(L,(const char *)&outdata, sizeof(outdata)); + return 1; +} + /** * @brief Sets the lua path to include "./lualibs/?.lua", in order for a script to be * able to do "require('foobar')" if foobar.lua is within lualibs folder. @@ -359,10 +426,13 @@ int set_pm3_libraries(lua_State *L) {"clearCommandBuffer", l_clearCommandBuffer}, {"console", l_CmdConsole}, {"iso15693_crc", l_iso15693_crc}, - {"aes128_decrypt", l_aes128decrypt}, - {"aes128_encrypt", l_aes128encrypt}, + {"aes128_decrypt", l_aes128decrypt_cbc}, + {"aes128_decrypt_ecb", l_aes128decrypt_ecb}, + {"aes128_encrypt", l_aes128encrypt_cbc}, + {"aes128_encrypt_ecb", l_aes128encrypt_ecb}, {"crc16", l_crc16}, {"crc64", l_crc64}, + {"sha1", l_sha1}, {NULL, NULL} }; diff --git a/client/util.c b/client/util.c index 1fc684b69..9f2142c6a 100644 --- a/client/util.c +++ b/client/util.c @@ -394,7 +394,7 @@ int hextobinstring(char *target, char *source) // convert binary array of 0x00/0x01 values to hex (safe to do in place as target will always be shorter than source) // return number of bits converted -int binarraytohex(char *target, char *source, int length) +int binarraytohex(char *target,char *source, int length) { unsigned char i, x; int j = length; diff --git a/common/sha1.c b/common/sha1.c new file mode 100644 index 000000000..d20c54a42 --- /dev/null +++ b/common/sha1.c @@ -0,0 +1,665 @@ +/* + * FIPS-180-1 compliant SHA-1 implementation + * + * Copyright (C) 2006-2014, ARM Limited, All Rights Reserved + * This file is part of mbed TLS (https://tls.mbed.org) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * The SHA-1 standard was published by NIST in 1993. + * + * http://www.itl.nist.gov/fipspubs/fip180-1.htm + */ + +#if !defined(POLARSSL_CONFIG_FILE) +//#include "polarssl/config.h" +#define POLARSSL_SHA1_C + +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_SHA1_C) + +#include "sha1.h" + +#include + +#if defined(POLARSSL_FS_IO) +#include +#endif + +#if defined(POLARSSL_SELF_TEST) +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#include +#define polarssl_printf printf +#endif /* POLARSSL_PLATFORM_C */ +#endif /* POLARSSL_SELF_TEST */ + +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +#if !defined(POLARSSL_SHA1_ALT) + +/* + * 32-bit integer manipulation macros (big endian) + */ +#ifndef GET_UINT32_BE +#define GET_UINT32_BE(n,b,i) \ +{ \ + (n) = ( (uint32_t) (b)[(i) ] << 24 ) \ + | ( (uint32_t) (b)[(i) + 1] << 16 ) \ + | ( (uint32_t) (b)[(i) + 2] << 8 ) \ + | ( (uint32_t) (b)[(i) + 3] ); \ +} +#endif + +#ifndef PUT_UINT32_BE +#define PUT_UINT32_BE(n,b,i) \ +{ \ + (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ + (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ + (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ + (b)[(i) + 3] = (unsigned char) ( (n) ); \ +} +#endif + +void sha1_init( sha1_context *ctx ) +{ + memset( ctx, 0, sizeof( sha1_context ) ); +} + +void sha1_free( sha1_context *ctx ) +{ + if( ctx == NULL ) + return; + + polarssl_zeroize( ctx, sizeof( sha1_context ) ); +} + +/* + * SHA-1 context setup + */ +void sha1_starts( sha1_context *ctx ) +{ + ctx->total[0] = 0; + ctx->total[1] = 0; + + ctx->state[0] = 0x67452301; + ctx->state[1] = 0xEFCDAB89; + ctx->state[2] = 0x98BADCFE; + ctx->state[3] = 0x10325476; + ctx->state[4] = 0xC3D2E1F0; +} + +void sha1_process( sha1_context *ctx, const unsigned char data[64] ) +{ + uint32_t temp, W[16], A, B, C, D, E; + + GET_UINT32_BE( W[ 0], data, 0 ); + GET_UINT32_BE( W[ 1], data, 4 ); + GET_UINT32_BE( W[ 2], data, 8 ); + GET_UINT32_BE( W[ 3], data, 12 ); + GET_UINT32_BE( W[ 4], data, 16 ); + GET_UINT32_BE( W[ 5], data, 20 ); + GET_UINT32_BE( W[ 6], data, 24 ); + GET_UINT32_BE( W[ 7], data, 28 ); + GET_UINT32_BE( W[ 8], data, 32 ); + GET_UINT32_BE( W[ 9], data, 36 ); + GET_UINT32_BE( W[10], data, 40 ); + GET_UINT32_BE( W[11], data, 44 ); + GET_UINT32_BE( W[12], data, 48 ); + GET_UINT32_BE( W[13], data, 52 ); + GET_UINT32_BE( W[14], data, 56 ); + GET_UINT32_BE( W[15], data, 60 ); + +#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) + +#define R(t) \ +( \ + temp = W[( t - 3 ) & 0x0F] ^ W[( t - 8 ) & 0x0F] ^ \ + W[( t - 14 ) & 0x0F] ^ W[ t & 0x0F], \ + ( W[t & 0x0F] = S(temp,1) ) \ +) + +#define P(a,b,c,d,e,x) \ +{ \ + e += S(a,5) + F(b,c,d) + K + x; b = S(b,30); \ +} + + A = ctx->state[0]; + B = ctx->state[1]; + C = ctx->state[2]; + D = ctx->state[3]; + E = ctx->state[4]; + +#define F(x,y,z) (z ^ (x & (y ^ z))) +#define K 0x5A827999 + + P( A, B, C, D, E, W[0] ); + P( E, A, B, C, D, W[1] ); + P( D, E, A, B, C, W[2] ); + P( C, D, E, A, B, W[3] ); + P( B, C, D, E, A, W[4] ); + P( A, B, C, D, E, W[5] ); + P( E, A, B, C, D, W[6] ); + P( D, E, A, B, C, W[7] ); + P( C, D, E, A, B, W[8] ); + P( B, C, D, E, A, W[9] ); + P( A, B, C, D, E, W[10] ); + P( E, A, B, C, D, W[11] ); + P( D, E, A, B, C, W[12] ); + P( C, D, E, A, B, W[13] ); + P( B, C, D, E, A, W[14] ); + P( A, B, C, D, E, W[15] ); + P( E, A, B, C, D, R(16) ); + P( D, E, A, B, C, R(17) ); + P( C, D, E, A, B, R(18) ); + P( B, C, D, E, A, R(19) ); + +#undef K +#undef F + +#define F(x,y,z) (x ^ y ^ z) +#define K 0x6ED9EBA1 + + P( A, B, C, D, E, R(20) ); + P( E, A, B, C, D, R(21) ); + P( D, E, A, B, C, R(22) ); + P( C, D, E, A, B, R(23) ); + P( B, C, D, E, A, R(24) ); + P( A, B, C, D, E, R(25) ); + P( E, A, B, C, D, R(26) ); + P( D, E, A, B, C, R(27) ); + P( C, D, E, A, B, R(28) ); + P( B, C, D, E, A, R(29) ); + P( A, B, C, D, E, R(30) ); + P( E, A, B, C, D, R(31) ); + P( D, E, A, B, C, R(32) ); + P( C, D, E, A, B, R(33) ); + P( B, C, D, E, A, R(34) ); + P( A, B, C, D, E, R(35) ); + P( E, A, B, C, D, R(36) ); + P( D, E, A, B, C, R(37) ); + P( C, D, E, A, B, R(38) ); + P( B, C, D, E, A, R(39) ); + +#undef K +#undef F + +#define F(x,y,z) ((x & y) | (z & (x | y))) +#define K 0x8F1BBCDC + + P( A, B, C, D, E, R(40) ); + P( E, A, B, C, D, R(41) ); + P( D, E, A, B, C, R(42) ); + P( C, D, E, A, B, R(43) ); + P( B, C, D, E, A, R(44) ); + P( A, B, C, D, E, R(45) ); + P( E, A, B, C, D, R(46) ); + P( D, E, A, B, C, R(47) ); + P( C, D, E, A, B, R(48) ); + P( B, C, D, E, A, R(49) ); + P( A, B, C, D, E, R(50) ); + P( E, A, B, C, D, R(51) ); + P( D, E, A, B, C, R(52) ); + P( C, D, E, A, B, R(53) ); + P( B, C, D, E, A, R(54) ); + P( A, B, C, D, E, R(55) ); + P( E, A, B, C, D, R(56) ); + P( D, E, A, B, C, R(57) ); + P( C, D, E, A, B, R(58) ); + P( B, C, D, E, A, R(59) ); + +#undef K +#undef F + +#define F(x,y,z) (x ^ y ^ z) +#define K 0xCA62C1D6 + + P( A, B, C, D, E, R(60) ); + P( E, A, B, C, D, R(61) ); + P( D, E, A, B, C, R(62) ); + P( C, D, E, A, B, R(63) ); + P( B, C, D, E, A, R(64) ); + P( A, B, C, D, E, R(65) ); + P( E, A, B, C, D, R(66) ); + P( D, E, A, B, C, R(67) ); + P( C, D, E, A, B, R(68) ); + P( B, C, D, E, A, R(69) ); + P( A, B, C, D, E, R(70) ); + P( E, A, B, C, D, R(71) ); + P( D, E, A, B, C, R(72) ); + P( C, D, E, A, B, R(73) ); + P( B, C, D, E, A, R(74) ); + P( A, B, C, D, E, R(75) ); + P( E, A, B, C, D, R(76) ); + P( D, E, A, B, C, R(77) ); + P( C, D, E, A, B, R(78) ); + P( B, C, D, E, A, R(79) ); + +#undef K +#undef F + + ctx->state[0] += A; + ctx->state[1] += B; + ctx->state[2] += C; + ctx->state[3] += D; + ctx->state[4] += E; +} + +/* + * SHA-1 process buffer + */ +void sha1_update( sha1_context *ctx, const unsigned char *input, size_t ilen ) +{ + size_t fill; + uint32_t left; + + if( ilen == 0 ) + return; + + left = ctx->total[0] & 0x3F; + fill = 64 - left; + + ctx->total[0] += (uint32_t) ilen; + ctx->total[0] &= 0xFFFFFFFF; + + if( ctx->total[0] < (uint32_t) ilen ) + ctx->total[1]++; + + if( left && ilen >= fill ) + { + memcpy( (void *) (ctx->buffer + left), input, fill ); + sha1_process( ctx, ctx->buffer ); + input += fill; + ilen -= fill; + left = 0; + } + + while( ilen >= 64 ) + { + sha1_process( ctx, input ); + input += 64; + ilen -= 64; + } + + if( ilen > 0 ) + memcpy( (void *) (ctx->buffer + left), input, ilen ); +} + +static const unsigned char sha1_padding[64] = +{ + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* + * SHA-1 final digest + */ +void sha1_finish( sha1_context *ctx, unsigned char output[20] ) +{ + uint32_t last, padn; + uint32_t high, low; + unsigned char msglen[8]; + + high = ( ctx->total[0] >> 29 ) + | ( ctx->total[1] << 3 ); + low = ( ctx->total[0] << 3 ); + + PUT_UINT32_BE( high, msglen, 0 ); + PUT_UINT32_BE( low, msglen, 4 ); + + last = ctx->total[0] & 0x3F; + padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); + + sha1_update( ctx, sha1_padding, padn ); + sha1_update( ctx, msglen, 8 ); + + PUT_UINT32_BE( ctx->state[0], output, 0 ); + PUT_UINT32_BE( ctx->state[1], output, 4 ); + PUT_UINT32_BE( ctx->state[2], output, 8 ); + PUT_UINT32_BE( ctx->state[3], output, 12 ); + PUT_UINT32_BE( ctx->state[4], output, 16 ); +} + +#endif /* !POLARSSL_SHA1_ALT */ + +/* + * output = SHA-1( input buffer ) + */ +void sha1( const unsigned char *input, size_t ilen, unsigned char output[20] ) +{ + sha1_context ctx; + + sha1_init( &ctx ); + sha1_starts( &ctx ); + sha1_update( &ctx, input, ilen ); + sha1_finish( &ctx, output ); + sha1_free( &ctx ); +} + +#if defined(POLARSSL_FS_IO) +/* + * output = SHA-1( file contents ) + */ +int sha1_file( const char *path, unsigned char output[20] ) +{ + FILE *f; + size_t n; + sha1_context ctx; + unsigned char buf[1024]; + + if( ( f = fopen( path, "rb" ) ) == NULL ) + return( POLARSSL_ERR_SHA1_FILE_IO_ERROR ); + + sha1_init( &ctx ); + sha1_starts( &ctx ); + + while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) + sha1_update( &ctx, buf, n ); + + sha1_finish( &ctx, output ); + sha1_free( &ctx ); + + if( ferror( f ) != 0 ) + { + fclose( f ); + return( POLARSSL_ERR_SHA1_FILE_IO_ERROR ); + } + + fclose( f ); + return( 0 ); +} +#endif /* POLARSSL_FS_IO */ + +/* + * SHA-1 HMAC context setup + */ +void sha1_hmac_starts( sha1_context *ctx, const unsigned char *key, + size_t keylen ) +{ + size_t i; + unsigned char sum[20]; + + if( keylen > 64 ) + { + sha1( key, keylen, sum ); + keylen = 20; + key = sum; + } + + memset( ctx->ipad, 0x36, 64 ); + memset( ctx->opad, 0x5C, 64 ); + + for( i = 0; i < keylen; i++ ) + { + ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] ); + ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] ); + } + + sha1_starts( ctx ); + sha1_update( ctx, ctx->ipad, 64 ); + + polarssl_zeroize( sum, sizeof( sum ) ); +} + +/* + * SHA-1 HMAC process buffer + */ +void sha1_hmac_update( sha1_context *ctx, const unsigned char *input, + size_t ilen ) +{ + sha1_update( ctx, input, ilen ); +} + +/* + * SHA-1 HMAC final digest + */ +void sha1_hmac_finish( sha1_context *ctx, unsigned char output[20] ) +{ + unsigned char tmpbuf[20]; + + sha1_finish( ctx, tmpbuf ); + sha1_starts( ctx ); + sha1_update( ctx, ctx->opad, 64 ); + sha1_update( ctx, tmpbuf, 20 ); + sha1_finish( ctx, output ); + + polarssl_zeroize( tmpbuf, sizeof( tmpbuf ) ); +} + +/* + * SHA1 HMAC context reset + */ +void sha1_hmac_reset( sha1_context *ctx ) +{ + sha1_starts( ctx ); + sha1_update( ctx, ctx->ipad, 64 ); +} + +/* + * output = HMAC-SHA-1( hmac key, input buffer ) + */ +void sha1_hmac( const unsigned char *key, size_t keylen, + const unsigned char *input, size_t ilen, + unsigned char output[20] ) +{ + sha1_context ctx; + + sha1_init( &ctx ); + sha1_hmac_starts( &ctx, key, keylen ); + sha1_hmac_update( &ctx, input, ilen ); + sha1_hmac_finish( &ctx, output ); + sha1_free( &ctx ); +} + +#if defined(POLARSSL_SELF_TEST) +/* + * FIPS-180-1 test vectors + */ +static const unsigned char sha1_test_buf[3][57] = +{ + { "abc" }, + { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" }, + { "" } +}; + +static const int sha1_test_buflen[3] = +{ + 3, 56, 1000 +}; + +static const unsigned char sha1_test_sum[3][20] = +{ + { 0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E, + 0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0, 0xD8, 0x9D }, + { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE, + 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1 }, + { 0x34, 0xAA, 0x97, 0x3C, 0xD4, 0xC4, 0xDA, 0xA4, 0xF6, 0x1E, + 0xEB, 0x2B, 0xDB, 0xAD, 0x27, 0x31, 0x65, 0x34, 0x01, 0x6F } +}; + +/* + * RFC 2202 test vectors + */ +static const unsigned char sha1_hmac_test_key[7][26] = +{ + { "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B" + "\x0B\x0B\x0B\x0B" }, + { "Jefe" }, + { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" + "\xAA\xAA\xAA\xAA" }, + { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10" + "\x11\x12\x13\x14\x15\x16\x17\x18\x19" }, + { "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C" + "\x0C\x0C\x0C\x0C" }, + { "" }, /* 0xAA 80 times */ + { "" } +}; + +static const int sha1_hmac_test_keylen[7] = +{ + 20, 4, 20, 25, 20, 80, 80 +}; + +static const unsigned char sha1_hmac_test_buf[7][74] = +{ + { "Hi There" }, + { "what do ya want for nothing?" }, + { "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" }, + { "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" }, + { "Test With Truncation" }, + { "Test Using Larger Than Block-Size Key - Hash Key First" }, + { "Test Using Larger Than Block-Size Key and Larger" + " Than One Block-Size Data" } +}; + +static const int sha1_hmac_test_buflen[7] = +{ + 8, 28, 50, 50, 20, 54, 73 +}; + +static const unsigned char sha1_hmac_test_sum[7][20] = +{ + { 0xB6, 0x17, 0x31, 0x86, 0x55, 0x05, 0x72, 0x64, 0xE2, 0x8B, + 0xC0, 0xB6, 0xFB, 0x37, 0x8C, 0x8E, 0xF1, 0x46, 0xBE, 0x00 }, + { 0xEF, 0xFC, 0xDF, 0x6A, 0xE5, 0xEB, 0x2F, 0xA2, 0xD2, 0x74, + 0x16, 0xD5, 0xF1, 0x84, 0xDF, 0x9C, 0x25, 0x9A, 0x7C, 0x79 }, + { 0x12, 0x5D, 0x73, 0x42, 0xB9, 0xAC, 0x11, 0xCD, 0x91, 0xA3, + 0x9A, 0xF4, 0x8A, 0xA1, 0x7B, 0x4F, 0x63, 0xF1, 0x75, 0xD3 }, + { 0x4C, 0x90, 0x07, 0xF4, 0x02, 0x62, 0x50, 0xC6, 0xBC, 0x84, + 0x14, 0xF9, 0xBF, 0x50, 0xC8, 0x6C, 0x2D, 0x72, 0x35, 0xDA }, + { 0x4C, 0x1A, 0x03, 0x42, 0x4B, 0x55, 0xE0, 0x7F, 0xE7, 0xF2, + 0x7B, 0xE1 }, + { 0xAA, 0x4A, 0xE5, 0xE1, 0x52, 0x72, 0xD0, 0x0E, 0x95, 0x70, + 0x56, 0x37, 0xCE, 0x8A, 0x3B, 0x55, 0xED, 0x40, 0x21, 0x12 }, + { 0xE8, 0xE9, 0x9D, 0x0F, 0x45, 0x23, 0x7D, 0x78, 0x6D, 0x6B, + 0xBA, 0xA7, 0x96, 0x5C, 0x78, 0x08, 0xBB, 0xFF, 0x1A, 0x91 } +}; + +/* + * Checkup routine + */ +int sha1_self_test( int verbose ) +{ + int i, j, buflen, ret = 0; + unsigned char buf[1024]; + unsigned char sha1sum[20]; + sha1_context ctx; + + sha1_init( &ctx ); + + /* + * SHA-1 + */ + for( i = 0; i < 3; i++ ) + { + if( verbose != 0 ) + polarssl_printf( " SHA-1 test #%d: ", i + 1 ); + + sha1_starts( &ctx ); + + if( i == 2 ) + { + memset( buf, 'a', buflen = 1000 ); + + for( j = 0; j < 1000; j++ ) + sha1_update( &ctx, buf, buflen ); + } + else + sha1_update( &ctx, sha1_test_buf[i], + sha1_test_buflen[i] ); + + sha1_finish( &ctx, sha1sum ); + + if( memcmp( sha1sum, sha1_test_sum[i], 20 ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto exit; + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + } + + if( verbose != 0 ) + polarssl_printf( "\n" ); + + for( i = 0; i < 7; i++ ) + { + if( verbose != 0 ) + polarssl_printf( " HMAC-SHA-1 test #%d: ", i + 1 ); + + if( i == 5 || i == 6 ) + { + memset( buf, 0xAA, buflen = 80 ); + sha1_hmac_starts( &ctx, buf, buflen ); + } + else + sha1_hmac_starts( &ctx, sha1_hmac_test_key[i], + sha1_hmac_test_keylen[i] ); + + sha1_hmac_update( &ctx, sha1_hmac_test_buf[i], + sha1_hmac_test_buflen[i] ); + + sha1_hmac_finish( &ctx, sha1sum ); + + buflen = ( i == 4 ) ? 12 : 20; + + if( memcmp( sha1sum, sha1_hmac_test_sum[i], buflen ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto exit; + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + } + + if( verbose != 0 ) + polarssl_printf( "\n" ); + +exit: + sha1_free( &ctx ); + + return( ret ); +} + +#endif /* POLARSSL_SELF_TEST */ + +#endif /* POLARSSL_SHA1_C */ + diff --git a/common/sha1.h b/common/sha1.h new file mode 100644 index 000000000..056bba7e4 --- /dev/null +++ b/common/sha1.h @@ -0,0 +1,213 @@ +/** + * \file sha1.h + * + * \brief SHA-1 cryptographic hash function + * + * Copyright (C) 2006-2014, ARM Limited, All Rights Reserved + * + * This file is part of mbed TLS (https://tls.mbed.org) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_SHA1_H +#define POLARSSL_SHA1_H + +#if !defined(POLARSSL_CONFIG_FILE) +//#include "config.h" +/** + * \def POLARSSL_SHA1_C + * + * Enable the SHA1 cryptographic hash algorithm. + * + * Module: library/sha1.c + * Caller: library/md.c + * library/ssl_cli.c + * library/ssl_srv.c + * library/ssl_tls.c + * library/x509write_crt.c + * + * This module is required for SSL/TLS and SHA1-signed certificates. + */ +#define POLARSSL_SHA1_C + +#else +#include POLARSSL_CONFIG_FILE +#endif + +#include + +#if defined(_MSC_VER) && !defined(EFIX64) && !defined(EFI32) +#include +typedef UINT32 uint32_t; +#else +#include +#endif + +#define POLARSSL_ERR_SHA1_FILE_IO_ERROR -0x0076 /**< Read/write error in file. */ + +#if !defined(POLARSSL_SHA1_ALT) +// Regular implementation +// + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief SHA-1 context structure + */ +typedef struct +{ + uint32_t total[2]; /*!< number of bytes processed */ + uint32_t state[5]; /*!< intermediate digest state */ + unsigned char buffer[64]; /*!< data block being processed */ + + unsigned char ipad[64]; /*!< HMAC: inner padding */ + unsigned char opad[64]; /*!< HMAC: outer padding */ +} +sha1_context; + +/** + * \brief Initialize SHA-1 context + * + * \param ctx SHA-1 context to be initialized + */ +void sha1_init( sha1_context *ctx ); + +/** + * \brief Clear SHA-1 context + * + * \param ctx SHA-1 context to be cleared + */ +void sha1_free( sha1_context *ctx ); + +/** + * \brief SHA-1 context setup + * + * \param ctx context to be initialized + */ +void sha1_starts( sha1_context *ctx ); + +/** + * \brief SHA-1 process buffer + * + * \param ctx SHA-1 context + * \param input buffer holding the data + * \param ilen length of the input data + */ +void sha1_update( sha1_context *ctx, const unsigned char *input, size_t ilen ); + +/** + * \brief SHA-1 final digest + * + * \param ctx SHA-1 context + * \param output SHA-1 checksum result + */ +void sha1_finish( sha1_context *ctx, unsigned char output[20] ); + +/* Internal use */ +void sha1_process( sha1_context *ctx, const unsigned char data[64] ); + +#ifdef __cplusplus +} +#endif + +#else /* POLARSSL_SHA1_ALT */ +#include "sha1_alt.h" +#endif /* POLARSSL_SHA1_ALT */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Output = SHA-1( input buffer ) + * + * \param input buffer holding the data + * \param ilen length of the input data + * \param output SHA-1 checksum result + */ +void sha1( const unsigned char *input, size_t ilen, unsigned char output[20] ); + +/** + * \brief Output = SHA-1( file contents ) + * + * \param path input file name + * \param output SHA-1 checksum result + * + * \return 0 if successful, or POLARSSL_ERR_SHA1_FILE_IO_ERROR + */ +int sha1_file( const char *path, unsigned char output[20] ); + +/** + * \brief SHA-1 HMAC context setup + * + * \param ctx HMAC context to be initialized + * \param key HMAC secret key + * \param keylen length of the HMAC key + */ +void sha1_hmac_starts( sha1_context *ctx, const unsigned char *key, + size_t keylen ); + +/** + * \brief SHA-1 HMAC process buffer + * + * \param ctx HMAC context + * \param input buffer holding the data + * \param ilen length of the input data + */ +void sha1_hmac_update( sha1_context *ctx, const unsigned char *input, + size_t ilen ); + +/** + * \brief SHA-1 HMAC final digest + * + * \param ctx HMAC context + * \param output SHA-1 HMAC checksum result + */ +void sha1_hmac_finish( sha1_context *ctx, unsigned char output[20] ); + +/** + * \brief SHA-1 HMAC context reset + * + * \param ctx HMAC context to be reset + */ +void sha1_hmac_reset( sha1_context *ctx ); + +/** + * \brief Output = HMAC-SHA-1( hmac key, input buffer ) + * + * \param key HMAC secret key + * \param keylen length of the HMAC key + * \param input buffer holding the data + * \param ilen length of the input data + * \param output HMAC-SHA-1 result + */ +void sha1_hmac( const unsigned char *key, size_t keylen, + const unsigned char *input, size_t ilen, + unsigned char output[20] ); + +/** + * \brief Checkup routine + * + * \return 0 if successful, or 1 if the test failed + */ +int sha1_self_test( int verbose ); + +#ifdef __cplusplus +} +#endif + +#endif /* sha1.h */ From be290d68bdc8601efaff25f86dc02e317b509536 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Sun, 31 May 2015 16:08:58 -0400 Subject: [PATCH 13/26] new lua script from @iceman1001 + bug fix in hf mfu --- client/cmdhfmfu.c | 1 + client/scripts/didump.lua | 473 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 474 insertions(+) create mode 100644 client/scripts/didump.lua diff --git a/client/cmdhfmfu.c b/client/cmdhfmfu.c index 5d211558e..731ab72f5 100644 --- a/client/cmdhfmfu.c +++ b/client/cmdhfmfu.c @@ -617,6 +617,7 @@ uint32_t GetHF14AMfU_Type(void){ } } } else { + ul_switch_off_field(); // Infinition MY-D tests Exam high nibble uint8_t nib = (card.uid[1] & 0xf0) >> 4; switch ( nib ){ diff --git a/client/scripts/didump.lua b/client/scripts/didump.lua new file mode 100644 index 000000000..2386d42d9 --- /dev/null +++ b/client/scripts/didump.lua @@ -0,0 +1,473 @@ +local cmds = require('commands') +local getopt = require('getopt') +local utils = require('utils') +local lib14a = require('read14a') + +example =[[ + script run didump + script run didump -k aabbccddeeff +]] +author = "Iceman" +usage = "script run didump -k " +desc = [[ +This is a script to dump and decrypt the data of a specific type of Mifare Mini token. + +Arguments: + -h : this help + -k : Mifare Key A. +]] + +local band=bit32.band +local bor=bit32.bor +local bnot=bit32.bnot +local bxor=bit32.bxor +local lshift=bit32.lshift +local rshift=bit32.rshift + +local FOO = 'AF62D2EC0491968CC52A1A7165F865FE' +local BAR = '286329204469736E65792032303133' +local RANDOM = FOO..BAR +local outputTemplate = os.date("toydump_%Y-%m-%d_%H%M%S"); +local TIMEOUT = 2000 +local DEBUG = false +local numBlocks = 20 +local numSectors = 5 +local CHECKSUM_OFFSET = 12; -- +1??? +--- +-- A debug printout-function +function dbg(args) + if DEBUG then + print("###", args) + end +end +--- +-- This is only meant to be used when errors occur +function oops(err) + print("ERROR: ",err) + core.clearCommandBuffer() +end +--- +-- Usage help +function help() + print(desc) + print("Example usage") + print(example) +end +--- +-- Get checksum, +-- called: data is string (32 hex digits) +-- returns: number +local function getChecksum(data) + local chksum = data:sub(25,32) + return tonumber(chksum,16) +end +--- +-- calculate checksum +-- called: data is bytes (24 hex digits) +-- returns: number +local function calculateChecksum(data) + + -- Generate table + local _tbl = {} +_tbl[0] = { 0x0 } +_tbl[1] = { 0x77073096 } +_tbl[2] = { 0xEE0E612C } +_tbl[3] = { 0x990951BA } +_tbl[4] = { 0x76DC419 } +_tbl[5] = { 0x706AF48F } +_tbl[6] = { 0xE963A535 } +_tbl[7] = { 0x9E6495A3 } +_tbl[8] = { 0xEDB8832 } +_tbl[9] = { 0x79DCB8A4 } +_tbl[10] = { 0xE0D5E91E } +_tbl[11] = { 0x97D2D988 } +_tbl[12] = { 0x9B64C2B } +_tbl[13] = { 0x7EB17CBD } +_tbl[14] = { 0xE7B82D07 } +_tbl[15] = { 0x90BF1D91 } +_tbl[16] = { 0x1DB71064 } +_tbl[17] = { 0x6AB020F2 } +_tbl[18] = { 0xF3B97148 } +_tbl[19] = { 0x84BE41DE } +_tbl[20] = { 0x1ADAD47D } +_tbl[21] = { 0x6DDDE4EB } +_tbl[22] = { 0xF4D4B551 } +_tbl[23] = { 0x83D385C7 } +_tbl[24] = { 0x136C9856 } +_tbl[25] = { 0x646BA8C0 } +_tbl[26] = { 0xFD62F97A } +_tbl[27] = { 0x8A65C9EC } +_tbl[28] = { 0x14015C4F } +_tbl[29] = { 0x63066CD9 } +_tbl[30] = { 0xFA0F3D63 } +_tbl[31] = { 0x8D080DF5 } +_tbl[32] = { 0x3B6E20C8 } +_tbl[33] = { 0x4C69105E } +_tbl[34] = { 0xD56041E4 } +_tbl[35] = { 0xA2677172 } +_tbl[36] = { 0x3C03E4D1 } +_tbl[37] = { 0x4B04D447 } +_tbl[38] = { 0xD20D85FD } +_tbl[39] = { 0xA50AB56B } +_tbl[40] = { 0x35B5A8FA } +_tbl[41] = { 0x42B2986C } +_tbl[42] = { 0xDBBBC9D6 } +_tbl[43] = { 0xACBCF940 } +_tbl[44] = { 0x32D86CE3 } +_tbl[45] = { 0x45DF5C75 } +_tbl[46] = { 0xDCD60DCF } +_tbl[47] = { 0xABD13D59 } +_tbl[48] = { 0x26D930AC } +_tbl[49] = { 0x51DE003A } +_tbl[50] = { 0xC8D75180 } +_tbl[51] = { 0xBFD06116 } +_tbl[52] = { 0x21B4F4B5 } +_tbl[53] = { 0x56B3C423 } +_tbl[54] = { 0xCFBA9599 } +_tbl[55] = { 0xB8BDA50F } +_tbl[56] = { 0x2802B89E } +_tbl[57] = { 0x5F058808 } +_tbl[58] = { 0xC60CD9B2 } +_tbl[59] = { 0xB10BE924 } +_tbl[60] = { 0x2F6F7C87 } +_tbl[61] = { 0x58684C11 } +_tbl[62] = { 0xC1611DAB } +_tbl[63] = { 0xB6662D3D } +_tbl[64] = { 0x76DC4190 } +_tbl[65] = { 0x1DB7106 } +_tbl[66] = { 0x98D220BC } +_tbl[67] = { 0xEFD5102A } +_tbl[68] = { 0x71B18589 } +_tbl[69] = { 0x6B6B51F } +_tbl[70] = { 0x9FBFE4A5 } +_tbl[71] = { 0xE8B8D433 } +_tbl[72] = { 0x7807C9A2 } +_tbl[73] = { 0xF00F934 } +_tbl[74] = { 0x9609A88E } +_tbl[75] = { 0xE10E9818 } +_tbl[76] = { 0x7F6A0DBB } +_tbl[77] = { 0x86D3D2D } +_tbl[78] = { 0x91646C97 } +_tbl[79] = { 0xE6635C01 } +_tbl[80] = { 0x6B6B51F4 } +_tbl[81] = { 0x1C6C6162 } +_tbl[82] = { 0x856530D8 } +_tbl[83] = { 0xF262004E } +_tbl[84] = { 0x6C0695ED } +_tbl[85] = { 0x1B01A57B } +_tbl[86] = { 0x8208F4C1 } +_tbl[87] = { 0xF50FC457 } +_tbl[88] = { 0x65B0D9C6 } +_tbl[89] = { 0x12B7E950 } +_tbl[90] = { 0x8BBEB8EA } +_tbl[91] = { 0xFCB9887C } +_tbl[92] = { 0x62DD1DDF } +_tbl[93] = { 0x15DA2D49 } +_tbl[94] = { 0x8CD37CF3 } +_tbl[95] = { 0xFBD44C65 } +_tbl[96] = { 0x4DB26158 } +_tbl[97] = { 0x3AB551CE } +_tbl[98] = { 0xA3BC0074 } +_tbl[99] = { 0xD4BB30E2 } +_tbl[100] = { 0x4ADFA541 } +_tbl[101] = { 0x3DD895D7 } +_tbl[102] = { 0xA4D1C46D } +_tbl[103] = { 0xD3D6F4FB } +_tbl[104] = { 0x4369E96A } +_tbl[105] = { 0x346ED9FC } +_tbl[106] = { 0xAD678846 } +_tbl[107] = { 0xDA60B8D0 } +_tbl[108] = { 0x44042D73 } +_tbl[109] = { 0x33031DE5 } +_tbl[110] = { 0xAA0A4C5F } +_tbl[111] = { 0xDD0D7CC9 } +_tbl[112] = { 0x5005713C } +_tbl[113] = { 0x270241AA } +_tbl[114] = { 0xBE0B1010 } +_tbl[115] = { 0xC90C2086 } +_tbl[116] = { 0x5768B525 } +_tbl[117] = { 0x206F85B3 } +_tbl[118] = { 0xB966D409 } +_tbl[119] = { 0xCE61E49F } +_tbl[120] = { 0x5EDEF90E } +_tbl[121] = { 0x29D9C998 } +_tbl[122] = { 0xB0D09822 } +_tbl[123] = { 0xC7D7A8B4 } +_tbl[124] = { 0x59B33D17 } +_tbl[125] = { 0x2EB40D81 } +_tbl[126] = { 0xB7BD5C3B } +_tbl[127] = { 0xC0BA6CAD } +_tbl[128] = { 0xEDB88320 } +_tbl[129] = { 0x9ABFB3B6 } +_tbl[130] = { 0x3B6E20C } +_tbl[131] = { 0x74B1D29A } +_tbl[132] = { 0xEAD54739 } +_tbl[133] = { 0x9DD277AF } +_tbl[134] = { 0x4DB2615 } +_tbl[135] = { 0x73DC1683 } +_tbl[136] = { 0xE3630B12 } +_tbl[137] = { 0x94643B84 } +_tbl[138] = { 0xD6D6A3E } +_tbl[139] = { 0x7A6A5AA8 } +_tbl[140] = { 0xE40ECF0B } +_tbl[141] = { 0x9309FF9D } +_tbl[142] = { 0xA00AE27 } +_tbl[143] = { 0x7D079EB1 } +_tbl[144] = { 0xF00F9344 } +_tbl[145] = { 0x8708A3D2 } +_tbl[146] = { 0x1E01F268 } +_tbl[147] = { 0x6906C2FE } +_tbl[148] = { 0xF762575D } +_tbl[149] = { 0x806567CB } +_tbl[150] = { 0x196C3671 } +_tbl[151] = { 0x6E6B06E7 } +_tbl[152] = { 0xFED41B76 } +_tbl[153] = { 0x89D32BE0 } +_tbl[154] = { 0x10DA7A5A } +_tbl[155] = { 0x67DD4ACC } +_tbl[156] = { 0xF9B9DF6F } +_tbl[157] = { 0x8EBEEFF9 } +_tbl[158] = { 0x17B7BE43 } +_tbl[159] = { 0x60B08ED5 } +_tbl[160] = { 0xD6D6A3E8 } +_tbl[161] = { 0xA1D1937E } +_tbl[162] = { 0x38D8C2C4 } +_tbl[163] = { 0x4FDFF252 } +_tbl[164] = { 0xD1BB67F1 } +_tbl[165] = { 0xA6BC5767 } +_tbl[166] = { 0x3FB506DD } +_tbl[167] = { 0x48B2364B } +_tbl[168] = { 0xD80D2BDA } +_tbl[169] = { 0xAF0A1B4C } +_tbl[170] = { 0x36034AF6 } +_tbl[171] = { 0x41047A60 } +_tbl[172] = { 0xDF60EFC3 } +_tbl[173] = { 0xA867DF55 } +_tbl[174] = { 0x316E8EEF } +_tbl[175] = { 0x4669BE79 } +_tbl[176] = { 0xCB61B38C } +_tbl[177] = { 0xBC66831A } +_tbl[178] = { 0x256FD2A0 } +_tbl[179] = { 0x5268E236 } +_tbl[180] = { 0xCC0C7795 } +_tbl[181] = { 0xBB0B4703 } +_tbl[182] = { 0x220216B9 } +_tbl[183] = { 0x5505262F } +_tbl[184] = { 0xC5BA3BBE } +_tbl[185] = { 0xB2BD0B28 } +_tbl[186] = { 0x2BB45A92 } +_tbl[187] = { 0x5CB36A04 } +_tbl[188] = { 0xC2D7FFA7 } +_tbl[189] = { 0xB5D0CF31 } +_tbl[190] = { 0x2CD99E8B } +_tbl[191] = { 0x5BDEAE1D } +_tbl[192] = { 0x9B64C2B0 } +_tbl[193] = { 0xEC63F226 } +_tbl[194] = { 0x756AA39C } +_tbl[195] = { 0x26D930A } +_tbl[196] = { 0x9C0906A9 } +_tbl[197] = { 0xEB0E363F } +_tbl[198] = { 0x72076785 } +_tbl[199] = { 0x5005713 } +_tbl[200] = { 0x95BF4A82 } +_tbl[201] = { 0xE2B87A14 } +_tbl[202] = { 0x7BB12BAE } +_tbl[203] = { 0xCB61B38 } +_tbl[204] = { 0x92D28E9B } +_tbl[205] = { 0xE5D5BE0D } +_tbl[206] = { 0x7CDCEFB7 } +_tbl[207] = { 0xBDBDF21 } +_tbl[208] = { 0x86D3D2D4 } +_tbl[209] = { 0xF1D4E242 } +_tbl[210] = { 0x68DDB3F8 } +_tbl[211] = { 0x1FDA836E } +_tbl[212] = { 0x81BE16CD } +_tbl[213] = { 0xF6B9265B } +_tbl[214] = { 0x6FB077E1 } +_tbl[215] = { 0x18B74777 } +_tbl[216] = { 0x88085AE6 } +_tbl[217] = { 0xFF0F6A70 } +_tbl[218] = { 0x66063BCA } +_tbl[219] = { 0x11010B5C } +_tbl[220] = { 0x8F659EFF } +_tbl[221] = { 0xF862AE69 } +_tbl[222] = { 0x616BFFD3 } +_tbl[223] = { 0x166CCF45 } +_tbl[224] = { 0xA00AE278 } +_tbl[225] = { 0xD70DD2EE } +_tbl[226] = { 0x4E048354 } +_tbl[227] = { 0x3903B3C2 } +_tbl[228] = { 0xA7672661 } +_tbl[229] = { 0xD06016F7 } +_tbl[230] = { 0x4969474D } +_tbl[231] = { 0x3E6E77DB } +_tbl[232] = { 0xAED16A4A } +_tbl[233] = { 0xD9D65ADC } +_tbl[234] = { 0x40DF0B66 } +_tbl[235] = { 0x37D83BF0 } +_tbl[236] = { 0xA9BCAE53 } +_tbl[237] = { 0xDEBB9EC5 } +_tbl[238] = { 0x47B2CF7F } +_tbl[239] = { 0x30B5FFE9 } +_tbl[240] = { 0xBDBDF21C } +_tbl[241] = { 0xCABAC28A } +_tbl[242] = { 0x53B39330 } +_tbl[243] = { 0x24B4A3A6 } +_tbl[244] = { 0xBAD03605 } +_tbl[245] = { 0xCDD70693 } +_tbl[246] = { 0x54DE5729 } +_tbl[247] = { 0x23D967BF } +_tbl[248] = { 0xB3667A2E } +_tbl[249] = { 0xC4614AB8 } +_tbl[250] = { 0x5D681B02 } +_tbl[251] = { 0x2A6F2B94 } +_tbl[252] = { 0xB40BBE37 } +_tbl[253] = { 0xC30C8EA1 } +_tbl[254] = { 0x5A05DF1B } +_tbl[255] = { 0x2D02EF8D } + + + -- Calculate it + local ret = 0 + for i,item in pairs(data) do + local tmp = band(ret, 0xFF) + local index = band( bxor(tmp, item), 0xFF) + ret = bxor(rshift(ret,8), _tbl[index][1]) + end + return ret +end +--- +-- update checksum +-- called: data is string, ( >= 24 hex digits ) +-- returns: string, (data concat new checksum) +local function updateChecksum(data) + local part = data:sub(1,24) + local chksum = calculateChecksum( utils.ConvertHexToBytes(part)) + return string.format("%s%X", part, chksum) +end +--- +-- receives the answer from deviceside, used with a readblock command +local function waitCmd() + local response = core.WaitForResponseTimeout(cmds.CMD_ACK,TIMEOUT) + if response then + local count,cmd,arg0 = bin.unpack('LL',response) + if(arg0==1) then + local count,arg1,arg2,data = bin.unpack('LLH511',response,count) + return data:sub(1,32) + else + return nil, "Couldn't read block.." + end + end + return nil, "No response from device" +end + +local function selftest() + local testdata = '000F42430D0A14000001D11F'..'5D738517' + local chksum = getChecksum(testdata) + local calc = calculateChecksum( utils.ConvertHexToBytes(testdata:sub(1,24))) + print ('TESTDATA :: '..testdata) + print ('DATA :: '..testdata:sub(1,24)) + print (('CHKSUM :: %X'):format(chksum)) + print (('CHKSUM CALC :: %X'):format(calc)) + print ('UPDATE CHKSUM :: '..updateChecksum(testdata)) + + +end +--- +-- The main entry point +-- -d decrypt +-- -e encrypt +-- -v validate +function main(args) + + local cmd, result, err, blockNo, keyA + local blocks = {} + local decryptkey = '' + + -- Read the parameters + for o, a in getopt.getopt(args, 'hk:') do + if o == "h" then help() return end + if o == "k" then keyA = a end + end + + selftest() + + local tst2 = '00100100030209094312356432324E34B79A349B' + + -- validate input args. + keyA = keyA or '6dd747e86975' + if #(keyA) ~= 12 then + return oops( string.format('Wrong length of write key (was %d) expected 12', #keyA)) + end + + -- Turn off Debug + local cmdSetDbgOff = "hf mf dbg 0" + core.console( cmdSetDbgOff) + + -- GET TAG UID + + result, err = lib14a.read1443a(false) + if not result then + return oops(err) + end + + core.clearCommandBuffer() + + print(result.uid, keyA) + + local my = result.uid + if 1 == 1 then + return + end + + -- Show tag info + print((' Found tag %s'):format(result.name)) + + local longrandom = RANDOM..result.uid + local res = utils.Sha1Hex(longrandom) + res = utils.ConvertBytesToHex(utils.ConvertAsciiToBytes(res:sub(1,16))) + decryptkey = utils.SwapEndiannessStr(res:sub(1,8) , 32) + decryptkey = decryptkey..utils.SwapEndiannessStr( res:sub(9,16),32) + decryptkey = decryptkey..utils.SwapEndiannessStr( res:sub(17,24),32) + decryptkey = decryptkey..utils.SwapEndiannessStr( res:sub(25,32),32) + print('Decrypt key::',decryptkey) + print('Reading card data') + print('Raw','Decrypted') + for blockNo = 0, numBlocks-1, 1 do + + if core.ukbhit() then + print("aborted by user") + break + end + + cmd = Command:new{cmd = cmds.CMD_MIFARE_READBL, arg1 = blockNo ,arg2 = 0,arg3 = 0, data = keyA} + local err = core.SendCommand(cmd:getBytes()) + if err then return oops(err) end + local blockdata, err = waitCmd() + if err then return oops(err) end + + if blockNo%4 ~= 3 then + + -- blocks with zero not encrypted. + if string.find(blockdata, '^0+$') then + print(blockdata, blockdata) + else + local aes = core.aes128_decrypt_ecb(decryptkey, blockdata) + local bytes = utils.ConvertAsciiToBytes(aes) + local hex = utils.ConvertBytesToHex(bytes) + print(blockdata , hex) + end + elseif blockNo == 0 then + print(blockdata,blockdata) + else + -- Sectorblocks, not encrypted + local sectortrailer = keyA..blockdata:sub(13,20)..keyA + print(sectortrailer, sectortrailer, blockdata:sub(13,20)) + end + end + -- checksum fyra sista bytes i varje rad. (kanske inte för s0) + -- s0b1,s1b0,s2b0,s3b0 + -- +end + +main(args) From 4a74e2be72b133ceea811d6f559b5b1a0da52377 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Mon, 1 Jun 2015 00:18:03 -0400 Subject: [PATCH 14/26] add my_d move lean identification. --- client/cmdhfmfu.c | 56 +++++++++++++++++++++++++++-------------------- client/cmdhfmfu.h | 7 +++--- 2 files changed, 36 insertions(+), 27 deletions(-) diff --git a/client/cmdhfmfu.c b/client/cmdhfmfu.c index 731ab72f5..48f549ba8 100644 --- a/client/cmdhfmfu.c +++ b/client/cmdhfmfu.c @@ -16,16 +16,19 @@ #include "protocols.h" #include "data.h" -#define MAX_UL_BLOCKS 0x0f -#define MAX_ULC_BLOCKS 0x2b -#define MAX_ULEV1a_BLOCKS 0x13 -#define MAX_ULEV1b_BLOCKS 0x28 -#define MAX_NTAG_203 0x29 -#define MAX_NTAG_210 0x13 -#define MAX_NTAG_212 0x28 -#define MAX_NTAG_213 0x2c -#define MAX_NTAG_215 0x86 -#define MAX_NTAG_216 0xe6 +#define MAX_UL_BLOCKS 0x0f +#define MAX_ULC_BLOCKS 0x2b +#define MAX_ULEV1a_BLOCKS 0x13 +#define MAX_ULEV1b_BLOCKS 0x28 +#define MAX_NTAG_203 0x29 +#define MAX_NTAG_210 0x13 +#define MAX_NTAG_212 0x28 +#define MAX_NTAG_213 0x2c +#define MAX_NTAG_215 0x86 +#define MAX_NTAG_216 0xe6 +#define MAX_MY_D_NFC 0xff +#define MAX_MY_D_MOVE 0x25 +#define MAX_MY_D_MOVE_LEAN 0x0f #define KEYS_3DES_COUNT 7 uint8_t default_3des_keys[KEYS_3DES_COUNT][16] = { @@ -54,17 +57,18 @@ uint8_t default_pwd_pack[KEYS_PWD_COUNT][4] = { {0x32,0x0C,0x16,0x17}, // PACK 0x80,0x80 -- AMiiboo (sniffed) }; -#define MAX_UL_TYPES 16 +#define MAX_UL_TYPES 17 uint16_t UL_TYPES_ARRAY[MAX_UL_TYPES] = {UNKNOWN, UL, UL_C, UL_EV1_48, UL_EV1_128, NTAG, NTAG_203, - NTAG_210, NTAG_212, NTAG_213, NTAG_215, NTAG_216, MY_D, MY_D_NFC, MY_D_MOVE, MY_D_MOVE_NFC}; + NTAG_210, NTAG_212, NTAG_213, NTAG_215, NTAG_216, MY_D, MY_D_NFC, MY_D_MOVE, MY_D_MOVE_NFC, MY_D_MOVE_LEAN}; uint8_t UL_MEMORY_ARRAY[MAX_UL_TYPES] = {MAX_UL_BLOCKS, MAX_UL_BLOCKS, MAX_ULC_BLOCKS, MAX_ULEV1a_BLOCKS, MAX_ULEV1b_BLOCKS, MAX_NTAG_203, MAX_NTAG_203, MAX_NTAG_210, MAX_NTAG_212, MAX_NTAG_213, - MAX_NTAG_215, MAX_NTAG_216, MAX_UL_BLOCKS, MAX_UL_BLOCKS, MAX_UL_BLOCKS, MAX_UL_BLOCKS}; + MAX_NTAG_215, MAX_NTAG_216, MAX_UL_BLOCKS, MAX_MY_D_NFC, MAX_MY_D_MOVE, MAX_MY_D_MOVE, MAX_MY_D_MOVE_LEAN}; static int CmdHelp(const char *Cmd); +// get version nxp product type char *getProductTypeStr( uint8_t id){ static char buf[20]; @@ -285,12 +289,12 @@ static int ul_print_default( uint8_t *data){ PrintAndLog(" UID : %s ", sprint_hex(uid, 7)); PrintAndLog(" UID[0] : %02X, %s", uid[0], getTagInfo(uid[0]) ); - if ( uid[0] == 0x05 ) { + if ( uid[0] == 0x05 && ((uid[1] & 0xf0) >> 4) == 2 ) { // is infineon and 66RxxP uint8_t chip = (data[8] & 0xC7); // 11000111 mask, bit 3,4,5 RFU switch (chip){ - case 0xc2: PrintAndLog(" IC type : SLE 66R04P"); break; - case 0xc4: PrintAndLog(" IC type : SLE 66R16P"); break; - case 0xc6: PrintAndLog(" IC type : SLE 66R32P"); break; + case 0xc2: PrintAndLog(" IC type : SLE 66R04P 770 Bytes"); break; //77 pages + case 0xc4: PrintAndLog(" IC type : SLE 66R16P 2560 Bytes"); break; //256 pages + case 0xc6: PrintAndLog(" IC type : SLE 66R32P 5120 Bytes"); break; //512 pages /2 sectors } } // CT (cascade tag byte) 0x88 xor SN0 xor SN1 xor SN2 @@ -376,13 +380,15 @@ int ul_print_type(uint32_t tagtype, uint8_t spaces){ else if ( tagtype & NTAG_I2C_2K ) PrintAndLog("%sTYPE : NTAG I%sC 1904bytes (NT3H1201FHK)", spacer, "\xFD"); else if ( tagtype & MY_D ) - PrintAndLog("%sTYPE : INFINEON my-d\x99", spacer); + PrintAndLog("%sTYPE : INFINEON my-d\x99 (SLE 66RxxS)", spacer); else if ( tagtype & MY_D_NFC ) - PrintAndLog("%sTYPE : INFINEON my-d\x99 NFC", spacer); + PrintAndLog("%sTYPE : INFINEON my-d\x99 NFC (SLE 66RxxP)", spacer); else if ( tagtype & MY_D_MOVE ) - PrintAndLog("%sTYPE : INFINEON my-d\x99 move", spacer); + PrintAndLog("%sTYPE : INFINEON my-d\x99 move (SLE 66R01P)", spacer); else if ( tagtype & MY_D_MOVE_NFC ) - PrintAndLog("%sTYPE : INFINEON my-d\x99 move NFC", spacer); + PrintAndLog("%sTYPE : INFINEON my-d\x99 move NFC (SLE 66R01P)", spacer); + else if ( tagtype & MY_D_MOVE_LEAN ) + PrintAndLog("%sTYPE : INFINEON my-d\x99 move lean (SLE 66R01L)", spacer); else PrintAndLog("%sTYPE : Unknown %06x", spacer, tagtype); return 0; @@ -621,9 +627,11 @@ uint32_t GetHF14AMfU_Type(void){ // Infinition MY-D tests Exam high nibble uint8_t nib = (card.uid[1] & 0xf0) >> 4; switch ( nib ){ - case 1: tagtype = MY_D; break; - case 2: tagtype = (MY_D | MY_D_NFC); break; //notice: we can not currently distinguish between these two - case 3: tagtype = (MY_D_MOVE | MY_D_MOVE_NFC); break; //notice: we can not currently distinguish between these two + // case 0: tagtype = SLE66R35E7; break; //or SLE 66R35E7 - mifare compat... should have different sak/atqa for mf 1k + case 1: tagtype = MY_D; break; //or SLE 66RxxS ... up to 512 pages of 8 user bytes... + case 2: tagtype = (MY_D_NFC); break; //or SLE 66RxxP ... up to 512 pages of 8 user bytes... (or in nfc mode FF pages of 4 bytes) + case 3: tagtype = (MY_D_MOVE | MY_D_MOVE_NFC); break; //or SLE 66R01P // 38 pages of 4 bytes //notice: we can not currently distinguish between these two + case 7: tagtype = MY_D_MOVE_LEAN; break; //or SLE 66R01L // 16 pages of 4 bytes } } diff --git a/client/cmdhfmfu.h b/client/cmdhfmfu.h index 4ec48ff9d..132e4f908 100644 --- a/client/cmdhfmfu.h +++ b/client/cmdhfmfu.h @@ -42,9 +42,10 @@ typedef enum TAGTYPE_UL { MY_D_NFC = 0x001000, MY_D_MOVE = 0x002000, MY_D_MOVE_NFC = 0x004000, - NTAG_I2C_1K = 0x008000, - NTAG_I2C_2K = 0x010000, - MAGIC = 0x020000, + MY_D_MOVE_LEAN= 0x008000, + NTAG_I2C_1K = 0x010000, + NTAG_I2C_2K = 0x020000, + MAGIC = 0x040000, UL_MAGIC = UL | MAGIC, UL_C_MAGIC = UL_C | MAGIC, UL_ERROR = 0xFFFFFF, From 0d9a86c72441fd0510748bcd2d70ee1fb6f2ff57 Mon Sep 17 00:00:00 2001 From: pwpiwi Date: Mon, 1 Jun 2015 19:42:50 +0200 Subject: [PATCH 15/26] Fix issue #103 (hopefully). Quite an old bug which was previously masked by a big DMA_BUFFER_SIZE. --- armsrc/iso14443.c | 37 ++++++++++++++++--------------------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/armsrc/iso14443.c b/armsrc/iso14443.c index c7f49f140..c202e312d 100644 --- a/armsrc/iso14443.c +++ b/armsrc/iso14443.c @@ -24,6 +24,9 @@ #define TAG_READER_BUFFER_SIZE 2048 #define DEMOD_DMA_BUFFER_SIZE 1024 */ + +#define RECEIVE_SAMPLES_TIMEOUT 2000 + //============================================================================= // An ISO 14443 Type B tag. We listen for commands from the reader, using // a UART kind of thing that's implemented in software. When we get a @@ -658,9 +661,6 @@ static void GetSamplesFor14443Demod(int weTx, int n, int quiet) // free all previous allocations first BigBuf_free(); - // The command (reader -> tag) that we're receiving. - uint8_t *receivedCmd = BigBuf_malloc(MAX_FRAME_SIZE); - // The response (tag -> reader) that we're receiving. uint8_t *receivedResponse = BigBuf_malloc(MAX_FRAME_SIZE); @@ -669,8 +669,6 @@ static void GetSamplesFor14443Demod(int weTx, int n, int quiet) // Set up the demodulator for tag -> reader responses. DemodInit(receivedResponse); - // Set up the demodulator for the reader -> tag commands - UartInit(receivedCmd); // Setup and start DMA. FpgaSetupSscDma(dmaBuf, DMA_BUFFER_SIZE); @@ -695,8 +693,8 @@ static void GetSamplesFor14443Demod(int weTx, int n, int quiet) ci = upTo[0]; cq = upTo[1]; upTo += 2; - if(upTo - dmaBuf > DMA_BUFFER_SIZE) { - upTo -= DMA_BUFFER_SIZE; + if(upTo >= dmaBuf + DMA_BUFFER_SIZE) { + upTo = dmaBuf; AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) upTo; AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE; } @@ -707,15 +705,12 @@ static void GetSamplesFor14443Demod(int weTx, int n, int quiet) samples += 2; - Handle14443UartBit(1); - Handle14443UartBit(1); - if(Handle14443SamplesDemod(ci, cq)) { gotFrame = 1; } } - if(samples > 2000) { + if(samples > n) { break; } } @@ -724,8 +719,8 @@ static void GetSamplesFor14443Demod(int weTx, int n, int quiet) //Tracing if (tracing && Demod.len > 0) { uint8_t parity[MAX_PARITY_SIZE]; - GetParity(Demod.output , Demod.len, parity); - LogTrace(Demod.output,Demod.len, 0, 0, parity, FALSE); + GetParity(Demod.output, Demod.len, parity); + LogTrace(Demod.output, Demod.len, 0, 0, parity, FALSE); } } @@ -934,7 +929,7 @@ void ReadSTMemoryIso14443(uint32_t dwLast) CodeAndTransmit14443bAsReader(cmd1, sizeof(cmd1)); // LED_A_ON(); - GetSamplesFor14443Demod(TRUE, 2000,TRUE); + GetSamplesFor14443Demod(TRUE, RECEIVE_SAMPLES_TIMEOUT, TRUE); // LED_A_OFF(); if (Demod.len == 0) { @@ -952,7 +947,7 @@ void ReadSTMemoryIso14443(uint32_t dwLast) CodeAndTransmit14443bAsReader(cmd1, sizeof(cmd1)); // LED_A_ON(); - GetSamplesFor14443Demod(TRUE, 2000,TRUE); + GetSamplesFor14443Demod(TRUE, RECEIVE_SAMPLES_TIMEOUT, TRUE); // LED_A_OFF(); if (Demod.len != 3) { Dbprintf("Expected 3 bytes from tag, got %d", Demod.len); @@ -976,7 +971,7 @@ void ReadSTMemoryIso14443(uint32_t dwLast) CodeAndTransmit14443bAsReader(cmd1, 3); // Only first three bytes for this one // LED_A_ON(); - GetSamplesFor14443Demod(TRUE, 2000,TRUE); + GetSamplesFor14443Demod(TRUE, RECEIVE_SAMPLES_TIMEOUT, TRUE); // LED_A_OFF(); if (Demod.len != 10) { Dbprintf("Expected 10 bytes from tag, got %d", Demod.len); @@ -1008,7 +1003,7 @@ void ReadSTMemoryIso14443(uint32_t dwLast) CodeAndTransmit14443bAsReader(cmd1, sizeof(cmd1)); // LED_A_ON(); - GetSamplesFor14443Demod(TRUE, 2000,TRUE); + GetSamplesFor14443Demod(TRUE, RECEIVE_SAMPLES_TIMEOUT, TRUE); // LED_A_OFF(); if (Demod.len != 6) { // Check if we got an answer from the tag DbpString("Expected 6 bytes from tag, got less..."); @@ -1118,10 +1113,10 @@ void RAMFUNC SnoopIso14443(void) cq = upTo[1]; upTo += 2; lastRxCounter -= 2; - if(upTo - dmaBuf > DMA_BUFFER_SIZE) { - upTo -= DMA_BUFFER_SIZE; + if(upTo >= dmaBuf + DMA_BUFFER_SIZE) { + upTo = dmaBuf; lastRxCounter += DMA_BUFFER_SIZE; - AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) upTo; + AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) dmaBuf; AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE; } @@ -1237,8 +1232,8 @@ void SendRawCommand14443B(uint32_t datalen, uint32_t recv,uint8_t powerfield, ui if(recv) { + GetSamplesFor14443Demod(TRUE, RECEIVE_SAMPLES_TIMEOUT, TRUE); uint16_t iLen = MIN(Demod.len,USB_CMD_DATA_SIZE); - GetSamplesFor14443Demod(TRUE, 2000, TRUE); cmd_send(CMD_ACK,iLen,0,0,Demod.output,iLen); } if(!powerfield) From 04bb05670dfaac4ba29bbd614c3530036fdb6433 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Wed, 3 Jun 2015 16:52:20 -0400 Subject: [PATCH 16/26] Testing animal tags --- client/cmddata.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++-- common/lfdemod.c | 27 ++++++++++++++++ common/lfdemod.h | 1 + 3 files changed, 107 insertions(+), 2 deletions(-) diff --git a/client/cmddata.c b/client/cmddata.c index 765523518..089e7d5fc 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -40,7 +40,7 @@ void setDemodBuf(uint8_t *buff, size_t size, size_t startIdx) size = MAX_DEMOD_BUF_LEN; size_t i = 0; - for (; i < size; i++){ +for (; i < size; i++){ DemodBuffer[i]=buff[startIdx++]; } DemodBufferLen=size; @@ -500,7 +500,7 @@ int ASKbiphaseDemod(const char *Cmd, bool verbose) int offset=0, clk=0, invert=0, maxErr=0, ans=0; ans = sscanf(Cmd, "%i %i %i %i", &offset, &clk, &invert, &maxErr); if (ans>0) - ans = ASKDemod(Cmd+1, FALSE, FALSE, 0); + ans = ASKDemod(Cmd+2, FALSE, FALSE, 0); else ans = ASKDemod(Cmd, FALSE, FALSE, 0); if (!ans) { @@ -1457,6 +1457,83 @@ int CmdFSKdemodPyramid(const char *Cmd) return 1; } +// ISO11784/85 demod (aka animal tag) BIPHASE, inverted, rf/32, with preamble of 00000000001 (128bits) +// 8 databits + 1 parity (1) +// CIITT 16 chksum +// NATIONAL CODE, ICAR database +// COUNTRY CODE (ISO3166) +// FLAG (animal/non-animal) +int CmdIso11784demodBI(const char *Cmd){ + + int invert = 1; + int clk = 32; + int errCnt = 0; + int maxErr = 0; + uint8_t BitStream[MAX_DEMOD_BUF_LEN]; + size_t size = getFromGraphBuf(BitStream); + + errCnt = askdemod(BitStream, &size, &clk, &invert, maxErr, 0, 0); + if ( errCnt < 0 || errCnt > maxErr ) { + if (g_debugMode) PrintAndLog("DEBUG: no data or error found %d, clock: 32", errCnt); + return 0; + } + + errCnt = BiphaseRawDecode(BitStream, &size, maxErr, 1); + if (errCnt < 0 || errCnt > maxErr ) { + if (g_debugMode) PrintAndLog("Error BiphaseRawDecode: %d", errCnt); + return 0; + } + + int preambleIndex = ISO11784demodBI(BitStream, &size); + if (preambleIndex < 0){ + if (g_debugMode) PrintAndLog("Error ISO11784Demod , no startmarker found :: %d",preambleIndex); + return 0; + } + + setDemodBuf(BitStream, 128, preambleIndex); + //printDemodBuff(); + + size = removeParity(BitStream, preambleIndex + 11, 9, 1, 117); + if ( size <= 0 ) { + if (g_debugMode) PrintAndLog("Error removeParity:: %d", size); + return 0; + } + PrintAndLog("startmarker %d; Size %d", preambleIndex, size); + + //return 1; + //got a good demod + uint32_t NationalCodeA = bytebits_to_byteLSBF(BitStream,32); + uint32_t NationalCodeB = bytebits_to_byteLSBF(BitStream+32,6); + uint32_t countryCode = bytebits_to_byteLSBF(BitStream+38,10); + uint8_t dataBlockBit = BitStream[48]; + uint32_t reservedCode = bytebits_to_byteLSBF(BitStream+49,14); + uint8_t animalBit = BitStream[63]; + uint32_t crc16 = bytebits_to_byteLSBF(BitStream+64,16); + uint32_t extended = bytebits_to_byteLSBF(BitStream+80,24); + + PrintAndLog("NationalCode: %x%08x",NationalCodeB,NationalCodeA); + //add rest of print code here... + /* + uint8_t ByteStream[16] = {0x00}; + uint8_t bitCnt = 0; + uint8_t ByteCnt = 0; + size_t startIdx = preambleIndex + 11; //start after preamble + for (size_t idx = 0; idx < size-11; idx++){ + + //lsb first + ByteStream[ByteCnt] = ByteStream[ByteCnt] | (BitStream[startIdx+idx] << bitCnt); + bitCnt++; + if (bitCnt % 8 == 0){ + if (g_debugMode) PrintAndLog("byte %d: %02x", ByteCnt, ByteStream[ByteCnt]); + bitCnt = 0; + ByteCnt++; + } + } + */ + return 1; +} + + //by marshmellow //attempt to psk1 demod graph buffer int PSKDemod(const char *Cmd, bool verbose) diff --git a/common/lfdemod.c b/common/lfdemod.c index 7d40d22e5..c0f2bb712 100644 --- a/common/lfdemod.c +++ b/common/lfdemod.c @@ -537,6 +537,18 @@ uint32_t bytebits_to_byte(uint8_t* src, size_t numbits) return num; } +//least significant bit first +uint32_t bytebits_to_byteLSBF(uint8_t* src, size_t numbits) +{ + uint32_t num = 0; + for(int i = 0 ; i < numbits ; i++) + { + num = (num << 1) | (*src); + src++; + } + return num; +} + int IOdemodFSK(uint8_t *dest, size_t size) { if (justNoise(dest, size)) return -1; @@ -590,6 +602,21 @@ size_t removeParity(uint8_t *BitStream, size_t startIdx, uint8_t pLen, uint8_t p return bitCnt; } +// Ask/Biphase Demod then try to locate an ISO 11784/85 ID +// BitStream must contain previously askrawdemod and biphasedemoded data +int ISO11784demodBI(uint8_t *dest, size_t *size) +{ + //make sure buffer has enough data + if (*size < 128) return -1; + + size_t startIdx = 0; + uint8_t preamble[] = {0,0,0,0,0,0,0,0,0,0,1}; + + uint8_t errChk = preambleSearch(dest, preamble, sizeof(preamble), size, &startIdx); + if (errChk == 0) return -2; //preamble not found + return (int)startIdx; +} + // by marshmellow // FSK Demod then try to locate an AWID ID int AWIDdemodFSK(uint8_t *dest, size_t *size) diff --git a/common/lfdemod.h b/common/lfdemod.h index ab81c34c4..81157d192 100644 --- a/common/lfdemod.h +++ b/common/lfdemod.h @@ -19,6 +19,7 @@ int askdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int maxErr, uint8_t amp, uint8_t askType); int BiphaseRawDecode(uint8_t * BitStream, size_t *size, int offset, int invert); uint32_t bytebits_to_byte(uint8_t* src, size_t numbits); +uint32_t bytebits_to_byteLSBF(uint8_t* src, size_t numbits); uint16_t countFC(uint8_t *BitStream, size_t size, uint8_t fskAdj); int DetectASKClock(uint8_t dest[], size_t size, int *clock, int maxErr); uint8_t DetectCleanAskWave(uint8_t dest[], size_t size, uint8_t high, uint8_t low); From fd1d30cb76a384adc8176df1f0f35658c091d96c Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Wed, 3 Jun 2015 18:28:56 -0400 Subject: [PATCH 17/26] addition animal tags demod info --- client/cmddata.c | 35 ++++++++++++++--------------------- common/lfdemod.c | 13 +++++++------ common/lfdemod.h | 1 + 3 files changed, 22 insertions(+), 27 deletions(-) diff --git a/client/cmddata.c b/client/cmddata.c index 089e7d5fc..fd08b6dd1 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -1493,11 +1493,14 @@ int CmdIso11784demodBI(const char *Cmd){ setDemodBuf(BitStream, 128, preambleIndex); //printDemodBuff(); - size = removeParity(BitStream, preambleIndex + 11, 9, 1, 117); - if ( size <= 0 ) { + size = removeParity(BitStream, preambleIndex + 11, 9, 2, 117); + if ( size <= 103 ) { if (g_debugMode) PrintAndLog("Error removeParity:: %d", size); return 0; } + //char *bin = sprint_bin_break(BitStream,size,16); + //PrintAndLog("DEBUG BinStream:\n%s",bin); + PrintAndLog("startmarker %d; Size %d", preambleIndex, size); //return 1; @@ -1511,25 +1514,14 @@ int CmdIso11784demodBI(const char *Cmd){ uint32_t crc16 = bytebits_to_byteLSBF(BitStream+64,16); uint32_t extended = bytebits_to_byteLSBF(BitStream+80,24); - PrintAndLog("NationalCode: %x%08x",NationalCodeB,NationalCodeA); - //add rest of print code here... - /* - uint8_t ByteStream[16] = {0x00}; - uint8_t bitCnt = 0; - uint8_t ByteCnt = 0; - size_t startIdx = preambleIndex + 11; //start after preamble - for (size_t idx = 0; idx < size-11; idx++){ - - //lsb first - ByteStream[ByteCnt] = ByteStream[ByteCnt] | (BitStream[startIdx+idx] << bitCnt); - bitCnt++; - if (bitCnt % 8 == 0){ - if (g_debugMode) PrintAndLog("byte %d: %02x", ByteCnt, ByteStream[ByteCnt]); - bitCnt = 0; - ByteCnt++; - } - } - */ + PrintAndLog("NationalCode: %X%08X",NationalCodeB,NationalCodeA); + PrintAndLog("CountryCode: %d",countryCode); + PrintAndLog("dataBlockBit: %d",dataBlockBit); + PrintAndLog("reservedCode: %X",reservedCode); + PrintAndLog("animalBit: %d", animalBit); + PrintAndLog("CRC: %02X", crc16); + PrintAndLog("Extended: %x", extended); + return 1; } @@ -2289,6 +2281,7 @@ static command_t CommandTable[] = {"hexsamples", CmdHexsamples, 0, " [] -- Dump big buffer as hex bytes"}, {"hide", CmdHide, 1, "Hide graph window"}, {"hpf", CmdHpf, 1, "Remove DC offset from trace"}, + {"iso11784demod", CmdIso11784demodBI, 1, "Demodulate a ISO11784/85 Biphase tag from GraphBuffer"}, {"load", CmdLoad, 1, " -- Load trace (to graph window"}, {"ltrim", CmdLtrim, 1, " -- Trim samples from left of trace"}, {"rtrim", CmdRtrim, 1, " -- Trim samples from right of trace"}, diff --git a/common/lfdemod.c b/common/lfdemod.c index c0f2bb712..aa37bb9ef 100644 --- a/common/lfdemod.c +++ b/common/lfdemod.c @@ -526,7 +526,7 @@ int ParadoxdemodFSK(uint8_t *dest, size_t *size, uint32_t *hi2, uint32_t *hi, ui return (int)startIdx; } -uint32_t bytebits_to_byte(uint8_t* src, size_t numbits) +uint32_t bytebits_to_byte(uint8_t *src, size_t numbits) { uint32_t num = 0; for(int i = 0 ; i < numbits ; i++) @@ -538,13 +538,12 @@ uint32_t bytebits_to_byte(uint8_t* src, size_t numbits) } //least significant bit first -uint32_t bytebits_to_byteLSBF(uint8_t* src, size_t numbits) +uint32_t bytebits_to_byteLSBF(uint8_t *src, size_t numbits) { uint32_t num = 0; for(int i = 0 ; i < numbits ; i++) { - num = (num << 1) | (*src); - src++; + num = (num << 1) | *(src + (numbits-(i+1))); } return num; } @@ -581,7 +580,7 @@ int IOdemodFSK(uint8_t *dest, size_t size) // by marshmellow // takes a array of binary values, start position, length of bits per parity (includes parity bit), -// Parity Type (1 for odd 0 for even), and binary Length (length to run) +// Parity Type (1 for odd; 0 for even; 2 for just drop it), and binary Length (length to run) size_t removeParity(uint8_t *BitStream, size_t startIdx, uint8_t pLen, uint8_t pType, size_t bLen) { uint32_t parityWd = 0; @@ -593,7 +592,9 @@ size_t removeParity(uint8_t *BitStream, size_t startIdx, uint8_t pLen, uint8_t p } j--; // if parity fails then return 0 - if (parityTest(parityWd, pLen, pType) == 0) return -1; + if (pType != 2) { + if (parityTest(parityWd, pLen, pType) == 0) return -1; + } bitCnt+=(pLen-1); parityWd = 0; } diff --git a/common/lfdemod.h b/common/lfdemod.h index 81157d192..e21bfe11a 100644 --- a/common/lfdemod.h +++ b/common/lfdemod.h @@ -41,6 +41,7 @@ void psk1TOpsk2(uint8_t *BitStream, size_t size); size_t removeParity(uint8_t *BitStream, size_t startIdx, uint8_t pLen, uint8_t pType, size_t bLen); //tag specific +int ISO11784demodBI(uint8_t *dest, size_t *size); int AWIDdemodFSK(uint8_t *dest, size_t *size); int gProxII_Demod(uint8_t BitStream[], size_t *size); int HIDdemodFSK(uint8_t *dest, size_t *size, uint32_t *hi2, uint32_t *hi, uint32_t *lo); From b2c330b36778471de73683ca779d4850556db895 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Wed, 3 Jun 2015 23:59:22 -0400 Subject: [PATCH 18/26] bug fix - biphase invert + fdx-b adjustments --- client/cmddata.c | 44 +++++++++++++++++++++++--------------------- common/lfdemod.c | 2 +- common/lfdemod.h | 2 +- 3 files changed, 25 insertions(+), 23 deletions(-) diff --git a/client/cmddata.c b/client/cmddata.c index fd08b6dd1..dad0a7119 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -498,7 +498,7 @@ int ASKbiphaseDemod(const char *Cmd, bool verbose) { //ask raw demod GraphBuffer first int offset=0, clk=0, invert=0, maxErr=0, ans=0; - ans = sscanf(Cmd, "%i %i %i %i", &offset, &clk, &invert, &maxErr); + ans = sscanf(Cmd, "%i %i 0 %i", &offset, &clk, &maxErr); if (ans>0) ans = ASKDemod(Cmd+2, FALSE, FALSE, 0); else @@ -512,7 +512,7 @@ int ASKbiphaseDemod(const char *Cmd, bool verbose) size_t size = DemodBufferLen; uint8_t BitStream[MAX_DEMOD_BUF_LEN]; memcpy(BitStream, DemodBuffer, DemodBufferLen); - int errCnt = BiphaseRawDecode(BitStream, &size, offset, 0); + int errCnt = BiphaseRawDecode(BitStream, &size, offset, invert); if (errCnt < 0){ if (g_debugMode || verbose) PrintAndLog("Error BiphaseRawDecode: %d", errCnt); return 0; @@ -1457,13 +1457,13 @@ int CmdFSKdemodPyramid(const char *Cmd) return 1; } -// ISO11784/85 demod (aka animal tag) BIPHASE, inverted, rf/32, with preamble of 00000000001 (128bits) +// FDX-B ISO11784/85 demod (aka animal tag) BIPHASE, inverted, rf/32, with preamble of 00000000001 (128bits) // 8 databits + 1 parity (1) // CIITT 16 chksum // NATIONAL CODE, ICAR database -// COUNTRY CODE (ISO3166) +// COUNTRY CODE (ISO3166) or http://cms.abvma.ca/uploads/ManufacturersISOsandCountryCodes.pdf // FLAG (animal/non-animal) -int CmdIso11784demodBI(const char *Cmd){ +int CmdFDXBdemodBI(const char *Cmd){ int invert = 1; int clk = 32; @@ -1484,9 +1484,9 @@ int CmdIso11784demodBI(const char *Cmd){ return 0; } - int preambleIndex = ISO11784demodBI(BitStream, &size); + int preambleIndex = FDXBdemodBI(BitStream, &size); if (preambleIndex < 0){ - if (g_debugMode) PrintAndLog("Error ISO11784Demod , no startmarker found :: %d",preambleIndex); + if (g_debugMode) PrintAndLog("Error FDXBDemod , no startmarker found :: %d",preambleIndex); return 0; } @@ -1498,15 +1498,16 @@ int CmdIso11784demodBI(const char *Cmd){ if (g_debugMode) PrintAndLog("Error removeParity:: %d", size); return 0; } - //char *bin = sprint_bin_break(BitStream,size,16); - //PrintAndLog("DEBUG BinStream:\n%s",bin); - - PrintAndLog("startmarker %d; Size %d", preambleIndex, size); + if (g_debugMode) { + char *bin = sprint_bin_break(BitStream,size,16); + PrintAndLog("DEBUG BinStream:\n%s",bin); + } + PrintAndLog("\nFDX-B / ISO 11784/5 Animal Tag ID Found:"); + if (g_debugMode) PrintAndLog("startmarker %d; Size %d", preambleIndex, size); //return 1; //got a good demod - uint32_t NationalCodeA = bytebits_to_byteLSBF(BitStream,32); - uint32_t NationalCodeB = bytebits_to_byteLSBF(BitStream+32,6); + uint64_t NationalCode = ((uint64_t)(bytebits_to_byteLSBF(BitStream+32,6)) << 32) | bytebits_to_byteLSBF(BitStream,32); uint32_t countryCode = bytebits_to_byteLSBF(BitStream+38,10); uint8_t dataBlockBit = BitStream[48]; uint32_t reservedCode = bytebits_to_byteLSBF(BitStream+49,14); @@ -1514,13 +1515,14 @@ int CmdIso11784demodBI(const char *Cmd){ uint32_t crc16 = bytebits_to_byteLSBF(BitStream+64,16); uint32_t extended = bytebits_to_byteLSBF(BitStream+80,24); - PrintAndLog("NationalCode: %X%08X",NationalCodeB,NationalCodeA); - PrintAndLog("CountryCode: %d",countryCode); - PrintAndLog("dataBlockBit: %d",dataBlockBit); - PrintAndLog("reservedCode: %X",reservedCode); - PrintAndLog("animalBit: %d", animalBit); - PrintAndLog("CRC: %02X", crc16); - PrintAndLog("Extended: %x", extended); + PrintAndLog("Animal ID: %u-%012llu", countryCode, NationalCode); + PrintAndLog("National Code: %012llu", NationalCode); + PrintAndLog("CountryCode: %u", countryCode); + PrintAndLog("Extended Data: %s", dataBlockBit ? "True" : "False"); + PrintAndLog("reserved Code: %u", reservedCode); + PrintAndLog("Animal Tag: %s", animalBit ? "True" : "False"); + PrintAndLog("CRC: 0x%02X", crc16); + PrintAndLog("Extended: 0x%X", extended); return 1; } @@ -2270,6 +2272,7 @@ static command_t CommandTable[] = {"buffclear", CmdBuffClear, 1, "Clear sample buffer and graph window"}, {"dec", CmdDec, 1, "Decimate samples"}, {"detectclock", CmdDetectClockRate, 1, "[modulation] Detect clock rate of wave in GraphBuffer (options: 'a','f','n','p' for ask, fsk, nrz, psk respectively)"}, + {"fdxbdemod", CmdFDXBdemodBI , 1, "Demodulate a FDX-B ISO11784/85 Biphase tag from GraphBuffer"}, {"fskawiddemod", CmdFSKdemodAWID, 1, "Demodulate an AWID FSK tag from GraphBuffer"}, //{"fskfcdetect", CmdFSKfcDetect, 1, "Try to detect the Field Clock of an FSK wave"}, {"fskhiddemod", CmdFSKdemodHID, 1, "Demodulate a HID FSK tag from GraphBuffer"}, @@ -2281,7 +2284,6 @@ static command_t CommandTable[] = {"hexsamples", CmdHexsamples, 0, " [] -- Dump big buffer as hex bytes"}, {"hide", CmdHide, 1, "Hide graph window"}, {"hpf", CmdHpf, 1, "Remove DC offset from trace"}, - {"iso11784demod", CmdIso11784demodBI, 1, "Demodulate a ISO11784/85 Biphase tag from GraphBuffer"}, {"load", CmdLoad, 1, " -- Load trace (to graph window"}, {"ltrim", CmdLtrim, 1, " -- Trim samples from left of trace"}, {"rtrim", CmdRtrim, 1, " -- Trim samples from right of trace"}, diff --git a/common/lfdemod.c b/common/lfdemod.c index aa37bb9ef..f13a567c6 100644 --- a/common/lfdemod.c +++ b/common/lfdemod.c @@ -605,7 +605,7 @@ size_t removeParity(uint8_t *BitStream, size_t startIdx, uint8_t pLen, uint8_t p // Ask/Biphase Demod then try to locate an ISO 11784/85 ID // BitStream must contain previously askrawdemod and biphasedemoded data -int ISO11784demodBI(uint8_t *dest, size_t *size) +int FDXBdemodBI(uint8_t *dest, size_t *size) { //make sure buffer has enough data if (*size < 128) return -1; diff --git a/common/lfdemod.h b/common/lfdemod.h index e21bfe11a..d16aab9eb 100644 --- a/common/lfdemod.h +++ b/common/lfdemod.h @@ -41,7 +41,7 @@ void psk1TOpsk2(uint8_t *BitStream, size_t size); size_t removeParity(uint8_t *BitStream, size_t startIdx, uint8_t pLen, uint8_t pType, size_t bLen); //tag specific -int ISO11784demodBI(uint8_t *dest, size_t *size); +int FDXBdemodBI(uint8_t *dest, size_t *size); int AWIDdemodFSK(uint8_t *dest, size_t *size); int gProxII_Demod(uint8_t BitStream[], size_t *size); int HIDdemodFSK(uint8_t *dest, size_t *size, uint32_t *hi2, uint32_t *hi, uint32_t *lo); From ecfcb34cc5615d8546534ccdcba5cf9c091e98a3 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Thu, 4 Jun 2015 00:04:49 -0400 Subject: [PATCH 19/26] add fdx-b to lf search --- client/cmdlf.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/client/cmdlf.c b/client/cmdlf.c index dfbbe992a..edf029325 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -1072,6 +1072,12 @@ int CmdLFfind(const char *Cmd) return 1; } + ans=CmdFDXBdemodBI(""); + if (ans>0) { + PrintAndLog("\nValid FDX-B ID Found!"); + return 1; + } + ans=EM4x50Read("", false); if (ans>0) { PrintAndLog("\nValid EM4x50 ID Found!"); From cf4d3e21b01bcaa56addc04c0d5a5db4571158e7 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Thu, 4 Jun 2015 00:05:37 -0400 Subject: [PATCH 20/26] add fdx-b to cmddata.h --- client/cmddata.h | 1 + 1 file changed, 1 insertion(+) diff --git a/client/cmddata.h b/client/cmddata.h index c62307368..fcc51a6be 100644 --- a/client/cmddata.h +++ b/client/cmddata.h @@ -27,6 +27,7 @@ int CmdBitsamples(const char *Cmd); int CmdBuffClear(const char *Cmd); int CmdDec(const char *Cmd); int CmdDetectClockRate(const char *Cmd); +int CmdFDXBdemodBI(const char *Cmd); int CmdFSKdemodAWID(const char *Cmd); int CmdFSKdemodHID(const char *Cmd); int CmdFSKdemodIO(const char *Cmd); From 6eaa8da9dcc7543194435f706c72272783331df7 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Thu, 4 Jun 2015 12:53:19 -0400 Subject: [PATCH 21/26] Add CCITT Kermit CRC check for FDX-B demod --- client/cmddata.c | 16 ++++++++++--- common/crc16.c | 60 +++++++++++++++++++++++++++++------------------- common/crc16.h | 1 + 3 files changed, 51 insertions(+), 26 deletions(-) diff --git a/client/cmddata.c b/client/cmddata.c index dad0a7119..00caefd98 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -23,6 +23,7 @@ #include "lfdemod.h" #include "usb_cmd.h" #include "crc.h" +#include "crc16.h" uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN]; uint8_t g_debugMode; @@ -1501,9 +1502,10 @@ int CmdFDXBdemodBI(const char *Cmd){ if (g_debugMode) { char *bin = sprint_bin_break(BitStream,size,16); PrintAndLog("DEBUG BinStream:\n%s",bin); + PrintAndLog("0x%s", sprint_hex(BitStream,16)); } PrintAndLog("\nFDX-B / ISO 11784/5 Animal Tag ID Found:"); - if (g_debugMode) PrintAndLog("startmarker %d; Size %d", preambleIndex, size); + if (g_debugMode) PrintAndLog("Start marker %d; Size %d", preambleIndex, size); //return 1; //got a good demod @@ -1515,14 +1517,22 @@ int CmdFDXBdemodBI(const char *Cmd){ uint32_t crc16 = bytebits_to_byteLSBF(BitStream+64,16); uint32_t extended = bytebits_to_byteLSBF(BitStream+80,24); + uint64_t rawid = ((uint64_t)bytebits_to_byteLSBF(BitStream,32)<<32) | bytebits_to_byteLSBF(BitStream+32,32); + uint8_t raw[8]; + num_to_bytes(rawid, 8, raw); + uint8_t *ID = SwapEndian64(raw, 8, 4); + + if (g_debugMode) PrintAndLog("Raw ID Hex: %s", sprint_hex(ID,8)); + + uint16_t calcCrc = crc16_ccitt_kermit(ID, 8); PrintAndLog("Animal ID: %u-%012llu", countryCode, NationalCode); PrintAndLog("National Code: %012llu", NationalCode); PrintAndLog("CountryCode: %u", countryCode); PrintAndLog("Extended Data: %s", dataBlockBit ? "True" : "False"); PrintAndLog("reserved Code: %u", reservedCode); PrintAndLog("Animal Tag: %s", animalBit ? "True" : "False"); - PrintAndLog("CRC: 0x%02X", crc16); - PrintAndLog("Extended: 0x%X", extended); + PrintAndLog("CRC: 0x%04X - [%04X] - %s", crc16, calcCrc, (calcCrc == crc16) ? "Passed" : "Failed"); + PrintAndLog("Extended: 0x%X\n", extended); return 1; } diff --git a/common/crc16.c b/common/crc16.c index 973cd103c..d48df3b2c 100644 --- a/common/crc16.c +++ b/common/crc16.c @@ -11,35 +11,49 @@ unsigned short update_crc16( unsigned short crc, unsigned char c ) { - unsigned short i, v, tcrc = 0; + unsigned short i, v, tcrc = 0; - v = (crc ^ c) & 0xff; - for (i = 0; i < 8; i++) { - tcrc = ( (tcrc ^ v) & 1 ) ? ( tcrc >> 1 ) ^ 0x8408 : tcrc >> 1; - v >>= 1; - } + v = (crc ^ c) & 0xff; + for (i = 0; i < 8; i++) { + tcrc = ( (tcrc ^ v) & 1 ) ? ( tcrc >> 1 ) ^ 0x8408 : tcrc >> 1; + v >>= 1; + } - return ((crc >> 8) ^ tcrc)&0xffff; + return ((crc >> 8) ^ tcrc)&0xffff; } uint16_t crc16(uint8_t const *message, int length, uint16_t remainder, uint16_t polynomial) { - - if (length == 0) - return (~remainder); - - for (int byte = 0; byte < length; ++byte) { - remainder ^= (message[byte] << 8); - for (uint8_t bit = 8; bit > 0; --bit) { - if (remainder & 0x8000) { - remainder = (remainder << 1) ^ polynomial; - } else { - remainder = (remainder << 1); - } - } - } - return remainder; + + if (length == 0) return (~remainder); + + for (int byte = 0; byte < length; ++byte) { + remainder ^= (message[byte] << 8); + for (uint8_t bit = 8; bit > 0; --bit) { + if (remainder & 0x8000) { + remainder = (remainder << 1) ^ polynomial; + } else { + remainder = (remainder << 1); + } + } + } + return remainder; } uint16_t crc16_ccitt(uint8_t const *message, int length) { - return crc16(message, length, 0xffff, 0x1021); + return crc16(message, length, 0xffff, 0x1021); +} + +uint16_t crc16_ccitt_kermit(uint8_t const *message, int length) { + if (length == 0) return 0; + uint32_t crc = 0, q = 0; + uint8_t c; + + for (int i = 0; i < length; i++){ + c = message[i]; + q = (crc ^ c ) & 0xF; + crc = (crc >> 4) ^ (q * 0x1081); + q = (crc ^ (c >> 4)) & 0xF; + crc = (crc >> 4) ^ (q * 0x1081); + } + return crc; } diff --git a/common/crc16.h b/common/crc16.h index d16d83b5a..3656ce278 100644 --- a/common/crc16.h +++ b/common/crc16.h @@ -12,4 +12,5 @@ unsigned short update_crc16(unsigned short crc, unsigned char c); uint16_t crc16(uint8_t const *message, int length, uint16_t remainder, uint16_t polynomial); uint16_t crc16_ccitt(uint8_t const *message, int length); +uint16_t crc16_ccitt_kermit(uint8_t const *message, int length); #endif From c2c7f6c271b33c6d95aa47f339fe6d47c433d8d5 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Thu, 4 Jun 2015 13:10:33 -0400 Subject: [PATCH 22/26] fdx-b clean up --- client/cmddata.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/client/cmddata.c b/client/cmddata.c index 00caefd98..e85b3a6cc 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -1475,7 +1475,7 @@ int CmdFDXBdemodBI(const char *Cmd){ errCnt = askdemod(BitStream, &size, &clk, &invert, maxErr, 0, 0); if ( errCnt < 0 || errCnt > maxErr ) { - if (g_debugMode) PrintAndLog("DEBUG: no data or error found %d, clock: 32", errCnt); + if (g_debugMode) PrintAndLog("DEBUG: no data or error found %d, clock: %d", errCnt, clk); return 0; } @@ -1492,8 +1492,8 @@ int CmdFDXBdemodBI(const char *Cmd){ } setDemodBuf(BitStream, 128, preambleIndex); - //printDemodBuff(); + // remove but don't verify parity. (pType = 2) size = removeParity(BitStream, preambleIndex + 11, 9, 2, 117); if ( size <= 103 ) { if (g_debugMode) PrintAndLog("Error removeParity:: %d", size); @@ -1502,12 +1502,10 @@ int CmdFDXBdemodBI(const char *Cmd){ if (g_debugMode) { char *bin = sprint_bin_break(BitStream,size,16); PrintAndLog("DEBUG BinStream:\n%s",bin); - PrintAndLog("0x%s", sprint_hex(BitStream,16)); } PrintAndLog("\nFDX-B / ISO 11784/5 Animal Tag ID Found:"); if (g_debugMode) PrintAndLog("Start marker %d; Size %d", preambleIndex, size); - //return 1; //got a good demod uint64_t NationalCode = ((uint64_t)(bytebits_to_byteLSBF(BitStream+32,6)) << 32) | bytebits_to_byteLSBF(BitStream,32); uint32_t countryCode = bytebits_to_byteLSBF(BitStream+38,10); @@ -1520,14 +1518,14 @@ int CmdFDXBdemodBI(const char *Cmd){ uint64_t rawid = ((uint64_t)bytebits_to_byteLSBF(BitStream,32)<<32) | bytebits_to_byteLSBF(BitStream+32,32); uint8_t raw[8]; num_to_bytes(rawid, 8, raw); - uint8_t *ID = SwapEndian64(raw, 8, 4); + uint8_t *raw_ptr = SwapEndian64(raw, 8, 4); - if (g_debugMode) PrintAndLog("Raw ID Hex: %s", sprint_hex(ID,8)); + if (g_debugMode) PrintAndLog("Raw ID Hex: %s", sprint_hex(raw_ptr,8)); - uint16_t calcCrc = crc16_ccitt_kermit(ID, 8); - PrintAndLog("Animal ID: %u-%012llu", countryCode, NationalCode); + uint16_t calcCrc = crc16_ccitt_kermit(raw_ptr, 8); + PrintAndLog("Animal ID: %04u-%012llu", countryCode, NationalCode); PrintAndLog("National Code: %012llu", NationalCode); - PrintAndLog("CountryCode: %u", countryCode); + PrintAndLog("CountryCode: %04u", countryCode); PrintAndLog("Extended Data: %s", dataBlockBit ? "True" : "False"); PrintAndLog("reserved Code: %u", reservedCode); PrintAndLog("Animal Tag: %s", animalBit ? "True" : "False"); From 07b5a3c3ba774ec93007827cf1233b4edb699bad Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Fri, 5 Jun 2015 22:39:56 -0400 Subject: [PATCH 23/26] Modified kermit crc to use existing crc calc code --- client/cmddata.c | 7 +++---- common/crc16.c | 28 +++++++++++++++------------- common/crc16.h | 1 + 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/client/cmddata.c b/client/cmddata.c index e85b3a6cc..cf105f88b 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -1515,14 +1515,13 @@ int CmdFDXBdemodBI(const char *Cmd){ uint32_t crc16 = bytebits_to_byteLSBF(BitStream+64,16); uint32_t extended = bytebits_to_byteLSBF(BitStream+80,24); - uint64_t rawid = ((uint64_t)bytebits_to_byteLSBF(BitStream,32)<<32) | bytebits_to_byteLSBF(BitStream+32,32); + uint64_t rawid = ((uint64_t)bytebits_to_byte(BitStream,32)<<32) | bytebits_to_byte(BitStream+32,32); uint8_t raw[8]; num_to_bytes(rawid, 8, raw); - uint8_t *raw_ptr = SwapEndian64(raw, 8, 4); - if (g_debugMode) PrintAndLog("Raw ID Hex: %s", sprint_hex(raw_ptr,8)); + if (g_debugMode) PrintAndLog("Raw ID Hex: %s", sprint_hex(raw,8)); - uint16_t calcCrc = crc16_ccitt_kermit(raw_ptr, 8); + uint16_t calcCrc = crc16_ccitt_kermit(raw, 8); PrintAndLog("Animal ID: %04u-%012llu", countryCode, NationalCode); PrintAndLog("National Code: %012llu", NationalCode); PrintAndLog("CountryCode: %04u", countryCode); diff --git a/common/crc16.c b/common/crc16.c index d48df3b2c..a37f1d7e3 100644 --- a/common/crc16.c +++ b/common/crc16.c @@ -8,7 +8,6 @@ #include "crc16.h" - unsigned short update_crc16( unsigned short crc, unsigned char c ) { unsigned short i, v, tcrc = 0; @@ -44,16 +43,19 @@ uint16_t crc16_ccitt(uint8_t const *message, int length) { } uint16_t crc16_ccitt_kermit(uint8_t const *message, int length) { - if (length == 0) return 0; - uint32_t crc = 0, q = 0; - uint8_t c; - - for (int i = 0; i < length; i++){ - c = message[i]; - q = (crc ^ c ) & 0xF; - crc = (crc >> 4) ^ (q * 0x1081); - q = (crc ^ (c >> 4)) & 0xF; - crc = (crc >> 4) ^ (q * 0x1081); - } - return crc; + return bit_reverse_uint16(crc16(message, length, 0x0000, 0x1021)); +} + +uint16_t bit_reverse_uint16 (uint16_t value) { + const uint16_t mask0 = 0x5555; + const uint16_t mask1 = 0x3333; + const uint16_t mask2 = 0x0F0F; + const uint16_t mask3 = 0x00FF; + + value = (((~mask0) & value) >> 1) | ((mask0 & value) << 1); + value = (((~mask1) & value) >> 2) | ((mask1 & value) << 2); + value = (((~mask2) & value) >> 4) | ((mask2 & value) << 4); + value = (((~mask3) & value) >> 8) | ((mask3 & value) << 8); + + return value; } diff --git a/common/crc16.h b/common/crc16.h index 3656ce278..8eb4befbc 100644 --- a/common/crc16.h +++ b/common/crc16.h @@ -13,4 +13,5 @@ unsigned short update_crc16(unsigned short crc, unsigned char c); uint16_t crc16(uint8_t const *message, int length, uint16_t remainder, uint16_t polynomial); uint16_t crc16_ccitt(uint8_t const *message, int length); uint16_t crc16_ccitt_kermit(uint8_t const *message, int length); +uint16_t bit_reverse_uint16 (uint16_t value); #endif From 8e2e6c8eb0b762bba6e7cad2d257a219a51390ae Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Sun, 7 Jun 2015 00:42:57 -0400 Subject: [PATCH 24/26] add clock to ask rawdemod outputs fix biphase invert bug (correctly) --- client/cmddata.c | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/client/cmddata.c b/client/cmddata.c index cf105f88b..976dc0846 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -41,7 +41,7 @@ void setDemodBuf(uint8_t *buff, size_t size, size_t startIdx) size = MAX_DEMOD_BUF_LEN; size_t i = 0; -for (; i < size; i++){ + for (; i < size; i++){ DemodBuffer[i]=buff[startIdx++]; } DemodBufferLen=size; @@ -344,8 +344,8 @@ int ASKDemod(const char *Cmd, bool verbose, bool emSearch, uint8_t askType) setDemodBuf(BitStream,BitLen,0); if (verbose || g_debugMode){ if (errCnt>0) PrintAndLog("# Errors during Demoding (shown as 7 in bit stream): %d",errCnt); - if (askType) PrintAndLog("ASK/Manchester decoded bitstream:"); - else PrintAndLog("ASK/Raw decoded bitstream:"); + if (askType) PrintAndLog("ASK/Manchester - Clock: %d - Decoded bitstream:",clk); + else PrintAndLog("ASK/Raw - Clock: %d - Decoded bitstream:",clk); // Now output the bitstream to the scrollback by line of 16 bits printDemodBuff(); @@ -499,21 +499,19 @@ int ASKbiphaseDemod(const char *Cmd, bool verbose) { //ask raw demod GraphBuffer first int offset=0, clk=0, invert=0, maxErr=0, ans=0; - ans = sscanf(Cmd, "%i %i 0 %i", &offset, &clk, &maxErr); - if (ans>0) - ans = ASKDemod(Cmd+2, FALSE, FALSE, 0); - else - ans = ASKDemod(Cmd, FALSE, FALSE, 0); - if (!ans) { - if (g_debugMode || verbose) PrintAndLog("Error AskDemod: %d", ans); - return 0; - } + ans = sscanf(Cmd, "%i %i %i %i", &offset, &clk, &invert, &maxErr); - //attempt to Biphase decode DemodBuffer - size_t size = DemodBufferLen; - uint8_t BitStream[MAX_DEMOD_BUF_LEN]; - memcpy(BitStream, DemodBuffer, DemodBufferLen); - int errCnt = BiphaseRawDecode(BitStream, &size, offset, invert); + uint8_t BitStream[MAX_DEMOD_BUF_LEN]; + size_t size = getFromGraphBuf(BitStream); + + int errCnt = askdemod(BitStream, &size, &clk, 0, maxErr, 0, 0); + if ( errCnt < 0 || errCnt > maxErr ) { + if (g_debugMode) PrintAndLog("DEBUG: no data or error found %d, clock: %d", errCnt, clk); + return 0; + } + + //attempt to Biphase decode BitStream + errCnt = BiphaseRawDecode(BitStream, &size, offset, invert); if (errCnt < 0){ if (g_debugMode || verbose) PrintAndLog("Error BiphaseRawDecode: %d", errCnt); return 0; @@ -525,7 +523,7 @@ int ASKbiphaseDemod(const char *Cmd, bool verbose) //success set DemodBuffer and return setDemodBuf(BitStream, size, 0); if (g_debugMode || verbose){ - PrintAndLog("Biphase Decoded using offset: %d - # errors:%d - data:",offset,errCnt); + PrintAndLog("Biphase Decoded using offset: %d - clock: %d - # errors:%d - data:",offset,clk,errCnt); printDemodBuff(); } return 1; From c7d672129049e1dd274a8c24174c6035bcdb5964 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Sun, 14 Jun 2015 10:54:55 -0400 Subject: [PATCH 25/26] bug fix. askdemod edits invert pointer, cannot be 0 --- client/cmddata.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/client/cmddata.c b/client/cmddata.c index 976dc0846..77959cf3c 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -498,13 +498,12 @@ int CmdBiphaseDecodeRaw(const char *Cmd) int ASKbiphaseDemod(const char *Cmd, bool verbose) { //ask raw demod GraphBuffer first - int offset=0, clk=0, invert=0, maxErr=0, ans=0; - ans = sscanf(Cmd, "%i %i %i %i", &offset, &clk, &invert, &maxErr); + int offset=0, clk=0, invert=0, maxErr=0; + sscanf(Cmd, "%i %i %i %i", &offset, &clk, &invert, &maxErr); uint8_t BitStream[MAX_DEMOD_BUF_LEN]; size_t size = getFromGraphBuf(BitStream); - - int errCnt = askdemod(BitStream, &size, &clk, 0, maxErr, 0, 0); + int errCnt = askdemod(BitStream, &size, &clk, &invert, maxErr, 0, 0); if ( errCnt < 0 || errCnt > maxErr ) { if (g_debugMode) PrintAndLog("DEBUG: no data or error found %d, clock: %d", errCnt, clk); return 0; From fd227f4e7d7967ce06a2ef90828aa13159a80d98 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Sun, 14 Jun 2015 11:11:00 -0400 Subject: [PATCH 26/26] add comment --- client/cmddata.c | 1 + 1 file changed, 1 insertion(+) diff --git a/client/cmddata.c b/client/cmddata.c index 77959cf3c..309044e10 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -503,6 +503,7 @@ int ASKbiphaseDemod(const char *Cmd, bool verbose) uint8_t BitStream[MAX_DEMOD_BUF_LEN]; size_t size = getFromGraphBuf(BitStream); + //invert here inverts the ask raw demoded bits which has no effect on the demod, but we need the pointer int errCnt = askdemod(BitStream, &size, &clk, &invert, maxErr, 0, 0); if ( errCnt < 0 || errCnt > maxErr ) { if (g_debugMode) PrintAndLog("DEBUG: no data or error found %d, clock: %d", errCnt, clk);