chg: LF t55xx trace

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

View file

@ -18,7 +18,7 @@ SRC_LF = lfops.c hitag2.c
SRC_ISO15693 = iso15693.c iso15693tools.c
SRC_ISO14443a = epa.c iso14443a.c mifareutil.c mifarecmd.c mifaresniff.c
SRC_ISO14443b = iso14443.c
SRC_CRAPTO1 = crapto1.c crypto1.c des.c aes.c
SRC_CRAPTO1 = crapto1.c crypto1.c des.c aes.c desfire_key.c desfire_crypto.c
SRC_CRC = iso14443crc.c crc.c crc16.c crc32.c
THUMBSRC = start.c \
@ -41,9 +41,8 @@ ARMSRC = fpgaloader.c \
$(SRC_CRC) \
legic_prng.c \
iclass.c \
mifaredesfire.c \
desfire_crypto.c \
desfire_key.c
mifaredesfire.c
# stdint.h provided locally until GCC 4.5 becomes C99 compliant
APP_CFLAGS += -I.

View file

@ -18,9 +18,9 @@
#include "util.h"
#include "printf.h"
#include "string.h"
#include <stdarg.h>
#include "legicrf.h"
#include "../include/hitag2.h"
@ -842,7 +842,7 @@ void UsbPacketReceived(uint8_t *packet, int len)
MifareDES_Auth1(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
break;
case CMD_MIFARE_DESFIRE_AUTH2:
MifareDES_Auth2(c->arg[0],c->d.asBytes);
//MifareDES_Auth2(c->arg[0],c->d.asBytes);
break;
// case CMD_MIFARE_DES_READER:
// ReaderMifareDES(c->arg[0], c->arg[1], c->d.asBytes);

View file

@ -14,27 +14,21 @@
#include <stdint.h>
#include <stddef.h>
#include <sys/types.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include <strings.h>
#include "../include/common.h"
#include "../include/hitag2.h"
#include "../include/mifare.h"
//#include <openssl/des.h>
//#include <openssl/aes.h>
//#include "des.h"
//#include "aes.h"
#include "../common/desfire.h"
#include "../common/crc32.h"
//#include "desfire_crypto.h"
//#include "desfire_key.h"
// The large multi-purpose buffer, typically used to hold A/D samples,
// maybe processed in some way.
@ -156,6 +150,7 @@ void CopyIndala224toT55x7(int uid1, int uid2, int uid3, int uid4, int uid5, int
void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t PwdMode);
void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode );
void T55xxReadTrace(void);
void TurnReadLFOn();
int DemodPCF7931(uint8_t **outBlocks);
int IsBlock0PCF7931(uint8_t *Block);
int IsBlock1PCF7931(uint8_t *Block);
@ -213,26 +208,13 @@ bool InitDesfireCard();
void MifareSendCommand(uint8_t arg0,uint8_t arg1, uint8_t *datain);
void MifareDesfireGetInformation();
void MifareDES_Auth1(uint8_t arg0,uint8_t arg1,uint8_t arg2, uint8_t *datain);
void MifareDES_Auth2(uint32_t arg0, uint8_t *datain);
int mifare_des_auth2(uint32_t uid, uint8_t *key, uint8_t *blockData);
void ReaderMifareDES(uint32_t param, uint32_t param2, uint8_t * datain);
int DesfireAPDU(uint8_t *cmd, size_t cmd_len, uint8_t *dataout);
size_t CreateAPDU( uint8_t *datain, size_t len, uint8_t *dataout);
void OnSuccess();
void OnError();
// desfire_key.h
desfirekey_t Desfire_des_key_new (const uint8_t value[8]);
desfirekey_t Desfire_3des_key_new (const uint8_t value[16]);
desfirekey_t Desfire_des_key_new_with_version (const uint8_t value[8]);
desfirekey_t Desfire_3des_key_new_with_version (const uint8_t value[16]);
desfirekey_t Desfire_3k3des_key_new (const uint8_t value[24]);
desfirekey_t Desfire_3k3des_key_new_with_version (const uint8_t value[24]);
desfirekey_t Desfire_aes_key_new (const uint8_t value[16]);
desfirekey_t Desfire_aes_key_new_with_version (const uint8_t value[16], uint8_t version);
uint8_t Desfire_key_get_version (desfirekey_t key);
void Desfire_key_set_version (desfirekey_t key, uint8_t version);
desfirekey_t Desfire_session_key_new (const uint8_t rnda[], const uint8_t rndb[], desfirekey_t authkey);
// desfire_crypto.h
void *mifare_cryto_preprocess_data (desfiretag_t tag, void *data, size_t *nbytes, off_t offset, int communication_settings);
@ -247,8 +229,6 @@ void cmac_generate_subkeys (desfirekey_t key);
void cmac (const desfirekey_t key, uint8_t *ivect, const uint8_t *data, size_t len, uint8_t *cmac);
/// iso15693.h
void RecordRawAdcSamplesIso15693(void);
void AcquireRawAdcSamplesIso15693(void);

View file

