Skip to content

Commit

Permalink
A lot of changes...
Browse files Browse the repository at this point in the history
.. ntag simulation stuff from @marshmellows branch "ntag/sim"
.. hf mf mifare fixes from @pwpivi.
.. hw status command
.. speedtest function from @pwpivi
.. Viking Functionalities,   (not a proper DEMOD, but a start)
.. GetCountUS  better precision from @pwpivi
.. bin2hex,  hex2bin  from @holiman

...
starting with getting the T55x7 CONFIGURATION_BLOCK for different clone situations. Ripped from Adam Lauries RFidler,   nothing working or finished..
...
Started working with the T55x7 read command with password actually performs a write block...  See Issue iceman1001#136  Proxmark#136    Not solved yet.

...
Started add SHA256..   not working yet..
  • Loading branch information
iceman1001 committed Oct 4, 2015
1 parent 05beaa8 commit 0de8e38
Show file tree
Hide file tree
Showing 41 changed files with 2,223 additions and 238 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
- AWID26 command context added as 'lf awid' containing realtime demodulation as well as cloning/simulation based on tag numbers (Craig Young)
- Added 'hw status'. This command makes the ARM print out some runtime information. (holiman)
- Added 'hw ping'. This command just sends a usb packets and checks if the pm3 is responsive. Can be used to abort certain operations which supports abort over usb. (holiman)
- Added `data hex2bin` and `data bin2hex` for command line conversion between binary and hexadecimal (holiman)

### Changed
- Revised workflow for StandAloneMode14a (Craig Young)
Expand Down
39 changes: 24 additions & 15 deletions armsrc/appmain.c
Original file line number Diff line number Diff line change
Expand Up @@ -301,39 +301,42 @@ void SendVersion(void)

