Merge branch 'master' into topaz

This commit is contained in:
pwpiwi 2015-08-25 07:53:00 +02:00
commit 8e21541e77
43 changed files with 1519 additions and 231 deletions

View file

@ -90,6 +90,7 @@ CMDSRCS = nonce2key/crapto1.c\
cmdlf.c \
cmdlfio.c \
cmdlfhid.c \
cmdlfawid.c \
cmdlfem4x.c \
cmdlfhitag.c \
cmdlfti.c \

View file

@ -24,10 +24,11 @@
#include "usb_cmd.h"
#include "crc.h"
#include "crc16.h"
#include "loclass/cipherutils.h"
uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN];
uint8_t g_debugMode;
size_t DemodBufferLen;
uint8_t g_debugMode=0;
size_t DemodBufferLen=0;
static int CmdHelp(const char *Cmd);
//set the demod buffer with given array of binary (one bit per byte)
@ -1491,9 +1492,9 @@ int CmdFDXBdemodBI(const char *Cmd){
setDemodBuf(BitStream, 128, preambleIndex);
// remove but don't verify parity. (pType = 2)
// remove marker bits (1's every 9th digit after preamble) (pType = 2)
size = removeParity(BitStream, preambleIndex + 11, 9, 2, 117);
if ( size <= 103 ) {
if ( size != 104 ) {
if (g_debugMode) PrintAndLog("Error removeParity:: %d", size);
return 0;
}
@ -1943,26 +1944,14 @@ int CmdHpf(const char *Cmd)
RepaintGraphWindow();
return 0;
}
typedef struct {
uint8_t * buffer;
uint32_t numbits;
uint32_t position;
}BitstreamOut;
bool _headBit( BitstreamOut *stream)
{
int bytepos = stream->position >> 3; // divide by 8
int bitpos = (stream->position++) & 7; // mask out 00000111
return (*(stream->buffer + bytepos) >> (7-bitpos)) & 1;
}
uint8_t getByte(uint8_t bits_per_sample, BitstreamOut* b)
uint8_t getByte(uint8_t bits_per_sample, BitstreamIn* b)
{
int i;
uint8_t val = 0;
for(i =0 ; i < bits_per_sample; i++)
{
val |= (_headBit(b) << (7-i));
val |= (headBit(b) << (7-i));
}
return val;
}
@ -2002,7 +1991,7 @@ int getSamples(const char *Cmd, bool silent)
if(bits_per_sample < 8)
{
PrintAndLog("Unpacking...");
BitstreamOut bout = { got, bits_per_sample * n, 0};
BitstreamIn bout = { got, bits_per_sample * n, 0};
int j =0;
for (j = 0; j * bits_per_sample < n * 8 && j < n; j++) {
uint8_t sample = getByte(bits_per_sample, &bout);
@ -2265,6 +2254,99 @@ int CmdZerocrossings(const char *Cmd)
return 0;
}
int usage_data_bin2hex(){
PrintAndLog("Usage: data bin2hex <binary_digits>");
PrintAndLog(" This function will ignore all characters not 1 or 0 (but stop reading on whitespace)");
return 0;
}
/**
* @brief Utility for conversion via cmdline.
* @param Cmd
* @return
*/
int Cmdbin2hex(const char *Cmd)
{
int bg =0, en =0;
if(param_getptr(Cmd, &bg, &en, 0))
{
return usage_data_bin2hex();
}
//Number of digits supplied as argument
size_t length = en - bg +1;
size_t bytelen = (length+7) / 8;
uint8_t* arr = (uint8_t *) malloc(bytelen);
memset(arr, 0, bytelen);
BitstreamOut bout = { arr, 0, 0 };
for(; bg <= en ;bg++)
{
char c = Cmd[bg];
if( c == '1') pushBit(&bout, 1);
else if( c == '0') pushBit(&bout, 0);
else PrintAndLog("Ignoring '%c'", c);
}
if(bout.numbits % 8 != 0)
{
printf("[padded with %d zeroes]\n", 8-(bout.numbits % 8));
}
//Uses printf instead of PrintAndLog since the latter
// adds linebreaks to each printout - this way was more convenient since we don't have to
// allocate a string and write to that first...
for(size_t x = 0; x < bytelen ; x++)
{
printf("%02X", arr[x]);
}
printf("\n");
free(arr);
return 0;
}
int usage_data_hex2bin(){
PrintAndLog("Usage: data bin2hex <binary_digits>");
PrintAndLog(" This function will ignore all non-hexadecimal characters (but stop reading on whitespace)");
return 0;
}
int Cmdhex2bin(const char *Cmd)
{
int bg =0, en =0;
if(param_getptr(Cmd, &bg, &en, 0))
{
return usage_data_hex2bin();
}
while(bg <= en )
{
char x = Cmd[bg++];
// capitalize
if (x >= 'a' && x <= 'f')
x -= 32;
// convert to numeric value
if (x >= '0' && x <= '9')
x -= '0';
else if (x >= 'A' && x <= 'F')
x -= 'A' - 10;
else
continue;
//Uses printf instead of PrintAndLog since the latter
// adds linebreaks to each printout - this way was more convenient since we don't have to
// allocate a string and write to that first...
for(int i= 0 ; i < 4 ; ++i)
printf("%d",(x >> (3 - i)) & 1);
}
printf("\n");
return 0;
}
static command_t CommandTable[] =
{
{"help", CmdHelp, 1, "This help"},
@ -2273,6 +2355,7 @@ static command_t CommandTable[] =
{"askgproxiidemod", CmdG_Prox_II_Demod, 1, "Demodulate a G Prox II tag from GraphBuffer"},
{"autocorr", CmdAutoCorr, 1, "[window length] [g] -- Autocorrelation over window - g to save back to GraphBuffer (overwrite)"},
{"biphaserawdecode",CmdBiphaseDecodeRaw,1, "[offset] [invert<0|1>] [maxErr] -- Biphase decode bin stream in DemodBuffer (offset = 0|1 bits to shift the decode start)"},
{"bin2hex", Cmdbin2hex, 1, "bin2hex <digits> -- Converts binary to hexadecimal"},
{"bitsamples", CmdBitsamples, 0, "Get raw samples as bitstring"},
{"buffclear", CmdBuffClear, 1, "Clear sample buffer and graph window"},
{"dec", CmdDec, 1, "Decimate samples"},
@ -2287,6 +2370,7 @@ static command_t CommandTable[] =
{"getbitstream", CmdGetBitStream, 1, "Convert GraphBuffer's >=1 values to 1 and <1 to 0"},
{"grid", CmdGrid, 1, "<x> <y> -- overlay grid on graph window, use zero value to turn off either"},
{"hexsamples", CmdHexsamples, 0, "<bytes> [<offset>] -- Dump big buffer as hex bytes"},
{"hex2bin", Cmdhex2bin, 1, "hex2bin <hexadecimal> -- Converts hexadecimal to binary"},
{"hide", CmdHide, 1, "Hide graph window"},
{"hpf", CmdHpf, 1, "Remove DC offset from trace"},
{"load", CmdLoad, 1, "<filename> -- Load trace (to graph window"},

View file

@ -484,7 +484,7 @@ uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, ui
oddparity ^= (((frame[j] & 0xFF) >> k) & 0x01);
}
uint8_t parityBits = parityBytes[j>>3];
if (protocol != ISO_14443B && isResponse && (oddparity != ((parityBits >> (7-(j&0x0007))) & 0x01))) {
if (protocol != ISO_14443B && (isResponse || protocol == ISO_14443A) && (oddparity != ((parityBits >> (7-(j&0x0007))) & 0x01))) {
snprintf(line[j/16]+(( j % 16) * 4),110, "%02x! ", frame[j]);
} else {
snprintf(line[j/16]+(( j % 16) * 4), 110, " %02x ", frame[j]);

View file

@ -132,17 +132,21 @@ int CmdHF14BCmdRaw (const char *Cmd) {
bool reply = true;
bool crc = false;
bool power = false;
bool select = false;
bool SRx = false;
char buf[5] = "";
uint8_t data[100] = {0x00};
uint8_t datalen = 0;
unsigned int temp;
int i = 0;
if (strlen(Cmd)<3) {
PrintAndLog("Usage: hf 14b raw [-r] [-c] [-p] <0A 0B 0C ... hex>");
PrintAndLog("Usage: hf 14b raw [-r] [-c] [-p] [-s || -ss] <0A 0B 0C ... hex>");
PrintAndLog(" -r do not read response");
PrintAndLog(" -c calculate and append CRC");
PrintAndLog(" -p leave the field on after receive");
return 0;
PrintAndLog(" -s active signal field ON with select");
PrintAndLog(" -ss active signal field ON with select for SRx ST Microelectronics tags");
return 0;
}
// strip
@ -164,6 +168,14 @@ int CmdHF14BCmdRaw (const char *Cmd) {
case 'P':
power = true;
break;
case 's':
case 'S':
select = true;
if (Cmd[i+2]=='s' || Cmd[i+2]=='S') {
SRx = true;
i++;
}
break;
default:
PrintAndLog("Invalid option");
return 0;
@ -186,7 +198,7 @@ int CmdHF14BCmdRaw (const char *Cmd) {
continue;
}
PrintAndLog("Invalid char on input");
return 1;
return 0;
}
if (datalen == 0)
{
@ -194,11 +206,58 @@ int CmdHF14BCmdRaw (const char *Cmd) {
return 0;
}
if (select){ //auto select 14b tag
uint8_t cmd2[16];
bool crc2 = true;
uint8_t cmdLen;
if (SRx) {
// REQ SRx
cmdLen = 2;
cmd2[0] = 0x06;
cmd2[1] = 0x00;
} else {
cmdLen = 3;
// REQB
cmd2[0] = 0x05;
cmd2[1] = 0x00;
cmd2[2] = 0x08;
}
if (HF14BCmdRaw(true, &crc2, true, cmd2, &cmdLen, false)==0) return rawClose();
if ( SRx && (cmdLen != 3 || !crc2) ) return rawClose();
else if (cmd2[0] != 0x50 || cmdLen != 14 || !crc2) return rawClose();
uint8_t chipID = 0;
if (SRx) {
// select
chipID = cmd2[0];
cmd2[0] = 0x0E;
cmd2[1] = chipID;
cmdLen = 2;
} else {
// attrib
cmd2[0] = 0x1D;
// UID from cmd2[1 - 4]
cmd2[5] = 0x00;
cmd2[6] = 0x08;
cmd2[7] = 0x01;
cmd2[8] = 0x00;
cmdLen = 9;
}
if (HF14BCmdRaw(true, &crc2, true, cmd2, &cmdLen, false)==0) return rawClose();
if (cmdLen != 3 || !crc2) return rawClose();
if (SRx && cmd2[0] != chipID) return rawClose();
}
return HF14BCmdRaw(reply, &crc, power, data, &datalen, true);
}
// print full atqb info
static void print_atqb_resp(uint8_t *data){
PrintAndLog (" UID: %s", sprint_hex(data+1,4));
//PrintAndLog (" UID: %s", sprint_hex(data+1,4));
PrintAndLog (" App Data: %s", sprint_hex(data+5,4));
PrintAndLog (" Protocol: %s", sprint_hex(data+9,3));
uint8_t BitRate = data[9];
@ -233,18 +292,20 @@ static void print_atqb_resp(uint8_t *data){
else
maxFrame = 257;
PrintAndLog ("Max Frame Size: %d%s",maxFrame, (maxFrame == 257) ? "+ RFU" : "");
PrintAndLog ("Max Frame Size: %u%s",maxFrame, (maxFrame == 257) ? "+ RFU" : "");
uint8_t protocolT = data[10] & 0xF;
PrintAndLog (" Protocol Type: Protocol is %scompliant with ISO/IEC 14443-4",(protocolT) ? "" : "not " );
PrintAndLog ("Frame Wait Int: %d", data[11]>>4);
PrintAndLog ("Frame Wait Int: %u", data[11]>>4);
PrintAndLog (" App Data Code: Application is %s",(data[11]&4) ? "Standard" : "Proprietary");
PrintAndLog (" Frame Options: NAD is %ssupported",(data[11]&2) ? "" : "not ");
PrintAndLog (" Frame Options: CID is %ssupported",(data[11]&1) ? "" : "not ");
PrintAndLog ("Max Buf Length: %u (MBLI) %s",data[14]>>4, (data[14] & 0xF0) ? "" : "not supported");
return;
}
// get SRx chip model (from UID) // from ST Microelectronics
char *get_ST_Chip_Model(uint8_t data){
static char model[20];
char *retStr = model;
@ -263,20 +324,86 @@ char *get_ST_Chip_Model(uint8_t data){
return retStr;
}
static void print_st_info(uint8_t *data){
int print_ST_Lock_info(uint8_t model){
//assume connection open and tag selected...
uint8_t data[16] = {0x00};
uint8_t datalen = 2;
bool crc = true;
uint8_t resplen;
uint8_t blk1;
data[0] = 0x08;
if (model == 0x2) { //SR176 has special command:
data[1] = 0xf;
resplen = 4;
} else {
data[1] = 0xff;
resplen = 6;
}
//std read cmd
if (HF14BCmdRaw(true, &crc, true, data, &datalen, false)==0) return rawClose();
if (datalen != resplen || !crc) return rawClose();
PrintAndLog("Chip Write Protection Bits:");
// now interpret the data
switch (model){
case 0x0: //fall through (SRIX4K special)
case 0x3: //fall through (SRIx4K)
case 0x7: // (SRI4K)
//only need data[3]
blk1 = 9;
PrintAndLog(" raw: %s",printBits(1,data+3));
PrintAndLog(" 07/08:%slocked", (data[3] & 1) ? " not " : " " );
for (uint8_t i = 1; i<8; i++){
PrintAndLog(" %02u:%slocked", blk1, (data[3] & (1 << i)) ? " not " : " " );
blk1++;
}
break;
case 0x4: //fall through (SRIX512)
case 0x6: //fall through (SRI512)
case 0xC: // (SRT512)
//need data[2] and data[3]
blk1 = 0;
PrintAndLog(" raw: %s",printBits(2,data+2));
for (uint8_t b=2; b<4; b++){
for (uint8_t i=0; i<8; i++){
PrintAndLog(" %02u:%slocked", blk1, (data[b] & (1 << i)) ? " not " : " " );
blk1++;
}
}
break;
case 0x2: // (SR176)
//need data[2]
blk1 = 0;
PrintAndLog(" raw: %s",printBits(1,data+2));
for (uint8_t i = 0; i<8; i++){
PrintAndLog(" %02u/%02u:%slocked", blk1, blk1+1, (data[2] & (1 << i)) ? " " : " not " );
blk1+=2;
}
break;
default:
return rawClose();
}
return 1;
}
// print UID info from SRx chips (ST Microelectronics)
static void print_st_general_info(uint8_t *data){
//uid = first 8 bytes in data
PrintAndLog(" UID: %s", sprint_hex(SwapEndian64(data,8,8),8));
PrintAndLog(" MFG: %02X, %s", data[6], getTagInfo(data[6]));
PrintAndLog("Chip: %02X, %s", data[5]>>2, get_ST_Chip_Model(data[5]>>2));
PrintAndLog(" UID: %s", sprint_hex(SwapEndian64(data,8,8),8));
PrintAndLog(" MFG: %02X, %s", data[6], getTagInfo(data[6]));
PrintAndLog(" Chip: %02X, %s", data[5]>>2, get_ST_Chip_Model(data[5]>>2));
return;
}
int HF14BStdInfo(uint8_t *data, uint8_t *datalen){
// 14b get and print UID only (general info)
int HF14BStdReader(uint8_t *data, uint8_t *datalen){
//05 00 00 = find one tag in field
//1d xx xx xx xx 20 00 08 01 00 = attrib xx=crc
//a3 = ? (resp 03 e2 c2)
//02 = ? (resp 02 6a d3)
//1d xx xx xx xx 00 08 01 00 = attrib xx=UID (resp 10 [f9 e0])
//a3 = ? (resp 03 [e2 c2])
//02 = ? (resp 02 [6a d3])
// 022b (resp 02 67 00 [29 5b])
// 0200a40400 (resp 02 67 00 [29 5b])
// 0200a4040c07a0000002480300 (resp 02 67 00 [29 5b])
@ -289,24 +416,60 @@ int HF14BStdInfo(uint8_t *data, uint8_t *datalen){
//03 = ? (resp 03 [e3 c2])
//c2 = ? (resp c2 [66 15])
//b2 = ? (resp a3 [e9 67])
//a2 = ? (resp 02 [6a d3])
bool crc = true;
*datalen = 3;
//std read cmd
data[0] = 0x05;
data[1] = 0x00;
data[2] = 0x00;
data[2] = 0x08;
if (HF14BCmdRaw(true, &crc, false, data, datalen, false)==0) return 0;
if (HF14BCmdRaw(true, &crc, true, data, datalen, false)==0) return rawClose();
if (data[0] != 0x50 || *datalen != 14 || !crc) return 0;
if (data[0] != 0x50 || *datalen != 14 || !crc) return rawClose();
PrintAndLog ("\n14443-3b tag found:");
PrintAndLog (" UID: %s", sprint_hex(data+1,4));
uint8_t cmd2[16];
uint8_t cmdLen = 3;
bool crc2 = true;
cmd2[0] = 0x1D;
// UID from data[1 - 4]
cmd2[1] = data[1];
cmd2[2] = data[2];
cmd2[3] = data[3];
cmd2[4] = data[4];
cmd2[5] = 0x00;
cmd2[6] = 0x08;
cmd2[7] = 0x01;
cmd2[8] = 0x00;
cmdLen = 9;
// attrib
if (HF14BCmdRaw(true, &crc2, true, cmd2, &cmdLen, false)==0) return rawClose();
if (cmdLen != 3 || !crc2) return rawClose();
// add attrib responce to data
data[14] = cmd2[0];
rawClose();
return 1;
}
// 14b get and print Full Info (as much as we know)
int HF14BStdInfo(uint8_t *data, uint8_t *datalen){
if (!HF14BStdReader(data,datalen)) return 0;
//add more info here
print_atqb_resp(data);
return 1;
}
int HF14B_ST_Info(uint8_t *data, uint8_t *datalen){
// SRx get and print general info about SRx chip from UID
int HF14B_ST_Reader(uint8_t *data, uint8_t *datalen, bool closeCon){
bool crc = true;
*datalen = 2;
//wake cmd
@ -326,7 +489,6 @@ int HF14B_ST_Info(uint8_t *data, uint8_t *datalen){
*datalen = 2;
//leave power on
// verbose on for now for testing - turn off when functional
if (HF14BCmdRaw(true, &crc, true, data, datalen, false)==0) return rawClose();
if (*datalen != 3 || !crc || data[0] != chipID) return rawClose();
@ -335,19 +497,32 @@ int HF14B_ST_Info(uint8_t *data, uint8_t *datalen){
data[0] = 0x0B;
*datalen = 1;
//power off
// verbose on for now for testing - turn off when functional
if (HF14BCmdRaw(true, &crc, true, data, datalen, false)==0) return 0;
rawClose();
if (*datalen != 10 || !crc) return 0;
//leave power on
if (HF14BCmdRaw(true, &crc, true, data, datalen, false)==0) return rawClose();
if (*datalen != 10 || !crc) return rawClose();
//power off ?
if (closeCon) rawClose();
PrintAndLog("\n14443-3b ST tag found:");
print_st_info(data);
print_st_general_info(data);
return 1;
}
// SRx get and print full info (needs more info...)
int HF14B_ST_Info(uint8_t *data, uint8_t *datalen){
if (!HF14B_ST_Reader(data, datalen, false)) return 0;
//add locking bit information here.
if (print_ST_Lock_info(data[5]>>2))
rawClose();
return 1;
}
// test for other 14b type tags (mimic another reader - don't have tags to identify)
int HF14B_Other_Info(uint8_t *data, uint8_t *datalen){
int HF14B_Other_Reader(uint8_t *data, uint8_t *datalen){
bool crc = true;
*datalen = 4;
//std read cmd
@ -356,11 +531,12 @@ int HF14B_Other_Info(uint8_t *data, uint8_t *datalen){
data[2] = 0x3f;
data[3] = 0x80;
if (HF14BCmdRaw(true, &crc, false, data, datalen, false)!=0) {
if (HF14BCmdRaw(true, &crc, true, data, datalen, false)!=0) {
if (*datalen > 2 || !crc) {
PrintAndLog ("\n14443-3b tag found:");
PrintAndLog ("Unknown tag type answered to a 0x000b3f80 command ans:");
PrintAndLog ("%s",sprint_hex(data,*datalen));
rawClose();
return 1;
}
}
@ -369,11 +545,12 @@ int HF14B_Other_Info(uint8_t *data, uint8_t *datalen){
*datalen = 1;
data[0] = 0x0a;
if (HF14BCmdRaw(true, &crc, false, data, datalen, false)!=0) {
if (HF14BCmdRaw(true, &crc, true, data, datalen, false)!=0) {
if (*datalen > 0) {
PrintAndLog ("\n14443-3b tag found:");
PrintAndLog ("Unknown tag type answered to a 0x0A command ans:");
PrintAndLog ("%s",sprint_hex(data,*datalen));
rawClose();
return 1;
}
}
@ -382,19 +559,20 @@ int HF14B_Other_Info(uint8_t *data, uint8_t *datalen){
*datalen = 1;
data[0] = 0x0c;
if (HF14BCmdRaw(true, &crc, false, data, datalen, false)!=0) {
if (HF14BCmdRaw(true, &crc, true, data, datalen, false)!=0) {
if (*datalen > 0) {
PrintAndLog ("\n14443-3b tag found:");
PrintAndLog ("Unknown tag type answered to a 0x0C command ans:");
PrintAndLog ("%s",sprint_hex(data,*datalen));
rawClose();
return 1;
}
}
rawClose();
return 0;
}
// get and print all info known about any known 14b tag
int HF14BInfo(bool verbose){
uint8_t data[100];
uint8_t datalen = 5;
@ -407,16 +585,41 @@ int HF14BInfo(bool verbose){
// try unknown 14b read commands (to be identified later)
// could be read of calypso, CEPAS, moneo, or pico pass.
if (HF14B_Other_Info(data, &datalen)) return 1;
if (HF14B_Other_Reader(data, &datalen)) return 1;
if (verbose) PrintAndLog("no 14443B tag found");
return 0;
}
// menu command to get and print all info known about any known 14b tag
int CmdHF14Binfo(const char *Cmd){
return HF14BInfo(true);
}
// get and print general info about all known 14b chips
int HF14BReader(bool verbose){
uint8_t data[100];
uint8_t datalen = 5;
// try std 14b (atqb)
if (HF14BStdReader(data, &datalen)) return 1;
// try st 14b
if (HF14B_ST_Reader(data, &datalen, true)) return 1;
// try unknown 14b read commands (to be identified later)
// could be read of calypso, CEPAS, moneo, or pico pass.
if (HF14B_Other_Reader(data, &datalen)) return 1;
if (verbose) PrintAndLog("no 14443B tag found");
return 0;
}
// menu command to get and print general info about all known 14b chips
int CmdHF14BReader(const char *Cmd){
return HF14BReader(true);
}
int CmdSriWrite( const char *Cmd){
/*
* For SRIX4K blocks 00 - 7F
@ -487,8 +690,9 @@ int CmdSriWrite( const char *Cmd){
static command_t CommandTable[] =
{
{"help", CmdHelp, 1, "This help"},
{"info", CmdHF14Binfo, 0, "Find and print info about a 14b type tag (HF ISO 14443b)"},
{"list", CmdHF14BList, 0, "[Deprecated] List ISO 14443b history"},
{"info", CmdHF14Binfo, 0, "Find and print details about a 14443B tag"},
{"list", CmdHF14BList, 0, "[Deprecated] List ISO 14443B history"},
{"reader", CmdHF14BReader, 0, "Act as a 14443B reader to identify a tag"},
{"sim", CmdHF14BSim, 0, "Fake ISO 14443B tag"},
{"snoop", CmdHF14BSnoop, 0, "Eavesdrop ISO 14443B"},
{"sri512read", CmdSri512Read, 0, "Read contents of a SRI512 tag"},

View file

@ -18,7 +18,6 @@ int CmdHF14AMifare(const char *Cmd)
uint32_t nt = 0, nr = 0;
uint64_t par_list = 0, ks_list = 0, r_key = 0;
int16_t isOK = 0;
uint8_t keyBlock[8] = {0};
UsbCommand c = {CMD_READER_MIFARE, {true, 0, 0}};
@ -74,22 +73,13 @@ start:
if (nonce2key(uid, nt, nr, par_list, ks_list, &r_key)) {
isOK = 2;
PrintAndLog("Key not found (lfsr_common_prefix list is null). Nt=%08x", nt);
} else {
printf("------------------------------------------------------------------\n");
PrintAndLog("Key found:%012"llx" \n", r_key);
num_to_bytes(r_key, 6, keyBlock);
isOK = mfCheckKeys(0, 0, 1, keyBlock, &r_key);
}
if (!isOK)
PrintAndLog("Found valid key:%012"llx, r_key);
else
{
if (isOK != 2) PrintAndLog("Found invalid key. ");
PrintAndLog("Failing is expected to happen in 25%% of all cases. Trying again with a different reader nonce...");
c.arg[0] = false;
goto start;
} else {
isOK = 0;
printf("------------------------------------------------------------------\n");
PrintAndLog("Found valid key:%012"llx" \n", r_key);
}
PrintAndLog("");
@ -689,7 +679,7 @@ int CmdHF14AMfNested(const char *Cmd)
for (j = 0; j < 2; j++) {
if (e_sector[i].foundKey[j]) continue;
res = mfCheckKeys(FirstBlockOfSector(i), j, 6, keyBlock, &key64);
res = mfCheckKeys(FirstBlockOfSector(i), j, true, 6, keyBlock, &key64);
if (!res) {
e_sector[i].Key[j] = key64;
@ -973,7 +963,7 @@ int CmdHF14AMfChk(const char *Cmd)
uint32_t max_keys = keycnt>USB_CMD_DATA_SIZE/6?USB_CMD_DATA_SIZE/6:keycnt;
for (uint32_t c = 0; c < keycnt; c+=max_keys) {
uint32_t size = keycnt-c>max_keys?max_keys:keycnt-c;
res = mfCheckKeys(b, t, size, &keyBlock[6*c], &key64);
res = mfCheckKeys(b, t, true, size, &keyBlock[6*c], &key64);
if (res != 1) {
if (!res) {
PrintAndLog("Found valid key:[%012"llx"]",key64);

View file

@ -18,6 +18,7 @@
#include "cmdhw.h"
#include "cmdmain.h"
#include "cmddata.h"
#include "data.h"
/* low-level hardware control */
@ -405,39 +406,72 @@ int CmdTune(const char *Cmd)
int CmdVersion(const char *Cmd)
{
clearCommandBuffer();
UsbCommand c = {CMD_VERSION};
static UsbCommand resp = {0, {0, 0, 0}};
if (resp.arg[0] == 0 && resp.arg[1] == 0) { // no cached information available
SendCommand(&c);
if (WaitForResponseTimeout(CMD_ACK,&resp,1000) && Cmd != NULL) {
if (WaitForResponseTimeout(CMD_ACK,&resp,1000)) {
PrintAndLog("Prox/RFID mark3 RFID instrument");
PrintAndLog((char*)resp.d.asBytes);
lookupChipID(resp.arg[0], resp.arg[1]);
}
} else if (Cmd != NULL) {
} else {
PrintAndLog("[[[ Cached information ]]]\n");
PrintAndLog("Prox/RFID mark3 RFID instrument");
PrintAndLog((char*)resp.d.asBytes);
lookupChipID(resp.arg[0], resp.arg[1]);
PrintAndLog("");
}
return 0;
}
int CmdStatus(const char *Cmd)
{
uint8_t speed_test_buffer[USB_CMD_DATA_SIZE];
sample_buf = speed_test_buffer;
clearCommandBuffer();
UsbCommand c = {CMD_STATUS};
SendCommand(&c);
if (!WaitForResponseTimeout(CMD_ACK,&c,1900)) {
PrintAndLog("Status command failed. USB Speed Test timed out");
}
return 0;
}
int CmdPing(const char *Cmd)
{
clearCommandBuffer();
UsbCommand resp;
UsbCommand c = {CMD_PING};
SendCommand(&c);
if (WaitForResponseTimeout(CMD_ACK,&resp,1000)) {
PrintAndLog("Ping successfull");
}else{
PrintAndLog("Ping failed");
}
return 0;
}
static command_t CommandTable[] =
{
{"help", CmdHelp, 1, "This help"},
{"detectreader", CmdDetectReader,0, "['l'|'h'] -- Detect external reader field (option 'l' or 'h' to limit to LF or HF)"},
{"fpgaoff", CmdFPGAOff, 0, "Set FPGA off"},
{"lcd", CmdLCD, 0, "<HEX command> <count> -- Send command/data to LCD"},
{"lcdreset", CmdLCDReset, 0, "Hardware reset LCD"},
{"readmem", CmdReadmem, 0, "[address] -- Read memory at decimal address from flash"},
{"reset", CmdReset, 0, "Reset the Proxmark3"},
{"setlfdivisor", CmdSetDivisor, 0, "<19 - 255> -- Drive LF antenna at 12Mhz/(divisor+1)"},
{"setmux", CmdSetMux, 0, "<loraw|hiraw|lopkd|hipkd> -- Set the ADC mux to a specific value"},
{"tune", CmdTune, 0, "Measure antenna tuning"},
{"version", CmdVersion, 0, "Show version information about the connected Proxmark"},
{NULL, NULL, 0, NULL}
{"help", CmdHelp, 1, "This help"},
{"detectreader", CmdDetectReader,0, "['l'|'h'] -- Detect external reader field (option 'l' or 'h' to limit to LF or HF)"},
{"fpgaoff", CmdFPGAOff, 0, "Set FPGA off"},
{"lcd", CmdLCD, 0, "<HEX command> <count> -- Send command/data to LCD"},
{"lcdreset", CmdLCDReset, 0, "Hardware reset LCD"},
{"readmem", CmdReadmem, 0, "[address] -- Read memory at decimal address from flash"},
{"reset", CmdReset, 0, "Reset the Proxmark3"},
{"setlfdivisor", CmdSetDivisor, 0, "<19 - 255> -- Drive LF antenna at 12Mhz/(divisor+1)"},
{"setmux", CmdSetMux, 0, "<loraw|hiraw|lopkd|hipkd> -- Set the ADC mux to a specific value"},
{"tune", CmdTune, 0, "Measure antenna tuning"},
{"version", CmdVersion, 0, "Show version information about the connected Proxmark"},
{"status", CmdStatus, 0, "Show runtime status information about the connected Proxmark"},
{"ping", CmdPing, 0, "Test if the pm3 is responsive"},
{NULL, NULL, 0, NULL}
};
int CmdHW(const char *Cmd)

View file

@ -22,6 +22,7 @@
#include "util.h"
#include "cmdlf.h"
#include "cmdlfhid.h"
#include "cmdlfawid.h"
#include "cmdlfti.h"
#include "cmdlfem4x.h"
#include "cmdlfhitag.h"
@ -388,7 +389,7 @@ int usage_lf_config()
PrintAndLog(" b <bps> Sets resolution of bits per sample. Default (max): 8");
PrintAndLog(" d <decim> Sets decimation. A value of N saves only 1 in N samples. Default: 1");
PrintAndLog(" a [0|1] Averaging - if set, will average the stored sample value when decimating. Default: 1");
PrintAndLog(" t <threshold> Sets trigger threshold. 0 means no threshold");
PrintAndLog(" t <threshold> Sets trigger threshold. 0 means no threshold (range: 0-128)");
PrintAndLog("Examples:");
PrintAndLog(" lf config b 8 L");
PrintAndLog(" Samples at 125KHz, 8bps.");
@ -1130,6 +1131,7 @@ static command_t CommandTable[] =
{"config", CmdLFSetConfig, 0, "Set config for LF sampling, bit/sample, decimation, frequency"},
{"flexdemod", CmdFlexdemod, 1, "Demodulate samples for FlexPass"},
{"hid", CmdLFHID, 1, "{ HID RFIDs... }"},
{"awid", CmdLFAWID, 1, "{ AWID RFIDs... }"},
{"io", CmdLFIO, 1, "{ ioProx tags... }"},
{"indalademod", CmdIndalaDemod, 1, "['224'] -- Demodulate samples for Indala 64 bit UID (option '224' for 224 bit)"},
{"indalaclone", CmdIndalaClone, 0, "<UID> ['l']-- Clone Indala to T55x7 (tag must be in antenna)(UID in HEX)(option 'l' for 224 UID"},

237
client/cmdlfawid.c Normal file
View file

@ -0,0 +1,237 @@
//-----------------------------------------------------------------------------
// Authored by Craig Young <cyoung@tripwire.com> based on cmdlfhid.c structure
//
// cmdlfhid.c is Copyright (C) 2010 iZsh <izsh at fail0verflow.com>
//
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
// at your option, any later version. See the LICENSE.txt file for the text of
// the license.
//-----------------------------------------------------------------------------
// Low frequency AWID26 commands
//-----------------------------------------------------------------------------
#include <stdio.h> // sscanf
#include "proxmark3.h" // Definitions, USB controls, etc
#include "ui.h" // PrintAndLog
#include "cmdparser.h" // CmdsParse, CmdsHelp
#include "cmdlfawid.h" // AWID function declarations
#include "lfdemod.h" // parityTest
#include "cmdmain.h"
static int CmdHelp(const char *Cmd);
int usage_lf_awid_fskdemod(void) {
PrintAndLog("Enables AWID26 compatible reader mode printing details of scanned AWID26 tags.");
PrintAndLog("By default, values are printed and logged until the button is pressed or another USB command is issued.");
PrintAndLog("If the ['1'] option is provided, reader mode is exited after reading a single AWID26 card.");
PrintAndLog("");
PrintAndLog("Usage: lf awid fskdemod ['1']");
PrintAndLog(" Options : ");
PrintAndLog(" 1 : (optional) stop after reading a single card");
PrintAndLog("");
PrintAndLog(" sample : lf awid fskdemod");
PrintAndLog(" : lf awid fskdemod 1");
return 0;
}
int usage_lf_awid_sim(void) {
PrintAndLog("Enables simulation of AWID26 card with specified facility-code and card number.");
PrintAndLog("Simulation runs until the button is pressed or another USB command is issued.");
PrintAndLog("Per AWID26 format, the facility-code is 8-bit and the card number is 16-bit. Larger values are truncated.");
PrintAndLog("");
PrintAndLog("Usage: lf awid sim <Facility-Code> <Card-Number>");
PrintAndLog(" Options : ");
PrintAndLog(" <Facility-Code> : 8-bit value representing the AWID facility code");
PrintAndLog(" <Card Number> : 16-bit value representing the AWID card number");
PrintAndLog("");
PrintAndLog(" sample : lf awid sim 224 1337");
return 0;
}
int usage_lf_awid_clone(void) {
PrintAndLog("Enables cloning of AWID26 card with specified facility-code and card number onto T55x7.");
PrintAndLog("The T55x7 must be on the antenna when issuing this command. T55x7 blocks are calculated and printed in the process.");
PrintAndLog("Per AWID26 format, the facility-code is 8-bit and the card number is 16-bit. Larger values are truncated.");
PrintAndLog("");
PrintAndLog("Usage: lf awid clone <Facility-Code> <Card-Number>");
PrintAndLog(" Options : ");
PrintAndLog(" <Facility-Code> : 8-bit value representing the AWID facility code");
PrintAndLog(" <Card Number> : 16-bit value representing the AWID card number");
PrintAndLog("");
PrintAndLog(" sample : lf awid clone 224 1337");
return 0;
}
int CmdAWIDDemodFSK(const char *Cmd)
{
int findone=0;
if(Cmd[0]=='1') findone=1;
if (Cmd[0]=='h' || Cmd[0] == 'H') return usage_lf_awid_fskdemod();
UsbCommand c={CMD_AWID_DEMOD_FSK};
c.arg[0]=findone;
SendCommand(&c);
return 0;
}
int getAWIDBits(unsigned int fc, unsigned int cn, uint8_t *AWIDBits)
{
int i;
uint32_t fcode=(fc & 0x000000FF), cnum=(cn & 0x0000FFFF), uBits=0;
if (fcode != fc)
PrintAndLog("NOTE: Facility code truncated for AWID26 format (8-bit facility code)");
if (cnum!=cn)
PrintAndLog("NOTE: Card number was truncated for AWID26 format (16-bit card number)");
AWIDBits[0] = 0x01; // 6-bit Preamble with 2 parity bits
AWIDBits[1] = 0x1D; // First byte from card format (26-bit) plus parity bits
AWIDBits[2] = 0x80; // Set the next two bits as 0b10 to finish card format
uBits = (fcode<<4) + (cnum>>12);
if (!parityTest(uBits,12,0))
AWIDBits[2] |= (1<<5); // If not already even parity, set bit to make even
uBits = AWIDBits[2]>>5;
if (!parityTest(uBits, 3, 1))
AWIDBits[2] |= (1<<4);
uBits = fcode>>5; // first 3 bits of facility-code
AWIDBits[2] += (uBits<<1);
if (!parityTest(uBits, 3, 1))
AWIDBits[2]++; // Set parity bit to make odd parity
uBits = (fcode & 0x1C)>>2;
AWIDBits[3] = 0;
if (!parityTest(uBits,3,1))
AWIDBits[3] |= (1<<4);
AWIDBits[3] += (uBits<<5);
uBits = ((fcode & 0x3)<<1) + ((cnum & 0x8000)>>15); // Grab/shift 2 LSBs from facility code and add shifted MSB from cardnum
if (!parityTest(uBits,3,1))
AWIDBits[3]++; // Set LSB for parity
AWIDBits[3]+= (uBits<<1);
uBits = (cnum & 0x7000)>>12;
AWIDBits[4] = uBits<<5;
if (!parityTest(uBits,3,1))
AWIDBits[4] |= (1<<4);
uBits = (cnum & 0x0E00)>>9;
AWIDBits[4] += (uBits<<1);
if (!parityTest(uBits,3,1))
AWIDBits[4]++; // Set LSB for parity
uBits = (cnum & 0x1C0)>>6; // Next bits from card number
AWIDBits[5]=(uBits<<5);
if (!parityTest(uBits,3,1))
AWIDBits[5] |= (1<<4); // Set odd parity bit as needed
uBits = (cnum & 0x38)>>3;
AWIDBits[5]+= (uBits<<1);
if (!parityTest(uBits,3,1))
AWIDBits[5]++; // Set odd parity bit as needed
uBits = (cnum & 0x7); // Last three bits from card number!
AWIDBits[6] = (uBits<<5);
if (!parityTest(uBits,3,1))
AWIDBits[6] |= (1<<4);
uBits = (cnum & 0x0FFF);
if (!parityTest(uBits,12,1))
AWIDBits[6] |= (1<<3);
else
AWIDBits[6]++;
for (i = 7; i<12; i++)
AWIDBits[i]=0x11;
return 1;
}
int CmdAWIDSim(const char *Cmd)
{
uint32_t fcode = 0, cnum = 0, fc=0, cn=0, i=0;
uint8_t *BS, BitStream[12];
uint64_t arg1 = (10<<8) + 8; // fcHigh = 10, fcLow = 8
uint64_t arg2 = 50; // clk RF/50 invert=0
BS = BitStream;
if (sscanf(Cmd, "%u %u", &fc, &cn ) != 2) {
return usage_lf_awid_sim();
}
fcode=(fc & 0x000000FF);
cnum=(cn & 0x0000FFFF);
if (fc!=fcode)
PrintAndLog("Facility-Code (%u) truncated to 8-bits: %u",fc,fcode);
if (cn!=cnum)
PrintAndLog("Card number (%u) truncated to 16-bits: %u",cn,cnum);
PrintAndLog("Emulating AWID26 -- FC: %u; CN: %u\n",fcode,cnum);
PrintAndLog("Press pm3-button to abort simulation or run another command");
// AWID uses: fcHigh: 10, fcLow: 8, clk: 50, invert: 0
if (getAWIDBits(fc, cn, BS)) {
PrintAndLog("Running 'lf simfsk c 50 H 10 L 8 d %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x'",
BS[0],BS[1],BS[2],BS[3],BS[4],BS[5],BS[6],
BS[7],BS[8],BS[9],BS[10],BS[11]);
} else
PrintAndLog("Error with tag bitstream generation.");
UsbCommand c;
c.cmd = CMD_FSK_SIM_TAG;
c.arg[0] = arg1; // fcHigh<<8 + fcLow
c.arg[1] = arg2; // Inversion and clk setting
c.arg[2] = 96; // Bitstream length: 96-bits == 12 bytes
for (i=0; i < 96; i++)
c.d.asBytes[i] = (BS[i/8] & (1<<(7-(i%8))))?1:0;
SendCommand(&c);
return 0;
}
int CmdAWIDClone(const char *Cmd)
{
uint32_t fc=0,cn=0,blocks[4] = {0x00107060, 0, 0, 0x11111111}, i=0;
uint8_t BitStream[12];
uint8_t *BS=BitStream;
UsbCommand c, resp;
if (sscanf(Cmd, "%u %u", &fc, &cn ) != 2) {
return usage_lf_awid_clone();
}
if ((fc & 0xFF) != fc) {
fc &= 0xFF;
PrintAndLog("Facility-Code Truncated to 8-bits (AWID26): %u", fc);
}
if ((cn & 0xFFFF) != cn) {
cn &= 0xFFFF;
PrintAndLog("Card Number Truncated to 16-bits (AWID26): %u", cn);
}
if (getAWIDBits(fc,cn,BS)) {
PrintAndLog("Preparing to clone AWID26 to T55x7 with FC: %u, CN: %u (Raw: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x)",
fc,cn, BS[0],BS[1],BS[2],BS[3],BS[4],BS[5],BS[6],BS[7],BS[8],BS[9],BS[10],BS[11]);
blocks[1] = (BS[0]<<24) + (BS[1]<<16) + (BS[2]<<8) + (BS[3]);
blocks[2] = (BS[4]<<24) + (BS[5]<<16) + (BS[6]<<8) + (BS[7]);
PrintAndLog("Block 0: 0x%08x", blocks[0]);
PrintAndLog("Block 1: 0x%08x", blocks[1]);
PrintAndLog("Block 2: 0x%08x", blocks[2]);
PrintAndLog("Block 3: 0x%08x", blocks[3]);
for (i=0; i<4; i++) {
c.cmd = CMD_T55XX_WRITE_BLOCK;
c.arg[0] = blocks[i];
c.arg[1] = i;
c.arg[2] = 0;
SendCommand(&c);
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)){
PrintAndLog("Error occurred, device did not respond during write operation.");
return -1;
}
}
}
return 0;
}
static command_t CommandTable[] =
{
{"help", CmdHelp, 1, "This help"},
{"fskdemod", CmdAWIDDemodFSK, 0, "['1'] Realtime AWID FSK demodulator (option '1' for one tag only)"},
{"sim", CmdAWIDSim, 0, "<Facility-Code> <Card Number> -- AWID tag simulator"},
{"clone", CmdAWIDClone, 0, "<Facility-Code> <Card Number> -- Clone AWID to T55x7 (tag must be in range of antenna)"},
{NULL, NULL, 0, NULL}
};
int CmdLFAWID(const char *Cmd)
{
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable);
return 0;
}

24
client/cmdlfawid.h Normal file
View file

@ -0,0 +1,24 @@
//-----------------------------------------------------------------------------
// Copyright (C) 2010 iZsh <izsh at fail0verflow.com>
//
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
// at your option, any later version. See the LICENSE.txt file for the text of
// the license.
//-----------------------------------------------------------------------------
// Low frequency AWID commands
//-----------------------------------------------------------------------------
#ifndef CMDLFAWID_H__
#define CMDLFAWID_H__
int CmdLFAWID(const char *Cmd);
//int CmdAWIDDemod(const char *Cmd);
int CmdAWIDDemodFSK(const char *Cmd);
int CmdAWIDSim(const char *Cmd);
int CmdAWIDClone(const char *Cmd);
int getAWIDBits(unsigned int fc, unsigned int cn, uint8_t *AWIDBits);
int usage_lf_awid_fskdemod(void);
int usage_lf_awid_clone(void);
int usage_lf_awid_sim(void);
#endif

View file

@ -242,6 +242,7 @@ int CmdT55xxReadBlock(const char *Cmd) {
c.d.asBytes[0] = 0x1;
}
clearCommandBuffer();
SendCommand(&c);
if ( !WaitForResponseTimeout(CMD_ACK,NULL,2500) ) {
PrintAndLog("command execution time out");
@ -670,6 +671,7 @@ int CmdT55xxWriteBlock(const char *Cmd)
}
UsbCommand c = {CMD_T55XX_WRITE_BLOCK, {data, block, 0}};
UsbCommand resp;
c.d.asBytes[0] = 0x0;
PrintAndLog("Writing to block: %d data : 0x%08X", block, data);
@ -680,7 +682,12 @@ int CmdT55xxWriteBlock(const char *Cmd)
c.d.asBytes[0] = 0x1;
PrintAndLog("pwd : 0x%08X", password);
}
clearCommandBuffer();
SendCommand(&c);
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)){
PrintAndLog("Error occurred, device did not ACK write operation. (May be due to old firmware)");
return -1;
}
return 0;
}
@ -878,6 +885,7 @@ int AquireData( uint8_t block ){
// c.d.asBytes[0] = 0x1;
// }
clearCommandBuffer();
SendCommand(&c);
if ( !WaitForResponseTimeout(CMD_ACK,NULL,2500) ) {
PrintAndLog("command execution time out");

View file

@ -97,8 +97,9 @@ void storeCommand(UsbCommand *command)
memcpy(destination, command, sizeof(UsbCommand));
cmd_head = (cmd_head +1) % CMD_BUFFER_SIZE; //increment head and wrap
}
/**
* @brief getCommand gets a command from an internal circular buffer.
* @param response location to write command
@ -117,9 +118,9 @@ int getCommand(UsbCommand* response)
cmd_tail = (cmd_tail +1 ) % CMD_BUFFER_SIZE;
return 1;
}
/**
* Waits for a certain response type. This method waits for a maximum of
* ms_timeout milliseconds for a specified response command.
@ -131,33 +132,34 @@ int getCommand(UsbCommand* response)
*/
bool WaitForResponseTimeout(uint32_t cmd, UsbCommand* response, size_t ms_timeout) {
UsbCommand resp;
UsbCommand resp;
if (response == NULL)
response = &resp;
// Wait until the command is received
for(size_t dm_seconds=0; dm_seconds < ms_timeout/10; dm_seconds++) {
while(getCommand(response)) {
if(response->cmd == cmd){
return true;
}
}
msleep(10); // XXX ugh
if (dm_seconds == 200) { // Two seconds elapsed
PrintAndLog("Waiting for a response from the proxmark...");
PrintAndLog("Don't forget to cancel its operation first by pressing on the button");
}
if (response == NULL) {
response = &resp;
}
return false;
// Wait until the command is received
for(size_t dm_seconds=0; dm_seconds < ms_timeout/10; dm_seconds++) {
while(getCommand(response)) {
if(response->cmd == cmd){
return true;
}
}
msleep(10); // XXX ugh
if (dm_seconds == 200) { // Two seconds elapsed
PrintAndLog("Waiting for a response from the proxmark...");
PrintAndLog("Don't forget to cancel its operation first by pressing on the button");
}
}
return false;
}
bool WaitForResponse(uint32_t cmd, UsbCommand* response) {
return WaitForResponseTimeout(cmd,response,-1);
}
//-----------------------------------------------------------------------------
// Entry point into our code: called whenever the user types a command and
// then presses Enter, which the full command line that they typed.
@ -166,6 +168,7 @@ void CommandReceived(char *Cmd) {
CmdsParse(CommandTable, Cmd);
}
//-----------------------------------------------------------------------------
// Entry point into our code: called whenever we received a packet over USB
// that we weren't necessarily expecting, for example a debug print.
@ -189,12 +192,13 @@ void UsbCommandReceived(UsbCommand *UC)
case CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K: {
memcpy(sample_buf+(UC->arg[0]),UC->d.asBytes,UC->arg[1]);
return;
} break;
default:
storeCommand(UC);
break;
}
storeCommand(UC);
}

View file

@ -84,6 +84,7 @@ typedef struct {
#define CMD_FSK_SIM_TAG 0x021E
#define CMD_ASK_SIM_TAG 0x021F
#define CMD_PSK_SIM_TAG 0x0220
#define CMD_AWID_DEMOD_FSK 0x0221
/* CMD_SET_ADC_MUX: ext1 is 0 for lopkd, 1 for loraw, 2 for hipkd, 3 for hiraw */

View file

@ -20,7 +20,8 @@ local _commands = {
CMD_BUFF_CLEAR = 0x0105,
CMD_READ_MEM = 0x0106,
CMD_VERSION = 0x0107,
CMD_STATUS = 0x0108,
CMD_PING = 0x0109,
--// For low-frequency tags
CMD_READ_TI_TYPE = 0x0202,
CMD_WRITE_TI_TYPE = 0x0203,
@ -54,6 +55,7 @@ local _commands = {
CMD_FSK_SIM_TAG = 0x021E,
CMD_ASK_SIM_TAG = 0x021F,
CMD_PSK_SIM_TAG = 0x0220,
CMD_AWID_DEMOD_FSK = 0x0221,
--/* CMD_SET_ADC_MUX: ext1 is 0 for lopkd, 1 for loraw, 2 for hipkd, 3 for hiraw */

View file

@ -181,7 +181,7 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t * key, uint8_t trgBlockNo
crypto1_get_lfsr(statelists[0].head.slhead + i, &key64);
num_to_bytes(key64, 6, keyBlock);
key64 = 0;
if (!mfCheckKeys(statelists[0].blockNo, statelists[0].keyType, 1, keyBlock, &key64)) {
if (!mfCheckKeys(statelists[0].blockNo, statelists[0].keyType, false, 1, keyBlock, &key64)) {
num_to_bytes(key64, 6, resultKey);
break;
}
@ -193,11 +193,11 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t * key, uint8_t trgBlockNo
return 0;
}
int mfCheckKeys (uint8_t blockNo, uint8_t keyType, uint8_t keycnt, uint8_t * keyBlock, uint64_t * key){
int mfCheckKeys (uint8_t blockNo, uint8_t keyType, bool clear_trace, uint8_t keycnt, uint8_t * keyBlock, uint64_t * key){
*key = 0;
UsbCommand c = {CMD_MIFARE_CHKKEYS, {blockNo, keyType, keycnt}};
UsbCommand c = {CMD_MIFARE_CHKKEYS, {((blockNo & 0xff) | ((keyType&0xff)<<8)), clear_trace, keycnt}};
memcpy(c.d.asBytes, keyBlock, 6 * keycnt);
SendCommand(&c);

View file

@ -50,7 +50,7 @@ typedef struct {
extern char logHexFileName[FILE_PATH_SIZE];
int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t * key, uint8_t trgBlockNo, uint8_t trgKeyType, uint8_t * ResultKeys, bool calibrate);
int mfCheckKeys (uint8_t blockNo, uint8_t keyType, uint8_t keycnt, uint8_t * keyBlock, uint64_t * key);
int mfCheckKeys (uint8_t blockNo, uint8_t keyType, bool clear_trace, uint8_t keycnt, uint8_t * keyBlock, uint64_t * key);
int mfEmlGetMem(uint8_t *data, int blockNum, int blocksCount);
int mfEmlSetMem(uint8_t *data, int blockNum, int blocksCount);

View file

@ -133,7 +133,7 @@ int nonce2key(uint32_t uid, uint32_t nt, uint32_t nr, uint64_t par_info, uint64_
key64 = *(last_keylist + i);
num_to_bytes(key64, 6, keyBlock);
key64 = 0;
if (!mfCheckKeys(0, 0, 1, keyBlock, &key64)) {
if (!mfCheckKeys(0, 0, false, 1, keyBlock, &key64)) {
*key = key64;
free(last_keylist);
last_keylist = NULL;

View file

@ -88,10 +88,33 @@ function mfcrack_inner()
while not core.ukbhit() do
local result = core.WaitForResponseTimeout(cmds.CMD_ACK,1000)
if result then
-- Unpacking the three arg-parameters
local count,cmd,isOK = bin.unpack('LL',result)
if isOK ~= 1 then return nil, "Error occurred" end
--[[
I don't understand, they cmd and args are defined as uint32_t, however,
looking at the returned data, they all look like 64-bit things:
print("result", bin.unpack("HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH", result))
FF 00 00 00 00 00 00 00 <-- 64 bits of data
FE FF FF FF 00 00 00 00 <-- 64 bits of data
00 00 00 00 00 00 00 00 <-- 64 bits of data
00 00 00 00 00 00 00 00 <-- 64 bits of data
04 7F 12 E2 00 <-- this is where 'data' starts
So below I use LI to pick out the "FEFF FFFF", don't know why it works..
--]]
-- Unpacking the arg-parameters
local count,cmd,isOK = bin.unpack('LI',result)
--print("response", isOK)--FF FF FF FF
if isOK == 0xFFFFFFFF then
return nil, "Button pressed. Aborted."
elseif isOK == 0xFFFFFFFE then
return nil, "Card is not vulnerable to Darkside attack (doesn't send NACK on authentication requests). You can try 'script run mfkeys' or 'hf mf chk' to test various known keys."
elseif isOK == 0xFFFFFFFD then
return nil, "Card is not vulnerable to Darkside attack (its random number generator is not predictable). You can try 'script run mfkeys' or 'hf mf chk' to test various known keys."
elseif isOK ~= 1 then
return nil, "Error occurred"
end
-- The data-part is left

View file

@ -47,6 +47,7 @@ char * printBits(size_t const size, void const * const ptr);
uint8_t *SwapEndian64(const uint8_t *src, const size_t len, const uint8_t blockSize);
char param_getchar(const char *line, int paramnum);
int param_getptr(const char *line, int *bg, int *en, int paramnum);
uint8_t param_get8(const char *line, int paramnum);
uint8_t param_get8ex(const char *line, int paramnum, int deflt, int base);
uint32_t param_get32ex(const char *line, int paramnum, int deflt, int base);