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.
/* crapto1.c\r
\r
- This program is free software; you can redistribute it and/or\r
- modify it under the terms of the GNU General Public License\r
- as published by the Free Software Foundation; either version 2\r
- of the License, or (at your option) any later version.\r
-\r
- This program is distributed in the hope that it will be useful,\r
- but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
- GNU General Public License for more details.\r
-\r
- You should have received a copy of the GNU General Public License\r
- along with this program; if not, write to the Free Software\r
- Foundation, Inc., 51 Franklin Street, Fifth Floor,\r
- Boston, MA 02110-1301, US$\r
-\r
- Copyright (C) 2008-2008 bla <blapost@gmail.com>\r
+ This program is free software; you can redistribute it and/or\r
+ modify it under the terms of the GNU General Public License\r
+ as published by the Free Software Foundation; either version 2\r
+ of the License, or (at your option) any later version.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License\r
+ along with this program; if not, write to the Free Software\r
+ Foundation, Inc., 51 Franklin Street, Fifth Floor,\r
+ Boston, MA 02110-1301, US$\r
+\r
+ Copyright (C) 2008-2008 bla <blapost@gmail.com>\r
*/\r
#include "crapto1.h"\r
#include <stdlib.h>\r
static uint8_t filterlut[1 << 20];\r
static void __attribute__((constructor)) fill_lut()\r
{\r
- uint32_t i;\r
- for(i = 0; i < 1 << 20; ++i)\r
- filterlut[i] = filter(i);\r
+ uint32_t i;\r
+ for(i = 0; i < 1 << 20; ++i)\r
+ filterlut[i] = filter(i);\r
}\r
#define filter(x) (filterlut[(x) & 0xfffff])\r
#endif\r
static void quicksort(uint32_t* const start, uint32_t* const stop)\r
{\r
uint32_t *it = start + 1, *rit = stop;\r
+ uint32_t tmp;\r
\r
if(it > rit)\r
return;\r
++it;\r
else if(*rit > *start)\r
--rit;\r
- else\r
- *it ^= ( (*it ^= *rit ), *rit ^= *it);\r
+ else {\r
+ tmp = *it;\r
+ *it = *rit;\r
+ *rit = tmp;\r
+ }\r
\r
if(*rit >= *start)\r
--rit;\r
- if(rit != start)\r
- *rit ^= ( (*rit ^= *start), *start ^= *rit);\r
+ if(rit != start) {\r
+ tmp = *rit;\r
+ *rit = *start;\r
+ *start = tmp;\r
+ }\r
\r
quicksort(start, rit - 1);\r
quicksort(rit + 1, stop);\r
eks >>= 1;\r
in >>= 2;\r
extend_table(o_head, &o_tail, oks & 1, LF_POLY_EVEN << 1 | 1,\r
- LF_POLY_ODD << 1, 0);\r
+ LF_POLY_ODD << 1, 0);\r
if(o_head > o_tail)\r
return sl;\r
\r
extend_table(e_head, &e_tail, eks & 1, LF_POLY_ODD,\r
- LF_POLY_EVEN << 1 | 1, in & 3);\r
+ LF_POLY_EVEN << 1 | 1, in & 3);\r
if(e_head > e_tail)\r
return sl;\r
}\r
o_tail = binsearch(o_head, o = o_tail);\r
e_tail = binsearch(e_head, e = e_tail);\r
sl = recover(o_tail--, o, oks,\r
- e_tail--, e, eks, rem, sl, in);\r
+ e_tail--, e, eks, rem, sl, in);\r
}\r
else if(*o_tail > *e_tail)\r
o_tail = binsearch(o_head, o_tail) - 1;\r
{\r
int out;\r
uint8_t ret;\r
+ uint32_t tmp;\r
\r
s->odd &= 0xffffff;\r
- s->odd ^= (s->odd ^= s->even, s->even ^= s->odd);\r
+ tmp = s->odd;\r
+ s->odd = s->even;\r
+ s->even = tmp;\r
\r
out = s->even & 1;\r
out ^= LF_POLY_EVEN & (s->even >>= 1);\r
*/\r
static struct Crypto1State*\r
check_pfx_parity(uint32_t prefix, uint32_t rresp, uint8_t parities[8][8],\r
- uint32_t odd, uint32_t even, struct Crypto1State* sl)\r
+ uint32_t odd, uint32_t even, struct Crypto1State* sl)\r
{\r
uint32_t ks1, nr, ks2, rr, ks3, c, good = 1;\r
\r
}\r
\r
return sl + good;\r
- } \r
+ }\r
\r
\r
/** lfsr_common_prefix\r
\r
odd = lfsr_prefix_ks(ks, 1);\r
even = lfsr_prefix_ks(ks, 0);\r
-\r
+ \r
s = statelist = malloc((sizeof *statelist) << 20);\r
if(!s || !odd || !even) {\r
free(statelist);\r
statelist = 0;\r
- goto out;\r
+ goto out;\r
}\r
\r
for(o = odd; *o + 1; ++o)\r
//
//-----------------------------------------------------------------------------
-#include "proxmark3.h"
+#include "../include/proxmark3.h"
#include "apps.h"
#include "util.h"
#include "string.h"
// 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;
SUB_SECOND_HALF,
SUB_BOTH
} sub;
- uint8_t *output;
+ uint8_t *output;
} Demod;
static RAMFUNC int ManchesterDecoding(int v)
clear_trace();
iso14a_set_trigger(FALSE);
- int lastRxCounter;
+ int lastRxCounter;
uint8_t *upTo;
int smpl;
int maxBehindBy = 0;
if(ManchesterDecoding(smpl & 0x0F)) {
time_stop = (GetCountSspClk()-time_0) << 4;
- rsamples = samples - Demod.samples;
+ rsamples = samples - Demod.samples;
LED_B_ON();
if(tracing) {
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;
Dbprintf("Done...");
}
+ void AppendCrc(uint8_t* data, int len)
+ {
+ ComputeCrc14443(CRC_ICLASS,data,len,data+len,data+len+1);
+ }
/**
* @brief Does the actual simulation
// 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} ;
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;
// 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;
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);
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..
} 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) {
} 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
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();
}
{
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();
+ }
}
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);
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!!
//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...
}
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))
{
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();
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);
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
if (workFlags & 0x01) {\r
if(!iso14443a_select_card(uid, NULL, &cuid)) {\r
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");\r
-- break;\r
++ //break;\r
};\r
\r
if(mifare_classic_halt(NULL, cuid)) {\r
if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");\r
-- break;\r
++ //break;\r
};\r
};\r
\r
//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++];
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){
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(" <invert>, 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) {
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(" <invert>, 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
//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] <invert> [maxError] [amplify]");
-- PrintAndLog(" [set clock as integer] optional, if not set, autodetect");
-- PrintAndLog(" <invert>, 1 to invert output");
-- PrintAndLog(" [set maximum allowed errors], default = 100");
-- PrintAndLog(" <amplify>, '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){
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] <invert> [maxError] [amplify]");
++ PrintAndLog(" [set clock as integer] optional, if not set, autodetect");
++ PrintAndLog(" <invert>, 1 to invert output");
++ PrintAndLog(" [set maximum allowed errors], default = 100");
++ PrintAndLog(" <amplify>, '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];
//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
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] <invert> [fchigh] [fclow]");
-- PrintAndLog(" [set clock as integer] optional, omit for autodetect.");
-- PrintAndLog(" <invert>, 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);
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] <invert> [fchigh] [fclow]");
++ PrintAndLog(" [set clock as integer] optional, omit for autodetect.");
++ PrintAndLog(" <invert>, 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
}
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);
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){
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){
//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;
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};
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);
// 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(" <invert>, 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;
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(" <invert>, 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
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);
}
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
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);
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
*/
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)++;
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;
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;
PrintAndLog(" x (Optional) Crack, performs the 'reader attack', nr/ar attack against a legitimate reader, fishes out the key(s)");\r
PrintAndLog("");\r
PrintAndLog(" sample: hf mf sim u 0a0a0a0a ");\r
++ PrintAndLog(" : hf mf sim u 0a0a0a0a i x");\r
return 0;\r
}\r
uint8_t pnr = 0;\r
\r
int CmdHF14AMfCSetBlk(const char *Cmd)\r
{\r
- uint8_t uid[8] = {0x00};\r
+ //uint8_t uid[8] = {0x00};\r
uint8_t memBlock[16] = {0x00};\r
uint8_t blockNo = 0;\r
int res;\r
\r
PrintAndLog("--block number:%2d data:%s", blockNo, sprint_hex(memBlock, 16));\r
\r
- res = mfCSetBlock(blockNo, memBlock, uid, 0, CSETBLOCK_SINGLE_OPER);\r
+ //res = mfCSetBlock(blockNo, memBlock, uid, 0, CSETBLOCK_SINGLE_OPER);\r
+ res = mfCSetBlock(blockNo, memBlock, NULL, 0, CSETBLOCK_SINGLE_OPER);\r
if (res) {\r
PrintAndLog("Can't write block. error=%d", res);\r
return 1;\r
'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.
while IN>0 do\r
I=I+1\r
IN , D = math.floor(IN/B), math.modf(IN,B)+1\r
-- OUT=string.sub(K,D,D)..OUT\r
++ OUT = string.sub(K,D,D)..OUT\r
end\r
return OUT\r
end,\r
end\r
local s={}\r
for i = 1, #(bytes) do\r
- s[i] = string.format("%02X",bytes[i]) \r
+ s[i] = string.format("%02X",bytes[i]) \r
end\r
return table.concat(s)\r
end, \r
return table.concat(t) \r
end,\r
\r
++ Chars2num = function(s)\r
++ return (s:byte(1)*16777216)+(s:byte(2)*65536)+(s:byte(3)*256)+(s:byte(4))\r
++ end,\r
++ \r
++ -- use length of string to determine 8,16,32,64 bits\r
++ bytes_to_int = function(str,endian,signed) \r
++ local t={str:byte(1,-1)}\r
++ if endian=="big" then --reverse bytes\r
++ local tt={}\r
++ for k=1,#t do\r
++ tt[#t-k+1]=t[k]\r
++ end\r
++ t=tt\r
++ end\r
++ local n=0\r
++ for k=1,#t do\r
++ n=n+t[k]*2^((k-1)*8)\r
++ end\r
++ if signed then\r
++ n = (n > 2^(#t*8-1) -1) and (n - 2^(#t*8)) or n -- if last bit set, negative.\r
++ end\r
++ return n\r
++ end,\r
++ \r
-- function convertStringToBytes(str)\r
-- local bytes = {}\r
-- local strLength = string.len(str)\r
/* crapto1.c\r
\r
- This program is free software; you can redistribute it and/or\r
- modify it under the terms of the GNU General Public License\r
- as published by the Free Software Foundation; either version 2\r
- of the License, or (at your option) any later version.\r
-\r
- This program is distributed in the hope that it will be useful,\r
- but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
- GNU General Public License for more details.\r
-\r
- You should have received a copy of the GNU General Public License\r
- along with this program; if not, write to the Free Software\r
- Foundation, Inc., 51 Franklin Street, Fifth Floor,\r
- Boston, MA 02110-1301, US$\r
-\r
- Copyright (C) 2008-2008 bla <blapost@gmail.com>\r
+ This program is free software; you can redistribute it and/or\r
+ modify it under the terms of the GNU General Public License\r
+ as published by the Free Software Foundation; either version 2\r
+ of the License, or (at your option) any later version.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License\r
+ along with this program; if not, write to the Free Software\r
+ Foundation, Inc., 51 Franklin Street, Fifth Floor,\r
+ Boston, MA 02110-1301, US$\r
+\r
+ Copyright (C) 2008-2008 bla <blapost@gmail.com>\r
*/\r
#include "crapto1.h"\r
#include <stdlib.h>\r
static uint8_t filterlut[1 << 20];\r
static void __attribute__((constructor)) fill_lut()\r
{\r
- uint32_t i;\r
- for(i = 0; i < 1 << 20; ++i)\r
- filterlut[i] = filter(i);\r
+ uint32_t i;\r
+ for(i = 0; i < 1 << 20; ++i)\r
+ filterlut[i] = filter(i);\r
}\r
#define filter(x) (filterlut[(x) & 0xfffff])\r
#endif\r
} bucket_info[2][0x100];\r
uint32_t numbuckets;\r
} bucket_info_t;\r
- \r
+ \r
\r
static void bucket_sort_intersect(uint32_t* const estart, uint32_t* const estop,\r
uint32_t* const ostart, uint32_t* const ostop,\r
uint32_t *p1, *p2;\r
uint32_t *start[2];\r
uint32_t *stop[2];\r
- \r
+ \r
start[0] = estart;\r
stop[0] = estop;\r
start[1] = ostart;\r
stop[1] = ostop;\r
- \r
+ \r
// init buckets to be empty\r
for (uint32_t i = 0; i < 2; i++) {\r
for (uint32_t j = 0x00; j <= 0xff; j++) {\r
bucket[i][j].bp = bucket[i][j].head;\r
}\r
}\r
- \r
+ \r
// sort the lists into the buckets based on the MSB (contribution bits)\r
- for (uint32_t i = 0; i < 2; i++) { \r
+ for (uint32_t i = 0; i < 2; i++) {\r
for (p1 = start[i]; p1 <= stop[i]; p1++) {\r
uint32_t bucket_index = (*p1 & 0xff000000) >> 24;\r
*(bucket[i][bucket_index].bp++) = *p1;\r
}\r
}\r
\r
- \r
+ \r
// write back intersecting buckets as sorted list.\r
// fill in bucket_info with head and tail of the bucket contents in the list and number of non-empty buckets.\r
uint32_t nonempty_bucket;\r
*p ^= in;\r
} else { // drop\r
*p-- = *(*end)--;\r
- } \r
- }\r
+ }\r
- \r
+ }\r
+ \r
}\r
\r
\r
static inline void\r
extend_table_simple(uint32_t *tbl, uint32_t **end, int bit)\r
{\r
- for(*tbl <<= 1; tbl <= *end; *++tbl <<= 1) \r
+ for(*tbl <<= 1; tbl <= *end; *++tbl <<= 1)\r
if(filter(*tbl) ^ filter(*tbl | 1)) { // replace\r
*tbl |= filter(*tbl) ^ bit;\r
} else if(filter(*tbl) == bit) { // insert\r
}\r
\r
bucket_sort_intersect(e_head, e_tail, o_head, o_tail, &bucket_info, bucket);\r
- \r
+ \r
for (int i = bucket_info.numbuckets - 1; i >= 0; i--) {\r
sl = recover(bucket_info.bucket_info[1][i].head, bucket_info.bucket_info[1][i].tail, oks,\r
- bucket_info.bucket_info[0][i].head, bucket_info.bucket_info[0][i].tail, eks,\r
+ bucket_info.bucket_info[0][i].head, bucket_info.bucket_info[0][i].tail, eks,\r
rem, sl, in, bucket);\r
}\r
- \r
+ \r
return sl;\r
}\r
/** lfsr_recovery\r
}\r
}\r
\r
- \r
+ \r
// initialize statelists: add all possible states which would result into the rightmost 2 bits of the keystream\r
for(i = 1 << 20; i >= 0; --i) {\r
if(filter(i) == (oks & 1))\r
for (uint32_t i = 0; i < 2; i++)\r
for (uint32_t j = 0; j <= 0xff; j++)\r
free(bucket[i][j].head);\r
- \r
+ \r
return statelist;\r
}\r
\r
void lfsr_rollback_bit(struct Crypto1State *s, uint32_t in, int fb)\r
{\r
int out;\r
+ uint32_t tmp;\r
\r
s->odd &= 0xffffff;\r
- s->odd ^= (s->odd ^= s->even, s->even ^= s->odd);\r
+ tmp = s->odd;\r
+ s->odd = s->even;\r
+ s->even = tmp;\r
\r
out = s->even & 1;\r
out ^= LF_POLY_EVEN & (s->even >>= 1);\r
*/\r
static struct Crypto1State*\r
brute_top(uint32_t prefix, uint32_t rresp, unsigned char parities[8][8],\r
- uint32_t odd, uint32_t even, struct Crypto1State* sl, uint8_t no_chk)\r
+ uint32_t odd, uint32_t even, struct Crypto1State* sl, uint8_t no_chk)\r
{\r
struct Crypto1State s;\r
uint32_t ks1, nr, ks2, rr, ks3, good, c;\r
for(c = 0; c < 8; ++c) {\r
s.odd = odd ^ fastfwd[1][c];\r
s.even = even ^ fastfwd[0][c];\r
- \r
+ \r
lfsr_rollback_bit(&s, 0, 0);\r
lfsr_rollback_bit(&s, 0, 0);\r
lfsr_rollback_bit(&s, 0, 0);\r
- \r
+ \r
lfsr_rollback_word(&s, 0, 0);\r
lfsr_rollback_word(&s, prefix | c << 5, 1);\r
- \r
+ \r
sl->odd = s.odd;\r
sl->even = s.even;\r
- \r
+ \r
if (no_chk)\r
break;\r
- \r
+ \r
ks1 = crypto1_word(&s, prefix | c << 5, 1);\r
ks2 = crypto1_word(&s,0,0);\r
ks3 = crypto1_word(&s, 0,0);\r
}\r
\r
return ++sl;\r
- } \r
+ }\r
\r
\r
/** lfsr_common_prefix\r
odd = lfsr_prefix_ks(ks, 1);\r
even = lfsr_prefix_ks(ks, 0);\r
\r
- statelist = malloc((sizeof *statelist) << 21); //how large should be? \r
+ statelist = malloc((sizeof *statelist) << 21); //how large should be?\r
if(!statelist || !odd || !even)\r
{\r
free(statelist);\r
free(odd);\r
free(even);\r
- return 0;\r
+ return 0;\r
}\r
\r
s = statelist;\r
s = brute_top(pfx, rr, par, *o, *e, s, no_par);\r
}\r
\r
- s->odd = s->even = -1; \r
+ s->odd = s->even = -1;\r
//printf("state count = %d\n",s-statelist);\r
\r
free(odd);\r