// measure the USB Speed by sending SpeedTestBufferSize bytes to client and measuring the elapsed time.
// Note: this mimics GetFromBigbuf(), i.e. we have the overhead of the UsbCommand structure included.
void printUSBSpeed(uint32_t SpeedTestBufferSize)
void printUSBSpeed(void)
{
Dbprintf("USB Speed:");
Dbprintf(" Sending %d bytes payload...", SpeedTestBufferSize);
Dbprintf(" Sending USB packets to client...");

#define USB_SPEED_TEST_MIN_TIME 1500 // in milliseconds
uint8_t *test_data = BigBuf_get_addr();
uint32_t end_time;

uint32_t start_time = GetTickCount();
uint32_t start_time = end_time = GetTickCount();
uint32_t bytes_transferred = 0;

LED_B_ON();
for(size_t i=0; i < SpeedTestBufferSize; i += USB_CMD_DATA_SIZE) {
size_t len = MIN((SpeedTestBufferSize - i), USB_CMD_DATA_SIZE);
cmd_send(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K,0,len,0,test_data,len);
while(end_time < start_time + USB_SPEED_TEST_MIN_TIME) {
cmd_send(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K, 0, USB_CMD_DATA_SIZE, 0, test_data, USB_CMD_DATA_SIZE);
end_time = GetTickCount();
bytes_transferred += USB_CMD_DATA_SIZE;
}
LED_B_OFF();

uint32_t end_time = GetTickCount();

Dbprintf(" Time elapsed: %dms, USB Transfer Speed PM3 -> Client = %d Bytes/s",
end_time - start_time,
1000* SpeedTestBufferSize / (end_time - start_time));
Dbprintf(" Time elapsed: %dms", end_time - start_time);
Dbprintf(" Bytes transferred: %d", bytes_transferred);
Dbprintf(" USB Transfer Speed PM3 -> Client = %d Bytes/s",
1000 * bytes_transferred / (end_time - start_time));

}

/**
* Prints runtime information about the PM3.
**/
void SendStatus(uint32_t SpeedTestBufferSize)
void SendStatus(void)
{
BigBuf_print_status();
Fpga_print_status();
printConfig(); //LF Sampling config
printUSBSpeed(SpeedTestBufferSize);
printUSBSpeed();
Dbprintf("Various");
Dbprintf(" MF_DBGLEVEL........%d", MF_DBGLEVEL);
Dbprintf(" ToSendMax..........%d", ToSendMax);
Expand Down Expand Up @@ -998,6 +1001,11 @@ void UsbPacketReceived(uint8_t *packet, int len)
case CMD_AWID_DEMOD_FSK: // Set realtime AWID demodulation
CmdAWIDdemodFSK(c->arg[0], 0, 0, 1);
break;
case CMD_VIKING_CLONE_TAG:
CopyViKingtoT55x7(c->arg[0],c->arg[1]);
break;


#endif

#ifdef WITH_HITAG
Expand Down Expand Up @@ -1232,8 +1240,9 @@ void UsbPacketReceived(uint8_t *packet, int len)

LED_B_ON();
uint8_t *BigBuf = BigBuf_get_addr();
size_t len = 0;
for(size_t i=0; i<c->arg[1]; i += USB_CMD_DATA_SIZE) {
size_t len = MIN((c->arg[1] - i),USB_CMD_DATA_SIZE);
len = MIN((c->arg[1] - i),USB_CMD_DATA_SIZE);
cmd_send(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K,i,len,BigBuf_get_traceLen(),BigBuf+c->arg[0]+i,len);
}
// Trigger a finish downloading signal with an ACK frame
Expand Down Expand Up @@ -1269,7 +1278,7 @@ void UsbPacketReceived(uint8_t *packet, int len)
SendVersion();
break;
case CMD_STATUS:
SendStatus(c->arg[0]);
SendStatus();
break;
case CMD_PING:
cmd_send(CMD_ACK,0,0,0,0,0);
Expand Down
1 change: 1 addition & 0 deletions armsrc/apps.h
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ void ReaderIClass(uint8_t arg0);
void ReaderIClass_Replay(uint8_t arg0,uint8_t *MAC);
void IClass_iso14443A_GetPublic(uint8_t arg0);

void CopyViKingtoT55x7(uint32_t block1,uint32_t block2);
// hitag2.h
void SnoopHitag(uint32_t type);
void SimulateHitagTag(bool tag_mem_supplied, byte_t* data);
Expand Down
102 changes: 77 additions & 25 deletions armsrc/iso14443a.c
Original file line number Diff line number Diff line change
Expand Up @@ -1047,7 +1047,7 @@ void SimulateIso14443aTag(int tagType, int flags, byte_t* data)
response3a[0] = sak & 0xFB;
ComputeCrc14443(CRC_14443_A, response3a, 1, &response3a[1], &response3a[2]);

uint8_t response5[] = { 0x01, 0x01, 0x01, 0x01 }; // Very random tag nonce
uint8_t response5[] = { 0x00, 0x00, 0x00, 0x00 }; // Very random tag nonce
uint8_t response6[] = { 0x04, 0x58, 0x80, 0x02, 0x00, 0x00 }; // dummy ATS (pseudo-ATR), answer to RATS:
// Format byte = 0x58: FSCI=0x08 (FSC=256), TA(1) and TC(1) present,
// TA(1) = 0x80: different divisors not supported, DR = 1, DS = 1
Expand Down Expand Up @@ -1151,9 +1151,9 @@ void SimulateIso14443aTag(int tagType, int flags, byte_t* data)
} else if(receivedCmd[0] == 0x30) { // Received a (plain) READ
uint8_t block = receivedCmd[1];
if ( tagType == 7 ) {
uint8_t start = 4 * block;
uint16_t start = 4 * block;

if ( block < 4 ) {
/*if ( block < 4 ) {
//NTAG 215
uint8_t blockdata[50] = {
data[0],data[1],data[2], 0x88 ^ data[0] ^ data[1] ^ data[2],
Expand All @@ -1167,12 +1167,12 @@ void SimulateIso14443aTag(int tagType, int flags, byte_t* data)
0x00,0x00};
AppendCrc14443a(blockdata+start, 16);
EmSendCmdEx( blockdata+start, MAX_MIFARE_FRAME_SIZE, false);
} else {
} else {*/
uint8_t emdata[MAX_MIFARE_FRAME_SIZE];
emlGetMemBt( emdata, start, 16);
AppendCrc14443a(emdata, 16);
EmSendCmdEx(emdata, sizeof(emdata), false);
}
//}
p_response = NULL;

} else {
Expand Down Expand Up @@ -1417,9 +1417,11 @@ void SimulateIso14443aTag(int tagType, int flags, byte_t* data)
BigBuf_free_keep_EM();
LED_A_OFF();

if (MF_DBGLEVEL >= 4){
Dbprintf("-[ Wake ups after halt [%d]", happened);
Dbprintf("-[ Messages after halt [%d]", happened2);
Dbprintf("-[ Num of received cmd [%d]", cmdsRecvd);
}
}


Expand Down Expand Up @@ -2194,7 +2196,7 @@ int32_t dist_nt(uint32_t nt1, uint32_t nt2) {
nttmp1 = nt1;
nttmp2 = nt2;

for (i = 1; i < 32768; i++) {
for (i = 1; i < 0xFFFF; i++) {
nttmp1 = prng_successor(nttmp1, 1);
if (nttmp1 == nt2) return i;
nttmp2 = prng_successor(nttmp2, 1);
Expand All @@ -2204,6 +2206,28 @@ int32_t dist_nt(uint32_t nt1, uint32_t nt2) {
return(-99999); // either nt1 or nt2 are invalid nonces
}

int32_t dist_nt_ex32(uint32_t nt1, uint32_t nt2, bool *result) {

uint16_t i;
uint32_t nttmp1, nttmp2;

if (nt1 == nt2) return 0;

nttmp1 = nt1;
nttmp2 = nt2;

*result = true;
for (i = 1; i < 0xFFFFFFFF; i++) {
nttmp1 = prng_successor(nttmp1, 1);
if (nttmp1 == nt2) return i;

nttmp2 = prng_successor(nttmp2, 1);
if (nttmp2 == nt1) return -i;
}

*result = false;
return(-99999); // either nt1 or nt2 are invalid nonces
}

//-----------------------------------------------------------------------------
// Recover several bits of the cypher stream. This implements (first stages of)
Expand Down Expand Up @@ -2244,6 +2268,7 @@ void ReaderMifare(bool first_try)
byte_t par_list[8] = {0x00};
byte_t ks_list[8] = {0x00};

#define PRNG_SEQUENCE_LENGTH (1 << 16);
static uint32_t sync_time = 0;
static uint32_t sync_cycles = 0;
int catch_up_cycles = 0;
Expand All @@ -2254,7 +2279,7 @@ void ReaderMifare(bool first_try)
if (first_try) {
mf_nr_ar3 = 0;
sync_time = GetCountSspClk() & 0xfffffff8;
sync_cycles = 65536; // theory: Mifare Classic's random generator repeats every 2^16 cycles (and so do the nonces).
sync_cycles = PRNG_SEQUENCE_LENGTH; //65536; //0x10000 // theory: Mifare Classic's random generator repeats every 2^16 cycles (and so do the nonces).
nt_attacked = 0;
nt = 0;
par[0] = 0;
Expand All @@ -2271,8 +2296,12 @@ void ReaderMifare(bool first_try)
LED_C_OFF();


#define DARKSIDE_MAX_TRIES 32 // number of tries to sync on PRNG cycle. Then give up.
uint16_t unsuccessfull_tries = 0;
#define MAX_UNEXPECTED_RANDOM 5 // maximum number of unexpected (i.e. real) random numbers when trying to sync. Then give up.
#define MAX_SYNC_TRIES 16
uint16_t unexpected_random = 0;
uint16_t sync_tries = 0;
int16_t debug_info_nr = -1;
uint32_t debug_info[MAX_SYNC_TRIES];

for(uint16_t i = 0; TRUE; i++) {

Expand All @@ -2290,16 +2319,20 @@ void ReaderMifare(bool first_try)
continue;
}

sync_time = (sync_time & 0xfffffff8) + sync_cycles + catch_up_cycles;
catch_up_cycles = 0;
if (debug_info_nr == -1) {
sync_time = (sync_time & 0xfffffff8) + sync_cycles + catch_up_cycles;
catch_up_cycles = 0;

// if we missed the sync time already, advance to the next nonce repeat
while(GetCountSspClk() > sync_time) {
sync_time = (sync_time & 0xfffffff8) + sync_cycles;
}
// if we missed the sync time already, advance to the next nonce repeat
while(GetCountSspClk() > sync_time) {
sync_time = (sync_time & 0xfffffff8) + sync_cycles;
}

// Transmit MIFARE_CLASSIC_AUTH at synctime. Should result in returning the same tag nonce (== nt_attacked)
ReaderTransmit(mf_auth, sizeof(mf_auth), &sync_time);
// Transmit MIFARE_CLASSIC_AUTH at synctime. Should result in returning the same tag nonce (== nt_attacked)
ReaderTransmit(mf_auth, sizeof(mf_auth), &sync_time);
} else {
ReaderTransmit(mf_auth, sizeof(mf_auth), NULL);
}

// Receive the (4 Byte) "random" nonce
if (!ReaderReceive(receivedAnswer, receivedAnswerPar)) {
Expand All @@ -2317,19 +2350,32 @@ void ReaderMifare(bool first_try)
int nt_distance = dist_nt(previous_nt, nt);
if (nt_distance == 0) {
nt_attacked = nt;
}
else {
} else {
if (nt_distance == -99999) { // invalid nonce received
unsuccessfull_tries++;
if (!nt_attacked && unsuccessfull_tries > DARKSIDE_MAX_TRIES) {
unexpected_random++;
if (!nt_attacked && unexpected_random > MAX_UNEXPECTED_RANDOM) {
isOK = -3; // Card has an unpredictable PRNG. Give up
break;
} else {
continue; // continue trying...
}
}
if (++sync_tries > MAX_SYNC_TRIES) {
if (sync_tries > 2 * MAX_SYNC_TRIES) {
isOK = -4; // Card's PRNG runs at an unexpected frequency or resets unexpectedly
break;
} else { // continue for a while, just to collect some debug info
debug_info[++debug_info_nr] = nt_distance;
continue;
}
}
sync_cycles = (sync_cycles - nt_distance);
if (MF_DBGLEVEL >= 3) Dbprintf("calibrating in cycle %d. nt_distance=%d, Sync_cycles: %d\n", i, nt_distance, sync_cycles);
if (sync_cycles <= 0) {
sync_cycles += PRNG_SEQUENCE_LENGTH;
}
if (MF_DBGLEVEL >= 3) {
Dbprintf("calibrating in cycle %d. nt_distance=%d, Sync_cycles: %d\n", i, nt_distance, sync_cycles);
}
continue;
}
}
Expand Down Expand Up @@ -2401,8 +2447,15 @@ void ReaderMifare(bool first_try)

mf_nr_ar[3] &= 0x1F;

byte_t buf[28] = {0x00};
if (isOK == -4) {
if (MF_DBGLEVEL >= 3) {
for(uint16_t i = 0; i < MAX_SYNC_TRIES; i++) {
Dbprintf("collected debug info[%d] = %d\n", i, debug_info[i]);
}
}
}

byte_t buf[28];
memcpy(buf + 0, uid, 4);
num_to_bytes(nt, 4, buf + 4);
memcpy(buf + 8, par_list, 8);
Expand All @@ -2418,8 +2471,7 @@ void ReaderMifare(bool first_try)
set_tracing(FALSE);
}


/*
/**
*MIFARE 1K simulate.
*
*@param flags :
Expand Down
Loading

0 comments on commit 0de8e38

Please sign in to comment.