From: iceman1001 Date: Fri, 6 Mar 2015 08:02:15 +0000 (+0100) Subject: Merge branch 'master' of https://github.com/Proxmark/proxmark3 X-Git-Url: http://cvs.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/commitdiff_plain/3ac59c7fed24cc69e2c9f626e5e4392769779e13?ds=inline;hp=-c Merge branch 'master' of https://github.com/Proxmark/proxmark3 Conflicts: armsrc/crapto1.c armsrc/iclass.c client/nonce2key/crapto1.c --- 3ac59c7fed24cc69e2c9f626e5e4392769779e13 diff --combined armsrc/Makefile index be4351d8,75ccdece..35742316 --- a/armsrc/Makefile +++ b/armsrc/Makefile @@@ -43,10 -43,8 +43,9 @@@ ARMSRC = fpgaloader.c legic_prng.c \ iclass.c \ BigBuf.c \ - cipher.c \ - cipherutils.c\ + optimized_cipher.c + # stdint.h provided locally until GCC 4.5 becomes C99 compliant APP_CFLAGS += -I. diff --combined armsrc/crapto1.c index c0a7fc32,bcd31171..2fdeb924 --- a/armsrc/crapto1.c +++ b/armsrc/crapto1.c @@@ -1,21 -1,21 +1,21 @@@ /* crapto1.c - 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, US$ - - Copyright (C) 2008-2008 bla + 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, US$ + + Copyright (C) 2008-2008 bla */ #include "crapto1.h" #include @@@ -24,9 -24,9 +24,9 @@@ static uint8_t filterlut[1 << 20]; static void __attribute__((constructor)) fill_lut() { - uint32_t i; - for(i = 0; i < 1 << 20; ++i) - filterlut[i] = filter(i); + uint32_t i; + for(i = 0; i < 1 << 20; ++i) + filterlut[i] = filter(i); } #define filter(x) (filterlut[(x) & 0xfffff]) #endif @@@ -34,6 -34,7 +34,7 @@@ static void quicksort(uint32_t* const start, uint32_t* const stop) { uint32_t *it = start + 1, *rit = stop; + uint32_t tmp; if(it > rit) return; @@@ -43,13 -44,19 +44,19 @@@ ++it; else if(*rit > *start) --rit; - else - *it ^= ( (*it ^= *rit ), *rit ^= *it); + else { + tmp = *it; + *it = *rit; + *rit = tmp; + } if(*rit >= *start) --rit; - if(rit != start) - *rit ^= ( (*rit ^= *start), *start ^= *rit); + if(rit != start) { + tmp = *rit; + *rit = *start; + *start = tmp; + } quicksort(start, rit - 1); quicksort(rit + 1, stop); @@@ -145,12 -152,12 +152,12 @@@ recover(uint32_t *o_head, uint32_t *o_t eks >>= 1; in >>= 2; extend_table(o_head, &o_tail, oks & 1, LF_POLY_EVEN << 1 | 1, - LF_POLY_ODD << 1, 0); + LF_POLY_ODD << 1, 0); if(o_head > o_tail) return sl; extend_table(e_head, &e_tail, eks & 1, LF_POLY_ODD, - LF_POLY_EVEN << 1 | 1, in & 3); + LF_POLY_EVEN << 1 | 1, in & 3); if(e_head > e_tail) return sl; } @@@ -163,7 -170,7 +170,7 @@@ o_tail = binsearch(o_head, o = o_tail); e_tail = binsearch(e_head, e = e_tail); sl = recover(o_tail--, o, oks, - e_tail--, e, eks, rem, sl, in); + e_tail--, e, eks, rem, sl, in); } else if(*o_tail > *e_tail) o_tail = binsearch(o_head, o_tail) - 1; @@@ -319,9 -326,12 +326,12 @@@ uint8_t lfsr_rollback_bit(struct Crypto { int out; uint8_t ret; + uint32_t tmp; s->odd &= 0xffffff; - s->odd ^= (s->odd ^= s->even, s->even ^= s->odd); + tmp = s->odd; + s->odd = s->even; + s->even = tmp; out = s->even & 1; out ^= LF_POLY_EVEN & (s->even >>= 1); @@@ -414,7 -424,7 +424,7 @@@ uint32_t *lfsr_prefix_ks(uint8_t ks[8] */ static struct Crypto1State* check_pfx_parity(uint32_t prefix, uint32_t rresp, uint8_t parities[8][8], - uint32_t odd, uint32_t even, struct Crypto1State* sl) + uint32_t odd, uint32_t even, struct Crypto1State* sl) { uint32_t ks1, nr, ks2, rr, ks3, c, good = 1; @@@ -440,7 -450,7 +450,7 @@@ } return sl + good; - } + } /** lfsr_common_prefix @@@ -454,12 -464,12 +464,12 @@@ lfsr_common_prefix(uint32_t pfx, uint32 odd = lfsr_prefix_ks(ks, 1); even = lfsr_prefix_ks(ks, 0); - + s = statelist = malloc((sizeof *statelist) << 20); if(!s || !odd || !even) { free(statelist); statelist = 0; - goto out; + goto out; } for(o = odd; *o + 1; ++o) diff --combined armsrc/iclass.c index def6cc97,260e6a60..f62d45de --- a/armsrc/iclass.c +++ b/armsrc/iclass.c @@@ -36,7 -36,7 +36,7 @@@ // //----------------------------------------------------------------------------- -#include "proxmark3.h" +#include "../include/proxmark3.h" #include "apps.h" #include "util.h" #include "string.h" @@@ -45,11 -45,10 +45,11 @@@ // Needed for CRC in emulation mode; // same construction as in ISO 14443; // different initial value (CRC_ICLASS) -#include "iso14443crc.h" -#include "iso15693tools.h" +#include "../common/iso14443crc.h" +#include "../common/iso15693tools.h" +//#include "iso15693tools.h" - #include "cipher.h" #include "protocols.h" + #include "optimized_cipher.h" static int timeout = 4096; @@@ -354,7 -353,7 +354,7 @@@ static struct SUB_SECOND_HALF, SUB_BOTH } sub; - uint8_t *output; + uint8_t *output; } Demod; static RAMFUNC int ManchesterDecoding(int v) @@@ -659,7 -658,7 +659,7 @@@ void RAMFUNC SnoopIClass(void clear_trace(); iso14a_set_trigger(FALSE); - int lastRxCounter; + int lastRxCounter; uint8_t *upTo; int smpl; int maxBehindBy = 0; @@@ -775,7 -774,7 +775,7 @@@ if(ManchesterDecoding(smpl & 0x0F)) { time_stop = (GetCountSspClk()-time_0) << 4; - rsamples = samples - Demod.samples; + rsamples = samples - Demod.samples; LED_B_ON(); if(tracing) { @@@ -945,7 -944,7 +945,7 @@@ static void CodeIClassTagAnswer(const u uint8_t b = cmd[i]; ToSend[++ToSendMax] = encode4Bits(b & 0xF); //Least significant half ToSend[++ToSendMax] = encode4Bits((b >>4) & 0xF);//Most significant half - } + } // Send EOF ToSend[++ToSendMax] = 0xB8; @@@ -1043,6 -1042,10 +1043,10 @@@ void SimulateIClass(uint32_t arg0, uint Dbprintf("Done..."); } + void AppendCrc(uint8_t* data, int len) + { + ComputeCrc14443(CRC_ICLASS,data,len,data+len,data+len+1); + } /** * @brief Does the actual simulation @@@ -1054,6 -1057,8 +1058,8 @@@ int doIClassSimulation( int simulationM // free eventually allocated BigBuf memory BigBuf_free_keep_EM(); + State cipher_state; + // State cipher_state_reserve; uint8_t *csn = BigBuf_get_EM_addr(); uint8_t *emulator = csn; uint8_t sof_data[] = { 0x0F} ; @@@ -1070,12 -1075,20 +1076,20 @@@ ComputeCrc14443(CRC_ICLASS, anticoll_data, 8, &anticoll_data[8], &anticoll_data[9]); ComputeCrc14443(CRC_ICLASS, csn_data, 8, &csn_data[8], &csn_data[9]); + uint8_t diversified_key[8] = { 0 }; // e-Purse uint8_t card_challenge_data[8] = { 0x00 }; if(simulationMode == MODE_FULLSIM) { + //The diversified key should be stored on block 3 + //Get the diversified key from emulator memory + memcpy(diversified_key, emulator+(8*3),8); + //Card challenge, a.k.a e-purse is on block 2 memcpy(card_challenge_data,emulator + (8 * 2) , 8); + //Precalculate the cipher state, feeding it the CC + cipher_state = opt_doTagMAC_1(card_challenge_data,diversified_key); + } int exitLoop = 0; @@@ -1087,7 -1100,7 +1101,7 @@@ // Tag CSN uint8_t *modulated_response; - int modulated_response_size; + int modulated_response_size = 0; uint8_t* trace_data = NULL; int trace_data_size = 0; @@@ -1134,8 -1147,12 +1148,12 @@@ CodeIClassTagAnswer(card_challenge_data, sizeof(card_challenge_data)); memcpy(resp_cc, ToSend, ToSendMax); resp_cc_len = ToSendMax; - //This is used for responding to READ-block commands - uint8_t *data_response = BigBuf_malloc(8 * 2 + 2); + //This is used for responding to READ-block commands or other data which is dynamically generated + //First the 'trace'-data, not encoded for FPGA + uint8_t *data_generic_trace = BigBuf_malloc(8 + 2);//8 bytes data + 2byte CRC is max tag answer + //Then storage for the modulated data + //Each bit is doubled when modulated for FPGA, and we also have SOF and EOF (2 bytes) + uint8_t *data_response = BigBuf_malloc( (8+2) * 2 + 2); // Start from off (no field generated) //FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); @@@ -1155,9 -1172,9 +1173,9 @@@ LED_A_ON(); bool buttonPressed = false; - + uint8_t response_delay = 1; while(!exitLoop) { - + response_delay = 1; LED_B_OFF(); //Signal tracer // Can be used to get a trigger for an oscilloscope.. @@@ -1199,45 -1216,38 +1217,38 @@@ } else if(receivedCmd[0] == ICLASS_CMD_CHECK) { // Reader random and reader MAC!!! if(simulationMode == MODE_FULLSIM) - { //This is what we must do.. - //Reader just sent us NR and MAC(k,cc * nr) - //The diversified key should be stored on block 3 - //However, from a typical dump, the key will not be there - uint8_t *diversified_key = { 0 }; - //Get the diversified key from emulator memory - memcpy(diversified_key, emulator+(8*3),8); - uint8_t ccnr[12] = { 0 }; - //Put our cc there (block 2) - memcpy(ccnr, emulator + (8 * 2), 8); - //Put nr there - memcpy(ccnr+8, receivedCmd+1,4); - //Now, calc MAC - doMAC(ccnr,diversified_key, trace_data); + { + //NR, from reader, is in receivedCmd +1 + opt_doTagMAC_2(cipher_state,receivedCmd+1,data_generic_trace,diversified_key); + + trace_data = data_generic_trace; trace_data_size = 4; CodeIClassTagAnswer(trace_data , trace_data_size); memcpy(data_response, ToSend, ToSendMax); modulated_response = data_response; modulated_response_size = ToSendMax; + response_delay = 0;//We need to hurry here... + //exitLoop = true; }else { //Not fullsim, we don't respond - // We do not know what to answer, so lets keep quiet + // We do not know what to answer, so lets keep quiet modulated_response = resp_sof; modulated_response_size = 0; - trace_data = NULL; - trace_data_size = 0; + trace_data = NULL; + trace_data_size = 0; if (simulationMode == MODE_EXIT_AFTER_MAC){ - // dbprintf:ing ... - Dbprintf("CSN: %02x %02x %02x %02x %02x %02x %02x %02x" - ,csn[0],csn[1],csn[2],csn[3],csn[4],csn[5],csn[6],csn[7]); - Dbprintf("RDR: (len=%02d): %02x %02x %02x %02x %02x %02x %02x %02x %02x",len, - receivedCmd[0], receivedCmd[1], receivedCmd[2], - receivedCmd[3], receivedCmd[4], receivedCmd[5], - receivedCmd[6], receivedCmd[7], receivedCmd[8]); - if (reader_mac_buf != NULL) - { - memcpy(reader_mac_buf,receivedCmd+1,8); - } - exitLoop = true; + // dbprintf:ing ... + Dbprintf("CSN: %02x %02x %02x %02x %02x %02x %02x %02x" + ,csn[0],csn[1],csn[2],csn[3],csn[4],csn[5],csn[6],csn[7]); + Dbprintf("RDR: (len=%02d): %02x %02x %02x %02x %02x %02x %02x %02x %02x",len, + receivedCmd[0], receivedCmd[1], receivedCmd[2], + receivedCmd[3], receivedCmd[4], receivedCmd[5], + receivedCmd[6], receivedCmd[7], receivedCmd[8]); + if (reader_mac_buf != NULL) + { + memcpy(reader_mac_buf,receivedCmd+1,8); } + exitLoop = true; + } } } else if(receivedCmd[0] == ICLASS_CMD_HALT && len == 1) { @@@ -1248,13 -1258,40 +1259,40 @@@ } else if(simulationMode == MODE_FULLSIM && receivedCmd[0] == ICLASS_CMD_READ_OR_IDENTIFY && len == 4){ //Read block uint16_t blk = receivedCmd[1]; - trace_data = emulator+(blk << 3); - trace_data_size = 8; + //Take the data... + memcpy(data_generic_trace, emulator+(blk << 3),8); + //Add crc + AppendCrc(data_generic_trace, 8); + trace_data = data_generic_trace; + trace_data_size = 10; + CodeIClassTagAnswer(trace_data , trace_data_size); + memcpy(data_response, ToSend, ToSendMax); + modulated_response = data_response; + modulated_response_size = ToSendMax; + }else if(receivedCmd[0] == ICLASS_CMD_UPDATE && simulationMode == MODE_FULLSIM) + {//Probably the reader wants to update the nonce. Let's just ignore that for now. + // OBS! If this is implemented, don't forget to regenerate the cipher_state + //We're expected to respond with the data+crc, exactly what's already in the receivedcmd + //receivedcmd is now UPDATE 1b | ADDRESS 1b| DATA 8b| Signature 4b or CRC 2b| + + //Take the data... + memcpy(data_generic_trace, receivedCmd+2,8); + //Add crc + AppendCrc(data_generic_trace, 8); + trace_data = data_generic_trace; + trace_data_size = 10; CodeIClassTagAnswer(trace_data , trace_data_size); memcpy(data_response, ToSend, ToSendMax); modulated_response = data_response; modulated_response_size = ToSendMax; } + else if(receivedCmd[0] == ICLASS_CMD_PAGESEL) + {//Pagesel + //Pagesel enables to select a page in the selected chip memory and return its configuration block + //Chips with a single page will not answer to this command + // It appears we're fine ignoring this. + //Otherwise, we should answer 8bytes (block) + 2bytes CRC + } else { //#db# Unknown command received from reader (len=5): 26 1 0 f6 a 44 44 44 44 // Never seen this command before @@@ -1280,7 -1317,7 +1318,7 @@@ A legit tag has about 380us delay between reader EOT and tag SOF. **/ if(modulated_response_size > 0) { - SendIClassAnswer(modulated_response, modulated_response_size, 1); + SendIClassAnswer(modulated_response, modulated_response_size, response_delay); t2r_time = GetCountSspClk(); } @@@ -1367,17 -1404,17 +1405,17 @@@ static void TransmitIClassCommand(cons { if(*wait < 10) *wait = 10; - for(c = 0; c < *wait;) { - if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { - AT91C_BASE_SSC->SSC_THR = 0x00; // For exact timing! - c++; - } - if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { - volatile uint32_t r = AT91C_BASE_SSC->SSC_RHR; - (void)r; - } - WDT_HIT(); - } + for(c = 0; c < *wait;) { + if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { + AT91C_BASE_SSC->SSC_THR = 0x00; // For exact timing! + c++; + } + if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { + volatile uint32_t r = AT91C_BASE_SSC->SSC_RHR; + (void)r; + } + WDT_HIT(); + } } @@@ -1460,18 -1497,18 +1498,18 @@@ void CodeIClassCommand(const uint8_t * void ReaderTransmitIClass(uint8_t* frame, int len) { - int wait = 0; - int samples = 0; + int wait = 0; + int samples = 0; - // This is tied to other size changes - CodeIClassCommand(frame,len); + // This is tied to other size changes + CodeIClassCommand(frame,len); - // Select the card - TransmitIClassCommand(ToSend, ToSendMax, &samples, &wait); - if(trigger) - LED_A_ON(); + // Select the card + TransmitIClassCommand(ToSend, ToSendMax, &samples, &wait); + if(trigger) + LED_A_ON(); - // Store reader command in buffer + // Store reader command in buffer if (tracing) { uint8_t par[MAX_PARITY_SIZE]; GetParity(frame, len, par); @@@ -1507,7 -1544,7 +1545,7 @@@ static int GetIClassAnswer(uint8_t *rec for(;;) { WDT_HIT(); - if(BUTTON_PRESS()) return FALSE; + if(BUTTON_PRESS()) return FALSE; if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { AT91C_BASE_SSC->SSC_THR = 0x00; // To make use of exact timing of next command from reader!! @@@ -1672,20 -1709,20 +1710,20 @@@ void ReaderIClass(uint8_t arg0) //Then we can 'ship' back the 8 * 5 bytes of data, // with 0xFF:s in block 3 and 4. - LED_B_ON(); - //Send back to client, but don't bother if we already sent this - if(memcmp(last_csn, card_data, 8) != 0) + LED_B_ON(); + //Send back to client, but don't bother if we already sent this + if(memcmp(last_csn, card_data, 8) != 0) { if(!get_cc || (get_cc && read_status == 2)) { - cmd_send(CMD_ACK,read_status,0,0,card_data,datasize); + cmd_send(CMD_ACK,read_status,0,0,card_data,datasize); if(abort_after_read) { LED_A_OFF(); return; } - //Save that we already sent this.... - memcpy(last_csn, card_data, 8); + //Save that we already sent this.... + memcpy(last_csn, card_data, 8); } //If 'get_cc' was specified and we didn't get a CC, we'll just keep trying... } @@@ -1740,20 -1777,20 +1778,20 @@@ void ReaderIClass_Replay(uint8_t arg0, uint8_t read_status = handshakeIclassTag(card_data); if(read_status < 2) continue; - //for now replay captured auth (as cc not updated) - memcpy(check+5,MAC,4); + //for now replay captured auth (as cc not updated) + memcpy(check+5,MAC,4); if(sendCmdGetResponseWithRetries(check, sizeof(check),resp, 4, 5)) { - Dbprintf("Error: Authentication Fail!"); + Dbprintf("Error: Authentication Fail!"); continue; - } + } //first get configuration block (block 1) crc = block_crc_LUT[1]; - read[1]=1; - read[2] = crc >> 8; - read[3] = crc & 0xff; + read[1]=1; + read[2] = crc >> 8; + read[3] = crc & 0xff; if(sendCmdGetResponseWithRetries(read, sizeof(read),resp, 10, 10)) { @@@ -1761,12 -1798,12 +1799,12 @@@ continue; } - mem=resp[5]; - memory.k16= (mem & 0x80); - memory.book= (mem & 0x20); - memory.k2= (mem & 0x8); - memory.lockauth= (mem & 0x2); - memory.keyaccess= (mem & 0x1); + mem=resp[5]; + memory.k16= (mem & 0x80); + memory.book= (mem & 0x20); + memory.k2= (mem & 0x8); + memory.lockauth= (mem & 0x2); + memory.keyaccess= (mem & 0x1); cardsize = memory.k16 ? 255 : 32; WDT_HIT(); @@@ -1774,20 -1811,20 +1812,20 @@@ memset(card_data,0x0,USB_CMD_DATA_SIZE); uint8_t failedRead =0; uint32_t stored_data_length =0; - //then loop around remaining blocks + //then loop around remaining blocks for(int block=0; block < cardsize; block++){ read[1]= block; crc = block_crc_LUT[block]; - read[2] = crc >> 8; - read[3] = crc & 0xff; + read[2] = crc >> 8; + read[3] = crc & 0xff; if(!sendCmdGetResponseWithRetries(read, sizeof(read), resp, 10, 10)) { - Dbprintf(" %02x: %02x %02x %02x %02x %02x %02x %02x %02x", + Dbprintf(" %02x: %02x %02x %02x %02x %02x %02x %02x %02x", block, resp[0], resp[1], resp[2], - resp[3], resp[4], resp[5], - resp[6], resp[7]); + resp[3], resp[4], resp[5], + resp[6], resp[7]); //Fill up the buffer memcpy(card_data+stored_data_length,resp,8); @@@ -1851,7 -1888,7 +1889,7 @@@ void IClass_iso14443A_write(uint8_t arg uint8_t* resp = (((uint8_t *)BigBuf) + 3560); // Reset trace buffer - memset(trace, 0x44, RECV_CMD_OFFSET); + memset(trace, 0x44, RECV_CMD_OFFSET); traceLen = 0; // Setup SSC diff --combined armsrc/mifarecmd.c index a16cbf16,a16cbf16..94bc1c1c --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@@ -942,12 -942,12 +942,12 @@@ void MifareCSetBlock(uint32_t arg0, uin if (workFlags & 0x01) { if(!iso14443a_select_card(uid, NULL, &cuid)) { if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card"); -- break; ++ //break; }; if(mifare_classic_halt(NULL, cuid)) { if (MF_DBGLEVEL >= 1) Dbprintf("Halt error"); -- break; ++ //break; }; }; diff --combined client/cmddata.c index cfccc5b3,7b666c26..8b29dc9c --- a/client/cmddata.c +++ b/client/cmddata.c @@@ -32,12 -32,6 +32,12 @@@ static int CmdHelp(const char *Cmd) //by marshmellow void setDemodBuf(uint8_t *buff, size_t size, size_t startIdx) { + if (buff == NULL) + return; + + if ( size >= MAX_DEMOD_BUF_LEN) + size = MAX_DEMOD_BUF_LEN; + size_t i = 0; for (; i < size; i++){ DemodBuffer[i]=buff[startIdx++]; @@@ -227,7 -221,7 +227,7 @@@ void printBitStream(uint8_t BitStream[] return; } //by marshmellow --//print EM410x ID in multiple formats ++//print 64 bit EM410x ID in multiple formats void printEM410x(uint64_t id) { if (id !=0){ @@@ -317,36 -311,36 +317,19 @@@ int CmdAskEM410xDemod(const char *Cmd printDemodBuff(); } PrintAndLog("EM410x pattern found: "); ++ if (BitLen > 64) PrintAndLog("\nWarning! Length not what is expected - Length: %d bits\n",BitLen); printEM410x(lo); return 1; } return 0; } --//by marshmellow --//takes 3 arguments - clock, invert, maxErr as integers --//attempts to demodulate ask while decoding manchester --//prints binary found and saves in graphbuffer for further commands --int Cmdaskmandemod(const char *Cmd) ++int ASKmanDemod(const char *Cmd, bool verbose, bool emSearch) { int invert=0; int clk=0; int maxErr=100; -- char cmdp = param_getchar(Cmd, 0); -- if (strlen(Cmd) > 10 || cmdp == 'h' || cmdp == 'H') { -- PrintAndLog("Usage: data rawdemod am [clock] <0|1> [maxError]"); -- PrintAndLog(" [set clock as integer] optional, if not set, autodetect."); -- PrintAndLog(" , 1 for invert output"); -- PrintAndLog(" [set maximum allowed errors], default = 100."); -- PrintAndLog(""); -- PrintAndLog(" sample: data rawdemod am = demod an ask/manchester tag from GraphBuffer"); -- PrintAndLog(" : data rawdemod am 32 = demod an ask/manchester tag from GraphBuffer using a clock of RF/32"); -- PrintAndLog(" : data rawdemod am 32 1 = demod an ask/manchester tag from GraphBuffer using a clock of RF/32 and inverting data"); -- PrintAndLog(" : data rawdemod am 1 = demod an ask/manchester tag from GraphBuffer while inverting data"); -- PrintAndLog(" : data rawdemod am 64 1 0 = demod an ask/manchester tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors"); -- -- return 0; -- } ++ uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; sscanf(Cmd, "%i %i %i", &clk, &invert, &maxErr); if (invert != 0 && invert != 1) { @@@ -366,33 -360,33 +349,58 @@@ if (g_debugMode==1) PrintAndLog("no data found %d, errors:%d, bitlen:%d, clock:%d",errCnt,invert,BitLen,clk); return 0; } -- PrintAndLog("\nUsing Clock: %d - Invert: %d - Bits Found: %d",clk,invert,BitLen); ++ if (verbose) PrintAndLog("\nUsing Clock: %d - Invert: %d - Bits Found: %d",clk,invert,BitLen); //output if (errCnt>0){ -- PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt); ++ if (verbose) PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt); } -- PrintAndLog("ASK/Manchester decoded bitstream:"); ++ if (verbose) PrintAndLog("ASK/Manchester decoded bitstream:"); // Now output the bitstream to the scrollback by line of 16 bits setDemodBuf(BitStream,BitLen,0); -- printDemodBuff(); ++ if (verbose) printDemodBuff(); uint64_t lo =0; size_t idx=0; -- lo = Em410xDecode(BitStream, &BitLen, &idx); -- if (lo>0){ -- //set GraphBuffer for clone or sim command -- setDemodBuf(BitStream, BitLen, idx); -- if (g_debugMode){ -- PrintAndLog("DEBUG: idx: %d, Len: %d, Printing Demod Buffer:", idx, BitLen); -- printDemodBuff(); ++ if (emSearch){ ++ lo = Em410xDecode(BitStream, &BitLen, &idx); ++ if (lo>0){ ++ //set GraphBuffer for clone or sim command ++ setDemodBuf(BitStream, BitLen, idx); ++ if (g_debugMode){ ++ PrintAndLog("DEBUG: idx: %d, Len: %d, Printing Demod Buffer:", idx, BitLen); ++ printDemodBuff(); ++ } ++ if (verbose) PrintAndLog("EM410x pattern found: "); ++ if (verbose) printEM410x(lo); ++ return 1; } -- PrintAndLog("EM410x pattern found: "); -- printEM410x(lo); -- return 1; } return 1; } ++//by marshmellow ++//takes 3 arguments - clock, invert, maxErr as integers ++//attempts to demodulate ask while decoding manchester ++//prints binary found and saves in graphbuffer for further commands ++int Cmdaskmandemod(const char *Cmd) ++{ ++ char cmdp = param_getchar(Cmd, 0); ++ if (strlen(Cmd) > 10 || cmdp == 'h' || cmdp == 'H') { ++ PrintAndLog("Usage: data rawdemod am [clock] <0|1> [maxError]"); ++ PrintAndLog(" [set clock as integer] optional, if not set, autodetect."); ++ PrintAndLog(" , 1 for invert output"); ++ PrintAndLog(" [set maximum allowed errors], default = 100."); ++ PrintAndLog(""); ++ PrintAndLog(" sample: data rawdemod am = demod an ask/manchester tag from GraphBuffer"); ++ PrintAndLog(" : data rawdemod am 32 = demod an ask/manchester tag from GraphBuffer using a clock of RF/32"); ++ PrintAndLog(" : data rawdemod am 32 1 = demod an ask/manchester tag from GraphBuffer using a clock of RF/32 and inverting data"); ++ PrintAndLog(" : data rawdemod am 1 = demod an ask/manchester tag from GraphBuffer while inverting data"); ++ PrintAndLog(" : data rawdemod am 64 1 0 = demod an ask/manchester tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors"); ++ return 0; ++ } ++ return ASKmanDemod(Cmd, TRUE, TRUE); ++} ++ //by marshmellow //manchester decode //stricktly take 10 and 01 and convert to 0 and 1 @@@ -505,34 -499,34 +513,17 @@@ int CmdBiphaseDecodeRaw(const char *Cmd //takes 4 arguments - clock, invert, maxErr as integers and amplify as char //attempts to demodulate ask only //prints binary found and saves in graphbuffer for further commands --int Cmdaskrawdemod(const char *Cmd) ++int ASKrawDemod(const char *Cmd, bool verbose) { int invert=0; int clk=0; int maxErr=100; uint8_t askAmp = 0; char amp = param_getchar(Cmd, 0); -- char cmdp = param_getchar(Cmd, 0); -- if (strlen(Cmd) > 12 || cmdp == 'h' || cmdp == 'H') { -- PrintAndLog("Usage: data rawdemod ar [clock] [maxError] [amplify]"); -- PrintAndLog(" [set clock as integer] optional, if not set, autodetect"); -- PrintAndLog(" , 1 to invert output"); -- PrintAndLog(" [set maximum allowed errors], default = 100"); -- PrintAndLog(" , 'a' to attempt demod with ask amplification, default = no amp"); -- PrintAndLog(""); -- PrintAndLog(" sample: data rawdemod ar = demod an ask tag from GraphBuffer"); -- PrintAndLog(" : data rawdemod ar a = demod an ask tag from GraphBuffer, amplified"); -- PrintAndLog(" : data rawdemod ar 32 = demod an ask tag from GraphBuffer using a clock of RF/32"); -- PrintAndLog(" : data rawdemod ar 32 1 = demod an ask tag from GraphBuffer using a clock of RF/32 and inverting data"); -- PrintAndLog(" : data rawdemod ar 1 = demod an ask tag from GraphBuffer while inverting data"); -- PrintAndLog(" : data rawdemod ar 64 1 0 = demod an ask tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors"); -- PrintAndLog(" : data rawdemod ar 64 1 0 a = demod an ask tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors, and amp"); -- return 0; -- } uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; sscanf(Cmd, "%i %i %i %c", &clk, &invert, &maxErr, &); if (invert != 0 && invert != 1) { -- PrintAndLog("Invalid argument: %s", Cmd); ++ if (verbose) PrintAndLog("Invalid argument: %s", Cmd); return 0; } if (clk==1){ @@@ -545,26 -539,26 +536,50 @@@ int errCnt=0; errCnt = askrawdemod(BitStream, &BitLen, &clk, &invert, maxErr, askAmp); if (errCnt==-1||BitLen<16){ //throw away static - allow 1 and -1 (in case of threshold command first) -- PrintAndLog("no data found"); -- if (g_debugMode==1) PrintAndLog("errCnt: %d, BitLen: %d, clk: %d, invert: %d", errCnt, BitLen, clk, invert); ++ if (verbose) PrintAndLog("no data found"); ++ if (g_debugMode==1 && verbose) PrintAndLog("errCnt: %d, BitLen: %d, clk: %d, invert: %d", errCnt, BitLen, clk, invert); return 0; } -- PrintAndLog("Using Clock: %d - invert: %d - Bits Found: %d", clk, invert, BitLen); ++ if (verbose) PrintAndLog("Using Clock: %d - invert: %d - Bits Found: %d", clk, invert, BitLen); //move BitStream back to DemodBuffer setDemodBuf(BitStream,BitLen,0); //output -- if (errCnt>0){ ++ if (errCnt>0 && verbose){ PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d", errCnt); } -- PrintAndLog("ASK demoded bitstream:"); -- // Now output the bitstream to the scrollback by line of 16 bits -- printBitStream(BitStream,BitLen); -- ++ if (verbose){ ++ PrintAndLog("ASK demoded bitstream:"); ++ // Now output the bitstream to the scrollback by line of 16 bits ++ printBitStream(BitStream,BitLen); ++ } return 1; } ++//by marshmellow - see ASKrawDemod ++int Cmdaskrawdemod(const char *Cmd) ++{ ++ char cmdp = param_getchar(Cmd, 0); ++ if (strlen(Cmd) > 12 || cmdp == 'h' || cmdp == 'H') { ++ PrintAndLog("Usage: data rawdemod ar [clock] [maxError] [amplify]"); ++ PrintAndLog(" [set clock as integer] optional, if not set, autodetect"); ++ PrintAndLog(" , 1 to invert output"); ++ PrintAndLog(" [set maximum allowed errors], default = 100"); ++ PrintAndLog(" , 'a' to attempt demod with ask amplification, default = no amp"); ++ PrintAndLog(""); ++ PrintAndLog(" sample: data rawdemod ar = demod an ask tag from GraphBuffer"); ++ PrintAndLog(" : data rawdemod ar a = demod an ask tag from GraphBuffer, amplified"); ++ PrintAndLog(" : data rawdemod ar 32 = demod an ask tag from GraphBuffer using a clock of RF/32"); ++ PrintAndLog(" : data rawdemod ar 32 1 = demod an ask tag from GraphBuffer using a clock of RF/32 and inverting data"); ++ PrintAndLog(" : data rawdemod ar 1 = demod an ask tag from GraphBuffer while inverting data"); ++ PrintAndLog(" : data rawdemod ar 64 1 0 = demod an ask tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors"); ++ PrintAndLog(" : data rawdemod ar 64 1 0 a = demod an ask tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors, and amp"); ++ return 0; ++ } ++ return ASKrawDemod(Cmd, TRUE); ++} ++ int CmdAutoCorr(const char *Cmd) { static int CorrelBuffer[MAX_GRAPH_TRACE_LEN]; @@@ -820,7 -814,7 +835,7 @@@ int CmdDetectClockRate(const char *Cmd //fsk raw demod and print binary //takes 4 arguments - Clock, invert, fchigh, fclow //defaults: clock = 50, invert=1, fchigh=10, fclow=8 (RF/10 RF/8 (fsk2a)) --int CmdFSKrawdemod(const char *Cmd) ++int FSKrawDemod(const char *Cmd, bool verbose) { //raw fsk demod no manchester decoding no start bit finding just get binary from wave //set defaults @@@ -828,23 -822,23 +843,7 @@@ int invert=0; int fchigh=0; int fclow=0; -- char cmdp = param_getchar(Cmd, 0); -- if (strlen(Cmd) > 10 || cmdp == 'h' || cmdp == 'H') { -- PrintAndLog("Usage: data rawdemod fs [clock] [fchigh] [fclow]"); -- PrintAndLog(" [set clock as integer] optional, omit for autodetect."); -- PrintAndLog(" , 1 for invert output, can be used even if the clock is omitted"); -- PrintAndLog(" [fchigh], larger field clock length, omit for autodetect"); -- PrintAndLog(" [fclow], small field clock length, omit for autodetect"); -- PrintAndLog(""); -- PrintAndLog(" sample: data rawdemod fs = demod an fsk tag from GraphBuffer using autodetect"); -- PrintAndLog(" : data rawdemod fs 32 = demod an fsk tag from GraphBuffer using a clock of RF/32, autodetect fc"); -- PrintAndLog(" : data rawdemod fs 1 = demod an fsk tag from GraphBuffer using autodetect, invert output"); -- PrintAndLog(" : data rawdemod fs 32 1 = demod an fsk tag from GraphBuffer using a clock of RF/32, invert output, autodetect fc"); -- PrintAndLog(" : data rawdemod fs 64 0 8 5 = demod an fsk1 RF/64 tag from GraphBuffer"); -- PrintAndLog(" : data rawdemod fs 50 0 10 8 = demod an fsk2 RF/50 tag from GraphBuffer"); -- PrintAndLog(" : data rawdemod fs 50 1 10 8 = demod an fsk2a RF/50 tag from GraphBuffer"); -- return 0; -- } ++ //set options from parameters entered with the command sscanf(Cmd, "%i %i %i %i", &rfLen, &invert, &fchigh, &fclow); @@@ -876,22 -870,22 +875,50 @@@ rfLen = detectFSKClk(BitStream, BitLen, fchigh, fclow); if (rfLen == 0) rfLen = 50; } -- PrintAndLog("Args invert: %d - Clock:%d - fchigh:%d - fclow: %d",invert,rfLen,fchigh, fclow); ++ if (verbose) PrintAndLog("Args invert: %d - Clock:%d - fchigh:%d - fclow: %d",invert,rfLen,fchigh, fclow); int size = fskdemod(BitStream,BitLen,(uint8_t)rfLen,(uint8_t)invert,(uint8_t)fchigh,(uint8_t)fclow); if (size>0){ -- PrintAndLog("FSK decoded bitstream:"); setDemodBuf(BitStream,size,0); // Now output the bitstream to the scrollback by line of 16 bits if(size > (8*32)+2) size = (8*32)+2; //only output a max of 8 blocks of 32 bits most tags will have full bit stream inside that sample size ++ if (verbose) { ++ PrintAndLog("FSK decoded bitstream:"); printBitStream(BitStream,size); ++ } return 1; } else{ -- PrintAndLog("no FSK data found"); ++ if (verbose) PrintAndLog("no FSK data found"); } return 0; } ++//by marshmellow ++//fsk raw demod and print binary ++//takes 4 arguments - Clock, invert, fchigh, fclow ++//defaults: clock = 50, invert=1, fchigh=10, fclow=8 (RF/10 RF/8 (fsk2a)) ++int CmdFSKrawdemod(const char *Cmd) ++{ ++ char cmdp = param_getchar(Cmd, 0); ++ if (strlen(Cmd) > 10 || cmdp == 'h' || cmdp == 'H') { ++ PrintAndLog("Usage: data rawdemod fs [clock] [fchigh] [fclow]"); ++ PrintAndLog(" [set clock as integer] optional, omit for autodetect."); ++ PrintAndLog(" , 1 for invert output, can be used even if the clock is omitted"); ++ PrintAndLog(" [fchigh], larger field clock length, omit for autodetect"); ++ PrintAndLog(" [fclow], small field clock length, omit for autodetect"); ++ PrintAndLog(""); ++ PrintAndLog(" sample: data rawdemod fs = demod an fsk tag from GraphBuffer using autodetect"); ++ PrintAndLog(" : data rawdemod fs 32 = demod an fsk tag from GraphBuffer using a clock of RF/32, autodetect fc"); ++ PrintAndLog(" : data rawdemod fs 1 = demod an fsk tag from GraphBuffer using autodetect, invert output"); ++ PrintAndLog(" : data rawdemod fs 32 1 = demod an fsk tag from GraphBuffer using a clock of RF/32, invert output, autodetect fc"); ++ PrintAndLog(" : data rawdemod fs 64 0 8 5 = demod an fsk1 RF/64 tag from GraphBuffer"); ++ PrintAndLog(" : data rawdemod fs 50 0 10 8 = demod an fsk2 RF/50 tag from GraphBuffer"); ++ PrintAndLog(" : data rawdemod fs 50 1 10 8 = demod an fsk2a RF/50 tag from GraphBuffer"); ++ return 0; ++ } ++ return FSKrawDemod(Cmd, TRUE); ++} ++ //by marshmellow (based on existing demod + holiman's refactor) //HID Prox demod - FSK RF/50 with preamble of 00011101 (then manchester encoded) //print full HID Prox ID and some bit format details if found @@@ -1013,9 -1007,9 +1040,12 @@@ int CmdFSKdemodParadox(const char *Cmd } uint32_t fc = ((hi & 0x3)<<6) | (lo>>26); uint32_t cardnum = (lo>>10)&0xFFFF; ++ uint32_t rawLo = bytebits_to_byte(BitStream+idx+64,32); ++ uint32_t rawHi = bytebits_to_byte(BitStream+idx+32,32); ++ uint32_t rawHi2 = bytebits_to_byte(BitStream+idx,32); -- PrintAndLog("Paradox TAG ID: %x%08x - FC: %d - Card: %d - Checksum: %02x", -- hi>>10, (hi & 0x3)<<26 | (lo>>10), fc, cardnum, (lo>>2) & 0xFF ); ++ PrintAndLog("Paradox TAG ID: %x%08x - FC: %d - Card: %d - Checksum: %02x - RAW: %08x%08x%08x", ++ hi>>10, (hi & 0x3)<<26 | (lo>>10), fc, cardnum, (lo>>2) & 0xFF, rawHi2, rawHi, rawLo); setDemodBuf(BitStream,BitLen,idx); if (g_debugMode){ PrintAndLog("DEBUG: idx: %d, len: %d, Printing Demod Buffer:", idx, BitLen); @@@ -1185,16 -1179,16 +1215,16 @@@ int CmdFSKdemodAWID(const char *Cmd fc = bytebits_to_byte(BitStream+9, 8); cardnum = bytebits_to_byte(BitStream+17, 16); code1 = bytebits_to_byte(BitStream+8,fmtLen); -- PrintAndLog("AWID Found - BitLength: %d, FC: %d, Card: %d - Wiegand: %x, Raw: %x%08x%08x", fmtLen, fc, cardnum, code1, rawHi2, rawHi, rawLo); ++ PrintAndLog("AWID Found - BitLength: %d, FC: %d, Card: %d - Wiegand: %x, Raw: %08x%08x%08x", fmtLen, fc, cardnum, code1, rawHi2, rawHi, rawLo); } else { cardnum = bytebits_to_byte(BitStream+8+(fmtLen-17), 16); if (fmtLen>32){ code1 = bytebits_to_byte(BitStream+8,fmtLen-32); code2 = bytebits_to_byte(BitStream+8+(fmtLen-32),32); -- PrintAndLog("AWID Found - BitLength: %d -unknown BitLength- (%d) - Wiegand: %x%08x, Raw: %x%08x%08x", fmtLen, cardnum, code1, code2, rawHi2, rawHi, rawLo); ++ PrintAndLog("AWID Found - BitLength: %d -unknown BitLength- (%d) - Wiegand: %x%08x, Raw: %08x%08x%08x", fmtLen, cardnum, code1, code2, rawHi2, rawHi, rawLo); } else{ code1 = bytebits_to_byte(BitStream+8,fmtLen); -- PrintAndLog("AWID Found - BitLength: %d -unknown BitLength- (%d) - Wiegand: %x, Raw: %x%08x%08x", fmtLen, cardnum, code1, rawHi2, rawHi, rawLo); ++ PrintAndLog("AWID Found - BitLength: %d -unknown BitLength- (%d) - Wiegand: %x, Raw: %08x%08x%08x", fmtLen, cardnum, code1, rawHi2, rawHi, rawLo); } } if (g_debugMode){ @@@ -1305,21 -1299,21 +1335,21 @@@ int CmdFSKdemodPyramid(const char *Cmd fc = bytebits_to_byte(BitStream+73, 8); cardnum = bytebits_to_byte(BitStream+81, 16); code1 = bytebits_to_byte(BitStream+72,fmtLen); -- PrintAndLog("Pyramid ID Found - BitLength: %d, FC: %d, Card: %d - Wiegand: %x, Raw: %x%08x%08x%08x", fmtLen, fc, cardnum, code1, rawHi3, rawHi2, rawHi, rawLo); ++ PrintAndLog("Pyramid ID Found - BitLength: %d, FC: %d, Card: %d - Wiegand: %x, Raw: %08x%08x%08x%08x", fmtLen, fc, cardnum, code1, rawHi3, rawHi2, rawHi, rawLo); } else if (fmtLen==45){ fmtLen=42; //end = 10 bits not 7 like 26 bit fmt fc = bytebits_to_byte(BitStream+53, 10); cardnum = bytebits_to_byte(BitStream+63, 32); -- PrintAndLog("Pyramid ID Found - BitLength: %d, FC: %d, Card: %d - Raw: %x%08x%08x%08x", fmtLen, fc, cardnum, rawHi3, rawHi2, rawHi, rawLo); ++ PrintAndLog("Pyramid ID Found - BitLength: %d, FC: %d, Card: %d - Raw: %08x%08x%08x%08x", fmtLen, fc, cardnum, rawHi3, rawHi2, rawHi, rawLo); } else { cardnum = bytebits_to_byte(BitStream+81, 16); if (fmtLen>32){ //code1 = bytebits_to_byte(BitStream+(size-fmtLen),fmtLen-32); //code2 = bytebits_to_byte(BitStream+(size-32),32); -- PrintAndLog("Pyramid ID Found - BitLength: %d -unknown BitLength- (%d), Raw: %x%08x%08x%08x", fmtLen, cardnum, rawHi3, rawHi2, rawHi, rawLo); ++ PrintAndLog("Pyramid ID Found - BitLength: %d -unknown BitLength- (%d), Raw: %08x%08x%08x%08x", fmtLen, cardnum, rawHi3, rawHi2, rawHi, rawLo); } else{ //code1 = bytebits_to_byte(BitStream+(size-fmtLen),fmtLen); -- PrintAndLog("Pyramid ID Found - BitLength: %d -unknown BitLength- (%d), Raw: %x%08x%08x%08x", fmtLen, cardnum, rawHi3, rawHi2, rawHi, rawLo); ++ PrintAndLog("Pyramid ID Found - BitLength: %d -unknown BitLength- (%d), Raw: %08x%08x%08x%08x", fmtLen, cardnum, rawHi3, rawHi2, rawHi, rawLo); } } if (g_debugMode){ @@@ -1449,7 -1443,7 +1479,7 @@@ int CmdFSKdemod(const char *Cmd) //old //by marshmellow //attempt to psk1 demod graph buffer --int PSKDemod(const char *Cmd, uint8_t verbose) ++int PSKDemod(const char *Cmd, bool verbose) { int invert=0; int clk=0; @@@ -1460,7 -1454,7 +1490,7 @@@ clk=0; } if (invert != 0 && invert != 1) { -- PrintAndLog("Invalid argument: %s", Cmd); ++ if (verbose) PrintAndLog("Invalid argument: %s", Cmd); return -1; } uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; @@@ -1469,11 -1463,11 +1499,11 @@@ int errCnt=0; errCnt = pskRawDemod(BitStream, &BitLen,&clk,&invert); if (errCnt > maxErr){ -- if (g_debugMode==1) PrintAndLog("Too many errors found, clk: %d, invert: %d, numbits: %d, errCnt: %d",clk,invert,BitLen,errCnt); ++ if (g_debugMode==1 && verbose) PrintAndLog("Too many errors found, clk: %d, invert: %d, numbits: %d, errCnt: %d",clk,invert,BitLen,errCnt); return -1; } if (errCnt<0|| BitLen<16){ //throw away static - allow 1 and -1 (in case of threshold command first) -- if (g_debugMode==1) PrintAndLog("no data found, clk: %d, invert: %d, numbits: %d, errCnt: %d",clk,invert,BitLen,errCnt); ++ if (g_debugMode==1 && verbose) PrintAndLog("no data found, clk: %d, invert: %d, numbits: %d, errCnt: %d",clk,invert,BitLen,errCnt); return -1; } if (verbose) PrintAndLog("Tried PSK Demod using Clock: %d - invert: %d - Bits Found: %d",clk,invert,BitLen); @@@ -1567,27 -1561,27 +1597,12 @@@ int CmdIndalaDecode(const char *Cmd // takes 3 arguments - clock, invert, maxErr as integers // attempts to demodulate nrz only // prints binary found and saves in demodbuffer for further commands --int CmdNRZrawDemod(const char *Cmd) ++ ++int NRZrawDemod(const char *Cmd, bool verbose) { int invert=0; int clk=0; int maxErr=100; -- char cmdp = param_getchar(Cmd, 0); -- if (strlen(Cmd) > 10 || cmdp == 'h' || cmdp == 'H') { -- PrintAndLog("Usage: data rawdemod nr [clock] <0|1> [maxError]"); -- PrintAndLog(" [set clock as integer] optional, if not set, autodetect."); -- PrintAndLog(" , 1 for invert output"); -- PrintAndLog(" [set maximum allowed errors], default = 100."); -- PrintAndLog(""); -- PrintAndLog(" sample: data nrzrawdemod = demod a nrz/direct tag from GraphBuffer"); -- PrintAndLog(" : data nrzrawdemod 32 = demod a nrz/direct tag from GraphBuffer using a clock of RF/32"); -- PrintAndLog(" : data nrzrawdemod 32 1 = demod a nrz/direct tag from GraphBuffer using a clock of RF/32 and inverting data"); -- PrintAndLog(" : data nrzrawdemod 1 = demod a nrz/direct tag from GraphBuffer while inverting data"); -- PrintAndLog(" : data nrzrawdemod 64 1 0 = demod a nrz/direct tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors"); -- -- return 0; -- } -- sscanf(Cmd, "%i %i %i", &clk, &invert, &maxErr); if (clk==1){ invert=1; @@@ -1603,27 -1597,27 +1618,48 @@@ int errCnt=0; errCnt = nrzRawDemod(BitStream, &BitLen, &clk, &invert, maxErr); if (errCnt > maxErr){ -- if (g_debugMode==1) PrintAndLog("Too many errors found, clk: %d, invert: %d, numbits: %d, errCnt: %d",clk,invert,BitLen,errCnt); ++ if (g_debugMode==1 && verbose) PrintAndLog("Too many errors found, clk: %d, invert: %d, numbits: %d, errCnt: %d",clk,invert,BitLen,errCnt); return 0; } if (errCnt<0|| BitLen<16){ //throw away static - allow 1 and -1 (in case of threshold command first) -- if (g_debugMode==1) PrintAndLog("no data found, clk: %d, invert: %d, numbits: %d, errCnt: %d",clk,invert,BitLen,errCnt); ++ if (g_debugMode==1 && verbose) PrintAndLog("no data found, clk: %d, invert: %d, numbits: %d, errCnt: %d",clk,invert,BitLen,errCnt); return 0; } -- PrintAndLog("Tried NRZ Demod using Clock: %d - invert: %d - Bits Found: %d",clk,invert,BitLen); ++ if (verbose) ++ PrintAndLog("Tried NRZ Demod using Clock: %d - invert: %d - Bits Found: %d",clk,invert,BitLen); //prime demod buffer for output setDemodBuf(BitStream,BitLen,0); -- if (errCnt>0){ ++ if (errCnt>0 && verbose){ PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt); -- }else{ } ++ if (verbose) { PrintAndLog("NRZ demoded bitstream:"); // Now output the bitstream to the scrollback by line of 16 bits printDemodBuff(); ++ } return 1; } ++int CmdNRZrawDemod(const char *Cmd) ++{ ++ char cmdp = param_getchar(Cmd, 0); ++ if (strlen(Cmd) > 10 || cmdp == 'h' || cmdp == 'H') { ++ PrintAndLog("Usage: data rawdemod nr [clock] <0|1> [maxError]"); ++ PrintAndLog(" [set clock as integer] optional, if not set, autodetect."); ++ PrintAndLog(" , 1 for invert output"); ++ PrintAndLog(" [set maximum allowed errors], default = 100."); ++ PrintAndLog(""); ++ PrintAndLog(" sample: data nrzrawdemod = demod a nrz/direct tag from GraphBuffer"); ++ PrintAndLog(" : data nrzrawdemod 32 = demod a nrz/direct tag from GraphBuffer using a clock of RF/32"); ++ PrintAndLog(" : data nrzrawdemod 32 1 = demod a nrz/direct tag from GraphBuffer using a clock of RF/32 and inverting data"); ++ PrintAndLog(" : data nrzrawdemod 1 = demod a nrz/direct tag from GraphBuffer while inverting data"); ++ PrintAndLog(" : data nrzrawdemod 64 1 0 = demod a nrz/direct tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors"); ++ return 0; ++ } ++ return NRZrawDemod(Cmd, TRUE); ++} ++ // by marshmellow // takes 3 arguments - clock, invert, maxErr as integers // attempts to demodulate psk only @@@ -1645,7 -1639,7 +1681,7 @@@ int CmdPSK1rawDemod(const char *Cmd PrintAndLog(" : data psk1rawdemod 64 1 0 = demod a psk1 tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors"); return 0; } -- errCnt = PSKDemod(Cmd, 1); ++ errCnt = PSKDemod(Cmd, TRUE); //output if (errCnt<0){ if (g_debugMode) PrintAndLog("Error demoding: %d",errCnt); @@@ -1653,7 -1647,7 +1689,6 @@@ } if (errCnt>0){ PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt); -- }else{ } PrintAndLog("PSK demoded bitstream:"); // Now output the bitstream to the scrollback by line of 16 bits diff --combined client/cmddata.h index dada6e58,c1a7ecae..c7dbf297 --- a/client/cmddata.h +++ b/client/cmddata.h @@@ -14,9 -14,7 +14,9 @@@ command_t * CmdDataCommands(); int CmdData(const char *Cmd); +void setDemodBuf(uint8_t *buff, size_t size, size_t startIdx); void printDemodBuff(); - void printBitStream(uint8_t BitStream[], uint32_t bitLen); ++ int CmdAmp(const char *Cmd); int Cmdaskdemod(const char *Cmd); int CmdAskEM410xDemod(const char *Cmd); @@@ -60,12 -58,11 +60,17 @@@ int CmdThreshold(const char *Cmd) int CmdDirectionalThreshold(const char *Cmd); int CmdZerocrossings(const char *Cmd); int CmdIndalaDecode(const char *Cmd); ++int ASKmanDemod(const char *Cmd, bool verbose, bool emSearch); ++int ASKrawDemod(const char *Cmd, bool verbose); ++int FSKrawDemod(const char *Cmd, bool verbose); ++int PSKDemod(const char *Cmd, bool verbose); ++int NRZrawDemod(const char *Cmd, bool verbose); #define MAX_DEMOD_BUF_LEN (1024*128) extern uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN]; extern int DemodBufferLen; +extern uint8_t g_debugMode; #define BIGBUF_SIZE 40000 #endif diff --combined client/cmdhf15.c index c3ff7dd6,c3ff7dd6..1263329e --- a/client/cmdhf15.c +++ b/client/cmdhf15.c @@@ -668,9 -668,9 +668,9 @@@ int CmdHF15CmdRaw (const char *cmd) */ int prepareHF15Cmd(char **cmd, UsbCommand *c, uint8_t iso15cmd[], int iso15cmdlen) { int temp; -- uint8_t *req=c->d.asBytes; ++ uint8_t *req = c->d.asBytes; uint8_t uid[8] = {0x00}; -- uint32_t reqlen=0; ++ uint32_t reqlen = 0; // strip while (**cmd==' ' || **cmd=='\t') (*cmd)++; @@@ -763,10 -763,10 +763,10 @@@ int CmdHF15CmdSysinfo(const char *Cmd) UsbCommand resp; uint8_t *recv; UsbCommand c = {CMD_ISO_15693_COMMAND, {0, 1, 1}}; // len,speed,recv? -- uint8_t *req=c.d.asBytes; -- int reqlen=0; ++ uint8_t *req = c.d.asBytes; ++ int reqlen = 0; char cmdbuf[100]; -- char *cmd=cmdbuf; ++ char *cmd = cmdbuf; char output[2048]=""; int i; @@@ -782,13 -782,13 +782,11 @@@ PrintAndLog(" s selected tag"); PrintAndLog(" u unaddressed mode"); PrintAndLog(" * scan for tag"); -- PrintAndLog(" start#: page number to start 0-255"); -- PrintAndLog(" count#: number of pages"); return 0; } prepareHF15Cmd(&cmd, &c,(uint8_t[]){ISO15_CMD_SYSINFO},1); -- reqlen=c.arg[0]; ++ reqlen = c.arg[0]; reqlen=AddCrc(req,reqlen); c.arg[0]=reqlen; diff --combined client/cmdhfmf.c index 507e97fa,d0852ea5..3c9f2543 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@@ -1023,6 -1023,6 +1023,7 @@@ int CmdHF14AMf1kSim(const char *Cmd PrintAndLog(" x (Optional) Crack, performs the 'reader attack', nr/ar attack against a legitimate reader, fishes out the key(s)"); PrintAndLog(""); PrintAndLog(" sample: hf mf sim u 0a0a0a0a "); ++ PrintAndLog(" : hf mf sim u 0a0a0a0a i x"); return 0; } uint8_t pnr = 0; @@@ -1499,7 -1499,7 +1500,7 @@@ int CmdHF14AMfCSetUID(const char *Cmd int CmdHF14AMfCSetBlk(const char *Cmd) { - uint8_t uid[8] = {0x00}; + //uint8_t uid[8] = {0x00}; uint8_t memBlock[16] = {0x00}; uint8_t blockNo = 0; int res; @@@ -1521,8 -1521,7 +1522,8 @@@ PrintAndLog("--block number:%2d data:%s", blockNo, sprint_hex(memBlock, 16)); - res = mfCSetBlock(blockNo, memBlock, uid, 0, CSETBLOCK_SINGLE_OPER); + //res = mfCSetBlock(blockNo, memBlock, uid, 0, CSETBLOCK_SINGLE_OPER); + res = mfCSetBlock(blockNo, memBlock, NULL, 0, CSETBLOCK_SINGLE_OPER); if (res) { PrintAndLog("Can't write block. error=%d", res); return 1; diff --combined client/lualibs/mf_default_keys.lua index cca4699e,757112c6..810f0d6e --- a/client/lualibs/mf_default_keys.lua +++ b/client/lualibs/mf_default_keys.lua @@@ -158,22 -158,8 +158,8 @@@ local _keys = 'eff603e1efe9', '644672bd4afe', - 'b5ff67cba951', - } - - --[[ - Kiev metro cards - --]] - '8fe644038790', - 'f14ee7cae863', - '632193be1c3c', - '569369c5a0e5', - '9de89e070277', - 'eff603e1efe9', - '644672bd4afe', - 'b5ff67cba951', - } +} --- -- The keys above have just been pasted in, for completeness sake. They contain duplicates. diff --combined client/lualibs/utils.lua index 3015c419,c5baa406..f7749ca6 --- a/client/lualibs/utils.lua +++ b/client/lualibs/utils.lua @@@ -135,7 -135,7 +135,7 @@@ local Utils while IN>0 do I=I+1 IN , D = math.floor(IN/B), math.modf(IN,B)+1 -- OUT=string.sub(K,D,D)..OUT ++ OUT = string.sub(K,D,D)..OUT end return OUT end, @@@ -147,7 -147,7 +147,7 @@@ end local s={} for i = 1, #(bytes) do - s[i] = string.format("%02X",bytes[i]) + s[i] = string.format("%02X",bytes[i]) end return table.concat(s) end, @@@ -191,6 -191,6 +191,30 @@@ return table.concat(t) end, ++ Chars2num = function(s) ++ return (s:byte(1)*16777216)+(s:byte(2)*65536)+(s:byte(3)*256)+(s:byte(4)) ++ end, ++ ++ -- use length of string to determine 8,16,32,64 bits ++ bytes_to_int = function(str,endian,signed) ++ local t={str:byte(1,-1)} ++ if endian=="big" then --reverse bytes ++ local tt={} ++ for k=1,#t do ++ tt[#t-k+1]=t[k] ++ end ++ t=tt ++ end ++ local n=0 ++ for k=1,#t do ++ n=n+t[k]*2^((k-1)*8) ++ end ++ if signed then ++ n = (n > 2^(#t*8-1) -1) and (n - 2^(#t*8)) or n -- if last bit set, negative. ++ end ++ return n ++ end, ++ -- function convertStringToBytes(str) -- local bytes = {} -- local strLength = string.len(str) diff --combined client/nonce2key/crapto1.c index ca926a73,1015e27a..1d7441c7 --- a/client/nonce2key/crapto1.c +++ b/client/nonce2key/crapto1.c @@@ -1,21 -1,21 +1,21 @@@ /* crapto1.c - 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, US$ - - Copyright (C) 2008-2008 bla + 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, US$ + + Copyright (C) 2008-2008 bla */ #include "crapto1.h" #include @@@ -24,9 -24,9 +24,9 @@@ static uint8_t filterlut[1 << 20]; static void __attribute__((constructor)) fill_lut() { - uint32_t i; - for(i = 0; i < 1 << 20; ++i) - filterlut[i] = filter(i); + uint32_t i; + for(i = 0; i < 1 << 20; ++i) + filterlut[i] = filter(i); } #define filter(x) (filterlut[(x) & 0xfffff]) #endif @@@ -46,7 -46,7 +46,7 @@@ typedef struct bucket_info } bucket_info[2][0x100]; uint32_t numbuckets; } bucket_info_t; - + static void bucket_sort_intersect(uint32_t* const estart, uint32_t* const estop, uint32_t* const ostart, uint32_t* const ostop, @@@ -55,28 -55,28 +55,28 @@@ uint32_t *p1, *p2; uint32_t *start[2]; uint32_t *stop[2]; - + start[0] = estart; stop[0] = estop; start[1] = ostart; stop[1] = ostop; - + // init buckets to be empty for (uint32_t i = 0; i < 2; i++) { for (uint32_t j = 0x00; j <= 0xff; j++) { bucket[i][j].bp = bucket[i][j].head; } } - + // sort the lists into the buckets based on the MSB (contribution bits) - for (uint32_t i = 0; i < 2; i++) { + for (uint32_t i = 0; i < 2; i++) { for (p1 = start[i]; p1 <= stop[i]; p1++) { uint32_t bucket_index = (*p1 & 0xff000000) >> 24; *(bucket[i][bucket_index].bp++) = *p1; } } - + // write back intersecting buckets as sorted list. // fill in bucket_info with head and tail of the bucket contents in the list and number of non-empty buckets. uint32_t nonempty_bucket; @@@ -147,9 -147,9 +147,9 @@@ extend_table(uint32_t *tbl, uint32_t ** *p ^= in; } else { // drop *p-- = *(*end)--; - } - } + } - + } + } @@@ -159,7 -159,7 +159,7 @@@ static inline void extend_table_simple(uint32_t *tbl, uint32_t **end, int bit) { - for(*tbl <<= 1; tbl <= *end; *++tbl <<= 1) + for(*tbl <<= 1; tbl <= *end; *++tbl <<= 1) if(filter(*tbl) ^ filter(*tbl | 1)) { // replace *tbl |= filter(*tbl) ^ bit; } else if(filter(*tbl) == bit) { // insert @@@ -206,13 -206,13 +206,13 @@@ recover(uint32_t *o_head, uint32_t *o_t } bucket_sort_intersect(e_head, e_tail, o_head, o_tail, &bucket_info, bucket); - + for (int i = bucket_info.numbuckets - 1; i >= 0; i--) { sl = recover(bucket_info.bucket_info[1][i].head, bucket_info.bucket_info[1][i].tail, oks, - bucket_info.bucket_info[0][i].head, bucket_info.bucket_info[0][i].tail, eks, + bucket_info.bucket_info[0][i].head, bucket_info.bucket_info[0][i].tail, eks, rem, sl, in, bucket); } - + return sl; } /** lfsr_recovery @@@ -251,7 -251,7 +251,7 @@@ struct Crypto1State* lfsr_recovery32(ui } } - + // initialize statelists: add all possible states which would result into the rightmost 2 bits of the keystream for(i = 1 << 20; i >= 0; --i) { if(filter(i) == (oks & 1)) @@@ -282,7 -282,7 +282,7 @@@ out for (uint32_t i = 0; i < 2; i++) for (uint32_t j = 0; j <= 0xff; j++) free(bucket[i][j].head); - + return statelist; } @@@ -382,9 -382,12 +382,12 @@@ struct Crypto1State* lfsr_recovery64(ui void lfsr_rollback_bit(struct Crypto1State *s, uint32_t in, int fb) { int out; + uint32_t tmp; s->odd &= 0xffffff; - s->odd ^= (s->odd ^= s->even, s->even ^= s->odd); + tmp = s->odd; + s->odd = s->even; + s->even = tmp; out = s->even & 1; out ^= LF_POLY_EVEN & (s->even >>= 1); @@@ -481,7 -484,7 +484,7 @@@ uint32_t *lfsr_prefix_ks(uint8_t ks[8] */ static struct Crypto1State* brute_top(uint32_t prefix, uint32_t rresp, unsigned char parities[8][8], - uint32_t odd, uint32_t even, struct Crypto1State* sl, uint8_t no_chk) + uint32_t odd, uint32_t even, struct Crypto1State* sl, uint8_t no_chk) { struct Crypto1State s; uint32_t ks1, nr, ks2, rr, ks3, good, c; @@@ -489,20 -492,20 +492,20 @@@ for(c = 0; c < 8; ++c) { s.odd = odd ^ fastfwd[1][c]; s.even = even ^ fastfwd[0][c]; - + lfsr_rollback_bit(&s, 0, 0); lfsr_rollback_bit(&s, 0, 0); lfsr_rollback_bit(&s, 0, 0); - + lfsr_rollback_word(&s, 0, 0); lfsr_rollback_word(&s, prefix | c << 5, 1); - + sl->odd = s.odd; sl->even = s.even; - + if (no_chk) break; - + ks1 = crypto1_word(&s, prefix | c << 5, 1); ks2 = crypto1_word(&s,0,0); ks3 = crypto1_word(&s, 0,0); @@@ -521,7 -524,7 +524,7 @@@ } return ++sl; - } + } /** lfsr_common_prefix @@@ -542,13 -545,13 +545,13 @@@ lfsr_common_prefix(uint32_t pfx, uint32 odd = lfsr_prefix_ks(ks, 1); even = lfsr_prefix_ks(ks, 0); - statelist = malloc((sizeof *statelist) << 21); //how large should be? + statelist = malloc((sizeof *statelist) << 21); //how large should be? if(!statelist || !odd || !even) { free(statelist); free(odd); free(even); - return 0; + return 0; } s = statelist; @@@ -560,7 -563,7 +563,7 @@@ s = brute_top(pfx, rr, par, *o, *e, s, no_par); } - s->odd = s->even = -1; + s->odd = s->even = -1; //printf("state count = %d\n",s-statelist); free(odd);