ADD: @holiman's clearCommandBuffer in cmdlft55xx.c

ADD: @VERTCraig's AVID commands.

TEST: testing some changes to iso14443 demod.
This commit is contained in:
iceman1001 2015-07-18 20:43:14 +02:00
commit db25599d7f
18 changed files with 20489 additions and 307 deletions

View file

@ -2,12 +2,22 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
## [Unreleased][unreleased] ## [unreleased][unreleased]
### Added
- AWID26 command context added as 'lf awid' containing realtime demodulation as well as cloning/simulation based on tag numbers (Craig Young)
### Changed ### Changed
- Changed lf config's `threshold` to a graph (signed) metric and it will trigger on + or - value set to. (example: set to 50 and recording would begin at first graphed value of >= 50 or <= -50) (marshmellow) - Changed lf config's `threshold` to a graph (signed) metric and it will trigger on + or - value set to. (example: set to 50 and recording would begin at first graphed value of >= 50 or <= -50) (marshmellow)
- EPA functions (`hf epa`) now support both ISO 14443-A and 14443-B cards (frederikmoellers)
## [2.2.0][2015-07-12]
- Changed `hf 14b write` to `hf 14b sriwrite` as it only applied to sri tags (marshmellow) - Changed `hf 14b write` to `hf 14b sriwrite` as it only applied to sri tags (marshmellow)
- Added `hf 14b reader` to `hf search` (marshmellow) - Added `hf 14b reader` to `hf search` (marshmellow)
- Added compression of fpga config and data, *BOOTROM REFLASH REQUIRED* (piwi)
- Implemented better detection of mifare-tags that are not vulnerable to classic attacks (`hf mf mifare`, `hf mf nested`) (piwi)
### Added ### Added
- Add `hf 14b reader` to find and print general info about known 14b tags (marshmellow) - Add `hf 14b reader` to find and print general info about known 14b tags (marshmellow)

View file

@ -681,6 +681,9 @@ void UsbPacketReceived(uint8_t *packet, int len)
case CMD_EM4X_WRITE_WORD: case CMD_EM4X_WRITE_WORD:
EM4xWriteWord(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes[0]); EM4xWriteWord(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes[0]);
break; break;
case CMD_AWID_DEMOD_FSK: // Set realtime AWID demodulation
CmdAWIDdemodFSK(c->arg[0], 0, 0, 1);
break;
#endif #endif
#ifdef WITH_HITAG #ifdef WITH_HITAG

View file

@ -22,8 +22,8 @@
#include "../common/lfdemod.h" #include "../common/lfdemod.h"
#include "BigBuf.h" #include "BigBuf.h"
#include "fpgaloader.h" #include "fpgaloader.h"
#include "../include/hitag2.h" #include "hitag2.h"
#include "../include/mifare.h" #include "mifare.h"
//#include "des.h" //#include "des.h"
//#include "aes.h" //#include "aes.h"
#include "desfire.h" #include "desfire.h"
@ -77,6 +77,7 @@ void CmdFSKsimTAG(uint16_t arg1, uint16_t arg2, size_t size, uint8_t *BitStream)
void CmdASKsimTag(uint16_t arg1, uint16_t arg2, size_t size, uint8_t *BitStream); void CmdASKsimTag(uint16_t arg1, uint16_t arg2, size_t size, uint8_t *BitStream);
void CmdPSKsimTag(uint16_t arg1, uint16_t arg2, size_t size, uint8_t *BitStream); void CmdPSKsimTag(uint16_t arg1, uint16_t arg2, size_t size, uint8_t *BitStream);
void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol); void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol);
void CmdAWIDdemodFSK(int findone, int *high, int *low, int ledcontrol); // Realtime demodulation mode for AWID26
void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol); void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol);
void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol); void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol);
void CopyIOtoT55x7(uint32_t hi, uint32_t lo, uint8_t longFMT); // Clone an ioProx card to T5557/T5567 void CopyIOtoT55x7(uint32_t hi, uint32_t lo, uint8_t longFMT); // Clone an ioProx card to T5557/T5567

View file

