chg: LF t55xx trace

new:  LF t55xx info
This commit is contained in:
iceman1001
2014-10-06 19:42:50 +02:00
parent 75465377b9
commit f6c18637ca
25 changed files with 929 additions and 804 deletions

8
client/.history Normal file
View File

@@ -0,0 +1,8 @@
hw tune
lf read
data plot
data sample 4000
lf t55xx rd 0
lf t55xx trac
lf t55xx rd 1
lf t55xx rd 2

View File

@@ -74,12 +74,14 @@ int Cmdaskdemod(const char *Cmd)
int i;
int c, high = 0, low = 0;
// TODO: complain if we do not give 2 arguments here !
// (AL - this doesn't make sense! we're only using one argument!!!)
sscanf(Cmd, "%i", &c);
/* Detect high and lows and clock */
// (AL - clock???)
if (c != 0 && c != 1) {
PrintAndLog("Invalid argument: %s", Cmd);
return 0;
}
/* Detect high and lows */
for (i = 0; i < GraphTraceLen; ++i)
{
if (GraphBuffer[i] > high)
@@ -87,11 +89,7 @@ int Cmdaskdemod(const char *Cmd)
else if (GraphBuffer[i] < low)
low = GraphBuffer[i];
}
if (c != 0 && c != 1) {
PrintAndLog("Invalid argument: %s", Cmd);
return 0;
}
if (GraphBuffer[0] > 0) {
GraphBuffer[0] = 1-c;
} else {

View File

@@ -24,11 +24,13 @@
#include "util.h"
#include "cmdhfmfdes.h"
uint8_t CMDPOS = 0;
uint8_t LENPOS = 1;
uint8_t key_zero_data[16] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
uint8_t key_defa_data[16] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
uint8_t key_ones_data[16] = { 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01 };
uint8_t key_picc_data[16] = { 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f };
static int CmdHelp(const char *Cmd);
static void xor(unsigned char * dst, unsigned char * src, size_t len);
@@ -147,13 +149,13 @@ int CmdHF14ADesInfo(const char *Cmd){
PrintAndLog("Command unsuccessful");
return 0;
}
PrintAndLog("---Desfire Information---------------------------------------");
PrintAndLog("");
PrintAndLog("-- Desfire Information --------------------------------------");
PrintAndLog("-------------------------------------------------------------");
PrintAndLog(" UID : %s",sprint_hex(resp.d.asBytes, 7));
PrintAndLog(" Batch number : %s",sprint_hex(resp.d.asBytes+28,5));
PrintAndLog(" Production date : week %02x, 20%02x",resp.d.asBytes[33], resp.d.asBytes[34]);
PrintAndLog("-------------------------------------------------------------");
PrintAndLog(" -----------------------------------------------------------");
PrintAndLog(" Hardware Information");
PrintAndLog(" Vendor Id : %s", GetVendorStr(resp.d.asBytes[7]));
PrintAndLog(" Type : 0x%02X",resp.d.asBytes[8]);
@@ -161,7 +163,7 @@ int CmdHF14ADesInfo(const char *Cmd){
PrintAndLog(" Version : %d.%d",resp.d.asBytes[10], resp.d.asBytes[11]);
PrintAndLog(" Storage size : %s",GetCardSizeStr(resp.d.asBytes[12]));
PrintAndLog(" Protocol : %s",GetProtocolStr(resp.d.asBytes[13]));
PrintAndLog("-------------------------------------------------------------");
PrintAndLog(" -----------------------------------------------------------");
PrintAndLog(" Software Information");
PrintAndLog(" Vendor Id : %s",GetVendorStr(resp.d.asBytes[14]));
PrintAndLog(" Type : 0x%02X",resp.d.asBytes[15]);
@@ -171,53 +173,15 @@ int CmdHF14ADesInfo(const char *Cmd){
PrintAndLog(" Protocol : %s", GetProtocolStr(resp.d.asBytes[20]));
PrintAndLog("-------------------------------------------------------------");
// Master Key settings
GetKeySettings(NULL);
UsbCommand c1 = {CMD_MIFARE_DESFIRE, { 0x03, 0x01 }};
c1.d.asBytes[0] = GET_KEY_SETTINGS;
SendCommand(&c1);
if ( !WaitForResponseTimeout(CMD_ACK,&resp,1500) ) {
return 0;
}
PrintAndLog(" Master Key settings");
if ( resp.d.asBytes[3] & (1 << 3 ) )
PrintAndLog(" 0x08 Configuration changeable");
else
PrintAndLog(" 0x08 Configuration NOT changeable");
if ( resp.d.asBytes[3] & (1 << 2 ) )
PrintAndLog(" 0x04 PICC Master Key not required for create / delete");
else
PrintAndLog(" 0x04 PICC Master Key required for create / delete");
if ( resp.d.asBytes[3] & (1 << 1 ) )
PrintAndLog(" 0x02 Free directory list access without PICC Master Key");
else
PrintAndLog(" 0x02 Directory list access with PICC Master Key");
if ( resp.d.asBytes[3] & (1 << 0 ) )
PrintAndLog(" 0x01 Allow changing the Master Key");
else
PrintAndLog(" 0x01 Master Key is not changeable anymore");
// init len
UsbCommand c2 = {CMD_MIFARE_DESFIRE, { 0x03, 0x02 }};
c2.d.asBytes[0] = GET_KEY_VERSION;
c2.d.asBytes[1] = 0x00;
SendCommand(&c2);
if ( !WaitForResponseTimeout(CMD_ACK,&resp,1500) ) {
return 0;
}
PrintAndLog("");
PrintAndLog(" Max number of keys : %d", resp.d.asBytes[4]);
PrintAndLog(" Master key Version : %d (0x%02x)", resp.d.asBytes[3], resp.d.asBytes[3]);
PrintAndLog("-------------------------------------------------------------");
UsbCommand c3 = {CMD_MIFARE_DESFIRE, { 0x03, 0x01 }};
c3.d.asBytes[0] = GET_FREE_MEMORY;
SendCommand(&c3);
// Free memory on card
c.cmd = CMD_MIFARE_DESFIRE;
c.arg[0] = (INIT | DISCONNECT);
c.arg[1] = 0x01;
c.d.asBytes[0] = GET_FREE_MEMORY;
SendCommand(&c);
if ( !WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
return 0;
}
@@ -225,7 +189,7 @@ int CmdHF14ADesInfo(const char *Cmd){
uint8_t tmp[3];
memcpy(tmp, resp.d.asBytes+3,3);
PrintAndLog(" Free memory on card : %d bytes", le24toh( tmp ));
PrintAndLog(" Available free memory on card : %d bytes", le24toh( tmp ));
PrintAndLog("-------------------------------------------------------------");
/*
@@ -240,12 +204,7 @@ int CmdHF14ADesInfo(const char *Cmd){
keys 4,5,6,7 RW
keys 8,9,10,11 W
keys 12,13,14,15 R
Session key:
16 : RndA(byte0-byte3) + RndB(byte0-byte3) + RndA(byte4-byte7) + RndB(byte4-byte7)
8 : RndA(byte0-byte3) + RndB(byte0-byte3)
AES 16 : RndA(byte0-byte3) + RndB(byte0-byte3) + RndA(byte12-byte15) + RndB(byte12-byte15)
*/
return 1;
@@ -296,29 +255,202 @@ char * GetProtocolStr(uint8_t id){
return buf;
}
void GetKeySettings( uint8_t *aid){
char messStr[512] = {0x00};
char *str = messStr;
uint8_t isOK = 0;
uint32_t options = NONE;
UsbCommand c;
UsbCommand resp;
//memset(messStr, 0x00, 512);
c.cmd = CMD_MIFARE_DESFIRE;
if ( aid == NULL ){
PrintAndLog(" CMK - PICC, Card Master Key settings ");
PrintAndLog("");
c.arg[CMDPOS] = (INIT | DISCONNECT);
c.arg[LENPOS] = 0x01;
c.d.asBytes[0] = GET_KEY_SETTINGS; // 0x45
SendCommand(&c);
if ( !WaitForResponseTimeout(CMD_ACK,&resp,1000) ) {return;}
isOK = resp.arg[0] & 0xff;
if ( !isOK ){
PrintAndLog(" Can't select master application");
return;
}
str = (resp.d.asBytes[3] & (1 << 3 )) ? "YES":"NO";
PrintAndLog(" [0x08] Configuration changeable : %s", str);
str = (resp.d.asBytes[3] & (1 << 2 )) ? "NO":"YES";
PrintAndLog(" [0x04] CMK required for create/delete : %s",str);
str = (resp.d.asBytes[3] & (1 << 1 )) ? "NO":"YES";
PrintAndLog(" [0x02] Directory list access with CMK : %s",str);
str = (resp.d.asBytes[3] & (1 << 0 )) ? "YES" : "NO";
PrintAndLog(" [0x01] CMK is changeable : %s", str);
c.arg[LENPOS] = 0x02; //LEN
c.d.asBytes[0] = GET_KEY_VERSION; //0x64
c.d.asBytes[1] = 0x00;
SendCommand(&c);
if ( !WaitForResponseTimeout(CMD_ACK,&resp,1000) ) {
return;
}
isOK = resp.arg[0] & 0xff;
if ( !isOK ){
PrintAndLog(" Can't read key-version");
return;
}
PrintAndLog("");
PrintAndLog(" Max number of keys : %d", resp.d.asBytes[4]);
PrintAndLog(" Master key Version : %d (0x%02x)", resp.d.asBytes[3], resp.d.asBytes[3]);
PrintAndLog(" ----------------------------------------------------------");
c.arg[LENPOS] = 0x02; //LEN
c.d.asBytes[0] = AUTHENTICATE; //0x0A
c.d.asBytes[1] = 0x00; // KEY 0
SendCommand(&c);
if ( !WaitForResponseTimeout(CMD_ACK,&resp,1000) ) {return;}
isOK = resp.d.asBytes[2] & 0xff;
PrintAndLog(" [0x0A] Authenticate : %s", ( isOK==0xAE ) ? "NO":"YES");
c.d.asBytes[0] = AUTHENTICATE_ISO; //0x1A
SendCommand(&c);
if ( !WaitForResponseTimeout(CMD_ACK,&resp,1000) ) {return;}
isOK = resp.d.asBytes[2] & 0xff;
PrintAndLog(" [0x1A] Authenticate ISO : %s", ( isOK==0xAE ) ? "NO":"YES");
c.d.asBytes[0] = AUTHENTICATE_AES; //0xAA
SendCommand(&c);
if ( !WaitForResponseTimeout(CMD_ACK,&resp,1000) ) {return;}
isOK = resp.d.asBytes[2] & 0xff;
PrintAndLog(" [0xAA] Authenticate AES : %s", ( isOK==0xAE ) ? "NO":"YES");
PrintAndLog("");
PrintAndLog(" ----------------------------------------------------------");
} else {
PrintAndLog(" AMK - Application Master Key settings");
// SELECT AID
c.arg[0] = (INIT | CLEARTRACE);
c.arg[LENPOS] = 0x04;
c.d.asBytes[0] = SELECT_APPLICATION; // 0x5a
memcpy(c.d.asBytes+1, aid, 3);
SendCommand(&c);
if (!WaitForResponseTimeout(CMD_ACK,&resp,1500) ) {
PrintAndLog(" Timed-out");
return;
}
isOK = resp.arg[0] & 0xff;
if ( !isOK ){
PrintAndLog(" Can't select AID: %s",sprint_hex(aid,3));
return;
}
// KEY SETTINGS
options = NONE;
c.arg[0] = options;
c.arg[LENPOS] = 0x01;
c.d.asBytes[0] = GET_KEY_SETTINGS; // 0x45
SendCommand(&c);
if ( !WaitForResponseTimeout(CMD_ACK,&resp,1500) ) {
return;
}
isOK = resp.arg[0] & 0xff;
if ( !isOK ){
PrintAndLog(" Can't read Application Master key settings");
} else {
// Access rights.
uint8_t rights = (resp.d.asBytes[3] >> 4 && 0xff);
switch (rights){
case 0x00:
str = "AMK authentication is necessary to change any key (default)";
break;
case 0x0e:
str = "Authentication with the key to be changed (same KeyNo) is necessary to change a key";
break;
case 0x0f:
str = "All keys (except AMK,see Bit0) within this application are frozen";
break;
default:
str = "Authentication with the specified key is necessary to change any ley. A change key and a PICC master key (CMK) can only be changed after authentication with the master key. For keys other then the master or change key, an authentication with the same key is needed.";
break;
}
PrintAndLog("Changekey Access rights");
PrintAndLog("-- %s",str);
PrintAndLog("");
// same as CMK
str = (resp.d.asBytes[3] & (1 << 3 )) ? "YES":"NO";
PrintAndLog(" 0x08 Configuration changeable : %s", str);
str = (resp.d.asBytes[3] & (1 << 2 )) ? "NO":"YES";
PrintAndLog(" 0x04 AMK required for create/delete : %s",str);
str = (resp.d.asBytes[3] & (1 << 1 )) ? "NO":"YES";
PrintAndLog(" 0x02 Directory list access with AMK : %s",str);
str = (resp.d.asBytes[3] & (1 << 0 )) ? "YES" : "NO";
PrintAndLog(" 0x01 AMK is changeable : %s", str);
}
// KEY VERSION - AMK
c.arg[0] = NONE;
c.arg[LENPOS] = 0x02;
c.d.asBytes[0] = GET_KEY_VERSION; //0x64
c.d.asBytes[1] = 0x00;
SendCommand(&c);
if ( !WaitForResponseTimeout(CMD_ACK,&resp,1500) ) {
PrintAndLog(" Timed-out");
return;
}
int numOfKeys;
isOK = resp.arg[0] & 0xff;
if ( !isOK ){
PrintAndLog(" Can't read Application Master key version. Trying all keys");
numOfKeys = MAX_NUM_KEYS;
}
else{
numOfKeys = resp.d.asBytes[4];
PrintAndLog("");
PrintAndLog(" Max number of keys : %d", numOfKeys );
PrintAndLog(" Application Master key Version : %d (0x%02x)", resp.d.asBytes[3], resp.d.asBytes[3]);
PrintAndLog("-------------------------------------------------------------");
}
// LOOP over numOfKeys that we got before.
// From 0x01 to numOfKeys. We already got 0x00. (AMK)
for(int i=0x01; i<=0x0f; ++i){
}
}
}
int CmdHF14ADesEnumApplications(const char *Cmd){
uint32_t options = 0x00;
options |= INIT;
options |= DISCONNECT;
uint8_t isOK = 0x00;
uint8_t aid[3];
uint32_t options = (INIT | DISCONNECT);
UsbCommand c = {CMD_MIFARE_DESFIRE, {options , 0x01 }};
c.d.asBytes[0] = GET_APPLICATION_IDS; //0x6a
SendCommand(&c);
UsbCommand resp;
if ( !WaitForResponseTimeout(CMD_ACK,&resp,1500) ) {
return 0;
}
uint8_t isOK = resp.arg[0] & 0xff;
isOK = resp.arg[0] & 0xff;
if ( !isOK ){
PrintAndLog("Command unsuccessful");
return 0;
}
PrintAndLog("---Desfire Enum Applications --------------------------------");
PrintAndLog("");
PrintAndLog("-- Desfire Enumerate Applications ---------------------------");
PrintAndLog("-------------------------------------------------------------");
UsbCommand respAid;
@@ -331,47 +463,73 @@ int CmdHF14ADesEnumApplications(const char *Cmd){
PrintAndLog(" Aid %d : %02X %02X %02X ",num ,resp.d.asBytes[i],resp.d.asBytes[i+1],resp.d.asBytes[i+2]);
num++;
options = INIT;
UsbCommand cAid = {CMD_MIFARE_DESFIRE, { options, 0x04 }};
cAid.d.asBytes[0] = SELECT_APPLICATION; // 0x5a
cAid.d.asBytes[1] = resp.d.asBytes[i];
cAid.d.asBytes[2] = resp.d.asBytes[i+1];
cAid.d.asBytes[3] = resp.d.asBytes[i+2];
SendCommand(&cAid);
aid[0] = resp.d.asBytes[i];
aid[1] = resp.d.asBytes[i+1];
aid[2] = resp.d.asBytes[i+2];
GetKeySettings(aid);
// Select Application
c.arg[CMDPOS] = INIT;
c.arg[LENPOS] = 0x04;
c.d.asBytes[0] = SELECT_APPLICATION; // 0x5a
c.d.asBytes[1] = resp.d.asBytes[i];
c.d.asBytes[2] = resp.d.asBytes[i+1];
c.d.asBytes[3] = resp.d.asBytes[i+2];
SendCommand(&c);
if (!WaitForResponseTimeout(CMD_ACK,&respAid,1500) ) {
PrintAndLog(" Timed-out");
continue;
}
uint8_t isOK = respAid.arg[0] & 0xff;
if ( !isOK ){
isOK = respAid.d.asBytes[2] & 0xff;
if ( isOK != 0x00 ){
PrintAndLog(" Can't select AID: %s",sprint_hex(resp.d.asBytes+i,3));
continue;
}
options = DISCONNECT;
UsbCommand cFiles = {CMD_MIFARE_DESFIRE, { options, 0x01 }};
cFiles.d.asBytes[0] = GET_FILE_IDS; // 0x6f
SendCommand(&cFiles);
// Get File IDs
c.arg[CMDPOS] = NONE;
c.arg[LENPOS] = 0x01;
c.d.asBytes[0] = GET_FILE_IDS; // 0x6f
SendCommand(&c);
if ( !WaitForResponseTimeout(CMD_ACK,&respFiles,1500) ) {
PrintAndLog(" Timed-out");
continue;
} else {
uint8_t isOK = respFiles.arg[0] & 0xff;
isOK = respFiles.d.asBytes[2] & 0xff;
if ( !isOK ){
PrintAndLog(" No files found");
continue;
}
int respfileLen = resp.arg[1]-3-2;
for (int j=0; j< respfileLen; ++j){
PrintAndLog(" Fileid %d :", resp.d.asBytes[j+3]);
PrintAndLog(" Can't get file ids ");
} else {
int respfileLen = resp.arg[1]-3-2;
for (int j=0; j< respfileLen; ++j){
PrintAndLog(" Fileid %d :", resp.d.asBytes[j+3]);
}
}
}
// Get ISO File IDs
c.arg[CMDPOS] = DISCONNECT;
c.arg[LENPOS] = 0x01;
c.d.asBytes[0] = GET_ISOFILE_IDS; // 0x61
SendCommand(&c);
if ( !WaitForResponseTimeout(CMD_ACK,&respFiles,1500) ) {
PrintAndLog(" Timed-out");
continue;
} else {
isOK = respFiles.d.asBytes[2] & 0xff;
if ( !isOK ){
PrintAndLog(" Can't get ISO file ids ");
} else {
int respfileLen = resp.arg[1]-3-2;
for (int j=0; j< respfileLen; ++j){
PrintAndLog(" ISO Fileid %d :", resp.d.asBytes[j+3]);
}
}
}
}
PrintAndLog("-------------------------------------------------------------");
@@ -386,7 +544,7 @@ int CmdHF14ADesNonces(const char *Cmd){
//
// MIAFRE DesFire Authentication
//
#define BUFSIZE 64
#define BUFSIZE 256
int CmdHF14ADesAuth(const char *Cmd){
// NR DESC KEYLENGHT
@@ -395,22 +553,19 @@ int CmdHF14ADesAuth(const char *Cmd){
// 2 = 3DES 16
// 3 = 3K 3DES 24
// 4 = AES 16
// AUTHENTICTION MODES:
// 1 Normal
// 2 ISO
// 3 AES
uint8_t keylength = 8;
//unsigned char testinput[] = { 0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff,0x00};
unsigned char key[24]; // = { 0x75,0x28,0x78,0x39,0x74,0x93,0xCB,0x70};
unsigned char key[24];
if (strlen(Cmd)<3) {
PrintAndLog("Usage: hf mfdes auth <1|2|3> <1|2|3|4> <keyno> <key> ");
PrintAndLog(" AUTH modes 1 = normal, 2 = iso, 3 = aes");
PrintAndLog(" Crypto: 1 = DES 2 = 3DES 3 = 3K3DES 4 = AES");
PrintAndLog(" keynumber");
PrintAndLog(" Auth modes");
PrintAndLog(" 1 = normal, 2 = iso, 3 = aes");
PrintAndLog(" Crypto");
PrintAndLog(" 1 = DES 2 = 3DES 3 = 3K3DES 4 = AES");
PrintAndLog("");
PrintAndLog(" sample: hf mfdes auth 1 1 0 11223344");
PrintAndLog(" sample: hf mfdes auth 3 4 0 404142434445464748494a4b4c4d4e4f");
return 0;
}
uint8_t cmdAuthMode = param_get8(Cmd,0);
@@ -473,29 +628,27 @@ int CmdHF14ADesAuth(const char *Cmd){
c.d.asBytes[0] = keylength;
memcpy(c.d.asBytes+1, key, keylength);
//memcpy(c.d.asBytes + 30, testinput, keylength);
SendCommand(&c);
UsbCommand resp;
if (WaitForResponseTimeout(CMD_ACK,&resp,3000)) {
uint8_t isOK = resp.arg[0] & 0xff;
PrintAndLog("isOk:%02x", isOK);
} else {
PrintAndLog("Command execute timeout");
if (!WaitForResponseTimeout(CMD_ACK,&resp,3000)) {
PrintAndLog("Client command execute timeout");
return 0;
}
uint8_t * data= resp.d.asBytes;
uint8_t isOK = resp.arg[0] & 0xff;
if ( isOK) {
uint8_t * data= resp.d.asBytes;
// PrintAndLog("-------------------------------------------------------------");
PrintAndLog(" Key :%s",sprint_hex(key, keylength));
// PrintAndLog(" Plain :%s",sprint_hex(testinput, keylength));
PrintAndLog(" Encoded :%s",sprint_hex(data, keylength));
PrintAndLog("-------------------------------------------------------------");
//PrintAndLog(" Expected :B5 21 9E E8 1A A7 49 9D 21 96 68 7E 13 97 38 56");
PrintAndLog(" Key :%s",sprint_hex(key, keylength));
PrintAndLog(" SESSION :%s",sprint_hex(data, keylength));
PrintAndLog("-------------------------------------------------------------");
//PrintAndLog(" Expected :B5 21 9E E8 1A A7 49 9D 21 96 68 7E 13 97 38 56");
} else{
PrintAndLog("Client command failed.");
}
PrintAndLog("-------------------------------------------------------------");
return 1;
}

View File

@@ -18,22 +18,23 @@ int CmdHF14ADesNonces(const char *Cmd);
char * GetCardSizeStr( uint8_t fsize );
char * GetVendorStr( uint8_t id);
char * GetProtocolStr(uint8_t id);
void GetKeySettings( uint8_t * aid);
// Command options for Desfire behavior.
enum {
NONE = 0x00,
INIT = 0x01,
DISCONNECT = 0x02,
FOO = 0x04,
CLEARTRACE = 0x04,
BAR = 0x08,
} CmdOptions ;
#define CREATE_APPLICATION 0xca
#define DELETE_APPLICATION 0xda
#define GET_APPLICATION_IDS 0x6a
#define SELECT_APPLICATION 0x5a
#define FORMAT_PICC 0xfc
#define CREATE_APPLICATION 0xca
#define DELETE_APPLICATION 0xda
#define GET_APPLICATION_IDS 0x6a
#define SELECT_APPLICATION 0x5a
#define FORMAT_PICC 0xfc
#define GET_VERSION 0x60
#define READ_DATA 0xbd
#define WRITE_DATA 0x3d
@@ -48,6 +49,7 @@ enum {
#define ABORT_TRANSACTION 0xa7
#define GET_FREE_MEMORY 0x6e
#define GET_FILE_IDS 0x6f
#define GET_ISOFILE_IDS 0x61
#define GET_FILE_SETTINGS 0xf5
#define CHANGE_FILE_SETTINGS 0x5f
#define CREATE_STD_DATA_FILE 0xcd
@@ -65,9 +67,9 @@ enum {
#define GET_KEY_VERSION 0x64
#define AUTHENTICATION_FRAME 0xAF
#define MAX_NUM_KEYS 0x0F
#define MAX_APPLICATION_COUNT 28
#define MAX_FILE_COUNT 16
#define MAX_FILE_COUNT 32
#define MAX_FRAME_SIZE 60
#define NOT_YET_AUTHENTICATED 255
#define FRAME_PAYLOAD_SIZE (MAX_FRAME_SIZE - 5)

View File

@@ -21,7 +21,7 @@
#include "cmdlfem4x.h"
#include "util.h"
#include "data.h"
#define LF_TRACE_BUFF_SIZE 16000
#define LF_TRACE_BUFF_SIZE 12000
char *global_em410xId;
@@ -526,29 +526,20 @@ int CmdReadWord(const char *Cmd)
SendCommand(&c);
WaitForResponse(CMD_ACK, NULL);
uint8_t data[LF_TRACE_BUFF_SIZE];
memset(data, 0x00, LF_TRACE_BUFF_SIZE);
uint8_t data[LF_TRACE_BUFF_SIZE] = {0x00};
GetFromBigBuf(data,LF_TRACE_BUFF_SIZE,3560); //3560 -- should be offset..
WaitForResponseTimeout(CMD_ACK,NULL, 1500);
for (int j = 0; j < LF_TRACE_BUFF_SIZE; j++) {
GraphBuffer[j] = ((int)data[j]) - 128;
GraphBuffer[j] = ((int)data[j]);
}
GraphTraceLen = LF_TRACE_BUFF_SIZE;
// BiDirectional
//CmdDirectionalThreshold("70 -60");
// Askdemod
//Cmdaskdemod("1");
uint8_t bits[1000];
uint8_t bits[1000] = {0x00};
uint8_t * bitstream = bits;
memset(bitstream, 0x00, sizeof(bits));
manchester_decode(GraphBuffer, LF_TRACE_BUFF_SIZE, bitstream);
RepaintGraphWindow();
return 0;
}
@@ -575,28 +566,21 @@ int CmdReadWordPWD(const char *Cmd)
SendCommand(&c);
WaitForResponse(CMD_ACK, NULL);
uint8_t data[LF_TRACE_BUFF_SIZE];
memset(data, 0x00, LF_TRACE_BUFF_SIZE);
uint8_t data[LF_TRACE_BUFF_SIZE] = {0x00};
GetFromBigBuf(data,LF_TRACE_BUFF_SIZE,3560); //3560 -- should be offset..
WaitForResponseTimeout(CMD_ACK,NULL, 1500);
for (int j = 0; j < LF_TRACE_BUFF_SIZE; j++) {
GraphBuffer[j] = ((int)data[j]) - 128;
GraphBuffer[j] = ((int)data[j]);
}
GraphTraceLen = LF_TRACE_BUFF_SIZE;
// BiDirectional
//CmdDirectionalThreshold("70 -60");
// Askdemod
//Cmdaskdemod("1");
uint8_t bits[1000];
uint8_t bits[1000] = {0x00};
uint8_t * bitstream = bits;
memset(bitstream, 0x00, sizeof(bits));
manchester_decode(GraphBuffer, LF_TRACE_BUFF_SIZE, bitstream);
RepaintGraphWindow();
return 0;
}

View File

@@ -21,7 +21,8 @@
#include "util.h"
#include "data.h"
#define LF_TRACE_BUFF_SIZE 16000
#define LF_TRACE_BUFF_SIZE 12000 // 32 x 32 x 10 (32 bit times numofblock (7), times clock skip..)
static int CmdHelp(const char *Cmd);
@@ -50,33 +51,25 @@ int CmdReadBlk(const char *Cmd)
SendCommand(&c);
WaitForResponse(CMD_ACK, NULL);
uint8_t data[LF_TRACE_BUFF_SIZE];
memset(data, 0x00, LF_TRACE_BUFF_SIZE);
uint8_t data[LF_TRACE_BUFF_SIZE] = {0x00};
GetFromBigBuf(data,LF_TRACE_BUFF_SIZE,3560); //3560 -- should be offset..
WaitForResponseTimeout(CMD_ACK,NULL, 1500);
for (int j = 0; j < LF_TRACE_BUFF_SIZE; j++) {
GraphBuffer[j] = ((int)data[j]) - 128;
GraphBuffer[j] = ((int)data[j]) ;
}
GraphTraceLen = LF_TRACE_BUFF_SIZE;
// BiDirectional
//CmdDirectionalThreshold("70 60");
// Askdemod
//Cmdaskdemod("1");
uint8_t bits[1000];
uint8_t bits[1000] = {0x00};
uint8_t * bitstream = bits;
memset(bitstream, 0x00, sizeof(bits));
manchester_decode(GraphBuffer, LF_TRACE_BUFF_SIZE, bitstream);
RepaintGraphWindow();
return 0;
}
int CmdReadBlkPWD(const char *Cmd)
{
int Block = -1; //default to invalid block
@@ -100,8 +93,7 @@ int CmdReadBlkPWD(const char *Cmd)
SendCommand(&c);
WaitForResponse(CMD_ACK, NULL);
uint8_t data[LF_TRACE_BUFF_SIZE];
memset(data, 0x00, LF_TRACE_BUFF_SIZE);
uint8_t data[LF_TRACE_BUFF_SIZE] = {0x00};
GetFromBigBuf(data,LF_TRACE_BUFF_SIZE,3560); //3560 -- should be offset..
WaitForResponseTimeout(CMD_ACK,NULL, 1500);
@@ -111,21 +103,14 @@ int CmdReadBlkPWD(const char *Cmd)
}
GraphTraceLen = LF_TRACE_BUFF_SIZE;
// BiDirectional
//CmdDirectionalThreshold("70 -60");
// Askdemod
//Cmdaskdemod("1");
uint8_t bits[1000];
uint8_t bits[1000] = {0x00};
uint8_t * bitstream = bits;
memset(bitstream, 0x00, sizeof(bits));
manchester_decode(GraphBuffer, LF_TRACE_BUFF_SIZE, bitstream);
manchester_decode(GraphBuffer, LF_TRACE_BUFF_SIZE, bitstream);
RepaintGraphWindow();
return 0;
}
int CmdWriteBlk(const char *Cmd)
{
int Block = 8; //default to invalid block
@@ -177,39 +162,251 @@ int CmdWriteBlkPWD(const char *Cmd)
int CmdReadTrace(const char *Cmd)
{
PrintAndLog(" Reading page 1 - tracedata");
UsbCommand c = {CMD_T55XX_READ_TRACE, {0, 0, 0}};
SendCommand(&c);
UsbCommand c = {CMD_T55XX_READ_TRACE, {0, 0, 0}};
SendCommand(&c);
WaitForResponse(CMD_ACK, NULL);
uint8_t data[LF_TRACE_BUFF_SIZE];
memset(data, 0x00, LF_TRACE_BUFF_SIZE);
uint8_t data[LF_TRACE_BUFF_SIZE] = {0x00};
GetFromBigBuf(data,LF_TRACE_BUFF_SIZE,3560); //3560 -- should be offset..
WaitForResponseTimeout(CMD_ACK,NULL, 1500);
for (int j = 0; j < LF_TRACE_BUFF_SIZE; j++) {
GraphBuffer[j] = ((int)data[j]) - 128;
GraphBuffer[j] = ((int)data[j]);
//GraphBuffer[j] = ((int)data[j]) - 128;
}
GraphTraceLen = LF_TRACE_BUFF_SIZE;
// BiDirectional
//CmdDirectionalThreshold("70 -60");
// Askdemod
//Cmdaskdemod("1");
uint8_t bits[1000];
uint8_t bits[1000] = {0x00};
uint8_t * bitstream = bits;
memset(bitstream, 0x00, sizeof(bits));
manchester_decode(GraphBuffer, LF_TRACE_BUFF_SIZE, bitstream);
RepaintGraphWindow();
uint8_t si = 5;
uint32_t bl0 = PackBits(si, 32, bitstream);
uint32_t bl1 = PackBits(si+32, 32, bitstream);
uint32_t acl = PackBits(si, 8, bitstream);
si += 8;
uint32_t mfc = PackBits(si, 8, bitstream);
si += 8;
uint32_t cid = PackBits(si, 5, bitstream);
si += 5;
uint32_t icr = PackBits(si, 3, bitstream);
si += 3;
uint32_t year = PackBits(si, 4, bitstream);
si += 4;
uint32_t quarter = PackBits(si, 2, bitstream);
si += 2;
uint32_t num = PackBits(si, 12, bitstream);
si += 12;
uint32_t wafer = PackBits(si, 5, bitstream);
si += 5;
uint32_t dw = PackBits(si, 15, bitstream);
PrintAndLog("");
PrintAndLog("-- T55xx Trace Information ----------------------------------");
PrintAndLog("-------------------------------------------------------------");
PrintAndLog(" ACL Allocation class (ISO/IEC 15963-1) : 0x%02X (%d)", acl, acl);
PrintAndLog(" MFC Manufacturer ID (ISO/IEC 7816-6) : 0x%02X (%d)", mfc, mfc);
PrintAndLog(" CID : 0x%02X (%d)", cid, cid);
PrintAndLog(" ICR IC Revision : %d",icr );
PrintAndLog(" Manufactured");
PrintAndLog(" Year/Quarter : %d/%d",2000+year, quarter );
PrintAndLog(" Number : %d", num );
PrintAndLog(" Wafer number : %d", wafer);
PrintAndLog(" Die Number : %d", dw);
PrintAndLog("-------------------------------------------------------------");
PrintAndLog(" Raw Data");
PrintAndLog(" Block 0 : %08X", bl0);
PrintAndLog(" Block 1 : %08X", bl1);
PrintAndLog("-------------------------------------------------------------");
/*
TRACE - BLOCK O
Bits Definition HEX
1-8 ACL Allocation class (ISO/IEC 15963-1) 0xE0
9-16 MFC Manufacturer ID (ISO/IEC 7816-6) 0x15 Atmel Corporation
17-21 CID 0x1 = Atmel ATA5577M1 0x2 = Atmel ATA5577M2
22-24 ICR IC revision
25-28 YEAR (BCD encoded) 9 (= 2009)
29-30 QUARTER 1,2,3,4
31-32 Number
TRACE - BLOCK 1
1-12 Number
13-17 Wafer number
18-32 DW, die number sequential
*/
return 0;
}
int CmdInfo(const char *Cmd){
/*
Page 0 Block 0 Configuration data.
Normal mode
Extended mode
*/
// läs block 0 - data finns i graphbuff
CmdReadBlk("0");
uint8_t bits[1000] = {0x00};
uint8_t * bitstream = bits;
manchester_decode(GraphBuffer, LF_TRACE_BUFF_SIZE, bitstream);
uint8_t si = 5;
uint32_t bl0 = PackBits(si, 32, bitstream);
uint32_t safer = PackBits(si, 4, bitstream); si += 4;
uint32_t resv = PackBits(si, 7, bitstream); si += 7;
uint32_t dbr = PackBits(si, 3, bitstream); si += 3;
uint32_t extend = PackBits(si, 1, bitstream); si += 1;
uint32_t datamodulation = PackBits(si, 5, bitstream); si += 5;
uint32_t pskcf = PackBits(si, 2, bitstream); si += 2;
uint32_t aor = PackBits(si, 1, bitstream); si += 1;
uint32_t otp = PackBits(si, 1, bitstream); si += 1;
uint32_t maxblk = PackBits(si, 3, bitstream); si += 3;
uint32_t pwd = PackBits(si, 1, bitstream); si += 1;
uint32_t sst = PackBits(si, 1, bitstream); si += 1;
uint32_t fw = PackBits(si, 1, bitstream); si += 1;
uint32_t inv = PackBits(si, 1, bitstream); si += 1;
uint32_t por = PackBits(si, 1, bitstream); si += 1;
PrintAndLog("");
PrintAndLog("-- T55xx Configuration --------------------------------------");
PrintAndLog("-------------------------------------------------------------");
PrintAndLog(" Safer key : %s", GetSaferStr(safer));
PrintAndLog(" reserved : %d", resv);
PrintAndLog(" Data bit rate : %s", GetBitRateStr(dbr));
PrintAndLog(" eXtended mode : %s", (extend) ? "Yes - Warning":"No");
PrintAndLog(" Modulation : %s", GetModulationStr(datamodulation) );
PrintAndLog(" PSK clock freq : %d", pskcf);
PrintAndLog(" AOR - Answer on Request : %s", (aor) ? "Yes":"No");
PrintAndLog(" OTP - One Time Pad : %s", (otp) ? "Yes - Warning":"No" );
PrintAndLog(" Max block : %d", maxblk);
PrintAndLog(" Password mode : %s", (pwd) ? "Yes":"No");
PrintAndLog(" Sequence Start Terminator : %s", (sst) ? "Yes":"No");
PrintAndLog(" Fast Write : %s", (fw) ? "Yes":"No");
PrintAndLog(" Inverse data : %s", (inv) ? "Yes":"No");
PrintAndLog(" POR-Delay : %s", (por) ? "Yes":"No");
PrintAndLog("-------------------------------------------------------------");
PrintAndLog(" Raw Data");
PrintAndLog(" Block 0 : 0x%08X", bl0);
PrintAndLog("-------------------------------------------------------------");
return 0;
}
char * GetBitRateStr(uint32_t id){
static char buf[40];
char *retStr = buf;
switch (id){
case 0:
sprintf(retStr,"%d - RF/8",id);
break;
case 1:
sprintf(retStr,"%d - RF/16",id);
break;
case 2:
sprintf(retStr,"%d - RF/32",id);
break;
case 3:
sprintf(retStr,"%d - RF/40",id);
break;
case 4:
sprintf(retStr,"%d - RF/50",id);
break;
case 5:
sprintf(retStr,"%d - RF/64",id);
break;
case 6:
sprintf(retStr,"%d - RF/100",id);
break;
case 7:
sprintf(retStr,"%d - RF/128",id);
break;
default:
sprintf(retStr,"%d - (Unknown)",id);
break;
}
return buf;
}
char * GetSaferStr(uint32_t id){
static char buf[40];
char *retStr = buf;
sprintf(retStr,"%d",id);
if (id == 6) {
sprintf(retStr,"%d - pasdwd",id);
}
if (id == 9 ){
sprintf(retStr,"%d - testmode ",id);
}
return buf;
}
char * GetModulationStr( uint32_t id){
static char buf[40];
char *retStr = buf;
switch (id){
case 0:
sprintf(retStr,"%d - direct",id);
break;
case 1:
sprintf(retStr,"%d - PSK 1 phase change when input changes",id);
break;
case 2:
sprintf(retStr,"%d - PSK 2 phase change on bitclk if input high",id);
break;
case 3:
sprintf(retStr,"%d - PSK 3 phase change on rising edge of input",id);
break;
case 4:
sprintf(retStr,"%d - FSK 1 RF/8 RF/5",id);
break;
case 5:
sprintf(retStr,"%d - FSK 2 RF/8 RF/10",id);
break;
case 6:
sprintf(retStr,"%d - FSK 1a RF/5 RF/8",id);
break;
case 7:
sprintf(retStr,"%d - FSK 2a RF/10 RF/8",id);
break;
case 8:
sprintf(retStr,"%d - Manschester",id);
break;
case 16:
sprintf(retStr,"%d - Biphase",id);
break;
case 17:
sprintf(retStr,"%d - Reserved",id);
break;
default:
sprintf(retStr,"0x%02X (Unknown)",id);
break;
}
return buf;
}
uint32_t PackBits(uint8_t start, uint8_t len, uint8_t* bits){
int i = start;
int j = len-1;
uint32_t tmp = 0;
for (; j >= 0; --j, ++i){
tmp |= bits[i] << j;
}
return tmp;
}
static command_t CommandTable[] =
{
{"help", CmdHelp, 1, "This help"},
@@ -218,6 +415,7 @@ static command_t CommandTable[] =
{"wr", CmdWriteBlk, 0, "<Data> <Block> -- Write T55xx block data (page 0)"},
{"wrPWD", CmdWriteBlkPWD, 0, "<Data> <Block> <Password> -- Write T55xx block data in password mode(page 0)"},
{"trace", CmdReadTrace, 0, "Read T55xx traceability data (page 1)"},
{"info", CmdInfo, 0, "Read T55xx configuration data (page 0 / block 0"},
{NULL, NULL, 0, NULL}
};

View File

@@ -17,5 +17,9 @@ int CmdReadBlkPWD(const char *Cmd);
int CmdWriteBlk(const char *Cmd);
int CmdWriteBLkPWD(const char *Cmd);
int CmdReadTrace(const char *Cmd);
int CmdInfo(const char *Cmd);
char * GetBitRateStr(uint32_t id);
char * GetSaferStr(uint32_t id);
char * GetModulationStr( uint32_t id);
uint32_t PackBits(uint8_t start, uint8_t len, uint8_t* bitstream);
#endif

View File

@@ -12,11 +12,12 @@
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <time.h>
#include <readline/readline.h>
#include <pthread.h>
#include "ui.h"
#include "loclass/cipherutils.h"
double CursorScaleFactor;
int PlotGridX, PlotGridY, PlotGridXdefault= 64, PlotGridYdefault= 64;
@@ -85,22 +86,20 @@ void PrintAndLog(char *fmt, ...)
pthread_mutex_unlock(&print_lock);
}
void SetLogFilename(char *fn)
{
logfilename = fn;
}
int manchester_decode(const int * data, const size_t len, uint8_t * dataout){
int manchester_decode( int * data, const size_t len, uint8_t * dataout){
int bitlength = 0;
int i, clock, high, low, startindex;
low = startindex = 0;
high = 1;
uint8_t bitStream[len];
memset(bitStream, 0x00, len);
memset(bitStream, 0x00, len);
/* Detect high and lows */
for (i = 0; i < len; i++) {
@@ -112,19 +111,18 @@ int manchester_decode(const int * data, const size_t len, uint8_t * dataout){
/* get clock */
clock = GetT55x7Clock( data, len, high );
startindex = DetectFirstTransition(data, len, high, low);
startindex = DetectFirstTransition(data, len, high);
PrintAndLog(" Clock : %d", clock);
PrintAndLog(" startindex : %d", startindex);
PrintAndLog(" Clock : %d", clock);
PrintAndLog(" startindex : %d", startindex);
if (high != 1)
bitlength = ManchesterConvertFrom255(data, len, bitStream, high, low, clock, startindex);
else
bitlength= ManchesterConvertFrom1(data, len, bitStream, clock, startindex);
if ( bitlength > 0 ){
if ( bitlength > 0 )
PrintPaddedManchester(bitStream, bitlength, clock);
}
memcpy(dataout, bitStream, bitlength);
@@ -171,80 +169,112 @@ int manchester_decode(const int * data, const size_t len, uint8_t * dataout){
break;
default: break;
}
return 32;
PrintAndLog(" Found Clock : %d - trying to adjust", clock);
// When detected clock is 31 or 33 then then return
int clockmod = clock%8;
if ( clockmod == 7 )
clock += 1;
else if ( clockmod == 1 )
clock -= 1;
return clock;
}
int DetectFirstTransition(const int * data, const size_t len, int high, int low){
int DetectFirstTransition(const int * data, const size_t len, int threshold){
int i, retval;
retval = 0;
/*
Detect first transition Lo-Hi (arbitrary)
skip to the first high
*/
for (i = 0; i < len; ++i)
if (data[i] == high)
break;
/* now look for the first low */
for (; i < len; ++i) {
if (data[i] == low) {
retval = i;
int i =0;
/* now look for the first threshold */
for (; i < len; ++i) {
if (data[i] == threshold) {
break;
}
}
return retval;
}
return i;
}
int ManchesterConvertFrom255(const int * data, const size_t len, uint8_t * dataout, int high, int low, int clock, int startIndex){
int i, j, hithigh, hitlow, first, bit, bitIndex;
i = startIndex;
int i, j, z, hithigh, hitlow, bitIndex, startType;
i = 0;
bitIndex = 0;
int isDamp = 0;
int damplimit = (int)((high / 2) * 0.3);
int dampHi = (high/2)+damplimit;
int dampLow = (high/2)-damplimit;
int firstST = 0;
/*
* We assume the 1st bit is zero, it may not be
* the case: this routine (I think) has an init problem.
* Ed.
*/
bit = 0;
// i = clock frame of data
for (; i < (int)(len / clock); i++)
{
hithigh = 0;
hitlow = 0;
first = 1;
startType = -1;
z = startIndex + (i*clock);
isDamp = 0;
/* Find out if we hit both high and low peaks */
for (j = 0; j < clock; j++)
{
if (data[(i * clock) + j] == high)
{
if (data[z+j] == high){
hithigh = 1;
else if (data[(i * clock) + j] == low)
if ( startType == -1)
startType = 1;
}
if (data[z+j] == low ){
hitlow = 1;
/* it doesn't count if it's the first part of our read
because it's really just trailing from the last sequence */
if (first && (hithigh || hitlow))
hithigh = hitlow = 0;
else
first = 0;
if ( startType == -1)
startType = 0;
}
if (hithigh && hitlow)
break;
}
// No high value found, are we in a dampening field?
if ( !hithigh ) {
//PrintAndLog(" # Entering damp test at index : %d (%d)", z+j, j);
for (j = 0; j < clock/2; j++)
{
if (
(data[z+j] <= dampHi && data[z+j] >= dampLow)
){
isDamp = 1;
}
else
isDamp = 0;
}
}
/* If we didn't hit both high and low peaks, we had a bit transition */
if (!hithigh || !hitlow)
bit ^= 1;
dataout[bitIndex++] = bit;
/* Manchester Switching..
0: High -> Low
1: Low -> High
*/
if (startType == 0)
dataout[bitIndex++] = 1;
else if (startType == 1)
dataout[bitIndex++] = 0;
else
dataout[bitIndex++] = 2;
if ( isDamp ) {
firstST++;
}
if ( firstST == 4)
break;
}
return bitIndex;
}
int ManchesterConvertFrom1(const int * data, const size_t len, uint8_t * dataout, int clock, int startIndex){
PrintAndLog(" Path B");
int i,j, bitindex, lc, tolerance, warnings;
warnings = 0;
int upperlimit = len*2/clock+8;
@@ -253,7 +283,7 @@ int manchester_decode(const int * data, const size_t len, uint8_t * dataout){
tolerance = clock/4;
uint8_t decodedArr[len];
/* Then detect duration between 2 successive transitions */
/* Detect duration between 2 successive transitions */
for (bitindex = 1; i < len; i++) {
if (data[i-1] != data[i]) {
@@ -350,19 +380,19 @@ int manchester_decode(const int * data, const size_t len, uint8_t * dataout){
PrintAndLog("%s", sprint_hex(decodedArr, j));
}
void PrintPaddedManchester( uint8_t* bitStream, size_t len, size_t blocksize){
PrintAndLog(" Manchester decoded bitstream : %d bits", len);
PrintAndLog(" Manchester decoded : %d bits", len);
uint8_t mod = len % blocksize;
uint8_t div = len / blocksize;
int i;
// Now output the bitstream to the scrollback by line of 16 bits
for (i = 0; i < div*blocksize; i+=blocksize) {
uint8_t mod = len % blocksize;
uint8_t div = len / blocksize;
int i;
// Now output the bitstream to the scrollback by line of 16 bits
for (i = 0; i < div*blocksize; i+=blocksize) {
PrintAndLog(" %s", sprint_bin(bitStream+i,blocksize) );
}
if ( mod > 0 ){
PrintAndLog(" %s", sprint_bin(bitStream+i, mod) );
}
}
}
if ( mod > 0 )
PrintAndLog(" %s", sprint_bin(bitStream+i, mod) );
}

View File

@@ -25,9 +25,9 @@ extern int PlotGridX, PlotGridY, PlotGridXdefault, PlotGridYdefault;
extern int offline;
extern int flushAfterWrite; //buzzy
int manchester_decode(const int * data, const size_t len, uint8_t * dataout);
int manchester_decode( int * data, const size_t len, uint8_t * dataout);
int GetT55x7Clock( const int * data, const size_t len, int high );
int DetectFirstTransition(const int * data, const size_t len, int high, int low);
int DetectFirstTransition(const int * data, const size_t len, int low);
void PrintPaddedManchester( uint8_t * bitStream, size_t len, size_t blocksize);
void ManchesterDiffDecodedString( const uint8_t *bitStream, size_t len, uint8_t invert );
int ManchesterConvertFrom255(const int * data, const size_t len, uint8_t * dataout, int high, int low, int clock, int startIndex);