@ -11,5 +11,4 @@
#include "des.h"
//#include "aes.h"
#endif

View file

@ -16,8 +16,8 @@
*
* $Id$
*/
#include "desfire_key.h"
#include <stdlib.h>
#include "desfire_key.h"
static inline void update_key_schedules (desfirekey_t key);
@ -29,67 +29,68 @@ static inline void update_key_schedules (desfirekey_t key) {
// }
}
desfirekey_t Desfire_des_key_new (const uint8_t value[8]) {
void Desfire_des_key_new (const uint8_t value[8], desfirekey_t key) {
uint8_t data[8];
memcpy (data, value, 8);
for (int n=0; n < 8; n++)
data[n] &= 0xfe;
return Desfire_des_key_new_with_version (data);
Desfire_des_key_new_with_version (data, key);
}
desfirekey_t Desfire_des_key_new_with_version (const uint8_t value[8]) {
desfirekey_t key = NULL;
void Desfire_des_key_new_with_version (const uint8_t value[8], desfirekey_t key) {
if ( key != NULL) {
key->type = T_DES;
memcpy (key->data, value, 8);
memcpy (key->data+8, value, 8);
update_key_schedules (key);
return key;
}
}
desfirekey_t Desfire_3des_key_new (const uint8_t value[16]) {
void Desfire_3des_key_new (const uint8_t value[16], desfirekey_t key) {
uint8_t data[16];
memcpy (data, value, 16);
for (int n=0; n < 8; n++)
data[n] &= 0xfe;
for (int n=8; n < 16; n++)
data[n] |= 0x01;
return Desfire_3des_key_new_with_version (data);
Desfire_3des_key_new_with_version (data, key);
}
desfirekey_t Desfire_3des_key_new_with_version (const uint8_t value[16]) {
desfirekey_t key = NULL;
void Desfire_3des_key_new_with_version (const uint8_t value[16], desfirekey_t key) {
if ( key != NULL ){
key->type = T_3DES;
memcpy (key->data, value, 16);
update_key_schedules (key);
return key;
}
}
desfirekey_t Desfire_3k3des_key_new (const uint8_t value[24]) {
void Desfire_3k3des_key_new (const uint8_t value[24], desfirekey_t key) {
uint8_t data[24];
memcpy (data, value, 24);
for (int n=0; n < 8; n++)
data[n] &= 0xfe;
return Desfire_3k3des_key_new_with_version (data);
Desfire_3k3des_key_new_with_version (data, key);
}
desfirekey_t Desfire_3k3des_key_new_with_version (const uint8_t value[24]) {
desfirekey_t key = NULL;
void Desfire_3k3des_key_new_with_version (const uint8_t value[24], desfirekey_t key) {
if ( key != NULL){
key->type = T_3K3DES;
memcpy (key->data, value, 24);
update_key_schedules (key);
return key;
}
}
desfirekey_t Desfire_aes_key_new (const uint8_t value[16]) {
return Desfire_aes_key_new_with_version (value, 0);
void Desfire_aes_key_new (const uint8_t value[16], desfirekey_t key) {
Desfire_aes_key_new_with_version (value, 0, key);
}
desfirekey_t Desfire_aes_key_new_with_version (const uint8_t value[16], uint8_t version) {
desfirekey_t key = NULL;
void Desfire_aes_key_new_with_version (const uint8_t value[16], uint8_t version, desfirekey_t key) {
if (key != NULL) {
memcpy (key->data, value, 16);
key->type = T_AES;
key->aes_version = version;
return key;
}
}
uint8_t Desfire_key_get_version (desfirekey_t key) {
@ -98,7 +99,6 @@ uint8_t Desfire_key_get_version (desfirekey_t key) {
for (int n = 0; n < 8; n++) {
version |= ((key->data[n] & 1) << (7 - n));
}
return version;
}
@ -118,9 +118,7 @@ void Desfire_key_set_version (desfirekey_t key, uint8_t version)
}
}
desfirekey_t Desfire_session_key_new (const uint8_t rnda[], const uint8_t rndb[], desfirekey_t authkey) {
desfirekey_t key = NULL;
void Desfire_session_key_new (const uint8_t rnda[], const uint8_t rndb[], desfirekey_t authkey, desfirekey_t key) {
uint8_t buffer[24];
@ -128,14 +126,14 @@ desfirekey_t Desfire_session_key_new (const uint8_t rnda[], const uint8_t rndb[]
case T_DES:
memcpy (buffer, rnda, 4);
memcpy (buffer+4, rndb, 4);
key = Desfire_des_key_new_with_version (buffer);
Desfire_des_key_new_with_version (buffer, key);
break;
case T_3DES:
memcpy (buffer, rnda, 4);
memcpy (buffer+4, rndb, 4);
memcpy (buffer+8, rnda+4, 4);
memcpy (buffer+12, rndb+4, 4);
key = Desfire_3des_key_new_with_version (buffer);
Desfire_3des_key_new_with_version (buffer, key);
break;
case T_3K3DES:
memcpy (buffer, rnda, 4);
@ -144,15 +142,14 @@ desfirekey_t Desfire_session_key_new (const uint8_t rnda[], const uint8_t rndb[]
memcpy (buffer+12, rndb+6, 4);
memcpy (buffer+16, rnda+12, 4);
memcpy (buffer+20, rndb+12, 4);
key = Desfire_3k3des_key_new (buffer);
Desfire_3k3des_key_new (buffer, key);
break;
case T_AES:
memcpy (buffer, rnda, 4);
memcpy (buffer+4, rndb, 4);
memcpy (buffer+8, rnda+12, 4);
memcpy (buffer+12, rndb+12, 4);
key = Desfire_aes_key_new (buffer);
Desfire_aes_key_new (buffer, key);
break;
}
return key;
}

View file

@ -1,10 +1,17 @@
#ifndef __DESFIRE_KEY_H
#define __DESFIRE_KEY_H
#include <string.h>
#include <stdint.h>
#include <stdarg.h>
#ifndef __DESFIRE_KEY_INCLUDED
#define __DESFIRE_KEY_INCLUDED
#include "iso14443a.h"
#include "../common/desfire.h"
// desfire_key.h
void Desfire_des_key_new (const uint8_t value[8], desfirekey_t key);
void Desfire_3des_key_new (const uint8_t value[16], desfirekey_t key);
void Desfire_des_key_new_with_version (const uint8_t value[8], desfirekey_t key);
void Desfire_3des_key_new_with_version (const uint8_t value[16], desfirekey_t key);
void Desfire_3k3des_key_new (const uint8_t value[24], desfirekey_t key);
void Desfire_3k3des_key_new_with_version (const uint8_t value[24], desfirekey_t key);
void Desfire_aes_key_new (const uint8_t value[16], desfirekey_t key);
void Desfire_aes_key_new_with_version (const uint8_t value[16], uint8_t version,desfirekey_t key);
uint8_t Desfire_key_get_version (desfirekey_t key);
void Desfire_key_set_version (desfirekey_t key, uint8_t version);
void Desfire_session_key_new (const uint8_t rnda[], const uint8_t rndb[], desfirekey_t authkey, desfirekey_t key);
#endif

View file

@ -1205,13 +1205,6 @@ static void TransmitFor14443a(const uint8_t *cmd, int len, uint32_t *timing)
// clear TXRDY
AT91C_BASE_SSC->SSC_THR = SEC_Y;
// for(uint16_t c = 0; c < 10;) { // standard delay for each transfer (allow tag to be ready after last transmission)
// if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
// AT91C_BASE_SSC->SSC_THR = SEC_Y;
// c++;
// }
// }
uint16_t c = 0;
for(;;) {
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
@ -1224,7 +1217,6 @@ static void TransmitFor14443a(const uint8_t *cmd, int len, uint32_t *timing)
}
NextTransferTime = MAX(NextTransferTime, LastTimeProxToAirStart + REQUEST_GUARD_TIME);
}

View file

@ -31,8 +31,10 @@ void LFSetupFPGAForADC(int divisor, bool lf_field)
// Connect the A/D to the peak-detected low-frequency path.
SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
// Give it a bit of time for the resonant antenna to settle.
SpinDelay(50);
SpinDelay(150);
// Now set up the SSC to get the ADC samples that are now streaming at us.
FpgaSetupSsc();
}
@ -1143,19 +1145,20 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol)
* To compensate antenna falling times shorten the write times
* and enlarge the gap ones.
*/
#define START_GAP 250
#define WRITE_GAP 160
#define WRITE_0 144 // 192
#define WRITE_1 400 // 432 for T55x7; 448 for E5550
#define START_GAP 30*8 // 10 - 50fc 250
#define WRITE_GAP 20*8 // 8 - 30fc
#define WRITE_0 24*8 // 16 - 31fc 24fc 192
#define WRITE_1 54*8 // 48 - 63fc 54fc 432 for T55x7; 448 for E5550
// VALUES TAKEN FROM EM4x function: SendForward
// START_GAP = 440; //(55*8)
// WRITE_GAP = 128; //(16*8)
// WRITE_1 = 256 32*8; //32 cycles at 125Khz (8us each) 1
// //These timings work for 4469/4269/4305 (with the 55*8 above)
// WRITE_0 = 23*8 , 9*8 SpinDelayUs(23*8); // (8us each) 0
// START_GAP = 440; (55*8) cycles at 125Khz (8us = 1cycle)
// WRITE_GAP = 128; (16*8)
// WRITE_1 = 256 32*8; (32*8)
// These timings work for 4469/4269/4305 (with the 55*8 above)
// WRITE_0 = 23*8 , 9*8 SpinDelayUs(23*8);
#define T55xx_SAMPLES_SIZE 12000 // 32 x 32 x 10 (32 bit times numofblock (7), times clock skip..)
// Write one bit to card
void T55xxWriteBit(int bit)
@ -1163,7 +1166,7 @@ void T55xxWriteBit(int bit)
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
if (bit == 0)
if (!bit)
SpinDelayUs(WRITE_0);
else
SpinDelayUs(WRITE_1);
@ -1174,15 +1177,11 @@ void T55xxWriteBit(int bit)
// Write one card block in page 0, no lock
void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t PwdMode)
{
unsigned int i;
uint32_t i = 0;
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
// Give it a bit of time for the resonant antenna to settle.
// And for the tag to fully power up
SpinDelay(150);
// Set up FPGA, 125kHz
// Wait for config.. (192+8190xPOW)x8 == 67ms
LFSetupFPGAForADC(0, true);
// Now start writting
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
@ -1219,28 +1218,16 @@ void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t PwdMod
void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode)
{
uint8_t *dest = mifare_get_bigbufptr();
uint16_t bufferlength = 16000;
uint16_t bufferlength = T55xx_SAMPLES_SIZE;
uint32_t i = 0;
// Clear destination buffer before sending the command 0x80 = average.
memset(dest, 0x80, bufferlength);
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
// Set up FPGA, 125kHz
// Wait for config.. (192+8190xPOW)x8 == 67ms
LFSetupFPGAForADC(0, true);
// Connect the A/D to the peak-detected low-frequency path.
SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
// Now set up the SSC to get the ADC samples that are now streaming at us.
FpgaSetupSsc();
LED_D_ON();
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
// Give it a bit of time for the resonant antenna to settle.
// And for the tag to fully power up
SpinDelay(150);
// Now start writting
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
SpinDelayUs(START_GAP);
@ -1259,8 +1246,7 @@ void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode)
T55xxWriteBit(Block & i);
// Turn field on to read the response
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
TurnReadLFOn();
// Now do the acquisition
i = 0;
@ -1271,14 +1257,13 @@ void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode)
}
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
LED_D_OFF();
++i;
LED_D_OFF();
if (i > bufferlength) break;
}
}
cmd_send(CMD_ACK,0,0,0,0,0);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
LED_D_OFF();
}
@ -1286,28 +1271,14 @@ void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode)
// Read card traceability data (page 1)
void T55xxReadTrace(void){
uint8_t *dest = mifare_get_bigbufptr();
uint16_t bufferlength = 16000;
uint16_t bufferlength = T55xx_SAMPLES_SIZE;
int i=0;
// Clear destination buffer before sending the command 0x80 = average
memset(dest, 0x80, bufferlength);
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
LFSetupFPGAForADC(0, true);
// Connect the A/D to the peak-detected low-frequency path.
SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
// Now set up the SSC to get the ADC samples that are now streaming at us.
FpgaSetupSsc();
LED_D_ON();
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
// Give it a bit of time for the resonant antenna to settle.
// And for the tag to fully power up
SpinDelay(150);
// Now start writting
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
SpinDelayUs(START_GAP);
@ -1316,11 +1287,9 @@ void T55xxReadTrace(void){
T55xxWriteBit(1); //Page 1
// Turn field on to read the response
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
TurnReadLFOn();
// Now do the acquisition
i = 0;
for(;;) {
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
AT91C_BASE_SSC->SSC_THR = 0x43;
@ -1328,18 +1297,26 @@ void T55xxReadTrace(void){
}
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
LED_D_OFF();
++i;
LED_D_OFF();
if (i >= bufferlength) break;
}
}
cmd_send(CMD_ACK,0,0,0,0,0);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
LED_D_OFF();
}
void TurnReadLFOn(){
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
// Give it a bit of time for the resonant antenna to settle.
//SpinDelay(30);
SpinDelayUs(8*150);
}
/*-------------- Cloning routines -----------*/
// Copy HID id to card and setup block 0 config
void CopyHIDtoT55x7(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT)
@ -1596,7 +1573,6 @@ void WriteEM410x(uint32_t card, uint32_t id_hi, uint32_t id_lo)
// Clone Indala 64-bit tag by UID to T55x7
void CopyIndala64toT55x7(int hi, int lo)
{
//Program the 2 data blocks for supplied 64bit UID
// and the block 0 for Indala64 format
T55xxWriteBlock(hi,1,0,0);
@ -1607,15 +1583,13 @@ void CopyIndala64toT55x7(int hi, int lo)
2 << T55x7_MAXBLOCK_SHIFT,
0, 0, 0);
//Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=2;Inverse data)
// T5567WriteBlock(0x603E1042,0);
// T5567WriteBlock(0x603E1042,0);
DbpString("DONE!");
}
void CopyIndala224toT55x7(int uid1, int uid2, int uid3, int uid4, int uid5, int uid6, int uid7)
{
//Program the 7 data blocks for supplied 224bit UID
// and the block 0 for Indala224 format
T55xxWriteBlock(uid1,1,0,0);
@ -1631,10 +1605,9 @@ void CopyIndala224toT55x7(int uid1, int uid2, int uid3, int uid4, int uid5, int
7 << T55x7_MAXBLOCK_SHIFT,
0,0,0);
//Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=7;Inverse data)
// T5567WriteBlock(0x603E10E2,0);
// T5567WriteBlock(0x603E10E2,0);
DbpString("DONE!");
}
@ -2059,7 +2032,7 @@ void EM4xLogin(uint32_t Password) {
void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode) {
uint8_t *dest = mifare_get_bigbufptr();
uint16_t bufferlength = 16000;
uint16_t bufferlength = 12000;
uint32_t i = 0;
// Clear destination buffer before sending the command 0x80 = average.
@ -2081,6 +2054,9 @@ void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode) {
SendForward(fwd_bit_count);
// // Turn field on to read the response
// TurnReadLFOn();
// Now do the acquisition
i = 0;
for(;;) {

View file

@ -45,7 +45,7 @@ enum {
NONE = 0x00,
INIT = 0x01,
DISCONNECT = 0x02,
FOO = 0x04,
CLEARTRACE = 0x04,
BAR = 0x08,
} CmdOptions ;
@ -53,7 +53,7 @@ void MifareSendCommand(uint8_t arg0, uint8_t arg1, uint8_t *datain){
/* ARG0 contains flags.
0x01 = init card.
0x02 = No Disconnect
0x02 = Disconnect
0x03
*/
uint8_t flags = arg0;
@ -67,17 +67,21 @@ void MifareSendCommand(uint8_t arg0, uint8_t arg1, uint8_t *datain){
print_result(" RX : ", datain, datalen);
}
if ( flags & CLEARTRACE ){
iso14a_clear_trace();
}
if ( flags & INIT ){
if ( !InitDesfireCard() )
return;
}
int len = DesfireAPDU(datain, datalen, resp);
print_result(" <--: ", resp, len);
if ( !len ) {
if (MF_DBGLEVEL >= 4) {
print_result("ERR <--: ", resp, len);
}
if ( !len ) {
OnError();
return;
}
@ -85,8 +89,9 @@ void MifareSendCommand(uint8_t arg0, uint8_t arg1, uint8_t *datain){
// reset the pcb_blocknum,
pcb_blocknum = 0;
if ( flags & DISCONNECT )
if ( flags & DISCONNECT ){
OnSuccess();
}
cmd_send(CMD_ACK,1,len,0,resp,len);
}
@ -178,87 +183,28 @@ void MifareDesfireGetInformation(){
void MifareDES_Auth1(uint8_t mode, uint8_t algo, uint8_t keyno, uint8_t *datain){
uint8_t null_key_data[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
//uint8_t new_key_data[8] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 };
int res = 0;
desfirekey_t default_key = Desfire_des_key_new_with_version (null_key_data);
// res = Desfire_select_application (tags[i], aid);
if (res < 0) {
print_result("default key: ", default_key->data, 24 );
return;
}
return;
// pcb cid cmd key crc1 cr2
//uint8_t cmd2[] = {0x02,0x00,GET_KEY_VERSION, 0x00, 0x00, 0x00 };
int len = 0;
//uint8_t PICC_MASTER_KEY8[8] = { 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47};
uint8_t PICC_MASTER_KEY16[16] = { 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f };
//uint8_t null_key_data8[8] = {0x00};
//uint8_t null_key_data16[16] = {0x00};
//uint8_t new_key_data8[8] = { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77};
//uint8_t new_key_data16[16] = { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF};
//uint8_t* bigbuffer = mifare_get_bigbufptr();
byte_t isOK = 1;
uint8_t resp[256];
uint8_t key[24];
uint8_t IV[16];
uint8_t resp[256] = {0x00};
uint8_t IV[16] = {0x00};
// första byten håller keylength.
uint8_t keylen = datain[0];
memcpy(key, datain+1, keylen);
size_t datalen = datain[0];
if (MF_DBGLEVEL >= 1) {
uint8_t cmd[40] = {0x00};
uint8_t encRndB[16] = {0x00};
uint8_t decRndB[16] = {0x00};
uint8_t nonce[16] = {0x00};
uint8_t both[32] = {0x00};
uint8_t encBoth[32] = {0x00};
Dbprintf("MODE: %d", mode);
Dbprintf("ALGO: %d", algo);
Dbprintf("KEYNO: %d", keyno);
Dbprintf("KEYLEN: %d", keylen);
print_result("KEY", key, keylen);
}
// card select - information
byte_t buf[USB_CMD_DATA_SIZE];
iso14a_card_select_t *card = (iso14a_card_select_t*)buf;
// test of DES on ARM side.
/*
if ( mode == 1){
uint8_t IV[8];
uint8_t plain[16];
uint8_t encData[16];
uint8_t tmpData[8];
uint8_t tmpPlain[8];
memset(IV, 0, 8);
memset(tmpData, 0 ,8);
memset(tmpPlain,0 ,8);
memcpy(key, datain, 8);
memcpy(plain, datain+30, 16);
for(uint8_t i=0; i< sizeof(plain); i=i+8 ){
memcpy(tmpPlain, plain+i, 8);
des_enc( &tmpData, &tmpPlain, &key);
memcpy(encData+i, tmpData, 8);
}
}
*/
iso14a_clear_trace();
iso14a_set_tracing(TRUE);
// power up the field
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
// select the card
isOK = iso14443a_select_card(resp, card, NULL);
if (isOK != 1) {
if (MF_DBGLEVEL >= 1) {
Dbprintf("CAN'T SELECT CARD, SOMETHING WENT WRONG BEFORE AUTH");
}
OnError();
return;
}
InitDesfireCard();
LED_A_ON();
LED_B_OFF();
@ -279,82 +225,78 @@ void MifareDES_Auth1(uint8_t mode, uint8_t algo, uint8_t keyno, uint8_t *datain
//SendDesfireCommand(AUTHENTICATE_ISO, &keyno, resp);
break;
case 3:{
//defaultkey
uint8_t keybytes[16];
if (datain[1] == 0xff){
memcpy(keybytes,PICC_MASTER_KEY16,16);
} else{
memcpy(keybytes, datain+1, datalen);
}
struct desfire_key defaultkey = {0};
desfirekey_t key = &defaultkey;
Desfire_aes_key_new( keybytes, key);
AesCtx ctx;
if ( AesCtxIni(&ctx, IV, key, KEY128, CBC) < 0 ){
if (MF_DBGLEVEL >= 1) {
if ( AesCtxIni(&ctx, IV, key->data, KEY128, CBC) < 0 ){
if( MF_DBGLEVEL >= 4) {
Dbprintf("AES context failed to init");
}
OnError();
return;
}
uint8_t real_cmd[6];
real_cmd[0] = 0x90;
real_cmd[1] = 0x02;
real_cmd[2] = AUTHENTICATE_AES;
real_cmd[3] = keyno;
AppendCrc14443a(real_cmd, 4);
ReaderTransmit(real_cmd, sizeof(real_cmd), NULL);
int len = ReaderReceive(resp);
if(!len) {
cmd[0] = AUTHENTICATE_AES;
cmd[1] = 0x00; //keynumber
len = DesfireAPDU(cmd, 2, resp);
if ( !len ) {
if (MF_DBGLEVEL >= 1) {
DbpString("Authentication failed. Card timeout.");
}
OnError();
return;
}
print_result("RX:", resp, len);
enum DESFIRE_STATUS status = resp[1];
if ( status != ADDITIONAL_FRAME) {
OnError();
return;
}
// tags enc nonce
uint8_t encRndB[16];
uint8_t decRndB[16];
uint8_t nonce[16];
uint8_t both[32];
uint8_t encBoth[32];
memset(nonce, 0, 16);
memcpy( encRndB, resp+2, 16);
memcpy( encRndB, resp+3, 16);
// dekryptera tagnonce.
AesDecrypt(&ctx, encRndB, decRndB, 16);
rol(decRndB,16);
memcpy(both, nonce,16);
memcpy(both+16, decRndB ,16 );
AesEncrypt(&ctx, both, encBoth, 32 );
uint8_t real_cmd_A[36];
real_cmd_A[0] = 0x03;
real_cmd_A[1] = ADDITIONAL_FRAME;
cmd[0] = ADDITIONAL_FRAME;
memcpy(cmd+1, encBoth, 32 );
memcpy(real_cmd_A+2, encBoth, sizeof(encBoth) );
AppendCrc14443a(real_cmd_A, 34);
ReaderTransmit(real_cmd_A, sizeof(real_cmd_A), NULL);
len = DesfireAPDU(cmd, 33, resp); // 1 + 32 == 33
if ( !len ) {
if (MF_DBGLEVEL >= 1) {
DbpString("Authentication failed. Card timeout.");
}
OnError();
return;
}
len = ReaderReceive(resp);
print_result("Auth1a ", resp, 36);
status = resp[1];
if ( status != OPERATION_OK) {
Dbprintf("Cmd Error: %02x Len: %d", status,len);
if ( resp[2] == 0x00 ){
// Create AES Session key
struct desfire_key sessionKey = {0};
desfirekey_t skey = &sessionKey;
Desfire_session_key_new( nonce, decRndB , key, skey );
print_result("SESSION : ", skey->data, 16);
} else {
DbpString("Authetication failed.");
OnError();
return;
}
break;
}
}
OnSuccess(resp);
OnSuccess();
cmd_send(CMD_ACK,1,len,0,resp,len);
}
// 3 olika ISO sätt att skicka data till DESFIRE (direkt, inkapslat, inkapslat ISO)
@ -365,7 +307,7 @@ int DesfireAPDU(uint8_t *cmd, size_t cmd_len, uint8_t *dataout){
uint32_t status = 0;
size_t wrappedLen = 0;
uint8_t wCmd[USB_CMD_DATA_SIZE];
uint8_t wCmd[USB_CMD_DATA_SIZE] = {0};
wrappedLen = CreateAPDU( cmd, cmd_len, wCmd);
@ -376,7 +318,10 @@ int DesfireAPDU(uint8_t *cmd, size_t cmd_len, uint8_t *dataout){
status = ReaderReceive(dataout);
if(!status){
if( status == 0x00){
if (MF_DBGLEVEL >= 4) {
Dbprintf("fukked");
}
return FALSE; //DATA LINK ERROR
}
// if we received an I- or R(ACK)-Block with a block number equal to the
@ -416,159 +361,6 @@ size_t CreateAPDU( uint8_t *datain, size_t len, uint8_t *dataout){
// crc_update(&desfire_crc32, byte, 8);
// uint32_t crc = crc_finish(&desfire_crc32);
/* Version
//uint8_t versionCmd1[] = {0x02, 0x60};
//uint8_t versionCmd2[] = {0x03, 0xaf};
//uint8_t versionCmd3[] = {0x02, 0xaf};
// AUTH 1 - CMD: 0x02, 0x0A, 0x00 = Auth
// 0x02 = status byte för simpla svar?!?
// 0x0a = krypto typ
// 0x00 = key nr
//uint8_t initAuthCmdDES[] = {0x02, 0x0a, 0x00}; // DES
//uint8_t initAuthCmd3DES[] = {0x02, 0x1a, 0x00}; // 3DES
//uint8_t initAuthCmdAES[] = {0x02, 0xaa, 0x00}; // AES
// auth 1 - answer command
// 0x03 = status byte för komplexa typer?
// 0xaf = additional frame
// LEN = 1+1+32+2 = 36
//uint8_t answerAuthCmd[34] = {0x03, 0xaf};
// Lägg till CRC
//AppendCrc14443a(versionCmd1,sizeof(versionCmd1));
*/
// Sending commands
/*ReaderTransmit(versionCmd1,sizeof(versionCmd1)+2, NULL);
len = ReaderReceive(buffer);
print_result("Get Version 3", buffer, 9);
*/
// for( int i = 0; i < 8; i++){
// // Auth 1 - Request authentication
// ReaderTransmit(initAuthCmdAES,sizeof(initAuthCmdAES)+2, NULL);
// //len = ReaderReceive(buffer);
// // 0xAE = authentication error
// if (buffer[1] == 0xae) {
// Dbprintf("Cmd Error: %02x", buffer[1]);
// OnError();
// return;
// }
// // tags enc nonce
// memcpy(encRndB, buffer+2, 16);
// // dekryptera svaret från tag.
// AesDecrypt(&ctx, encRndB, decRndB, 16);
// rol8(decRndB,16);
// memcpy(RndARndB, RndA,16);
// memcpy(RndARndB+16, decRndB ,16 );
// AesEncrypt(&ctx, RndARndB, encRndARndB, 32 );
// memcpy(answerAuthCmd+2, encRndARndB, 32);
// AppendCrc14443a(answerAuthCmd,sizeof(answerAuthCmd));
// ReaderTransmit(answerAuthCmd,sizeof(answerAuthCmd)+2, NULL);
// len = ReaderReceive(buffer);
// print_result("Auth1a ", buffer, 8);
// Dbprintf("Rx len: %02x", len);
// if (buffer[1] == 0xCA) {
// Dbprintf("Cmd Error: %02x Len: %d", buffer[1],len);
// cmd_send(CMD_ACK,0,0,0,0,0);
// key[1] = i;
// AesCtxIni(&ctx, iv, key, KEY128, CBC);
// }
// }
//des_dec(decRndB, encRndB, key);
//Do crypto magic
/*
DES_ede2_cbc_encrypt(e_RndB,RndB,sizeof(e_RndB),&ks1,&ks2,&iv,0);
memcpy(RndARndB,RndA,8);
memcpy(RndARndB+8,RndB,8);
PrintAndLog(" RA+B:%s",sprint_hex(RndARndB, 16));
DES_ede2_cbc_encrypt(RndARndB,RndARndB,sizeof(RndARndB),&ks1,&ks2,&e_RndB,1);
PrintAndLog("enc(RA+B):%s",sprint_hex(RndARndB, 16));
*/
int mifare_des_auth2(uint32_t uid, uint8_t *key, uint8_t *blockData){
uint8_t* buffer = mifare_get_bigbufptr();
uint8_t dcmd[19];
dcmd[0] = 0xAF;
memcpy(dcmd+1,key,16);
AppendCrc14443a(dcmd, 17);
ReaderTransmit(dcmd, sizeof(dcmd), NULL);
int len = ReaderReceive(buffer);
if(!len) {
if (MF_DBGLEVEL >= 1) Dbprintf("Authentication failed. Card timeout.");
len = ReaderReceive(buffer);
}
if(len==1) {
if (MF_DBGLEVEL >= 1) {
Dbprintf("NAK - Authentication failed.");
Dbprintf("Cmd Error: %02x", buffer[0]);
}
return 1;
}
if (len == 11){
if (MF_DBGLEVEL >= 1) {
Dbprintf("Auth2 Resp: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
buffer[0],buffer[1],buffer[2],buffer[3],buffer[4],
buffer[5],buffer[6],buffer[7],buffer[8],buffer[9],
buffer[10]);
}
return 0;
}
return 1;
}
void MifareDES_Auth2(uint32_t arg0, uint8_t *datain){
return;
uint32_t cuid = arg0;
uint8_t key[16];
byte_t isOK = 0;
byte_t dataoutbuf[16];
memset(key, 0, 16);
memcpy(key, datain, 16);
LED_A_ON();
LED_B_OFF();
LED_C_OFF();
if(mifare_des_auth2(cuid, key, dataoutbuf)){
if (MF_DBGLEVEL >= 1) Dbprintf("Authentication part2: Fail...");
}
isOK=1;
if (MF_DBGLEVEL >= 2) DbpString("AUTH 2 FINISHED");
LED_B_ON();
cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,11);
LED_B_OFF();
// Thats it...
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff();
}
void OnSuccess(){
pcb_blocknum = 0;
ReaderTransmit(deselect_cmd, 3 , NULL);

View file

@ -8,7 +8,7 @@
#include "../common/iso14443crc.h"
#include "iso14443a.h"
#include "crapto1.h"
#include "desfire_key.h"
#include "mifareutil.h"
#include "../include/common.h"

View file

@ -20,7 +20,7 @@ void print_result(char *name, uint8_t *buf, size_t len) {
if ( len % 16 == 0 ) {
for(; p-buf < len; p += 16)
Dbprintf("[%s:%02x/%02x] %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
Dbprintf("[%s:%d/%d] %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
name,
p-buf,
len,
@ -29,7 +29,7 @@ void print_result(char *name, uint8_t *buf, size_t len) {
}
else {
for(; p-buf < len; p += 8)
Dbprintf("[%s:%02x/%02x] %02x %02x %02x %02x %02x %02x %02x %02x", name, p-buf, len, p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
Dbprintf("[%s:%d/%d] %02x %02x %02x %02x %02x %02x %02x %02x", name, p-buf, len, p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
}
}

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,10 +89,6 @@ 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;

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("-------------------------------------------------------------");
/*
@ -241,11 +205,6 @@ int CmdHF14ADesInfo(const char *Cmd){
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,46 +463,72 @@ 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;
aid[0] = resp.d.asBytes[i];
aid[1] = resp.d.asBytes[i+1];
aid[2] = resp.d.asBytes[i+2];
GetKeySettings(aid);
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);
// 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;
}
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
@ -396,21 +554,18 @@ int CmdHF14ADesAuth(const char *Cmd){
// 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 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(" 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,13 +18,14 @@ 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 ;
@ -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);
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);
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;
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;
memset(bitstream, 0x00, sizeof(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,14 +86,12 @@ 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;
@ -112,7 +111,7 @@ 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);
@ -122,9 +121,8 @@ int manchester_decode(const int * data, const size_t len, uint8_t * dataout){
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 */
int i =0;
/* now look for the first threshold */
for (; i < len; ++i) {
if (data[i] == low) {
retval = 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;
/*
* We assume the 1st bit is zero, it may not be
* the case: this routine (I think) has an init problem.
* Ed.
*/
bit = 0;
int isDamp = 0;
int damplimit = (int)((high / 2) * 0.3);
int dampHi = (high/2)+damplimit;
int dampLow = (high/2)-damplimit;
int firstST = 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)
hitlow = 1;
if ( startType == -1)
startType = 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 (data[z+j] == low ){
hitlow = 1;
if ( startType == -1)
startType = 0;
}
if (hithigh && hitlow)
break;
}
/* If we didn't hit both high and low peaks, we had a bit transition */
if (!hithigh || !hitlow)
bit ^= 1;
// 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;
}
}
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) {
PrintAndLog(" %s", sprint_bin(bitStream+i,blocksize) );
}
if ( mod > 0 ){
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);

View file

@ -1,9 +1,10 @@
#ifndef __DESFIRE_H
#define __DESFIRE_H
#include <string.h>
#include <stdarg.h>
#include "aes.h"
#define DESFIRE(tag) ((struct desfire_tag *) tag)
#define DESFIRE_KEY(key) ((struct desfire_key *) key)
#define MAX_CRYPTO_BLOCK_SIZE 16
/* Mifare DESFire EV1 Application crypto operations */
@ -65,8 +66,9 @@ enum DESFIRE_CRYPTOALGO {
T_AES = 0x03
};
struct desfire_key {
#define DESFIRE_KEY(key) ((struct desfire_key *) key)
struct desfire_key {
enum DESFIRE_CRYPTOALGO type;
uint8_t data[24];
// DES_key_schedule ks1;
@ -77,9 +79,9 @@ struct desfire_key {
uint8_t cmac_sk2[24];
uint8_t aes_version;
};
typedef struct desfire_key *desfirekey_t;
#define DESFIRE(tag) ((struct desfire_tag *) tag)
struct desfire_tag {
iso14a_card_select_t info;
int active;

4
cp2tau Normal file
View file

@ -0,0 +1,4 @@
cp armsrc/obj/*.elf /z
cp armsrc/obj/*.s19 /z
cp bootrom/obj/*.elf /z
cp bootrom/obj/*.s19 /z

0
iceman.txt Normal file
View file