@ -13,13 +13,12 @@
#include "apps.h" #include "apps.h"
#include "util.h" #include "util.h"
#include "string.h" #include "string.h"
#include "iso14443crc.h" #include "iso14443crc.h"
#include "common.h"
#define RECEIVE_SAMPLES_TIMEOUT 0x0004FFFF #define RECEIVE_SAMPLES_TIMEOUT 800000
#define ISO14443B_DMA_BUFFER_SIZE 256 #define ISO14443B_DMA_BUFFER_SIZE 256
uint8_t PowerOn = TRUE;
// PCB Block number for APDUs // PCB Block number for APDUs
static uint8_t pcb_blocknum = 0; static uint8_t pcb_blocknum = 0;
@ -107,7 +106,7 @@ static void CodeIso14443bAsTag(const uint8_t *cmd, int len)
ToSendStuffBit(0); ToSendStuffBit(0);
ToSendStuffBit(0); ToSendStuffBit(0);
} }
for(i = 0; i < 2; i++) { for(i = 0; i < 10; i++) {
ToSendStuffBit(1); ToSendStuffBit(1);
ToSendStuffBit(1); ToSendStuffBit(1);
ToSendStuffBit(1); ToSendStuffBit(1);
@ -270,6 +269,7 @@ static void UartReset()
Uart.state = STATE_UNSYNCD; Uart.state = STATE_UNSYNCD;
Uart.byteCnt = 0; Uart.byteCnt = 0;
Uart.bitCnt = 0; Uart.bitCnt = 0;
Uart.posCnt = 0;
memset(Uart.output, 0x00, MAX_FRAME_SIZE); memset(Uart.output, 0x00, MAX_FRAME_SIZE);
} }
@ -528,15 +528,12 @@ static struct {
static RAMFUNC int Handle14443bSamplesDemod(int ci, int cq) static RAMFUNC int Handle14443bSamplesDemod(int ci, int cq)
{ {
int v; int v;
int ai, aq;
// The soft decision on the bit uses an estimate of just the // The soft decision on the bit uses an estimate of just the
// quadrant of the reference angle, not the exact angle. // quadrant of the reference angle, not the exact angle.
#define MAKE_SOFT_DECISION() { \ #define MAKE_SOFT_DECISION() { \
if(Demod.sumI > 0) { \ v = (Demod.sumI > 0) ? ci : -ci;\
v = ci; \
} else { \
v = -ci; \
} \
if(Demod.sumQ > 0) { \ if(Demod.sumQ > 0) { \
v += cq; \ v += cq; \
} else { \ } else { \
@ -557,39 +554,15 @@ static RAMFUNC int Handle14443bSamplesDemod(int ci, int cq)
} \ } \
} }
*/ */
// Subcarrier amplitude v = sqrt(ci^2 + cq^2), approximated here by max(abs(ci),abs(cq)) + 1/2*min(abs(ci),abs(cq))) // Subcarrier amplitude v = sqrt(ci^2 + cq^2), approximated here by max(abs(ci),abs(cq)) + 1/2*min(abs(ci),abs(cq)))
#define CHECK_FOR_SUBCARRIER() { \ #define CHECK_FOR_SUBCARRIER() { \
if(ci < 0) { \ ai = (abs(ci) >> 1); \
if(cq < 0) { /* ci < 0, cq < 0 */ \ aq = (abs(cq) >> 1); \
if (cq < ci) { \ v = MAX(abs(ci), abs(cq)) + MIN(ai, aq); \
v = -cq - (ci >> 1); \
} else { \
v = -ci - (cq >> 1); \
} \
} else { /* ci < 0, cq >= 0 */ \
if (cq < -ci) { \
v = -ci + (cq >> 1); \
} else { \
v = cq - (ci >> 1); \
} \
} \
} else { \
if(cq < 0) { /* ci >= 0, cq < 0 */ \
if (-cq < ci) { \
v = ci - (cq >> 1); \
} else { \
v = -cq + (ci >> 1); \
} \
} else { /* ci >= 0, cq >= 0 */ \
if (cq < ci) { \
v = ci + (cq >> 1); \
} else { \
v = cq + (ci >> 1); \
} \
} \
} \
} }
switch(Demod.state) { switch(Demod.state) {
case DEMOD_UNSYNCD: case DEMOD_UNSYNCD:
CHECK_FOR_SUBCARRIER(); CHECK_FOR_SUBCARRIER();
@ -620,11 +593,11 @@ static RAMFUNC int Handle14443bSamplesDemod(int ci, int cq)
case DEMOD_AWAITING_FALLING_EDGE_OF_SOF: case DEMOD_AWAITING_FALLING_EDGE_OF_SOF:
MAKE_SOFT_DECISION(); MAKE_SOFT_DECISION();
//Dbprintf("ICE: %d %d %d %d %d", v, Demod.sumI, Demod.sumQ, ci, cq );
if(v < 0) { // logic '0' detected if(v < 0) { // logic '0' detected
Demod.state = DEMOD_GOT_FALLING_EDGE_OF_SOF; Demod.state = DEMOD_GOT_FALLING_EDGE_OF_SOF;
Demod.posCount = 0; // start of SOF sequence Demod.posCount = 0; // start of SOF sequence
} else { } else {
//if(Demod.posCount > 200/4) { // maximum length of TR1 = 200 1/fs
if(Demod.posCount > 25*2) { // maximum length of TR1 = 200 1/fs if(Demod.posCount > 25*2) { // maximum length of TR1 = 200 1/fs
Demod.state = DEMOD_UNSYNCD; Demod.state = DEMOD_UNSYNCD;
} }
@ -731,6 +704,11 @@ static void DemodReset()
Demod.len = 0; Demod.len = 0;
Demod.state = DEMOD_UNSYNCD; Demod.state = DEMOD_UNSYNCD;
Demod.posCount = 0; Demod.posCount = 0;
Demod.sumI = 0;
Demod.sumQ = 0;
Demod.bitCount = 0;
Demod.thisBit = 0;
Demod.shiftReg = 0;
memset(Demod.output, 0x00, MAX_FRAME_SIZE); memset(Demod.output, 0x00, MAX_FRAME_SIZE);
} }
@ -760,25 +738,20 @@ static void GetSamplesFor14443bDemod(int n, bool quiet)
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ); FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ);
// The response (tag -> reader) that we're receiving. // The response (tag -> reader) that we're receiving.
uint8_t *resp = BigBuf_malloc(MAX_FRAME_SIZE);
// Set up the demodulator for tag -> reader responses. // Set up the demodulator for tag -> reader responses.
DemodInit(resp); DemodInit(BigBuf_malloc(MAX_FRAME_SIZE));
// The DMA buffer, used to stream samples from the FPGA // The DMA buffer, used to stream samples from the FPGA
int8_t *dmaBuf = (int8_t*) BigBuf_malloc(ISO14443B_DMA_BUFFER_SIZE); int8_t *dmaBuf = (int8_t*) BigBuf_malloc(ISO14443B_DMA_BUFFER_SIZE);
// Setup and start DMA.
FpgaSetupSscDma((uint8_t*) dmaBuf, ISO14443B_DMA_BUFFER_SIZE);
int8_t *upTo = dmaBuf; int8_t *upTo = dmaBuf;
lastRxCounter = ISO14443B_DMA_BUFFER_SIZE; lastRxCounter = ISO14443B_DMA_BUFFER_SIZE;
// Signal field is ON with the appropriate LED: // Signal field is ON with the appropriate LED:
LED_D_ON(); LED_D_ON();
// Setup and start DMA.
FpgaSetupSscDma((uint8_t*) dmaBuf, ISO14443B_DMA_BUFFER_SIZE);
for(;;) { for(;;) {
int behindBy = lastRxCounter - AT91C_BASE_PDC_SSC->PDC_RCR; int behindBy = lastRxCounter - AT91C_BASE_PDC_SSC->PDC_RCR;
if(behindBy > max) max = behindBy; if(behindBy > max) max = behindBy;
@ -799,11 +772,11 @@ static void GetSamplesFor14443bDemod(int n, bool quiet)
samples += 2; samples += 2;
if(Handle14443bSamplesDemod(ci | 0x01 , cq | 0x01)) { //
gotFrame = TRUE; gotFrame = Handle14443bSamplesDemod(ci , cq );
if ( gotFrame )
break; break;
} }
}
if(samples > n || gotFrame) { if(samples > n || gotFrame) {
break; break;
@ -840,9 +813,6 @@ static void TransmitFor14443b(void)
FpgaSetupSsc(); FpgaSetupSsc();
// Start the timer
StartCountSspClk();
while(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { while(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
AT91C_BASE_SSC->SSC_THR = 0xff; AT91C_BASE_SSC->SSC_THR = 0xff;
} }
@ -852,8 +822,6 @@ static void TransmitFor14443b(void)
// Signal we are transmitting with the Green LED // Signal we are transmitting with the Green LED
LED_B_ON(); LED_B_ON();
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX | FPGA_HF_READER_TX_SHALLOW_MOD); FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX | FPGA_HF_READER_TX_SHALLOW_MOD);
if ( !PowerOn )
SpinDelay(200);
for(c = 0; c < 10;) { for(c = 0; c < 10;) {
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
@ -898,7 +866,7 @@ static void CodeIso14443bAsReader(const uint8_t *cmd, int len)
ToSendReset(); ToSendReset();
// Establish initial reference level // Establish initial reference level
for(i = 0; i < 80; i++) { for(i = 0; i < 40; i++) {
ToSendStuffBit(1); ToSendStuffBit(1);
} }
// Send SOF // Send SOF
@ -1032,7 +1000,9 @@ int iso14443b_select_card()
// Set up ISO 14443 Type B communication (similar to iso14443a_setup) // Set up ISO 14443 Type B communication (similar to iso14443a_setup)
void iso14443b_setup() { void iso14443b_setup() {
FpgaDownloadAndGo(FPGA_BITSTREAM_HF); FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
BigBuf_free(); BigBuf_free();
// Set up the synchronous serial port // Set up the synchronous serial port
FpgaSetupSsc(); FpgaSetupSsc();
@ -1044,7 +1014,7 @@ void iso14443b_setup() {
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX | FPGA_HF_READER_TX_SHALLOW_MOD); FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX | FPGA_HF_READER_TX_SHALLOW_MOD);
// Start the timer // Start the timer
StartCountSspClk(); //StartCountSspClk();
DemodReset(); DemodReset();
UartReset(); UartReset();
@ -1353,21 +1323,9 @@ void RAMFUNC SnoopIso14443b(void)
void SendRawCommand14443B(uint32_t datalen, uint32_t recv, uint8_t powerfield, uint8_t data[]) void SendRawCommand14443B(uint32_t datalen, uint32_t recv, uint8_t powerfield, uint8_t data[])
{ {
iso14443b_setup(); iso14443b_setup();
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
BigBuf_free();
if ( !PowerOn ){
FpgaSetupSsc();
}
SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
// Start the timer
StartCountSspClk();
DemodReset();
UartReset();
if ( datalen == 0 && recv == 0 && powerfield == 0){ if ( datalen == 0 && recv == 0 && powerfield == 0){
clear_trace();
} else { } else {
set_tracing(TRUE); set_tracing(TRUE);
CodeAndTransmit14443bAsReader(data, datalen); CodeAndTransmit14443bAsReader(data, datalen);
@ -1383,7 +1341,6 @@ void SendRawCommand14443B(uint32_t datalen, uint32_t recv, uint8_t powerfield, u
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
FpgaDisableSscDma(); FpgaDisableSscDma();
LED_D_OFF(); LED_D_OFF();
PowerOn = 0;
} }
} }

View file

@ -841,6 +841,96 @@ void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol)
if (ledcontrol) LED_A_OFF(); if (ledcontrol) LED_A_OFF();
} }
// loop to get raw HID waveform then FSK demodulate the TAG ID from it
void CmdAWIDdemodFSK(int findone, int *high, int *low, int ledcontrol)
{
uint8_t *dest = BigBuf_get_addr();
//const size_t sizeOfBigBuff = BigBuf_max_traceLen();
size_t size;
int idx=0;
// Configure to go in 125Khz listen mode
LFSetupFPGAForADC(95, true);
while(!BUTTON_PRESS()) {
WDT_HIT();
if (ledcontrol) LED_A_ON();
DoAcquisition_default(-1,true);
// FSK demodulator
//size = sizeOfBigBuff; //variable size will change after demod so re initialize it before use
size = 50*128*2; //big enough to catch 2 sequences of largest format
idx = AWIDdemodFSK(dest, &size);
if (idx>0 && size==96){
// Index map
// 0 10 20 30 40 50 60
// | | | | | | |
// 01234567 890 1 234 5 678 9 012 3 456 7 890 1 234 5 678 9 012 3 456 7 890 1 234 5 678 9 012 3 - to 96
// -----------------------------------------------------------------------------
// 00000001 000 1 110 1 101 1 011 1 101 1 010 0 000 1 000 1 010 0 001 0 110 1 100 0 000 1 000 1
// premable bbb o bbb o bbw o fff o fff o ffc o ccc o ccc o ccc o ccc o ccc o wxx o xxx o xxx o - to 96
// |---26 bit---| |-----117----||-------------142-------------|
// b = format bit len, o = odd parity of last 3 bits
// f = facility code, c = card number
// w = wiegand parity
// (26 bit format shown)
//get raw ID before removing parities
uint32_t rawLo = bytebits_to_byte(dest+idx+64,32);
uint32_t rawHi = bytebits_to_byte(dest+idx+32,32);
uint32_t rawHi2 = bytebits_to_byte(dest+idx,32);
size = removeParity(dest, idx+8, 4, 1, 88);
// ok valid card found!
// Index map
// 0 10 20 30 40 50 60
// | | | | | | |
// 01234567 8 90123456 7890123456789012 3 456789012345678901234567890123456
// -----------------------------------------------------------------------------
// 00011010 1 01110101 0000000010001110 1 000000000000000000000000000000000
// bbbbbbbb w ffffffff cccccccccccccccc w xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
// |26 bit| |-117--| |-----142------|
// b = format bit len, o = odd parity of last 3 bits
// f = facility code, c = card number
// w = wiegand parity
// (26 bit format shown)
uint32_t fc = 0;
uint32_t cardnum = 0;
uint32_t code1 = 0;
uint32_t code2 = 0;
uint8_t fmtLen = bytebits_to_byte(dest,8);
if (fmtLen==26){
fc = bytebits_to_byte(dest+9, 8);
cardnum = bytebits_to_byte(dest+17, 16);
code1 = bytebits_to_byte(dest+8,fmtLen);
Dbprintf("AWID Found - BitLength: %d, FC: %d, Card: %d - Wiegand: %x, Raw: %08x%08x%08x", fmtLen, fc, cardnum, code1, rawHi2, rawHi, rawLo);
} else {
cardnum = bytebits_to_byte(dest+8+(fmtLen-17), 16);
if (fmtLen>32){
code1 = bytebits_to_byte(dest+8,fmtLen-32);
code2 = bytebits_to_byte(dest+8+(fmtLen-32),32);
Dbprintf("AWID Found - BitLength: %d -unknown BitLength- (%d) - Wiegand: %x%08x, Raw: %08x%08x%08x", fmtLen, cardnum, code1, code2, rawHi2, rawHi, rawLo);
} else{
code1 = bytebits_to_byte(dest+8,fmtLen);
Dbprintf("AWID Found - BitLength: %d -unknown BitLength- (%d) - Wiegand: %x, Raw: %08x%08x%08x", fmtLen, cardnum, code1, rawHi2, rawHi, rawLo);
}
}
if (findone){
if (ledcontrol) LED_A_OFF();
return;
}
// reset
}
idx = 0;
WDT_HIT();
}
DbpString("Stopped");
if (ledcontrol) LED_A_OFF();
}
void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol) void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol)
{ {
uint8_t *dest = BigBuf_get_addr(); uint8_t *dest = BigBuf_get_addr();

View file

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

View file

@ -209,7 +209,7 @@ void annotateTopaz(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize)
void annotateIso7816(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize){ void annotateIso7816(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize){
int pos = (cmd[0] == 2 || cmd[0] == 3) ? 1 : 2; int pos = (cmd[0] == 2 || cmd[0] == 3) ? 2 : 3;
switch ( cmd[pos] ){ switch ( cmd[pos] ){
case ISO7816_READ_BINARY :snprintf(exp, size, "READ BIN");break; case ISO7816_READ_BINARY :snprintf(exp, size, "READ BIN");break;

View file

@ -22,6 +22,7 @@
#include "util.h" #include "util.h"
#include "cmdlf.h" #include "cmdlf.h"
#include "cmdlfhid.h" #include "cmdlfhid.h"
#include "cmdlfawid.h"
#include "cmdlfti.h" #include "cmdlfti.h"
#include "cmdlfem4x.h" #include "cmdlfem4x.h"
#include "cmdlfhitag.h" #include "cmdlfhitag.h"
@ -1157,6 +1158,7 @@ static command_t CommandTable[] =
{ {
{"help", CmdHelp, 1, "This help"}, {"help", CmdHelp, 1, "This help"},
{"em4x", CmdLFEM4X, 1, "{ EM4X RFIDs... }"}, {"em4x", CmdLFEM4X, 1, "{ EM4X RFIDs... }"},
{"awid", CmdLFAWID, 1, "{ AWID RFIDs... }"},
{"hid", CmdLFHID, 1, "{ HID RFIDs... }"}, {"hid", CmdLFHID, 1, "{ HID RFIDs... }"},
{"hitag", CmdLFHitag, 1, "{ HITAG RFIDs... }"}, {"hitag", CmdLFHitag, 1, "{ HITAG RFIDs... }"},
{"io", CmdLFIO, 1, "{ IOPROX RFIDs... }"}, {"io", CmdLFIO, 1, "{ IOPROX RFIDs... }"},

233
client/cmdlfawid.c Normal file
View file

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

24
client/cmdlfawid.h Normal file
View file

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

View file

@ -1,208 +0,0 @@
//-----------------------------------------------------------------------------
//
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
// at your option, any later version. See the LICENSE.txt file for the text of
// the license.
//-----------------------------------------------------------------------------
// Low frequency AWID26 commands
//-----------------------------------------------------------------------------
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include <stdbool.h>
#include "proxmark3.h"
#include "ui.h"
//#include "graph.h"
#include "cmdmain.h"
#include "cmdparser.h"
//#include "cmddata.h"
#include "cmdlf.h"
#include "cmdlfawid26.h"
#include "util.h"
//#include "data.h"
static int CmdHelp(const char *Cmd);
int CmdClone(const char *Cmd)
{
char cmdp = param_getchar(Cmd, 0);
if (strlen(Cmd) < 1 || cmdp == 'h' || cmdp == 'H') {
PrintAndLog("Usage: lf awid26 clone <facility> <id>");
PrintAndLog(" [], ");
PrintAndLog("");
PrintAndLog(" sample: lf awid26 clone 15 2233");
return 0;
}
//sscanf(Cmd, "%d %d", &facilitycode, &cardno);
// char block0 = "00107060";
// char block1 = "00107060";
// char block2 = "00107060";
// char block3 = "00107060";
unsigned char buf[10] = {0x00};
unsigned char *resp = buf;
awid26_hex_to_uid(resp, "");
// PrintAndLog("Writing block %d with data %08X", Block, Data);
return 0;
}
// convert 96 bit AWID FSK data to 8 digit BCD UID
bool awid26_hex_to_uid(unsigned char *response, char *awid26)
{
//uint8_t i, tmp[96], tmp1[7];
//uint8_t tmp[96] = {0x00};
//int site;
//int id;
//if(!hextobinarray(tmp, awid26))
return false;
// // data is in blocks of 4 bits - every 4th bit is parity, except the first
// // block which is all zeros
// for(i= 0 ; i < 4 ; ++i)
// if(tmp[i] != 0x00)
// return false;
// // discard 1st block
// memcpy(tmp, tmp + 4, 92);
// // check and strip parity on the rest
// for(i= 1 ; i < 23 ; ++i)
// if(tmp[(i * 4) - 1] != GetParity(tmp + (i - 1) * 4, ODD, 3))
// return false;
// else
// memcpy((tmp + (i - 1) * 3), tmp + (i - 1) * 4, 3);
// // discard the rest of the header - 1 more 3 bit block
// memcpy(tmp, tmp + 3, 66);
// // next 8 bits is data length - should be 26: 0x1A
// binarraytohex(tmp1, tmp, 8);
// if(strcmp(tmp1, "1A") != 0)
// return false;
// memcpy(tmp, tmp +8, 58);
// // standard wiegand parity check - even for 1st 12 bits, odd for 2nd 12
// if(tmp[0] != GetParity(tmp + 1, EVEN, 12))
// return false;
// if(tmp[25] != GetParity(tmp + 13, ODD, 12))
// return false;
// // convert to hex, ignoring parity bits
// if(!binarraytohex(tmp1, tmp + 1, 24))
// return false;
// // convert hex to site/id
// sscanf(tmp1,"%2X%4X", &site, &id);
// // final output 8 byte BCD
// sprintf(response,"%03d%05d", site, id);
return true;
}
// convert null-terminated BCD UID (8 digits) to 96 bit awid26 encoded binary array
bool bcd_to_awid26_bin(unsigned char *awid26, unsigned char *bcd)
{
// char i, p, tmp1[8], tmp2[26];
// int tmpint;
// if(strlen(bcd) != 8)
// return false;
// // convert BCD site code to HEX
// sscanf(bcd, "%03d", &tmpint);
// sprintf(tmp2, "%02x", tmpint);
// memcpy(tmp1, tmp2, 2);
// // convert BCD ID to HEX
// sscanf(bcd + 3, "%05d", &tmpint);;
// sprintf(tmp2, "%04x", tmpint);
// // copy with trailing NULL
// memcpy(tmp1 + 2, tmp2, 5);
// // convert full HEX to binary, leaving room for parity prefix
// hextobinarray(tmp2 + 1, tmp1);
// wiegand_add_parity(tmp2, tmp2 + 1, 24);
// memset(awid26, '\x0', 96);
// // magic 18 bit awid26 header (we will overwrite the last two bits)
// hextobinarray(awid26, "011D8");
// // copy to target leaving space for parity bits
// for(i= 0, p= 18 ; i < 26 ; ++i, ++p)
// {
// // skip target bit if this is a parity location
// if(!((p + 1) % 4))
// p += 1;
// awid26[p]= tmp2[i];
// }
// // add parity bits
// for(i= 1 ; i < 24 ; ++i)
// awid26[((i + 1) * 4) - 1]= GetParity(&awid26[i * 4], ODD, 3);
return false;
}
// int CmdReadTrace(const char *Cmd)
// {
// uint8_t bits[LF_BITSSTREAM_LEN] = {0x00};
// uint8_t * bitstream = bits;
// 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 lotid = 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 );
// return 0;
// }
static command_t CommandTable[] =
{
{"help", CmdHelp, 1, "This help"},
{"clone", CmdClone, 1, "<facility> <id> -- clone AWID26 to t55xx tag"},
{NULL, NULL, 0, NULL}
};
int CmdLFAWID26(const char *Cmd)
{
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable);
return 0;
}

View file

@ -1,18 +0,0 @@
//-----------------------------------------------------------------------------
//
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
// at your option, any later version. See the LICENSE.txt file for the text of
// the license.
//-----------------------------------------------------------------------------
// Low frequency AWID 26 commands
//-----------------------------------------------------------------------------
#ifndef CMDLFAWID26_H__
#define CMDLFAWID26_H__
int CmdLFAWID26(const char *Cmd);
int CmdClone(const char *Cmd);
bool awid26_hex_to_uid(unsigned char *response, char *awid26);
bool bcd_to_awid26_bin(unsigned char *awid26, unsigned char *bcd);
#endif

View file

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

View file

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

View file

@ -54,6 +54,7 @@ local _commands = {
CMD_FSK_SIM_TAG = 0x021E, CMD_FSK_SIM_TAG = 0x021E,
CMD_ASK_SIM_TAG = 0x021F, CMD_ASK_SIM_TAG = 0x021F,
CMD_PSK_SIM_TAG = 0x0220, CMD_PSK_SIM_TAG = 0x0220,
CMD_AWID_DEMOD_FSK = 0x0221,
--/* CMD_SET_ADC_MUX: ext1 is 0 for lopkd, 1 for loraw, 2 for hipkd, 3 for hiraw */ --/* CMD_SET_ADC_MUX: ext1 is 0 for lopkd, 1 for loraw, 2 for hipkd, 3 for hiraw */

View file

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

76
tools/mfkey/mfkey32v2.c Normal file
View file

@ -0,0 +1,76 @@
#define __STDC_FORMAT_MACROS
#include <inttypes.h>
#define llx PRIx64
#define lli PRIi64
// Test-file: test2.c
#include "crapto1.h"
#include <stdio.h>
#include <stdlib.h>
int main (int argc, char *argv[]) {
struct Crypto1State *s,*t;
uint64_t key; // recovered key
uint32_t uid; // serial number
uint32_t nt0; // tag challenge first
uint32_t nt1; // tag challenge second
uint32_t nr0_enc; // first encrypted reader challenge
uint32_t ar0_enc; // first encrypted reader response
uint32_t nr1_enc; // second encrypted reader challenge
uint32_t ar1_enc; // second encrypted reader response
uint32_t ks2; // keystream used to encrypt reader response
printf("MIFARE Classic key recovery - based 32 bits of keystream VERSION2\n");
printf("Recover key from two 32-bit reader authentication answers only");
printf("This version implements Moebius two different nonce solution (like the supercard)\n\n");
if (argc < 8) {
printf(" syntax: %s <uid> <nt> <{nr_0}> <{ar_0}> <nt1> <{nr_1}> <{ar_1}>\n\n",argv[0]);
return 1;
}
sscanf(argv[1],"%x",&uid);
sscanf(argv[2],"%x",&nt0);
sscanf(argv[3],"%x",&nr0_enc);
sscanf(argv[4],"%x",&ar0_enc);
sscanf(argv[5],"%x",&nt1);
sscanf(argv[6],"%x",&nr1_enc);
sscanf(argv[7],"%x",&ar1_enc);
printf("Recovering key for:\n");
printf(" uid: %08x\n",uid);
printf(" nt_0: %08x\n",nt0);
printf(" {nr_0}: %08x\n",nr0_enc);
printf(" {ar_0}: %08x\n",ar0_enc);
printf(" nt_1: %08x\n",nt1);
printf(" {nr_1}: %08x\n",nr1_enc);
printf(" {ar_1}: %08x\n",ar1_enc);
// Generate lfsr succesors of the tag challenge
printf("\nLFSR succesors of the tag challenge:\n");
printf(" nt': %08x\n",prng_successor(nt0, 64));
printf(" nt'': %08x\n",prng_successor(nt0, 96));
// Extract the keystream from the messages
printf("\nKeystream used to generate {ar} and {at}:\n");
ks2 = ar0_enc ^ prng_successor(nt0, 64);
printf(" ks2: %08x\n",ks2);
s = lfsr_recovery32(ar0_enc ^ prng_successor(nt0, 64), 0);
for(t = s; t->odd | t->even; ++t) {
lfsr_rollback_word(t, 0, 0);
lfsr_rollback_word(t, nr0_enc, 1);
lfsr_rollback_word(t, uid ^ nt0, 0);
crypto1_get_lfsr(t, &key);
crypto1_word(t, uid ^ nt1, 0);
crypto1_word(t, nr1_enc, 1);
if (ar1_enc == (crypto1_word(t, 0, 0) ^ prng_successor(nt1, 64))) {
printf("\nFound Key: [%012"llx"]\n\n",key);
break;}
}
free(s);
return 0;
}

20000
traces/quadrakey-521512301.pm3 Normal file

File diff suppressed because it is too large Load diff