Merge branch 'master' into GenericTracing
Conflicts: armsrc/iso14443.c armsrc/iso14443a.c client/cmdhf.c client/cmdhf14b.c
This commit is contained in:
97
armsrc/BigBuf.c
Normal file
97
armsrc/BigBuf.c
Normal file
@@ -0,0 +1,97 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Jonathan Westhues, Aug 2005
|
||||
// Gerhard de Koning Gans, April 2008, May 2011
|
||||
//
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
// BigBuf and functions to allocate/free parts of it.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include <stdint.h>
|
||||
#include "proxmark3.h"
|
||||
#include "apps.h"
|
||||
#include "string.h"
|
||||
|
||||
// BigBuf is the large multi-purpose buffer, typically used to hold A/D samples or traces.
|
||||
// Also used to hold various smaller buffers and the Mifare Emulator Memory.
|
||||
|
||||
// declare it as uint32_t to achieve alignment to 4 Byte boundary
|
||||
static uint32_t BigBuf[BIGBUF_SIZE/sizeof(uint32_t)];
|
||||
|
||||
// High memory mark
|
||||
static uint16_t BigBuf_hi = BIGBUF_SIZE;
|
||||
|
||||
// pointer to the emulator memory.
|
||||
static uint8_t *emulator_memory = NULL;
|
||||
|
||||
// trace related global variables
|
||||
// (only one left). ToDo: make this static as well?
|
||||
uint16_t traceLen = 0;
|
||||
|
||||
|
||||
// get the address of BigBuf
|
||||
uint8_t *BigBuf_get_addr(void)
|
||||
{
|
||||
return (uint8_t *)BigBuf;
|
||||
}
|
||||
|
||||
|
||||
// get the address of the emulator memory. Allocate part of Bigbuf for it, if not yet done
|
||||
uint8_t *BigBuf_get_EM_addr(void)
|
||||
{
|
||||
if (emulator_memory == NULL) { // not yet allocated
|
||||
emulator_memory = BigBuf_malloc(CARD_MEMORY_SIZE);
|
||||
}
|
||||
|
||||
return emulator_memory;
|
||||
}
|
||||
|
||||
|
||||
// clear ALL of BigBuf
|
||||
void BigBuf_Clear(void)
|
||||
{
|
||||
memset(BigBuf,0,BIGBUF_SIZE);
|
||||
Dbprintf("Buffer cleared (%i bytes)",BIGBUF_SIZE);
|
||||
}
|
||||
|
||||
|
||||
// allocate a chunk of memory from BigBuf. We allocate high memory first. The unallocated memory
|
||||
// at the beginning of BigBuf is always for traces/samples
|
||||
uint8_t *BigBuf_malloc(uint16_t chunksize)
|
||||
{
|
||||
if (BigBuf_hi - chunksize < 0) {
|
||||
return NULL; // no memory left
|
||||
} else {
|
||||
chunksize = (chunksize + 3) & 0xfffc; // round to next multiple of 4
|
||||
BigBuf_hi -= chunksize; // aligned to 4 Byte boundary
|
||||
return (uint8_t *)BigBuf + BigBuf_hi;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// free ALL allocated chunks. The whole BigBuf is available for traces or samples again.
|
||||
void BigBuf_free(void)
|
||||
{
|
||||
BigBuf_hi = BIGBUF_SIZE;
|
||||
emulator_memory = NULL;
|
||||
}
|
||||
|
||||
|
||||
// free allocated chunks EXCEPT the emulator memory
|
||||
void BigBuf_free_keep_EM(void)
|
||||
{
|
||||
if (emulator_memory != NULL) {
|
||||
BigBuf_hi = emulator_memory - (uint8_t *)BigBuf;
|
||||
} else {
|
||||
BigBuf_hi = BIGBUF_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// return the maximum trace length (i.e. the unallocated size of BigBuf)
|
||||
uint16_t BigBuf_max_traceLen(void)
|
||||
{
|
||||
return BigBuf_hi;
|
||||
}
|
||||
34
armsrc/BigBuf.h
Normal file
34
armsrc/BigBuf.h
Normal file
@@ -0,0 +1,34 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Jonathan Westhues, Aug 2005
|
||||
// Gerhard de Koning Gans, April 2008, May 2011
|
||||
//
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
// BigBuf and functions to allocate/free parts of it.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef __BIGBUF_H
|
||||
#define __BIGBUF_H
|
||||
|
||||
|
||||
#define BIGBUF_SIZE 40000
|
||||
#define MAX_FRAME_SIZE 256 // maximum allowed ISO14443 frame
|
||||
#define MAX_PARITY_SIZE ((MAX_FRAME_SIZE + 7) / 8)
|
||||
#define MAX_MIFARE_FRAME_SIZE 18 // biggest Mifare frame is answer to a read (one block = 16 Bytes) + 2 Bytes CRC
|
||||
#define MAX_MIFARE_PARITY_SIZE 3 // need 18 parity bits for the 18 Byte above. 3 Bytes are enough to store these
|
||||
#define CARD_MEMORY_SIZE 4096
|
||||
#define DMA_BUFFER_SIZE 128
|
||||
|
||||
extern uint8_t *BigBuf_get_addr(void);
|
||||
extern uint8_t *BigBuf_get_EM_addr(void);
|
||||
extern uint16_t BigBuf_max_traceLen(void);
|
||||
void BigBuf_Clear(void);
|
||||
extern uint8_t *BigBuf_malloc(uint16_t);
|
||||
extern void BigBuf_free(void);
|
||||
extern void BigBuf_free_keep_EM(void);
|
||||
|
||||
extern uint16_t traceLen;
|
||||
|
||||
#endif /* __BIGBUF_H */
|
||||
@@ -10,15 +10,16 @@ APP_INCLUDES = apps.h
|
||||
|
||||
#remove one of the following defines and comment out the relevant line
|
||||
#in the next section to remove that particular feature from compilation
|
||||
APP_CFLAGS = -DWITH_LF -DWITH_ISO15693 -DWITH_ISO14443a -DWITH_ISO14443b -DWITH_ICLASS -DWITH_LEGICRF -DWITH_HITAG -fno-strict-aliasing
|
||||
APP_CFLAGS = -DWITH_LF -DWITH_ISO15693 -DWITH_ISO14443a -DWITH_ISO14443b -DWITH_ICLASS -DWITH_LEGICRF -DWITH_HITAG -DWITH_CRC -fno-strict-aliasing
|
||||
#-DWITH_LCD
|
||||
|
||||
#SRC_LCD = fonts.c LCD.c
|
||||
SRC_LF = lfops.c hitag2.c
|
||||
SRC_LF = lfops.c hitag2.c lfsampling.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
|
||||
SRC_CRAPTO1 = crapto1.c crypto1.c des.c aes.c
|
||||
SRC_CRC = iso14443crc.c crc.c crc16.c crc32.c
|
||||
|
||||
THUMBSRC = start.c \
|
||||
$(SRC_LCD) \
|
||||
@@ -34,15 +35,14 @@ THUMBSRC = start.c \
|
||||
# These are to be compiled in ARM mode
|
||||
ARMSRC = fpgaloader.c \
|
||||
legicrf.c \
|
||||
iso14443crc.c \
|
||||
crc16.c \
|
||||
lfdemod.c \
|
||||
$(SRC_ISO14443a) \
|
||||
$(SRC_ISO14443b) \
|
||||
$(SRC_CRAPTO1) \
|
||||
$(SRC_CRC) \
|
||||
legic_prng.c \
|
||||
iclass.c \
|
||||
crc.c
|
||||
BigBuf.c \
|
||||
|
||||
# stdint.h provided locally until GCC 4.5 becomes C99 compliant
|
||||
APP_CFLAGS += -I.
|
||||
|
||||
1168
armsrc/aes.c
Normal file
1168
armsrc/aes.c
Normal file
File diff suppressed because it is too large
Load Diff
30
armsrc/aes.h
Normal file
30
armsrc/aes.h
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* AES Cryptographic Algorithm Header File. Include this header file in
|
||||
* your source which uses these given APIs. (This source is kept under
|
||||
* public domain)
|
||||
*/
|
||||
|
||||
// AES context structure
|
||||
typedef struct {
|
||||
unsigned int Ek[60];
|
||||
unsigned int Dk[60];
|
||||
unsigned int Iv[4];
|
||||
unsigned char Nr;
|
||||
unsigned char Mode;
|
||||
} AesCtx;
|
||||
|
||||
// key length in bytes
|
||||
#define KEY128 16
|
||||
#define KEY192 24
|
||||
#define KEY256 32
|
||||
// block size in bytes
|
||||
#define BLOCKSZ 16
|
||||
// mode
|
||||
#define EBC 0
|
||||
#define CBC 1
|
||||
|
||||
// AES API function prototype
|
||||
|
||||
int AesCtxIni(AesCtx *pCtx, unsigned char *pIV, unsigned char *pKey, unsigned int KeyLen, unsigned char Mode);
|
||||
int AesEncrypt(AesCtx *pCtx, unsigned char *pData, unsigned char *pCipher, unsigned int DataLen);
|
||||
int AesDecrypt(AesCtx *pCtx, unsigned char *pCipher, unsigned char *pData, unsigned int CipherLen);
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
#include "legicrf.h"
|
||||
#include <hitag2.h>
|
||||
|
||||
#include "lfsampling.h"
|
||||
#ifdef WITH_LCD
|
||||
#include "LCD.h"
|
||||
#endif
|
||||
@@ -42,12 +42,6 @@ int ToSendMax;
|
||||
static int ToSendBit;
|
||||
struct common_area common_area __attribute__((section(".commonarea")));
|
||||
|
||||
void BufferClear(void)
|
||||
{
|
||||
memset(BigBuf,0,sizeof(BigBuf));
|
||||
Dbprintf("Buffer cleared (%i bytes)",sizeof(BigBuf));
|
||||
}
|
||||
|
||||
void ToSendReset(void)
|
||||
{
|
||||
ToSendMax = -1;
|
||||
@@ -246,7 +240,10 @@ void MeasureAntennaTuningHf(void)
|
||||
|
||||
void SimulateTagHfListen(void)
|
||||
{
|
||||
uint8_t *dest = (uint8_t *)BigBuf+FREE_BUFFER_OFFSET;
|
||||
// ToDo: historically this used the free buffer, which was 2744 Bytes long.
|
||||
// There might be a better size to be defined:
|
||||
#define HF_14B_SNOOP_BUFFER_SIZE 2744
|
||||
uint8_t *dest = BigBuf_malloc(HF_14B_SNOOP_BUFFER_SIZE);
|
||||
uint8_t v = 0;
|
||||
int i;
|
||||
int p = 0;
|
||||
@@ -281,7 +278,7 @@ void SimulateTagHfListen(void)
|
||||
p = 0;
|
||||
i++;
|
||||
|
||||
if(i >= FREE_BUFFER_SIZE) {
|
||||
if(i >= HF_14B_SNOOP_BUFFER_SIZE) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -629,16 +626,17 @@ void UsbPacketReceived(uint8_t *packet, int len)
|
||||
|
||||
switch(c->cmd) {
|
||||
#ifdef WITH_LF
|
||||
case CMD_SET_LF_SAMPLING_CONFIG:
|
||||
setSamplingConfig((sample_config *) c->d.asBytes);
|
||||
break;
|
||||
case CMD_ACQUIRE_RAW_ADC_SAMPLES_125K:
|
||||
AcquireRawAdcSamples125k(c->arg[0]);
|
||||
cmd_send(CMD_ACK,0,0,0,0,0);
|
||||
cmd_send(CMD_ACK,SampleLF(),0,0,0,0);
|
||||
break;
|
||||
case CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K:
|
||||
ModThenAcquireRawAdcSamples125k(c->arg[0],c->arg[1],c->arg[2],c->d.asBytes);
|
||||
break;
|
||||
case CMD_LF_SNOOP_RAW_ADC_SAMPLES:
|
||||
SnoopLFRawAdcSamples(c->arg[0], c->arg[1]);
|
||||
cmd_send(CMD_ACK,0,0,0,0,0);
|
||||
cmd_send(CMD_ACK,SnoopLF(),0,0,0,0);
|
||||
break;
|
||||
case CMD_HID_DEMOD_FSK:
|
||||
CmdHIDdemodFSK(c->arg[0], 0, 0, 1);
|
||||
@@ -801,9 +799,18 @@ void UsbPacketReceived(uint8_t *packet, int len)
|
||||
case CMD_MIFAREU_READBL:
|
||||
MifareUReadBlock(c->arg[0],c->d.asBytes);
|
||||
break;
|
||||
case CMD_MIFAREUC_AUTH1:
|
||||
MifareUC_Auth1(c->arg[0],c->d.asBytes);
|
||||
break;
|
||||
case CMD_MIFAREUC_AUTH2:
|
||||
MifareUC_Auth2(c->arg[0],c->d.asBytes);
|
||||
break;
|
||||
case CMD_MIFAREU_READCARD:
|
||||
MifareUReadCard(c->arg[0], c->arg[1], c->d.asBytes);
|
||||
break;
|
||||
break;
|
||||
case CMD_MIFAREUC_READCARD:
|
||||
MifareUReadCard(c->arg[0], c->arg[1], c->d.asBytes);
|
||||
break;
|
||||
case CMD_MIFARE_READSC:
|
||||
MifareReadSector(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
|
||||
break;
|
||||
@@ -858,6 +865,7 @@ void UsbPacketReceived(uint8_t *packet, int len)
|
||||
case CMD_MIFARE_SNIFFER:
|
||||
SniffMifare(c->arg[0]);
|
||||
break;
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef WITH_ICLASS
|
||||
@@ -881,7 +889,7 @@ void UsbPacketReceived(uint8_t *packet, int len)
|
||||
break;
|
||||
|
||||
case CMD_BUFF_CLEAR:
|
||||
BufferClear();
|
||||
BigBuf_Clear();
|
||||
break;
|
||||
|
||||
case CMD_MEASURE_ANTENNA_TUNING:
|
||||
@@ -905,17 +913,18 @@ void UsbPacketReceived(uint8_t *packet, int len)
|
||||
case CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K:
|
||||
|
||||
LED_B_ON();
|
||||
uint8_t *BigBuf = BigBuf_get_addr();
|
||||
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);
|
||||
cmd_send(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K,i,len,0,((byte_t*)BigBuf)+c->arg[0]+i,len);
|
||||
cmd_send(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K,i,len,traceLen,BigBuf+c->arg[0]+i,len);
|
||||
}
|
||||
// Trigger a finish downloading signal with an ACK frame
|
||||
cmd_send(CMD_ACK,0,0,0,0,0);
|
||||
cmd_send(CMD_ACK,1,0,traceLen,getSamplingConfig(),sizeof(sample_config));
|
||||
LED_B_OFF();
|
||||
break;
|
||||
|
||||
case CMD_DOWNLOADED_SIM_SAMPLES_125K: {
|
||||
uint8_t *b = (uint8_t *)BigBuf;
|
||||
uint8_t *b = BigBuf_get_addr();
|
||||
memcpy(b+c->arg[0], c->d.asBytes, USB_CMD_DATA_SIZE);
|
||||
cmd_send(CMD_ACK,0,0,0,0,0);
|
||||
break;
|
||||
|
||||
@@ -17,48 +17,10 @@
|
||||
#include "common.h"
|
||||
#include "hitag2.h"
|
||||
#include "mifare.h"
|
||||
|
||||
// The large multi-purpose buffer, typically used to hold A/D samples,
|
||||
// maybe processed in some way.
|
||||
#define BIGBUF_SIZE 40000
|
||||
uint32_t BigBuf[BIGBUF_SIZE / sizeof(uint32_t)];
|
||||
#define TRACE_OFFSET 0
|
||||
#define TRACE_SIZE 3000
|
||||
#define RECV_CMD_OFFSET (TRACE_OFFSET + TRACE_SIZE)
|
||||
#define MAX_FRAME_SIZE 256
|
||||
#define MAX_PARITY_SIZE ((MAX_FRAME_SIZE + 1)/ 8)
|
||||
#define RECV_CMD_PAR_OFFSET (RECV_CMD_OFFSET + MAX_FRAME_SIZE)
|
||||
#define RECV_RESP_OFFSET (RECV_CMD_PAR_OFFSET + MAX_PARITY_SIZE)
|
||||
#define RECV_RESP_PAR_OFFSET (RECV_RESP_OFFSET + MAX_FRAME_SIZE)
|
||||
#define CARD_MEMORY_OFFSET (RECV_RESP_PAR_OFFSET + MAX_PARITY_SIZE)
|
||||
#define CARD_MEMORY_SIZE 4096
|
||||
#define DMA_BUFFER_OFFSET CARD_MEMORY_OFFSET
|
||||
#define DMA_BUFFER_SIZE CARD_MEMORY_SIZE
|
||||
#define FREE_BUFFER_OFFSET (CARD_MEMORY_OFFSET + CARD_MEMORY_SIZE)
|
||||
#define FREE_BUFFER_SIZE (BIGBUF_SIZE - FREE_BUFFER_OFFSET - 1)
|
||||
|
||||
/*
|
||||
The statements above translates into this :
|
||||
BIGBUF_SIZE = 40000
|
||||
TRACE_OFFSET = 0
|
||||
TRACE_SIZE = 3000
|
||||
RECV_CMD_OFFSET = 3000
|
||||
MAX_FRAME_SIZE = 256
|
||||
MAX_PARITY_SIZE = 32
|
||||
RECV_CMD_PAR_OFFSET = 3256
|
||||
RECV_RESP_OFFSET = 3288
|
||||
RECV_RESP_PAR_OFFSET= 3544
|
||||
CARD_MEMORY_OFFSET = 3576
|
||||
CARD_MEMORY_SIZE = 4096
|
||||
DMA_BUFFER_OFFSET = 3576
|
||||
DMA_BUFFER_SIZE = 4096
|
||||
FREE_BUFFER_OFFSET = 7672
|
||||
FREE_BUFFER_SIZE = 32327
|
||||
*/
|
||||
#include "../common/crc32.h"
|
||||
#include "BigBuf.h"
|
||||
|
||||
extern const uint8_t OddByteParity[256];
|
||||
extern uint8_t *trace; // = (uint8_t *) BigBuf;
|
||||
extern int traceLen; // = 0;
|
||||
extern int rsamples; // = 0;
|
||||
extern int tracing; // = TRUE;
|
||||
extern uint8_t trigger;
|
||||
@@ -81,12 +43,8 @@ int AvgAdc(int ch);
|
||||
void ToSendStuffBit(int b);
|
||||
void ToSendReset(void);
|
||||
void ListenReaderField(int limit);
|
||||
void AcquireRawAdcSamples125k(int at134khz);
|
||||
void SnoopLFRawAdcSamples(int divisor, int trigger_threshold);
|
||||
void DoAcquisition125k(int trigger_threshold);
|
||||
extern int ToSendMax;
|
||||
extern uint8_t ToSend[];
|
||||
extern uint32_t BigBuf[];
|
||||
|
||||
/// fpga.h
|
||||
void FpgaSendCommand(uint16_t cmd, uint16_t v);
|
||||
@@ -144,6 +102,10 @@ void SetAdcMuxFor(uint32_t whichGpio);
|
||||
#define FPGA_HF_ISO14443A_READER_MOD (4<<0)
|
||||
|
||||
/// lfops.h
|
||||
extern uint8_t decimation;
|
||||
extern uint8_t bits_per_sample ;
|
||||
extern bool averaging;
|
||||
|
||||
void AcquireRawAdcSamples125k(int divisor);
|
||||
void ModThenAcquireRawAdcSamples125k(int delay_off,int period_0,int period_1,uint8_t *command);
|
||||
void ReadTItag(void);
|
||||
@@ -198,7 +160,9 @@ void ReaderMifare(bool first_try);
|
||||
int32_t dist_nt(uint32_t nt1, uint32_t nt2);
|
||||
void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *data);
|
||||
void MifareUReadBlock(uint8_t arg0,uint8_t *datain);
|
||||
void MifareUReadCard(uint8_t arg0, int arg1, uint8_t *datain);
|
||||
void MifareUC_Auth1(uint8_t arg0, uint8_t *datain);
|
||||
void MifareUC_Auth2(uint32_t arg0, uint8_t *datain);
|
||||
void MifareUReadCard(uint8_t arg0, int Pages, uint8_t *datain);
|
||||
void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain);
|
||||
void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain);
|
||||
void MifareUWriteBlock(uint8_t arg0,uint8_t *datain);
|
||||
@@ -215,6 +179,25 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
|
||||
void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
|
||||
void MifareCIdent(); // is "magic chinese" card?
|
||||
|
||||
//desfire
|
||||
void Mifare_DES_Auth1(uint8_t arg0,uint8_t *datain);
|
||||
void Mifare_DES_Auth2(uint32_t arg0, uint8_t *datain);
|
||||
|
||||
// mifaredesfire.h
|
||||
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 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(uint8_t reason);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// iso15693.h
|
||||
void RecordRawAdcSamplesIso15693(void);
|
||||
void AcquireRawAdcSamplesIso15693(void);
|
||||
|
||||
383
armsrc/des.c
Normal file
383
armsrc/des.c
Normal file
@@ -0,0 +1,383 @@
|
||||
/* des.c */
|
||||
/*
|
||||
This file is part of the ARM-Crypto-Lib.
|
||||
Copyright (C) 2006-2010 Daniel Otte (daniel.otte@rub.de)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* \file des.c
|
||||
* \author Daniel Otte
|
||||
* \email daniel.otte@rub.de
|
||||
* \date 2007-06-16
|
||||
* \brief DES and EDE-DES implementation
|
||||
* \license GPLv3 or later
|
||||
*
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
const uint8_t sbox[256] = {
|
||||
/* S-box 1 */
|
||||
0xE4, 0xD1, 0x2F, 0xB8, 0x3A, 0x6C, 0x59, 0x07,
|
||||
0x0F, 0x74, 0xE2, 0xD1, 0xA6, 0xCB, 0x95, 0x38,
|
||||
0x41, 0xE8, 0xD6, 0x2B, 0xFC, 0x97, 0x3A, 0x50,
|
||||
0xFC, 0x82, 0x49, 0x17, 0x5B, 0x3E, 0xA0, 0x6D,
|
||||
/* S-box 2 */
|
||||
0xF1, 0x8E, 0x6B, 0x34, 0x97, 0x2D, 0xC0, 0x5A,
|
||||
0x3D, 0x47, 0xF2, 0x8E, 0xC0, 0x1A, 0x69, 0xB5,
|
||||
0x0E, 0x7B, 0xA4, 0xD1, 0x58, 0xC6, 0x93, 0x2F,
|
||||
0xD8, 0xA1, 0x3F, 0x42, 0xB6, 0x7C, 0x05, 0xE9,
|
||||
/* S-box 3 */
|
||||
0xA0, 0x9E, 0x63, 0xF5, 0x1D, 0xC7, 0xB4, 0x28,
|
||||
0xD7, 0x09, 0x34, 0x6A, 0x28, 0x5E, 0xCB, 0xF1,
|
||||
0xD6, 0x49, 0x8F, 0x30, 0xB1, 0x2C, 0x5A, 0xE7,
|
||||
0x1A, 0xD0, 0x69, 0x87, 0x4F, 0xE3, 0xB5, 0x2C,
|
||||
/* S-box 4 */
|
||||
0x7D, 0xE3, 0x06, 0x9A, 0x12, 0x85, 0xBC, 0x4F,
|
||||
0xD8, 0xB5, 0x6F, 0x03, 0x47, 0x2C, 0x1A, 0xE9,
|
||||
0xA6, 0x90, 0xCB, 0x7D, 0xF1, 0x3E, 0x52, 0x84,
|
||||
0x3F, 0x06, 0xA1, 0xD8, 0x94, 0x5B, 0xC7, 0x2E,
|
||||
/* S-box 5 */
|
||||
0x2C, 0x41, 0x7A, 0xB6, 0x85, 0x3F, 0xD0, 0xE9,
|
||||
0xEB, 0x2C, 0x47, 0xD1, 0x50, 0xFA, 0x39, 0x86,
|
||||
0x42, 0x1B, 0xAD, 0x78, 0xF9, 0xC5, 0x63, 0x0E,
|
||||
0xB8, 0xC7, 0x1E, 0x2D, 0x6F, 0x09, 0xA4, 0x53,
|
||||
/* S-box 6 */
|
||||
0xC1, 0xAF, 0x92, 0x68, 0x0D, 0x34, 0xE7, 0x5B,
|
||||
0xAF, 0x42, 0x7C, 0x95, 0x61, 0xDE, 0x0B, 0x38,
|
||||
0x9E, 0xF5, 0x28, 0xC3, 0x70, 0x4A, 0x1D, 0xB6,
|
||||
0x43, 0x2C, 0x95, 0xFA, 0xBE, 0x17, 0x60, 0x8D,
|
||||
/* S-box 7 */
|
||||
0x4B, 0x2E, 0xF0, 0x8D, 0x3C, 0x97, 0x5A, 0x61,
|
||||
0xD0, 0xB7, 0x49, 0x1A, 0xE3, 0x5C, 0x2F, 0x86,
|
||||
0x14, 0xBD, 0xC3, 0x7E, 0xAF, 0x68, 0x05, 0x92,
|
||||
0x6B, 0xD8, 0x14, 0xA7, 0x95, 0x0F, 0xE2, 0x3C,
|
||||
/* S-box 8 */
|
||||
0xD2, 0x84, 0x6F, 0xB1, 0xA9, 0x3E, 0x50, 0xC7,
|
||||
0x1F, 0xD8, 0xA3, 0x74, 0xC5, 0x6B, 0x0E, 0x92,
|
||||
0x7B, 0x41, 0x9C, 0xE2, 0x06, 0xAD, 0xF3, 0x58,
|
||||
0x21, 0xE7, 0x4A, 0x8D, 0xFC, 0x90, 0x35, 0x6B
|
||||
};
|
||||
|
||||
const uint8_t e_permtab[] ={
|
||||
4, 6, /* 4 bytes in 6 bytes out*/
|
||||
32, 1, 2, 3, 4, 5,
|
||||
4, 5, 6, 7, 8, 9,
|
||||
8, 9, 10, 11, 12, 13,
|
||||
12, 13, 14, 15, 16, 17,
|
||||
16, 17, 18, 19, 20, 21,
|
||||
20, 21, 22, 23, 24, 25,
|
||||
24, 25, 26, 27, 28, 29,
|
||||
28, 29, 30, 31, 32, 1
|
||||
};
|
||||
|
||||
const uint8_t p_permtab[] ={
|
||||
4, 4, /* 32 bit -> 32 bit */
|
||||
16, 7, 20, 21,
|
||||
29, 12, 28, 17,
|
||||
1, 15, 23, 26,
|
||||
5, 18, 31, 10,
|
||||
2, 8, 24, 14,
|
||||
32, 27, 3, 9,
|
||||
19, 13, 30, 6,
|
||||
22, 11, 4, 25
|
||||
};
|
||||
|
||||
const uint8_t ip_permtab[] ={
|
||||
8, 8, /* 64 bit -> 64 bit */
|
||||
58, 50, 42, 34, 26, 18, 10, 2,
|
||||
60, 52, 44, 36, 28, 20, 12, 4,
|
||||
62, 54, 46, 38, 30, 22, 14, 6,
|
||||
64, 56, 48, 40, 32, 24, 16, 8,
|
||||
57, 49, 41, 33, 25, 17, 9, 1,
|
||||
59, 51, 43, 35, 27, 19, 11, 3,
|
||||
61, 53, 45, 37, 29, 21, 13, 5,
|
||||
63, 55, 47, 39, 31, 23, 15, 7
|
||||
};
|
||||
|
||||
const uint8_t inv_ip_permtab[] ={
|
||||
8, 8, /* 64 bit -> 64 bit */
|
||||
40, 8, 48, 16, 56, 24, 64, 32,
|
||||
39, 7, 47, 15, 55, 23, 63, 31,
|
||||
38, 6, 46, 14, 54, 22, 62, 30,
|
||||
37, 5, 45, 13, 53, 21, 61, 29,
|
||||
36, 4, 44, 12, 52, 20, 60, 28,
|
||||
35, 3, 43, 11, 51, 19, 59, 27,
|
||||
34, 2, 42, 10, 50, 18, 58, 26,
|
||||
33, 1, 41, 9, 49, 17, 57, 25
|
||||
};
|
||||
|
||||
const uint8_t pc1_permtab[] ={
|
||||
8, 7, /* 64 bit -> 56 bit*/
|
||||
57, 49, 41, 33, 25, 17, 9,
|
||||
1, 58, 50, 42, 34, 26, 18,
|
||||
10, 2, 59, 51, 43, 35, 27,
|
||||
19, 11, 3, 60, 52, 44, 36,
|
||||
63, 55, 47, 39, 31, 23, 15,
|
||||
7, 62, 54, 46, 38, 30, 22,
|
||||
14, 6, 61, 53, 45, 37, 29,
|
||||
21, 13, 5, 28, 20, 12, 4
|
||||
};
|
||||
|
||||
const uint8_t pc2_permtab[] ={
|
||||
7, 6, /* 56 bit -> 48 bit */
|
||||
14, 17, 11, 24, 1, 5,
|
||||
3, 28, 15, 6, 21, 10,
|
||||
23, 19, 12, 4, 26, 8,
|
||||
16, 7, 27, 20, 13, 2,
|
||||
41, 52, 31, 37, 47, 55,
|
||||
30, 40, 51, 45, 33, 48,
|
||||
44, 49, 39, 56, 34, 53,
|
||||
46, 42, 50, 36, 29, 32
|
||||
};
|
||||
|
||||
const uint8_t splitin6bitword_permtab[] = {
|
||||
8, 8, /* 64 bit -> 64 bit */
|
||||
64, 64, 1, 6, 2, 3, 4, 5,
|
||||
64, 64, 7, 12, 8, 9, 10, 11,
|
||||
64, 64, 13, 18, 14, 15, 16, 17,
|
||||
64, 64, 19, 24, 20, 21, 22, 23,
|
||||
64, 64, 25, 30, 26, 27, 28, 29,
|
||||
64, 64, 31, 36, 32, 33, 34, 35,
|
||||
64, 64, 37, 42, 38, 39, 40, 41,
|
||||
64, 64, 43, 48, 44, 45, 46, 47
|
||||
};
|
||||
|
||||
const uint8_t shiftkey_permtab[] = {
|
||||
7, 7, /* 56 bit -> 56 bit */
|
||||
2, 3, 4, 5, 6, 7, 8, 9,
|
||||
10, 11, 12, 13, 14, 15, 16, 17,
|
||||
18, 19, 20, 21, 22, 23, 24, 25,
|
||||
26, 27, 28, 1,
|
||||
30, 31, 32, 33, 34, 35, 36, 37,
|
||||
38, 39, 40, 41, 42, 43, 44, 45,
|
||||
46, 47, 48, 49, 50, 51, 52, 53,
|
||||
54, 55, 56, 29
|
||||
};
|
||||
|
||||
const uint8_t shiftkeyinv_permtab[] = {
|
||||
7, 7,
|
||||
28, 1, 2, 3, 4, 5, 6, 7,
|
||||
8, 9, 10, 11, 12, 13, 14, 15,
|
||||
16, 17, 18, 19, 20, 21, 22, 23,
|
||||
24, 25, 26, 27,
|
||||
56, 29, 30, 31, 32, 33, 34, 35,
|
||||
36, 37, 38, 39, 40, 41, 42, 43,
|
||||
44, 45, 46, 47, 48, 49, 50, 51,
|
||||
52, 53, 54, 55
|
||||
};
|
||||
|
||||
/*
|
||||
1 0
|
||||
1 0
|
||||
2 1
|
||||
2 1
|
||||
2 1
|
||||
2 1
|
||||
2 1
|
||||
2 1
|
||||
----
|
||||
1 0
|
||||
2 1
|
||||
2 1
|
||||
2 1
|
||||
2 1
|
||||
2 1
|
||||
2 1
|
||||
1 0
|
||||
*/
|
||||
#define ROTTABLE 0x7EFC
|
||||
#define ROTTABLE_INV 0x3F7E
|
||||
/******************************************************************************/
|
||||
|
||||
void permute(const uint8_t *ptable, const uint8_t *in, uint8_t *out){
|
||||
uint8_t ob; /* in-bytes and out-bytes */
|
||||
uint8_t byte, bit; /* counter for bit and byte */
|
||||
ob = ptable[1];
|
||||
ptable = &(ptable[2]);
|
||||
for(byte=0; byte<ob; ++byte){
|
||||
uint8_t x,t=0;
|
||||
for(bit=0; bit<8; ++bit){
|
||||
x=*ptable++ -1 ;
|
||||
t<<=1;
|
||||
if((in[x/8]) & (0x80>>(x%8)) ){
|
||||
t|=0x01;
|
||||
}
|
||||
}
|
||||
out[byte]=t;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
void changeendian32(uint32_t * a){
|
||||
*a = (*a & 0x000000FF) << 24 |
|
||||
(*a & 0x0000FF00) << 8 |
|
||||
(*a & 0x00FF0000) >> 8 |
|
||||
(*a & 0xFF000000) >> 24;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
static inline
|
||||
void shiftkey(uint8_t *key){
|
||||
uint8_t k[7];
|
||||
memcpy(k, key, 7);
|
||||
permute((uint8_t*)shiftkey_permtab, k, key);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
static inline
|
||||
void shiftkey_inv(uint8_t *key){
|
||||
uint8_t k[7];
|
||||
memcpy(k, key, 7);
|
||||
permute((uint8_t*)shiftkeyinv_permtab, k, key);
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
static inline
|
||||
uint64_t splitin6bitwords(uint64_t a){
|
||||
uint64_t ret=0;
|
||||
a &= 0x0000ffffffffffffLL;
|
||||
permute((uint8_t*)splitin6bitword_permtab, (uint8_t*)&a, (uint8_t*)&ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
static inline
|
||||
uint8_t substitute(uint8_t a, uint8_t * sbp){
|
||||
uint8_t x;
|
||||
x = sbp[a>>1];
|
||||
x = (a&1)?x&0x0F:x>>4;
|
||||
return x;
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
uint32_t des_f(uint32_t r, uint8_t* kr){
|
||||
uint8_t i;
|
||||
uint32_t t=0,ret;
|
||||
uint64_t data;
|
||||
uint8_t *sbp; /* sboxpointer */
|
||||
permute((uint8_t*)e_permtab, (uint8_t*)&r, (uint8_t*)&data);
|
||||
for(i=0; i<7; ++i)
|
||||
((uint8_t*)&data)[i] ^= kr[i];
|
||||
|
||||
/* Sbox substitution */
|
||||
data = splitin6bitwords(data);
|
||||
sbp=(uint8_t*)sbox;
|
||||
for(i=0; i<8; ++i){
|
||||
uint8_t x;
|
||||
x = substitute(((uint8_t*)&data)[i], sbp);
|
||||
t<<=4;
|
||||
t |= x;
|
||||
sbp += 32;
|
||||
}
|
||||
changeendian32(&t);
|
||||
|
||||
permute((uint8_t*)p_permtab,(uint8_t*)&t, (uint8_t*)&ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
void des_enc(void* out, const void* in, const void* key){
|
||||
#define R *((uint32_t*)&(data[4]))
|
||||
#define L *((uint32_t*)&(data[0]))
|
||||
|
||||
uint8_t data[8],kr[6],k[7];
|
||||
uint8_t i;
|
||||
|
||||
permute((uint8_t*)ip_permtab, (uint8_t*)in, data);
|
||||
permute((uint8_t*)pc1_permtab, (const uint8_t*)key, k);
|
||||
for(i=0; i<8; ++i){
|
||||
shiftkey(k);
|
||||
if(ROTTABLE&((1<<((i<<1)+0))) )
|
||||
shiftkey(k);
|
||||
permute((uint8_t*)pc2_permtab, k, kr);
|
||||
L ^= des_f(R, kr);
|
||||
|
||||
shiftkey(k);
|
||||
if(ROTTABLE&((1<<((i<<1)+1))) )
|
||||
shiftkey(k);
|
||||
permute((uint8_t*)pc2_permtab, k, kr);
|
||||
R ^= des_f(L, kr);
|
||||
|
||||
}
|
||||
/* L <-> R*/
|
||||
R ^= L;
|
||||
L ^= R;
|
||||
R ^= L;
|
||||
|
||||
permute((uint8_t*)inv_ip_permtab, data, (uint8_t*)out);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
void des_dec(void* out, const void* in, const uint8_t* key){
|
||||
#define R *((uint32_t*)&(data[4]))
|
||||
#define L *((uint32_t*)&(data[0]))
|
||||
|
||||
uint8_t data[8],kr[6],k[7];
|
||||
int8_t i;
|
||||
permute((uint8_t*)ip_permtab, (uint8_t*)in, data);
|
||||
permute((uint8_t*)pc1_permtab, (const uint8_t*)key, k);
|
||||
for(i=7; i>=0; --i){
|
||||
|
||||
permute((uint8_t*)pc2_permtab, k, kr);
|
||||
L ^= des_f(R, kr);
|
||||
shiftkey_inv(k);
|
||||
if(ROTTABLE&((1<<((i<<1)+1))) ){
|
||||
shiftkey_inv(k);
|
||||
}
|
||||
|
||||
permute((uint8_t*)pc2_permtab, k, kr);
|
||||
R ^= des_f(L, kr);
|
||||
shiftkey_inv(k);
|
||||
if(ROTTABLE&((1<<((i<<1)+0))) ){
|
||||
shiftkey_inv(k);
|
||||
}
|
||||
|
||||
}
|
||||
/* L <-> R*/
|
||||
R ^= L;
|
||||
L ^= R;
|
||||
R ^= L;
|
||||
|
||||
permute((uint8_t*)inv_ip_permtab, data, (uint8_t*)out);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
void tdes_enc(void* out, void* in, const void* key){
|
||||
des_enc(out, in, (uint8_t*)key + 0);
|
||||
des_dec(out, out, (uint8_t*)key + 8);
|
||||
des_enc(out, out, (uint8_t*)key +16);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
void tdes_dec(void* out, void* in, const uint8_t* key){
|
||||
des_dec(out, in, (uint8_t*)key +16);
|
||||
des_enc(out, out, (uint8_t*)key + 8);
|
||||
des_dec(out, out, (uint8_t*)key + 0);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
|
||||
107
armsrc/des.h
Normal file
107
armsrc/des.h
Normal file
@@ -0,0 +1,107 @@
|
||||
/* des.h */
|
||||
/*
|
||||
This file is part of the ARM-Crypto-Lib.
|
||||
Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* \file des.h
|
||||
* \author Daniel Otte
|
||||
* \date 2007-06-16
|
||||
* \brief des and tdes declarations
|
||||
* \license GPLv3 or later
|
||||
*
|
||||
*/
|
||||
#ifndef DES_H_
|
||||
#define DES_H_
|
||||
|
||||
/* the FIPS 46-3 (1999-10-25) name for triple DES is triple data encryption algorithm so TDEA.
|
||||
* Also we only implement the three key mode */
|
||||
|
||||
/** \def tdea_enc
|
||||
* \brief defining an alias for void tdes_enc(void* out, const void* in, const void* key)
|
||||
*/
|
||||
|
||||
/** \def tdea_dec
|
||||
* \brief defining an alias for void tdes_dec(void* out, const void* in, const void* key)
|
||||
*/
|
||||
|
||||
#define tdea_enc tdes_enc
|
||||
#define tdea_dec tdes_dec
|
||||
|
||||
/** \fn void des_enc(void* out, const void* in, const void* key)
|
||||
* \brief encrypt a block with DES
|
||||
*
|
||||
* This function encrypts a block of 64 bits (8 bytes) with the DES algorithm.
|
||||
* Key expansion is done automatically. The key is 64 bits long, but note that
|
||||
* only 56 bits are used (the LSB of each byte is dropped). The input and output
|
||||
* blocks may overlap.
|
||||
*
|
||||
* \param out pointer to the block (64 bit = 8 byte) where the ciphertext is written to
|
||||
* \param in pointer to the block (64 bit = 8 byte) where the plaintext is read from
|
||||
* \param key pointer to the key (64 bit = 8 byte)
|
||||
*/
|
||||
void des_enc(void* out, const void* in, const void* key);
|
||||
|
||||
/** \fn void des_dec(void* out, const void* in, const void* key)
|
||||
* \brief decrypt a block with DES
|
||||
*
|
||||
* This function decrypts a block of 64 bits (8 bytes) with the DES algorithm.
|
||||
* Key expansion is done automatically. The key is 64 bits long, but note that
|
||||
* only 56 bits are used (the LSB of each byte is dropped). The input and output
|
||||
* blocks may overlap.
|
||||
*
|
||||
* \param out pointer to the block (64 bit = 8 byte) where the plaintext is written to
|
||||
* \param in pointer to the block (64 bit = 8 byte) where the ciphertext is read from
|
||||
* \param key pointer to the key (64 bit = 8 byte)
|
||||
*/
|
||||
void des_dec(void* out, const void* in, const void* key);
|
||||
|
||||
/** \fn void tdes_enc(void* out, const void* in, const void* key)
|
||||
* \brief encrypt a block with Tripple-DES
|
||||
*
|
||||
* This function encrypts a block of 64 bits (8 bytes) with the Tripple-DES (EDE)
|
||||
* algorithm. Key expansion is done automatically. The key is 192 bits long, but
|
||||
* note that only 178 bits are used (the LSB of each byte is dropped). The input
|
||||
* and output blocks may overlap.
|
||||
*
|
||||
* \param out pointer to the block (64 bit = 8 byte) where the ciphertext is written to
|
||||
* \param in pointer to the block (64 bit = 8 byte) where the plaintext is read from
|
||||
* \param key pointer to the key (192 bit = 24 byte)
|
||||
*/
|
||||
void tdes_enc(void* out, const void* in, const void* key);
|
||||
|
||||
/** \fn void tdes_dec(void* out, const void* in, const void* key)
|
||||
* \brief decrypt a block with Tripple-DES
|
||||
*
|
||||
* This function decrypts a block of 64 bits (8 bytes) with the Tripple-DES (EDE)
|
||||
* algorithm. Key expansion is done automatically. The key is 192 bits long, but
|
||||
* note that only 178 bits are used (the LSB of each byte is dropped). The input
|
||||
* and output blocks may overlap.
|
||||
*
|
||||
* \param out pointer to the block (64 bit = 8 byte) where the plaintext is written to
|
||||
* \param in pointer to the block (64 bit = 8 byte) where the ciphertext is read from
|
||||
* \param key pointer to the key (192 bit = 24 byte)
|
||||
*/
|
||||
void tdes_dec(void* out, const void* in, const void* key);
|
||||
|
||||
#endif /*DES_H_*/
|
||||
|
||||
// Copied from des.h in desfire imp.
|
||||
typedef unsigned long DES_KS[16][2]; /* Single-key DES key schedule */
|
||||
typedef unsigned long DES3_KS[48][2]; /* Triple-DES key schedule */
|
||||
|
||||
|
||||
extern int Asmversion; /* 1 if we're linked with an asm version, 0 if C */
|
||||
114
armsrc/hitag2.c
114
armsrc/hitag2.c
@@ -24,15 +24,19 @@
|
||||
|
||||
static bool bQuiet;
|
||||
|
||||
bool bCrypto;
|
||||
bool bAuthenticating;
|
||||
bool bPwd;
|
||||
bool bSuccessful;
|
||||
static bool bCrypto;
|
||||
static bool bAuthenticating;
|
||||
static bool bPwd;
|
||||
static bool bSuccessful;
|
||||
|
||||
int LogTraceHitag(const uint8_t * btBytes, int iBits, int iSamples, uint32_t dwParity, int bReader)
|
||||
|
||||
static int LogTraceHitag(const uint8_t * btBytes, int iBits, int iSamples, uint32_t dwParity, int bReader)
|
||||
{
|
||||
static uint16_t traceLen = 0;
|
||||
uint8_t *trace = BigBuf_get_addr();
|
||||
|
||||
// Return when trace is full
|
||||
if (traceLen >= TRACE_SIZE) return FALSE;
|
||||
if (traceLen + sizeof(rsamples) + sizeof(dwParity) + sizeof(iBits) + nbytes(iBits) > BigBuf_max_traceLen()) return FALSE;
|
||||
|
||||
// Trace the random, i'm curious
|
||||
rsamples += iSamples;
|
||||
@@ -85,21 +89,17 @@ static struct hitag2_tag tag = {
|
||||
},
|
||||
};
|
||||
|
||||
//#define TRACE_LENGTH 3000
|
||||
//uint8_t *trace = (uint8_t *) BigBuf;
|
||||
//int traceLen = 0;
|
||||
//int rsamples = 0;
|
||||
// ToDo: define a meaningful maximum size for auth_table. The bigger this is, the lower will be the available memory for traces.
|
||||
// Historically it used to be FREE_BUFFER_SIZE, which was 2744.
|
||||
#define AUTH_TABLE_LENGTH 2744
|
||||
static byte_t* auth_table;
|
||||
static size_t auth_table_pos = 0;
|
||||
static size_t auth_table_len = AUTH_TABLE_LENGTH;
|
||||
|
||||
#define AUTH_TABLE_OFFSET FREE_BUFFER_OFFSET
|
||||
#define AUTH_TABLE_LENGTH FREE_BUFFER_SIZE
|
||||
byte_t* auth_table = (byte_t *)BigBuf+AUTH_TABLE_OFFSET;
|
||||
size_t auth_table_pos = 0;
|
||||
size_t auth_table_len = AUTH_TABLE_LENGTH;
|
||||
|
||||
byte_t password[4];
|
||||
byte_t NrAr[8];
|
||||
byte_t key[8];
|
||||
uint64_t cipher_state;
|
||||
static byte_t password[4];
|
||||
static byte_t NrAr[8];
|
||||
static byte_t key[8];
|
||||
static uint64_t cipher_state;
|
||||
|
||||
/* Following is a modified version of cryptolib.com/ciphers/hitag2/ */
|
||||
// Software optimized 48-bit Philips/NXP Mifare Hitag2 PCF7936/46/47/52 stream cipher algorithm by I.C. Wiener 2006-2007.
|
||||
@@ -177,14 +177,14 @@ static u32 _hitag2_byte (u64 * x)
|
||||
return c;
|
||||
}
|
||||
|
||||
int hitag2_reset(void)
|
||||
static int hitag2_reset(void)
|
||||
{
|
||||
tag.state = TAG_STATE_RESET;
|
||||
tag.crypto_active = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hitag2_init(void)
|
||||
static int hitag2_init(void)
|
||||
{
|
||||
// memcpy(&tag, &resetdata, sizeof(tag));
|
||||
hitag2_reset();
|
||||
@@ -300,7 +300,8 @@ static void hitag_send_frame(const byte_t* frame, size_t frame_len)
|
||||
LOW(GPIO_SSC_DOUT);
|
||||
}
|
||||
|
||||
void hitag2_handle_reader_command(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen)
|
||||
|
||||
static void hitag2_handle_reader_command(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen)
|
||||
{
|
||||
byte_t rx_air[HITAG_FRAME_LEN];
|
||||
|
||||
@@ -457,6 +458,7 @@ static void hitag_reader_send_bit(int bit) {
|
||||
LED_A_OFF();
|
||||
}
|
||||
|
||||
|
||||
static void hitag_reader_send_frame(const byte_t* frame, size_t frame_len)
|
||||
{
|
||||
// Send the content of the frame
|
||||
@@ -475,7 +477,7 @@ static void hitag_reader_send_frame(const byte_t* frame, size_t frame_len)
|
||||
|
||||
size_t blocknr;
|
||||
|
||||
bool hitag2_password(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen) {
|
||||
static bool hitag2_password(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen) {
|
||||
// Reset the transmission frame length
|
||||
*txlen = 0;
|
||||
|
||||
@@ -530,7 +532,7 @@ bool hitag2_password(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool hitag2_crypto(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen) {
|
||||
static bool hitag2_crypto(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen) {
|
||||
// Reset the transmission frame length
|
||||
*txlen = 0;
|
||||
|
||||
@@ -623,7 +625,7 @@ bool hitag2_crypto(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen) {
|
||||
}
|
||||
|
||||
|
||||
bool hitag2_authenticate(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen) {
|
||||
static bool hitag2_authenticate(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen) {
|
||||
// Reset the transmission frame length
|
||||
*txlen = 0;
|
||||
|
||||
@@ -663,7 +665,9 @@ bool hitag2_authenticate(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txl
|
||||
return true;
|
||||
}
|
||||
|
||||
bool hitag2_test_auth_attempts(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen) {
|
||||
|
||||
static bool hitag2_test_auth_attempts(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen) {
|
||||
|
||||
// Reset the transmission frame length
|
||||
*txlen = 0;
|
||||
|
||||
@@ -675,17 +679,17 @@ bool hitag2_test_auth_attempts(byte_t* rx, const size_t rxlen, byte_t* tx, size_
|
||||
if (bCrypto) {
|
||||
Dbprintf("auth: %02x%02x%02x%02x%02x%02x%02x%02x Failed, removed entry!",NrAr[0],NrAr[1],NrAr[2],NrAr[3],NrAr[4],NrAr[5],NrAr[6],NrAr[7]);
|
||||
|
||||
// Removing failed entry from authentiations table
|
||||
memcpy(auth_table+auth_table_pos,auth_table+auth_table_pos+8,8);
|
||||
auth_table_len -= 8;
|
||||
// Removing failed entry from authentiations table
|
||||
memcpy(auth_table+auth_table_pos,auth_table+auth_table_pos+8,8);
|
||||
auth_table_len -= 8;
|
||||
|
||||
// Return if we reached the end of the authentiactions table
|
||||
// Return if we reached the end of the authentications table
|
||||
bCrypto = false;
|
||||
if (auth_table_pos == auth_table_len) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Copy the next authentication attempt in row (at the same position, b/c we removed last failed entry)
|
||||
|
||||
// Copy the next authentication attempt in row (at the same position, b/c we removed last failed entry)
|
||||
memcpy(NrAr,auth_table+auth_table_pos,8);
|
||||
}
|
||||
*txlen = 5;
|
||||
@@ -718,6 +722,7 @@ bool hitag2_test_auth_attempts(byte_t* rx, const size_t rxlen, byte_t* tx, size_
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void SnoopHitag(uint32_t type) {
|
||||
int frame_count;
|
||||
int response;
|
||||
@@ -730,13 +735,15 @@ void SnoopHitag(uint32_t type) {
|
||||
byte_t rx[HITAG_FRAME_LEN];
|
||||
size_t rxlen=0;
|
||||
|
||||
auth_table_len = 0;
|
||||
auth_table_pos = 0;
|
||||
BigBuf_free();
|
||||
auth_table = (byte_t *)BigBuf_malloc(AUTH_TABLE_LENGTH);
|
||||
memset(auth_table, 0x00, AUTH_TABLE_LENGTH);
|
||||
|
||||
// Clean up trace and prepare it for storing frames
|
||||
iso14a_set_tracing(TRUE);
|
||||
iso14a_clear_trace();
|
||||
|
||||
auth_table_len = 0;
|
||||
auth_table_pos = 0;
|
||||
memset(auth_table, 0x00, AUTH_TABLE_LENGTH);
|
||||
|
||||
DbpString("Starting Hitag2 snoop");
|
||||
LED_D_ON();
|
||||
@@ -760,7 +767,7 @@ void SnoopHitag(uint32_t type) {
|
||||
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC1);
|
||||
AT91C_BASE_PIOA->PIO_BSR = GPIO_SSC_FRAME;
|
||||
|
||||
// Disable timer during configuration
|
||||
// Disable timer during configuration
|
||||
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS;
|
||||
|
||||
// Capture mode, defaul timer source = MCK/2 (TIMER_CLOCK1), TIOA is external trigger,
|
||||
@@ -940,13 +947,17 @@ void SimulateHitagTag(bool tag_mem_supplied, byte_t* data) {
|
||||
bool bQuitTraceFull = false;
|
||||
bQuiet = false;
|
||||
|
||||
// Clean up trace and prepare it for storing frames
|
||||
iso14a_set_tracing(TRUE);
|
||||
iso14a_clear_trace();
|
||||
auth_table_len = 0;
|
||||
auth_table_pos = 0;
|
||||
byte_t* auth_table;
|
||||
BigBuf_free();
|
||||
auth_table = (byte_t *)BigBuf_malloc(AUTH_TABLE_LENGTH);
|
||||
memset(auth_table, 0x00, AUTH_TABLE_LENGTH);
|
||||
|
||||
// Clean up trace and prepare it for storing frames
|
||||
iso14a_set_tracing(TRUE);
|
||||
iso14a_clear_trace();
|
||||
|
||||
DbpString("Starting Hitag2 simulation");
|
||||
LED_D_ON();
|
||||
hitag2_init();
|
||||
@@ -1126,19 +1137,20 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) {
|
||||
bool bStop;
|
||||
bool bQuitTraceFull = false;
|
||||
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
||||
// Reset the return status
|
||||
bSuccessful = false;
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
||||
// Reset the return status
|
||||
bSuccessful = false;
|
||||
|
||||
// Clean up trace and prepare it for storing frames
|
||||
iso14a_set_tracing(TRUE);
|
||||
iso14a_clear_trace();
|
||||
iso14a_set_tracing(TRUE);
|
||||
iso14a_clear_trace();
|
||||
|
||||
DbpString("Starting Hitag reader family");
|
||||
|
||||
// Check configuration
|
||||
switch(htf) {
|
||||
case RHT2F_PASSWORD: {
|
||||
Dbprintf("List identifier in password mode");
|
||||
Dbprintf("List identifier in password mode");
|
||||
memcpy(password,htd->pwd.password,4);
|
||||
blocknr = 0;
|
||||
bQuitTraceFull = false;
|
||||
@@ -1152,7 +1164,7 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) {
|
||||
Dbhexdump(8,NrAr,false);
|
||||
bQuiet = false;
|
||||
bCrypto = false;
|
||||
bAuthenticating = false;
|
||||
bAuthenticating = false;
|
||||
bQuitTraceFull = true;
|
||||
} break;
|
||||
|
||||
@@ -1160,17 +1172,17 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) {
|
||||
DbpString("Authenticating using key:");
|
||||
memcpy(key,htd->crypto.key,4); //HACK; 4 or 6?? I read both in the code.
|
||||
Dbhexdump(6,key,false);
|
||||
blocknr = 0;
|
||||
blocknr = 0;
|
||||
bQuiet = false;
|
||||
bCrypto = false;
|
||||
bAuthenticating = false;
|
||||
bAuthenticating = false;
|
||||
bQuitTraceFull = true;
|
||||
} break;
|
||||
|
||||
case RHT2F_TEST_AUTH_ATTEMPTS: {
|
||||
Dbprintf("Testing %d authentication attempts",(auth_table_len/8));
|
||||
auth_table_pos = 0;
|
||||
memcpy(NrAr,auth_table,8);
|
||||
memcpy(NrAr, auth_table, 8);
|
||||
bQuitTraceFull = false;
|
||||
bQuiet = false;
|
||||
bCrypto = false;
|
||||
|
||||
@@ -640,21 +640,25 @@ void RAMFUNC SnoopIClass(void)
|
||||
// The command (reader -> tag) that we're receiving.
|
||||
// The length of a received command will in most cases be no more than 18 bytes.
|
||||
// So 32 should be enough!
|
||||
uint8_t *readerToTagCmd = (((uint8_t *)BigBuf) + RECV_CMD_OFFSET);
|
||||
#define ICLASS_BUFFER_SIZE 32
|
||||
uint8_t readerToTagCmd[ICLASS_BUFFER_SIZE];
|
||||
// The response (tag -> reader) that we're receiving.
|
||||
uint8_t *tagToReaderResponse = (((uint8_t *)BigBuf) + RECV_RESP_OFFSET);
|
||||
uint8_t tagToReaderResponse[ICLASS_BUFFER_SIZE];
|
||||
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
|
||||
|
||||
// reset traceLen to 0
|
||||
// free all BigBuf memory
|
||||
BigBuf_free();
|
||||
// The DMA buffer, used to stream samples from the FPGA
|
||||
uint8_t *dmaBuf = BigBuf_malloc(DMA_BUFFER_SIZE);
|
||||
|
||||
// reset traceLen to 0
|
||||
iso14a_set_tracing(TRUE);
|
||||
iso14a_clear_trace();
|
||||
iso14a_set_trigger(FALSE);
|
||||
|
||||
// The DMA buffer, used to stream samples from the FPGA
|
||||
int8_t *dmaBuf = ((int8_t *)BigBuf) + DMA_BUFFER_OFFSET;
|
||||
int lastRxCounter;
|
||||
int8_t *upTo;
|
||||
int lastRxCounter;
|
||||
uint8_t *upTo;
|
||||
int smpl;
|
||||
int maxBehindBy = 0;
|
||||
|
||||
@@ -703,7 +707,7 @@ void RAMFUNC SnoopIClass(void)
|
||||
(DMA_BUFFER_SIZE-1);
|
||||
if(behindBy > maxBehindBy) {
|
||||
maxBehindBy = behindBy;
|
||||
if(behindBy > 400) {
|
||||
if(behindBy > (9 * DMA_BUFFER_SIZE / 10)) {
|
||||
Dbprintf("blew circular buffer! behindBy=0x%x", behindBy);
|
||||
goto done;
|
||||
}
|
||||
@@ -1064,27 +1068,28 @@ int doIClassSimulation(uint8_t csn[], int breakAfterMacReceived, uint8_t *reader
|
||||
int trace_data_size = 0;
|
||||
//uint8_t sof = 0x0f;
|
||||
|
||||
// free eventually allocated BigBuf memory
|
||||
BigBuf_free();
|
||||
// Respond SOF -- takes 1 bytes
|
||||
uint8_t *resp1 = (((uint8_t *)BigBuf) + FREE_BUFFER_OFFSET);
|
||||
uint8_t *resp1 = BigBuf_malloc(2);
|
||||
int resp1Len;
|
||||
|
||||
// Anticollision CSN (rotated CSN)
|
||||
// 22: Takes 2 bytes for SOF/EOF and 10 * 2 = 20 bytes (2 bytes/byte)
|
||||
uint8_t *resp2 = (((uint8_t *)BigBuf) + FREE_BUFFER_OFFSET + 2);
|
||||
uint8_t *resp2 = BigBuf_malloc(28);
|
||||
int resp2Len;
|
||||
|
||||
// CSN
|
||||
// 22: Takes 2 bytes for SOF/EOF and 10 * 2 = 20 bytes (2 bytes/byte)
|
||||
uint8_t *resp3 = (((uint8_t *)BigBuf) + FREE_BUFFER_OFFSET + 30);
|
||||
uint8_t *resp3 = BigBuf_malloc(30);
|
||||
int resp3Len;
|
||||
|
||||
// e-Purse
|
||||
// 18: Takes 2 bytes for SOF/EOF and 8 * 2 = 16 bytes (2 bytes/byte)
|
||||
uint8_t *resp4 = (((uint8_t *)BigBuf) + FREE_BUFFER_OFFSET + 60);
|
||||
// 18: Takes 2 bytes for SOF/EOF and 8 * 2 = 16 bytes (2 bytes/bit)
|
||||
uint8_t *resp4 = BigBuf_malloc(20);
|
||||
int resp4Len;
|
||||
|
||||
// + 1720..
|
||||
uint8_t *receivedCmd = (((uint8_t *)BigBuf) + RECV_CMD_OFFSET);
|
||||
uint8_t *receivedCmd = BigBuf_malloc(MAX_FRAME_SIZE);
|
||||
memset(receivedCmd, 0x44, MAX_FRAME_SIZE);
|
||||
int len;
|
||||
|
||||
@@ -1529,7 +1534,7 @@ uint8_t handshakeIclassTag(uint8_t *card_data)
|
||||
static uint8_t identify[] = { 0x0c };
|
||||
static uint8_t select[] = { 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
static uint8_t readcheck_cc[]= { 0x88, 0x02 };
|
||||
uint8_t *resp = (((uint8_t *)BigBuf) + RECV_RESP_OFFSET);
|
||||
uint8_t resp[ICLASS_BUFFER_SIZE];
|
||||
|
||||
uint8_t read_status = 0;
|
||||
|
||||
@@ -1587,7 +1592,7 @@ void ReaderIClass(uint8_t arg0) {
|
||||
while(!BUTTON_PRESS())
|
||||
{
|
||||
|
||||
if(traceLen > TRACE_SIZE) {
|
||||
if(traceLen > BigBuf_max_traceLen()) {
|
||||
DbpString("Trace full");
|
||||
break;
|
||||
}
|
||||
@@ -1650,7 +1655,7 @@ void ReaderIClass_Replay(uint8_t arg0, uint8_t *MAC) {
|
||||
int keyaccess;
|
||||
} memory;
|
||||
|
||||
uint8_t* resp = (((uint8_t *)BigBuf) + RECV_RESP_OFFSET);
|
||||
uint8_t resp[ICLASS_BUFFER_SIZE];
|
||||
|
||||
setupIclassReader();
|
||||
|
||||
@@ -1659,7 +1664,7 @@ void ReaderIClass_Replay(uint8_t arg0, uint8_t *MAC) {
|
||||
|
||||
WDT_HIT();
|
||||
|
||||
if(traceLen > TRACE_SIZE) {
|
||||
if(traceLen > BigBuf_max_traceLen()) {
|
||||
DbpString("Trace full");
|
||||
break;
|
||||
}
|
||||
|
||||
1528
armsrc/iso14443.c
1528
armsrc/iso14443.c
File diff suppressed because it is too large
Load Diff
@@ -146,6 +146,7 @@ void iso14a_set_trigger(bool enable) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
void iso14a_set_timeout(uint32_t timeout) {
|
||||
iso14a_timeout = timeout;
|
||||
}
|
||||
@@ -188,7 +189,6 @@ void AppendCrc14443a(uint8_t* data, int len)
|
||||
ComputeCrc14443(CRC_14443_A,data,len,data+len,data+len+1);
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// ISO 14443 Type A - Miller decoder
|
||||
//=============================================================================
|
||||
@@ -526,9 +526,6 @@ void RAMFUNC SnoopIso14443a(uint8_t param) {
|
||||
// bit 1 - trigger from first reader 7-bit request
|
||||
|
||||
LEDsoff();
|
||||
// init trace buffer
|
||||
iso14a_clear_trace();
|
||||
iso14a_set_tracing(TRUE);
|
||||
|
||||
// We won't start recording the frames that we acquire until we trigger;
|
||||
// a good trigger condition to get started is probably when we see a
|
||||
@@ -536,22 +533,25 @@ void RAMFUNC SnoopIso14443a(uint8_t param) {
|
||||
// triggered == FALSE -- to wait first for card
|
||||
bool triggered = !(param & 0x03);
|
||||
|
||||
// Allocate memory from BigBuf for some buffers
|
||||
// free all previous allocations first
|
||||
BigBuf_free();
|
||||
|
||||
// The command (reader -> tag) that we're receiving.
|
||||
// The length of a received command will in most cases be no more than 18 bytes.
|
||||
// So 32 should be enough!
|
||||
uint8_t *receivedCmd = ((uint8_t *)BigBuf) + RECV_CMD_OFFSET;
|
||||
uint8_t *receivedCmdPar = ((uint8_t *)BigBuf) + RECV_CMD_PAR_OFFSET;
|
||||
uint8_t *receivedCmd = BigBuf_malloc(MAX_FRAME_SIZE);
|
||||
uint8_t *receivedCmdPar = BigBuf_malloc(MAX_PARITY_SIZE);
|
||||
|
||||
// The response (tag -> reader) that we're receiving.
|
||||
uint8_t *receivedResponse = ((uint8_t *)BigBuf) + RECV_RESP_OFFSET;
|
||||
uint8_t *receivedResponsePar = ((uint8_t *)BigBuf) + RECV_RESP_PAR_OFFSET;
|
||||
|
||||
// As we receive stuff, we copy it from receivedCmd or receivedResponse
|
||||
// into trace, along with its length and other annotations.
|
||||
//uint8_t *trace = (uint8_t *)BigBuf;
|
||||
uint8_t *receivedResponse = BigBuf_malloc(MAX_FRAME_SIZE);
|
||||
uint8_t *receivedResponsePar = BigBuf_malloc(MAX_PARITY_SIZE);
|
||||
|
||||
// The DMA buffer, used to stream samples from the FPGA
|
||||
uint8_t *dmaBuf = ((uint8_t *)BigBuf) + DMA_BUFFER_OFFSET;
|
||||
uint8_t *dmaBuf = BigBuf_malloc(DMA_BUFFER_SIZE);
|
||||
|
||||
// init trace buffer
|
||||
iso14a_clear_trace();
|
||||
iso14a_set_tracing(TRUE);
|
||||
|
||||
uint8_t *data = dmaBuf;
|
||||
uint8_t previous_data = 0;
|
||||
int maxDataLen = 0;
|
||||
@@ -591,7 +591,7 @@ void RAMFUNC SnoopIso14443a(uint8_t param) {
|
||||
// test for length of buffer
|
||||
if(dataLen > maxDataLen) {
|
||||
maxDataLen = dataLen;
|
||||
if(dataLen > 400) {
|
||||
if(dataLen > (9 * DMA_BUFFER_SIZE / 10)) {
|
||||
Dbprintf("blew circular buffer! dataLen=%d", dataLen);
|
||||
break;
|
||||
}
|
||||
@@ -820,7 +820,7 @@ int EmSendCmdPar(uint8_t *resp, uint16_t respLen, uint8_t *par);
|
||||
bool EmLogTrace(uint8_t *reader_data, uint16_t reader_len, uint32_t reader_StartTime, uint32_t reader_EndTime, uint8_t *reader_Parity,
|
||||
uint8_t *tag_data, uint16_t tag_len, uint32_t tag_StartTime, uint32_t tag_EndTime, uint8_t *tag_Parity);
|
||||
|
||||
static uint8_t* free_buffer_pointer = (((uint8_t *)BigBuf) + FREE_BUFFER_OFFSET);
|
||||
static uint8_t* free_buffer_pointer;
|
||||
|
||||
typedef struct {
|
||||
uint8_t* response;
|
||||
@@ -830,10 +830,6 @@ typedef struct {
|
||||
uint32_t ProxToAirDuration;
|
||||
} tag_response_info_t;
|
||||
|
||||
void reset_free_buffer() {
|
||||
free_buffer_pointer = (((uint8_t *)BigBuf) + FREE_BUFFER_OFFSET);
|
||||
}
|
||||
|
||||
bool prepare_tag_modulation(tag_response_info_t* response_info, size_t max_buffer_size) {
|
||||
// Example response, answer to MIFARE Classic read block will be 16 bytes + 2 CRC = 18 bytes
|
||||
// This will need the following byte array for a modulation sequence
|
||||
@@ -845,7 +841,8 @@ bool prepare_tag_modulation(tag_response_info_t* response_info, size_t max_buffe
|
||||
// ----------- +
|
||||
// 166 bytes, since every bit that needs to be send costs us a byte
|
||||
//
|
||||
|
||||
|
||||
|
||||
// Prepare the tag modulation bits from the message
|
||||
CodeIso14443aAsTag(response_info->response,response_info->response_n);
|
||||
|
||||
@@ -866,15 +863,22 @@ bool prepare_tag_modulation(tag_response_info_t* response_info, size_t max_buffe
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// "precompile" responses. There are 7 predefined responses with a total of 28 bytes data to transmit.
|
||||
// Coded responses need one byte per bit to transfer (data, parity, start, stop, correction)
|
||||
// 28 * 8 data bits, 28 * 1 parity bits, 7 start bits, 7 stop bits, 7 correction bits
|
||||
// -> need 273 bytes buffer
|
||||
#define ALLOCATED_TAG_MODULATION_BUFFER_SIZE 273
|
||||
|
||||
bool prepare_allocated_tag_modulation(tag_response_info_t* response_info) {
|
||||
// Retrieve and store the current buffer index
|
||||
response_info->modulation = free_buffer_pointer;
|
||||
|
||||
// Determine the maximum size we can use from our buffer
|
||||
size_t max_buffer_size = (((uint8_t *)BigBuf) + FREE_BUFFER_OFFSET + FREE_BUFFER_SIZE) - free_buffer_pointer;
|
||||
size_t max_buffer_size = ALLOCATED_TAG_MODULATION_BUFFER_SIZE;
|
||||
|
||||
// Forward the prepare tag modulation function to the inner function
|
||||
if (prepare_tag_modulation(response_info,max_buffer_size)) {
|
||||
if (prepare_tag_modulation(response_info, max_buffer_size)) {
|
||||
// Update the free buffer offset
|
||||
free_buffer_pointer += ToSendMax;
|
||||
return true;
|
||||
@@ -889,10 +893,6 @@ bool prepare_allocated_tag_modulation(tag_response_info_t* response_info) {
|
||||
//-----------------------------------------------------------------------------
|
||||
void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data)
|
||||
{
|
||||
// Enable and clear the trace
|
||||
iso14a_clear_trace();
|
||||
iso14a_set_tracing(TRUE);
|
||||
|
||||
uint8_t sak;
|
||||
|
||||
// The first response contains the ATQA (note: bytes are transmitted in reverse order).
|
||||
@@ -936,10 +936,11 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data)
|
||||
}
|
||||
|
||||
// The second response contains the (mandatory) first 24 bits of the UID
|
||||
uint8_t response2[5];
|
||||
uint8_t response2[5] = {0x00};
|
||||
|
||||
// Check if the uid uses the (optional) part
|
||||
uint8_t response2a[5];
|
||||
uint8_t response2a[5] = {0x00};
|
||||
|
||||
if (uid_2nd) {
|
||||
response2[0] = 0x88;
|
||||
num_to_bytes(uid_1st,3,response2+1);
|
||||
@@ -960,12 +961,12 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data)
|
||||
response2[4] = response2[0] ^ response2[1] ^ response2[2] ^ response2[3];
|
||||
|
||||
// Prepare the mandatory SAK (for 4 and 7 byte UID)
|
||||
uint8_t response3[3];
|
||||
uint8_t response3[3] = {0x00};
|
||||
response3[0] = sak;
|
||||
ComputeCrc14443(CRC_14443_A, response3, 1, &response3[1], &response3[2]);
|
||||
|
||||
// Prepare the optional second SAK (for 7 byte UID), drop the cascade bit
|
||||
uint8_t response3a[3];
|
||||
uint8_t response3a[3] = {0x00};
|
||||
response3a[0] = sak & 0xFB;
|
||||
ComputeCrc14443(CRC_14443_A, response3a, 1, &response3a[1], &response3a[2]);
|
||||
|
||||
@@ -1001,9 +1002,17 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data)
|
||||
.modulation_n = 0
|
||||
};
|
||||
|
||||
// Reset the offset pointer of the free buffer
|
||||
reset_free_buffer();
|
||||
|
||||
BigBuf_free_keep_EM();
|
||||
|
||||
// allocate buffers:
|
||||
uint8_t *receivedCmd = BigBuf_malloc(MAX_FRAME_SIZE);
|
||||
uint8_t *receivedCmdPar = BigBuf_malloc(MAX_PARITY_SIZE);
|
||||
free_buffer_pointer = BigBuf_malloc(ALLOCATED_TAG_MODULATION_BUFFER_SIZE);
|
||||
|
||||
// clear trace
|
||||
iso14a_clear_trace();
|
||||
iso14a_set_tracing(TRUE);
|
||||
|
||||
// Prepare the responses of the anticollision phase
|
||||
// there will be not enough time to do this at the moment the reader sends it REQA
|
||||
for (size_t i=0; i<TAG_RESPONSE_COUNT; i++) {
|
||||
@@ -1024,10 +1033,6 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data)
|
||||
// We need to listen to the high-frequency, peak-detected path.
|
||||
iso14443a_setup(FPGA_HF_ISO14443A_TAGSIM_LISTEN);
|
||||
|
||||
// buffers used on software Uart:
|
||||
uint8_t *receivedCmd = ((uint8_t *)BigBuf) + RECV_CMD_OFFSET;
|
||||
uint8_t *receivedCmdPar = ((uint8_t *)BigBuf) + RECV_CMD_PAR_OFFSET;
|
||||
|
||||
cmdsRecvd = 0;
|
||||
tag_response_info_t* p_response;
|
||||
|
||||
@@ -1188,6 +1193,7 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data)
|
||||
|
||||
Dbprintf("%x %x %x", happened, happened2, cmdsRecvd);
|
||||
LED_A_OFF();
|
||||
BigBuf_free_keep_EM();
|
||||
}
|
||||
|
||||
|
||||
@@ -1461,7 +1467,7 @@ static int EmSendCmd14443aRaw(uint8_t *resp, uint16_t respLen, bool correctionNe
|
||||
AT91C_BASE_SSC->SSC_THR = SEC_F;
|
||||
|
||||
// send cycle
|
||||
for(; i <= respLen; ) {
|
||||
for(; i < respLen; ) {
|
||||
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
|
||||
AT91C_BASE_SSC->SSC_THR = resp[i++];
|
||||
FpgaSendQueueDelay = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
||||
@@ -1661,8 +1667,8 @@ int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, u
|
||||
uint8_t sel_all[] = { 0x93,0x20 };
|
||||
uint8_t sel_uid[] = { 0x93,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
|
||||
uint8_t rats[] = { 0xE0,0x80,0x00,0x00 }; // FSD=256, FSDI=8, CID=0
|
||||
uint8_t *resp = ((uint8_t *)BigBuf) + RECV_RESP_OFFSET;
|
||||
uint8_t *resp_par = ((uint8_t *)BigBuf) + RECV_RESP_PAR_OFFSET;
|
||||
uint8_t resp[MAX_FRAME_SIZE]; // theoretically. A usual RATS will be much smaller
|
||||
uint8_t resp_par[MAX_PARITY_SIZE];
|
||||
byte_t uid_resp[4];
|
||||
size_t uid_resp_len;
|
||||
|
||||
@@ -1954,9 +1960,12 @@ void ReaderMifare(bool first_try)
|
||||
uint8_t mf_nr_ar[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
|
||||
static uint8_t mf_nr_ar3;
|
||||
|
||||
uint8_t* receivedAnswer = (((uint8_t *)BigBuf) + RECV_RESP_OFFSET);
|
||||
uint8_t* receivedAnswerPar = (((uint8_t *)BigBuf) + RECV_RESP_PAR_OFFSET);
|
||||
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
|
||||
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
|
||||
|
||||
// free eventually allocated BigBuf memory. We want all for tracing.
|
||||
BigBuf_free();
|
||||
|
||||
iso14a_clear_trace();
|
||||
iso14a_set_tracing(TRUE);
|
||||
|
||||
@@ -2166,10 +2175,10 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
|
||||
struct Crypto1State *pcs;
|
||||
pcs = &mpcs;
|
||||
uint32_t numReads = 0;//Counts numer of times reader read a block
|
||||
uint8_t* receivedCmd = get_bigbufptr_recvcmdbuf();
|
||||
uint8_t* receivedCmd_par = receivedCmd + MAX_FRAME_SIZE;
|
||||
uint8_t* response = get_bigbufptr_recvrespbuf();
|
||||
uint8_t* response_par = response + MAX_FRAME_SIZE;
|
||||
uint8_t receivedCmd[MAX_MIFARE_FRAME_SIZE];
|
||||
uint8_t receivedCmd_par[MAX_MIFARE_PARITY_SIZE];
|
||||
uint8_t response[MAX_MIFARE_FRAME_SIZE];
|
||||
uint8_t response_par[MAX_MIFARE_PARITY_SIZE];
|
||||
|
||||
uint8_t rATQA[] = {0x04, 0x00}; // Mifare classic 1k 4BUID
|
||||
uint8_t rUIDBCC1[] = {0xde, 0xad, 0xbe, 0xaf, 0x62};
|
||||
@@ -2186,6 +2195,8 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
|
||||
uint32_t ar_nr_responses[] = {0,0,0,0,0,0,0,0};
|
||||
uint8_t ar_nr_collected = 0;
|
||||
|
||||
// free eventually allocated BigBuf memory but keep Emulator Memory
|
||||
BigBuf_free_keep_EM();
|
||||
// clear trace
|
||||
iso14a_clear_trace();
|
||||
iso14a_set_tracing(TRUE);
|
||||
@@ -2656,18 +2667,20 @@ void RAMFUNC SniffMifare(uint8_t param) {
|
||||
// The command (reader -> tag) that we're receiving.
|
||||
// The length of a received command will in most cases be no more than 18 bytes.
|
||||
// So 32 should be enough!
|
||||
uint8_t *receivedCmd = (((uint8_t *)BigBuf) + RECV_CMD_OFFSET);
|
||||
uint8_t *receivedCmdPar = ((uint8_t *)BigBuf) + RECV_CMD_PAR_OFFSET;
|
||||
uint8_t receivedCmd[MAX_MIFARE_FRAME_SIZE];
|
||||
uint8_t receivedCmdPar[MAX_MIFARE_PARITY_SIZE];
|
||||
// The response (tag -> reader) that we're receiving.
|
||||
uint8_t *receivedResponse = (((uint8_t *)BigBuf) + RECV_RESP_OFFSET);
|
||||
uint8_t *receivedResponsePar = ((uint8_t *)BigBuf) + RECV_RESP_PAR_OFFSET;
|
||||
uint8_t receivedResponse[MAX_MIFARE_FRAME_SIZE];
|
||||
uint8_t receivedResponsePar[MAX_MIFARE_PARITY_SIZE];
|
||||
|
||||
// As we receive stuff, we copy it from receivedCmd or receivedResponse
|
||||
// into trace, along with its length and other annotations.
|
||||
//uint8_t *trace = (uint8_t *)BigBuf;
|
||||
|
||||
// The DMA buffer, used to stream samples from the FPGA
|
||||
uint8_t *dmaBuf = ((uint8_t *)BigBuf) + DMA_BUFFER_OFFSET;
|
||||
// free eventually allocated BigBuf memory
|
||||
BigBuf_free();
|
||||
// allocate the DMA buffer, used to stream samples from the FPGA
|
||||
uint8_t *dmaBuf = BigBuf_malloc(DMA_BUFFER_SIZE);
|
||||
uint8_t *data = dmaBuf;
|
||||
uint8_t previous_data = 0;
|
||||
int maxDataLen = 0;
|
||||
@@ -2726,7 +2739,7 @@ void RAMFUNC SniffMifare(uint8_t param) {
|
||||
// test for length of buffer
|
||||
if(dataLen > maxDataLen) { // we are more behind than ever...
|
||||
maxDataLen = dataLen;
|
||||
if(dataLen > 400) {
|
||||
if(dataLen > (9 * DMA_BUFFER_SIZE / 10)) {
|
||||
Dbprintf("blew circular buffer! dataLen=0x%x", dataLen);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -296,7 +296,7 @@ static void TransmitTo15693Reader(const uint8_t *cmd, int len, int *samples, int
|
||||
static int GetIso15693AnswerFromTag(uint8_t *receivedResponse, int maxLen, int *samples, int *elapsed)
|
||||
{
|
||||
int c = 0;
|
||||
uint8_t *dest = (uint8_t *)BigBuf;
|
||||
uint8_t *dest = BigBuf_get_addr();
|
||||
int getNext = 0;
|
||||
|
||||
int8_t prev = 0;
|
||||
@@ -446,7 +446,7 @@ static int GetIso15693AnswerFromTag(uint8_t *receivedResponse, int maxLen, int *
|
||||
static int GetIso15693AnswerFromSniff(uint8_t *receivedResponse, int maxLen, int *samples, int *elapsed)
|
||||
{
|
||||
int c = 0;
|
||||
uint8_t *dest = (uint8_t *)BigBuf;
|
||||
uint8_t *dest = BigBuf_get_addr();
|
||||
int getNext = 0;
|
||||
|
||||
int8_t prev = 0;
|
||||
@@ -596,7 +596,7 @@ static void BuildIdentifyRequest(void);
|
||||
//-----------------------------------------------------------------------------
|
||||
void AcquireRawAdcSamplesIso15693(void)
|
||||
{
|
||||
uint8_t *dest = (uint8_t *)BigBuf;
|
||||
uint8_t *dest = BigBuf_get_addr();
|
||||
|
||||
int c = 0;
|
||||
int getNext = 0;
|
||||
@@ -678,7 +678,7 @@ void AcquireRawAdcSamplesIso15693(void)
|
||||
|
||||
void RecordRawAdcSamplesIso15693(void)
|
||||
{
|
||||
uint8_t *dest = (uint8_t *)BigBuf;
|
||||
uint8_t *dest = BigBuf_get_addr();
|
||||
|
||||
int c = 0;
|
||||
int getNext = 0;
|
||||
@@ -878,8 +878,8 @@ int SendDataTag(uint8_t *send, int sendlen, int init, int speed, uint8_t **recv)
|
||||
LED_D_OFF();
|
||||
|
||||
int answerLen=0;
|
||||
uint8_t *answer = (((uint8_t *)BigBuf) + 3660);
|
||||
if (recv!=NULL) memset(BigBuf + 3660, 0, 100);
|
||||
uint8_t *answer = BigBuf_get_addr() + 3660;
|
||||
if (recv != NULL) memset(answer, 0, 100);
|
||||
|
||||
if (init) Iso15693InitReader();
|
||||
|
||||
@@ -999,9 +999,9 @@ void ReaderIso15693(uint32_t parameter)
|
||||
LED_C_OFF();
|
||||
LED_D_OFF();
|
||||
|
||||
uint8_t *answer1 = (((uint8_t *)BigBuf) + 3660); //
|
||||
uint8_t *answer2 = (((uint8_t *)BigBuf) + 3760);
|
||||
uint8_t *answer3 = (((uint8_t *)BigBuf) + 3860);
|
||||
uint8_t *answer1 = BigBuf_get_addr() + 3660;
|
||||
uint8_t *answer2 = BigBuf_get_addr() + 3760;
|
||||
uint8_t *answer3 = BigBuf_get_addr() + 3860;
|
||||
|
||||
int answerLen1 = 0;
|
||||
int answerLen2 = 0;
|
||||
@@ -1015,7 +1015,7 @@ void ReaderIso15693(uint32_t parameter)
|
||||
|
||||
|
||||
// Blank arrays
|
||||
memset(BigBuf + 3660, 0x00, 300);
|
||||
memset(answer1, 0x00, 300);
|
||||
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
|
||||
|
||||
@@ -1111,7 +1111,7 @@ void SimTagIso15693(uint32_t parameter, uint8_t *uid)
|
||||
LED_C_OFF();
|
||||
LED_D_OFF();
|
||||
|
||||
uint8_t *buf = (((uint8_t *)BigBuf) + 3660); //
|
||||
uint8_t *buf = BigBuf_get_addr() + 3660;
|
||||
|
||||
int answerLen1 = 0;
|
||||
int samples = 0;
|
||||
@@ -1213,7 +1213,7 @@ void BruteforceIso15693Afi(uint32_t speed)
|
||||
void DirectTag15693Command(uint32_t datalen,uint32_t speed, uint32_t recv, uint8_t data[]) {
|
||||
|
||||
int recvlen=0;
|
||||
uint8_t *recvbuf=(uint8_t *)BigBuf;
|
||||
uint8_t *recvbuf = BigBuf_get_addr();
|
||||
// UsbCommand n;
|
||||
|
||||
if (DEBUG) {
|
||||
|
||||
@@ -98,13 +98,14 @@ static uint32_t get_key_stream(int skip, int count)
|
||||
}
|
||||
|
||||
/* Write Time Data into LOG */
|
||||
uint8_t *BigBuf = BigBuf_get_addr();
|
||||
if(count == 6) { i = -1; } else { i = legic_read_count; }
|
||||
((uint8_t*)BigBuf)[OFFSET_LOG+128+i] = legic_prng_count();
|
||||
((uint8_t*)BigBuf)[OFFSET_LOG+256+i*4] = (legic_prng_bc >> 0) & 0xff;
|
||||
((uint8_t*)BigBuf)[OFFSET_LOG+256+i*4+1] = (legic_prng_bc >> 8) & 0xff;
|
||||
((uint8_t*)BigBuf)[OFFSET_LOG+256+i*4+2] = (legic_prng_bc >>16) & 0xff;
|
||||
((uint8_t*)BigBuf)[OFFSET_LOG+256+i*4+3] = (legic_prng_bc >>24) & 0xff;
|
||||
((uint8_t*)BigBuf)[OFFSET_LOG+384+i] = count;
|
||||
BigBuf[OFFSET_LOG+128+i] = legic_prng_count();
|
||||
BigBuf[OFFSET_LOG+256+i*4] = (legic_prng_bc >> 0) & 0xff;
|
||||
BigBuf[OFFSET_LOG+256+i*4+1] = (legic_prng_bc >> 8) & 0xff;
|
||||
BigBuf[OFFSET_LOG+256+i*4+2] = (legic_prng_bc >>16) & 0xff;
|
||||
BigBuf[OFFSET_LOG+256+i*4+3] = (legic_prng_bc >>24) & 0xff;
|
||||
BigBuf[OFFSET_LOG+384+i] = count;
|
||||
|
||||
/* Generate KeyStream */
|
||||
for(i=0; i<count; i++) {
|
||||
@@ -426,6 +427,7 @@ int LegicRfReader(int offset, int bytes) {
|
||||
|
||||
LegicCommonInit();
|
||||
|
||||
uint8_t *BigBuf = BigBuf_get_addr();
|
||||
memset(BigBuf, 0, 1024);
|
||||
|
||||
DbpString("setting up legic card");
|
||||
@@ -465,7 +467,7 @@ int LegicRfReader(int offset, int bytes) {
|
||||
LED_C_OFF();
|
||||
return -1;
|
||||
}
|
||||
((uint8_t*)BigBuf)[byte_index] = r;
|
||||
BigBuf[byte_index] = r;
|
||||
WDT_HIT();
|
||||
byte_index++;
|
||||
if(byte_index & 0x10) LED_C_ON(); else LED_C_OFF();
|
||||
@@ -480,7 +482,8 @@ int LegicRfReader(int offset, int bytes) {
|
||||
|
||||
void LegicRfWriter(int bytes, int offset) {
|
||||
int byte_index=0, addr_sz=0;
|
||||
|
||||
uint8_t *BigBuf = BigBuf_get_addr();
|
||||
|
||||
LegicCommonInit();
|
||||
|
||||
DbpString("setting up legic card");
|
||||
@@ -512,7 +515,7 @@ void LegicRfWriter(int bytes, int offset) {
|
||||
perform_setup_phase_rwd(SESSION_IV);
|
||||
legic_prng_forward(2);
|
||||
while(byte_index < bytes) {
|
||||
int r = legic_write_byte(((uint8_t*)BigBuf)[byte_index+offset], byte_index+offset, addr_sz);
|
||||
int r = legic_write_byte(BigBuf[byte_index+offset], byte_index+offset, addr_sz);
|
||||
if((r != 0) || BUTTON_PRESS()) {
|
||||
Dbprintf("operation aborted @ 0x%03.3x", byte_index);
|
||||
switch_off_tag_rwd();
|
||||
@@ -534,6 +537,8 @@ int timestamp;
|
||||
/* Handle (whether to respond) a frame in tag mode */
|
||||
static void frame_handle_tag(struct legic_frame const * const f)
|
||||
{
|
||||
uint8_t *BigBuf = BigBuf_get_addr();
|
||||
|
||||
/* First Part of Handshake (IV) */
|
||||
if(f->bits == 7) {
|
||||
if(f->data == SESSION_IV) {
|
||||
@@ -582,9 +587,9 @@ static void frame_handle_tag(struct legic_frame const * const f)
|
||||
if(legic_state == STATE_CON) {
|
||||
int key = get_key_stream(-1, 11); //legic_phase_drift, 11);
|
||||
int addr = f->data ^ key; addr = addr >> 1;
|
||||
int data = ((uint8_t*)BigBuf)[addr];
|
||||
int data = BigBuf[addr];
|
||||
int hash = LegicCRC(addr, data, 11) << 8;
|
||||
((uint8_t*)BigBuf)[OFFSET_LOG+legic_read_count] = (uint8_t)addr;
|
||||
BigBuf[OFFSET_LOG+legic_read_count] = (uint8_t)addr;
|
||||
legic_read_count++;
|
||||
|
||||
//Dbprintf("Data:%03.3x, key:%03.3x, addr: %03.3x, read_c:%u", f->data, key, addr, read_c);
|
||||
@@ -619,19 +624,19 @@ static void frame_handle_tag(struct legic_frame const * const f)
|
||||
int i;
|
||||
Dbprintf("IV: %03.3x", legic_prng_iv);
|
||||
for(i = 0; i<legic_read_count; i++) {
|
||||
Dbprintf("Read Nb: %u, Addr: %u", i, ((uint8_t*)BigBuf)[OFFSET_LOG+i]);
|
||||
Dbprintf("Read Nb: %u, Addr: %u", i, BigBuf[OFFSET_LOG+i]);
|
||||
}
|
||||
|
||||
for(i = -1; i<legic_read_count; i++) {
|
||||
uint32_t t;
|
||||
t = ((uint8_t*)BigBuf)[OFFSET_LOG+256+i*4];
|
||||
t |= ((uint8_t*)BigBuf)[OFFSET_LOG+256+i*4+1] << 8;
|
||||
t |= ((uint8_t*)BigBuf)[OFFSET_LOG+256+i*4+2] <<16;
|
||||
t |= ((uint8_t*)BigBuf)[OFFSET_LOG+256+i*4+3] <<24;
|
||||
t = BigBuf[OFFSET_LOG+256+i*4];
|
||||
t |= BigBuf[OFFSET_LOG+256+i*4+1] << 8;
|
||||
t |= BigBuf[OFFSET_LOG+256+i*4+2] <<16;
|
||||
t |= BigBuf[OFFSET_LOG+256+i*4+3] <<24;
|
||||
|
||||
Dbprintf("Cycles: %u, Frame Length: %u, Time: %u",
|
||||
((uint8_t*)BigBuf)[OFFSET_LOG+128+i],
|
||||
((uint8_t*)BigBuf)[OFFSET_LOG+384+i],
|
||||
BigBuf[OFFSET_LOG+128+i],
|
||||
BigBuf[OFFSET_LOG+384+i],
|
||||
t);
|
||||
}
|
||||
}
|
||||
|
||||
204
armsrc/lfops.c
204
armsrc/lfops.c
@@ -15,130 +15,44 @@
|
||||
#include "crc16.h"
|
||||
#include "string.h"
|
||||
#include "lfdemod.h"
|
||||
#include "lfsampling.h"
|
||||
|
||||
|
||||
/**
|
||||
* Does the sample acquisition. If threshold is specified, the actual sampling
|
||||
* is not commenced until the threshold has been reached.
|
||||
* @param trigger_threshold - the threshold
|
||||
* @param silent - is true, now outputs are made. If false, dbprints the status
|
||||
*/
|
||||
void DoAcquisition125k_internal(int trigger_threshold,bool silent)
|
||||
{
|
||||
uint8_t *dest = (uint8_t *)BigBuf;
|
||||
int n = sizeof(BigBuf);
|
||||
int i;
|
||||
|
||||
memset(dest, 0, n);
|
||||
i = 0;
|
||||
for(;;) {
|
||||
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
|
||||
AT91C_BASE_SSC->SSC_THR = 0x43;
|
||||
LED_D_ON();
|
||||
}
|
||||
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
|
||||
dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
||||
LED_D_OFF();
|
||||
if (trigger_threshold != -1 && dest[i] < trigger_threshold)
|
||||
continue;
|
||||
else
|
||||
trigger_threshold = -1;
|
||||
if (++i >= n) break;
|
||||
}
|
||||
}
|
||||
if(!silent)
|
||||
{
|
||||
Dbprintf("buffer samples: %02x %02x %02x %02x %02x %02x %02x %02x ...",
|
||||
dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]);
|
||||
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Perform sample aquisition.
|
||||
*/
|
||||
void DoAcquisition125k(int trigger_threshold)
|
||||
{
|
||||
DoAcquisition125k_internal(trigger_threshold, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup the FPGA to listen for samples. This method downloads the FPGA bitstream
|
||||
* if not already loaded, sets divisor and starts up the antenna.
|
||||
* @param divisor : 1, 88> 255 or negative ==> 134.8 KHz
|
||||
* 0 or 95 ==> 125 KHz
|
||||
*
|
||||
**/
|
||||
void LFSetupFPGAForADC(int divisor, bool lf_field)
|
||||
{
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
||||
if ( (divisor == 1) || (divisor < 0) || (divisor > 255) )
|
||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz
|
||||
else if (divisor == 0)
|
||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
|
||||
else
|
||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor);
|
||||
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | (lf_field ? FPGA_LF_ADC_READER_FIELD : 0));
|
||||
|
||||
// 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);
|
||||
// Now set up the SSC to get the ADC samples that are now streaming at us.
|
||||
FpgaSetupSsc();
|
||||
}
|
||||
/**
|
||||
* Initializes the FPGA, and acquires the samples.
|
||||
**/
|
||||
void AcquireRawAdcSamples125k(int divisor)
|
||||
{
|
||||
LFSetupFPGAForADC(divisor, true);
|
||||
// Now call the acquisition routine
|
||||
DoAcquisition125k_internal(-1,false);
|
||||
}
|
||||
/**
|
||||
* Initializes the FPGA for snoop-mode, and acquires the samples.
|
||||
**/
|
||||
|
||||
void SnoopLFRawAdcSamples(int divisor, int trigger_threshold)
|
||||
{
|
||||
LFSetupFPGAForADC(divisor, false);
|
||||
DoAcquisition125k(trigger_threshold);
|
||||
}
|
||||
|
||||
* Function to do a modulation and then get samples.
|
||||
* @param delay_off
|
||||
* @param period_0
|
||||
* @param period_1
|
||||
* @param command
|
||||
*/
|
||||
void ModThenAcquireRawAdcSamples125k(int delay_off, int period_0, int period_1, uint8_t *command)
|
||||
{
|
||||
|
||||
/* Make sure the tag is reset */
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
SpinDelay(2500);
|
||||
|
||||
|
||||
int divisor_used = 95; // 125 KHz
|
||||
// see if 'h' was specified
|
||||
|
||||
if (command[strlen((char *) command) - 1] == 'h')
|
||||
divisor_used = 88; // 134.8 KHz
|
||||
|
||||
sample_config sc = { 0,0,1, divisor_used, 0};
|
||||
setSamplingConfig(&sc);
|
||||
|
||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor_used);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
|
||||
// Give it a bit of time for the resonant antenna to settle.
|
||||
SpinDelay(50);
|
||||
/* Make sure the tag is reset */
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
SpinDelay(2500);
|
||||
|
||||
// And a little more time for the tag to fully power up
|
||||
SpinDelay(2000);
|
||||
LFSetupFPGAForADC(sc.divisor, 1);
|
||||
|
||||
// Now set up the SSC to get the ADC samples that are now streaming at us.
|
||||
FpgaSetupSsc();
|
||||
// And a little more time for the tag to fully power up
|
||||
SpinDelay(2000);
|
||||
|
||||
// now modulate the reader field
|
||||
while(*command != '\0' && *command != ' ') {
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
LED_D_OFF();
|
||||
SpinDelayUs(delay_off);
|
||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor_used);
|
||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, sc.divisor);
|
||||
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
|
||||
LED_D_ON();
|
||||
@@ -150,14 +64,16 @@ void ModThenAcquireRawAdcSamples125k(int delay_off, int period_0, int period_1,
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
LED_D_OFF();
|
||||
SpinDelayUs(delay_off);
|
||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor_used);
|
||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, sc.divisor);
|
||||
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
|
||||
|
||||
// now do the read
|
||||
DoAcquisition125k(-1);
|
||||
DoAcquisition_config(false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* blank r/w tag data stream
|
||||
...0000000000000000 01111111
|
||||
1010101010101010101010101010101010101010101010101010101010101010
|
||||
@@ -177,8 +93,8 @@ void ReadTItag(void)
|
||||
#define FREQLO 123200
|
||||
#define FREQHI 134200
|
||||
|
||||
signed char *dest = (signed char *)BigBuf;
|
||||
int n = sizeof(BigBuf);
|
||||
signed char *dest = (signed char *)BigBuf_get_addr();
|
||||
uint16_t n = BigBuf_max_traceLen();
|
||||
// 128 bit shift register [shift3:shift2:shift1:shift0]
|
||||
uint32_t shift3 = 0, shift2 = 0, shift1 = 0, shift0 = 0;
|
||||
|
||||
@@ -330,7 +246,8 @@ void AcquireTiType(void)
|
||||
#define TIBUFLEN 1250
|
||||
|
||||
// clear buffer
|
||||
memset(BigBuf,0,sizeof(BigBuf));
|
||||
uint32_t *BigBuf = (uint32_t *)BigBuf_get_addr();
|
||||
memset(BigBuf,0,BigBuf_max_traceLen()/sizeof(uint32_t));
|
||||
|
||||
// Set up the synchronous serial port
|
||||
AT91C_BASE_PIOA->PIO_PDR = GPIO_SSC_DIN;
|
||||
@@ -378,7 +295,7 @@ void AcquireTiType(void)
|
||||
AT91C_BASE_PIOA->PIO_PDR = GPIO_SSC_DOUT;
|
||||
AT91C_BASE_PIOA->PIO_ASR = GPIO_SSC_DIN | GPIO_SSC_DOUT;
|
||||
|
||||
char *dest = (char *)BigBuf;
|
||||
char *dest = (char *)BigBuf_get_addr();
|
||||
n = TIBUFLEN*32;
|
||||
// unpack buffer
|
||||
for (i=TIBUFLEN-1; i>=0; i--) {
|
||||
@@ -467,7 +384,7 @@ void WriteTItag(uint32_t idhi, uint32_t idlo, uint16_t crc)
|
||||
void SimulateTagLowFrequency(int period, int gap, int ledcontrol)
|
||||
{
|
||||
int i;
|
||||
uint8_t *tab = (uint8_t *)BigBuf;
|
||||
uint8_t *tab = BigBuf_get_addr();
|
||||
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT);
|
||||
@@ -527,7 +444,7 @@ void SimulateTagLowFrequencyBidir(int divisor, int t0)
|
||||
|
||||
// compose fc/8 fc/10 waveform
|
||||
static void fc(int c, int *n) {
|
||||
uint8_t *dest = (uint8_t *)BigBuf;
|
||||
uint8_t *dest = BigBuf_get_addr();
|
||||
int idx;
|
||||
|
||||
// for when we want an fc8 pattern every 4 logical bits
|
||||
@@ -631,11 +548,11 @@ void CmdHIDsimTAG(int hi, int lo, int ledcontrol)
|
||||
// loop to get raw HID waveform then FSK demodulate the TAG ID from it
|
||||
void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol)
|
||||
{
|
||||
uint8_t *dest = (uint8_t *)BigBuf;
|
||||
|
||||
size_t size=0; //, found=0;
|
||||
uint8_t *dest = BigBuf_get_addr();
|
||||
const size_t sizeOfBigBuff = BigBuf_max_traceLen();
|
||||
size_t size = 0;
|
||||
uint32_t hi2=0, hi=0, lo=0;
|
||||
|
||||
int idx=0;
|
||||
// Configure to go in 125Khz listen mode
|
||||
LFSetupFPGAForADC(95, true);
|
||||
|
||||
@@ -644,13 +561,12 @@ void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol)
|
||||
WDT_HIT();
|
||||
if (ledcontrol) LED_A_ON();
|
||||
|
||||
DoAcquisition125k_internal(-1,true);
|
||||
// FSK demodulator
|
||||
size = HIDdemodFSK(dest, sizeof(BigBuf), &hi2, &hi, &lo);
|
||||
|
||||
WDT_HIT();
|
||||
|
||||
if (size>0 && lo>0){
|
||||
DoAcquisition_default(-1,true);
|
||||
// FSK demodulator
|
||||
size = sizeOfBigBuff; //variable size will change after demod so re initialize it before use
|
||||
idx = HIDdemodFSK(dest, &size, &hi2, &hi, &lo);
|
||||
|
||||
if (idx>0 && lo>0){
|
||||
// final loop, go over previously decoded manchester data and decode into usable tag ID
|
||||
// 111000 bit pattern represent start of frame, 01 pattern represents a 1 and 10 represents a 0
|
||||
if (hi2 != 0){ //extra large HID tags
|
||||
@@ -706,6 +622,8 @@ void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol)
|
||||
}
|
||||
if (findone){
|
||||
if (ledcontrol) LED_A_OFF();
|
||||
*high = hi;
|
||||
*low = lo;
|
||||
return;
|
||||
}
|
||||
// reset
|
||||
@@ -719,9 +637,9 @@ void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol)
|
||||
|
||||
void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol)
|
||||
{
|
||||
uint8_t *dest = (uint8_t *)BigBuf;
|
||||
uint8_t *dest = BigBuf_get_addr();
|
||||
|
||||
size_t size=0;
|
||||
size_t size=0, idx=0;
|
||||
int clk=0, invert=0, errCnt=0;
|
||||
uint64_t lo=0;
|
||||
// Configure to go in 125Khz listen mode
|
||||
@@ -732,8 +650,8 @@ void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol)
|
||||
WDT_HIT();
|
||||
if (ledcontrol) LED_A_ON();
|
||||
|
||||
DoAcquisition125k_internal(-1,true);
|
||||
size = sizeof(BigBuf);
|
||||
DoAcquisition_default(-1,true);
|
||||
size = BigBuf_max_traceLen();
|
||||
//Dbprintf("DEBUG: Buffer got");
|
||||
//askdemod and manchester decode
|
||||
errCnt = askmandemod(dest, &size, &clk, &invert);
|
||||
@@ -741,7 +659,7 @@ void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol)
|
||||
WDT_HIT();
|
||||
|
||||
if (errCnt>=0){
|
||||
lo = Em410xDecode(dest,size);
|
||||
lo = Em410xDecode(dest, &size, &idx);
|
||||
//Dbprintf("DEBUG: EM GOT");
|
||||
if (lo>0){
|
||||
Dbprintf("EM TAG ID: %02x%08x - (%05d_%03d_%08d)",
|
||||
@@ -753,6 +671,8 @@ void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol)
|
||||
}
|
||||
if (findone){
|
||||
if (ledcontrol) LED_A_OFF();
|
||||
*high=lo>>32;
|
||||
*low=lo & 0xFFFFFFFF;
|
||||
return;
|
||||
}
|
||||
} else{
|
||||
@@ -771,7 +691,7 @@ void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol)
|
||||
|
||||
void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol)
|
||||
{
|
||||
uint8_t *dest = (uint8_t *)BigBuf;
|
||||
uint8_t *dest = BigBuf_get_addr();
|
||||
int idx=0;
|
||||
uint32_t code=0, code2=0;
|
||||
uint8_t version=0;
|
||||
@@ -783,10 +703,10 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol)
|
||||
while(!BUTTON_PRESS()) {
|
||||
WDT_HIT();
|
||||
if (ledcontrol) LED_A_ON();
|
||||
DoAcquisition125k_internal(-1,true);
|
||||
//fskdemod and get start index
|
||||
DoAcquisition_default(-1,true);
|
||||
//fskdemod and get start index
|
||||
WDT_HIT();
|
||||
idx = IOdemodFSK(dest,sizeof(BigBuf));
|
||||
idx = IOdemodFSK(dest, BigBuf_max_traceLen());
|
||||
if (idx>0){
|
||||
//valid tag found
|
||||
|
||||
@@ -819,6 +739,8 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol)
|
||||
if (findone){
|
||||
if (ledcontrol) LED_A_OFF();
|
||||
//LED_A_OFF();
|
||||
*high=code;
|
||||
*low=code2;
|
||||
return;
|
||||
}
|
||||
code=code2=0;
|
||||
@@ -958,11 +880,11 @@ void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t PwdMod
|
||||
// Read one card block in page 0
|
||||
void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode)
|
||||
{
|
||||
uint8_t *dest = (uint8_t *)BigBuf;
|
||||
uint8_t *dest = BigBuf_get_addr();
|
||||
//int m=0, i=0; //enio adjustment 12/10/14
|
||||
uint32_t m=0, i=0;
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
||||
m = sizeof(BigBuf);
|
||||
m = BigBuf_max_traceLen();
|
||||
// Clear destination buffer before sending the command
|
||||
memset(dest, 128, m);
|
||||
// Connect the A/D to the peak-detected low-frequency path.
|
||||
@@ -1023,11 +945,11 @@ void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode)
|
||||
|
||||
// Read card traceability data (page 1)
|
||||
void T55xxReadTrace(void){
|
||||
uint8_t *dest = (uint8_t *)BigBuf;
|
||||
uint8_t *dest = BigBuf_get_addr();
|
||||
int m=0, i=0;
|
||||
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
||||
m = sizeof(BigBuf);
|
||||
m = BigBuf_max_traceLen();
|
||||
// Clear destination buffer before sending the command
|
||||
memset(dest, 128, m);
|
||||
// Connect the A/D to the peak-detected low-frequency path.
|
||||
@@ -1377,8 +1299,8 @@ void CopyIndala224toT55x7(int uid1, int uid2, int uid3, int uid4, int uid5, int
|
||||
int DemodPCF7931(uint8_t **outBlocks) {
|
||||
uint8_t BitStream[256];
|
||||
uint8_t Blocks[8][16];
|
||||
uint8_t *GraphBuffer = (uint8_t *)BigBuf;
|
||||
int GraphTraceLen = sizeof(BigBuf);
|
||||
uint8_t *GraphBuffer = BigBuf_get_addr();
|
||||
int GraphTraceLen = BigBuf_max_traceLen();
|
||||
int i, j, lastval, bitidx, half_switch;
|
||||
int clock = 64;
|
||||
int tolerance = clock / 8;
|
||||
@@ -1388,7 +1310,9 @@ int DemodPCF7931(uint8_t **outBlocks) {
|
||||
int lmin=128, lmax=128;
|
||||
uint8_t dir;
|
||||
|
||||
AcquireRawAdcSamples125k(0);
|
||||
LFSetupFPGAForADC(95, true);
|
||||
DoAcquisition_default(0, 0);
|
||||
|
||||
|
||||
lmin = 64;
|
||||
lmax = 192;
|
||||
@@ -1795,7 +1719,7 @@ void EM4xLogin(uint32_t Password) {
|
||||
void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode) {
|
||||
|
||||
uint8_t fwd_bit_count;
|
||||
uint8_t *dest = (uint8_t *)BigBuf;
|
||||
uint8_t *dest = BigBuf_get_addr();
|
||||
int m=0, i=0;
|
||||
|
||||
//If password mode do login
|
||||
@@ -1805,7 +1729,7 @@ void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode) {
|
||||
fwd_bit_count = Prepare_Cmd( FWD_CMD_READ );
|
||||
fwd_bit_count += Prepare_Addr( Address );
|
||||
|
||||
m = sizeof(BigBuf);
|
||||
m = BigBuf_max_traceLen();
|
||||
// Clear destination buffer before sending the command
|
||||
memset(dest, 128, m);
|
||||
// Connect the A/D to the peak-detected low-frequency path.
|
||||
|
||||
252
armsrc/lfsampling.c
Normal file
252
armsrc/lfsampling.c
Normal file
@@ -0,0 +1,252 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
// Miscellaneous routines for low frequency sampling.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "proxmark3.h"
|
||||
#include "apps.h"
|
||||
#include "util.h"
|
||||
#include "string.h"
|
||||
|
||||
#include "lfsampling.h"
|
||||
|
||||
sample_config config = { 1, 8, 1, 88, 0 } ;
|
||||
|
||||
void printConfig()
|
||||
{
|
||||
Dbprintf("Sampling config: ");
|
||||
Dbprintf(" [q] divisor: %d ", config.divisor);
|
||||
Dbprintf(" [b] bps: %d ", config.bits_per_sample);
|
||||
Dbprintf(" [d] decimation: %d ", config.decimation);
|
||||
Dbprintf(" [a] averaging: %d ", config.averaging);
|
||||
Dbprintf(" [t] trigger threshold: %d ", config.trigger_threshold);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called from the USB-handler to set the sampling configuration
|
||||
* The sampling config is used for std reading and snooping.
|
||||
*
|
||||
* Other functions may read samples and ignore the sampling config,
|
||||
* such as functions to read the UID from a prox tag or similar.
|
||||
*
|
||||
* Values set to '0' implies no change (except for averaging)
|
||||
* @brief setSamplingConfig
|
||||
* @param sc
|
||||
*/
|
||||
void setSamplingConfig(sample_config *sc)
|
||||
{
|
||||
if(sc->divisor != 0) config.divisor = sc->divisor;
|
||||
if(sc->bits_per_sample!= 0) config.bits_per_sample= sc->bits_per_sample;
|
||||
if(sc->decimation!= 0) config.decimation= sc->decimation;
|
||||
if(sc->trigger_threshold != -1) config.trigger_threshold= sc->trigger_threshold;
|
||||
|
||||
config.averaging= sc->averaging;
|
||||
if(config.bits_per_sample > 8) config.bits_per_sample = 8;
|
||||
if(config.decimation < 1) config.decimation = 1;
|
||||
|
||||
printConfig();
|
||||
}
|
||||
|
||||
sample_config* getSamplingConfig()
|
||||
{
|
||||
return &config;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
uint8_t * buffer;
|
||||
uint32_t numbits;
|
||||
uint32_t position;
|
||||
} BitstreamOut;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Pushes bit onto the stream
|
||||
* @param stream
|
||||
* @param bit
|
||||
*/
|
||||
void pushBit( BitstreamOut* stream, uint8_t bit)
|
||||
{
|
||||
int bytepos = stream->position >> 3; // divide by 8
|
||||
int bitpos = stream->position & 7;
|
||||
*(stream->buffer+bytepos) |= (bit > 0) << (7 - bitpos);
|
||||
stream->position++;
|
||||
stream->numbits++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup the FPGA to listen for samples. This method downloads the FPGA bitstream
|
||||
* if not already loaded, sets divisor and starts up the antenna.
|
||||
* @param divisor : 1, 88> 255 or negative ==> 134.8 KHz
|
||||
* 0 or 95 ==> 125 KHz
|
||||
*
|
||||
**/
|
||||
void LFSetupFPGAForADC(int divisor, bool lf_field)
|
||||
{
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
||||
if ( (divisor == 1) || (divisor < 0) || (divisor > 255) )
|
||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz
|
||||
else if (divisor == 0)
|
||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
|
||||
else
|
||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor);
|
||||
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | (lf_field ? FPGA_LF_ADC_READER_FIELD : 0));
|
||||
|
||||
// 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);
|
||||
// Now set up the SSC to get the ADC samples that are now streaming at us.
|
||||
FpgaSetupSsc();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Does the sample acquisition. If threshold is specified, the actual sampling
|
||||
* is not commenced until the threshold has been reached.
|
||||
* This method implements decimation and quantization in order to
|
||||
* be able to provide longer sample traces.
|
||||
* Uses the following global settings:
|
||||
* @param decimation - how much should the signal be decimated. A decimation of N means we keep 1 in N samples, etc.
|
||||
* @param bits_per_sample - bits per sample. Max 8, min 1 bit per sample.
|
||||
* @param averaging If set to true, decimation will use averaging, so that if e.g. decimation is 3, the sample
|
||||
* value that will be used is the average value of the three samples.
|
||||
* @param trigger_threshold - a threshold. The sampling won't commence until this threshold has been reached. Set
|
||||
* to -1 to ignore threshold.
|
||||
* @param silent - is true, now outputs are made. If false, dbprints the status
|
||||
* @return the number of bits occupied by the samples.
|
||||
*/
|
||||
|
||||
uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averaging, int trigger_threshold,bool silent)
|
||||
{
|
||||
//.
|
||||
uint8_t *dest = BigBuf_get_addr();
|
||||
int bufsize = BigBuf_max_traceLen();
|
||||
|
||||
memset(dest, 0, bufsize);
|
||||
|
||||
if(bits_per_sample < 1) bits_per_sample = 1;
|
||||
if(bits_per_sample > 8) bits_per_sample = 8;
|
||||
|
||||
if(decimation < 1) decimation = 1;
|
||||
|
||||
// Use a bit stream to handle the output
|
||||
BitstreamOut data = { dest , 0, 0};
|
||||
int sample_counter = 0;
|
||||
uint8_t sample = 0;
|
||||
//If we want to do averaging
|
||||
uint32_t sample_sum =0 ;
|
||||
uint32_t sample_total_numbers =0 ;
|
||||
uint32_t sample_total_saved =0 ;
|
||||
|
||||
while(!BUTTON_PRESS()) {
|
||||
WDT_HIT();
|
||||
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
|
||||
AT91C_BASE_SSC->SSC_THR = 0x43;
|
||||
LED_D_ON();
|
||||
}
|
||||
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
|
||||
sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
||||
LED_D_OFF();
|
||||
if (trigger_threshold > 0 && sample < trigger_threshold)
|
||||
continue;
|
||||
|
||||
trigger_threshold = 0;
|
||||
sample_total_numbers++;
|
||||
|
||||
if(averaging)
|
||||
{
|
||||
sample_sum += sample;
|
||||
}
|
||||
//Check decimation
|
||||
if(decimation > 1)
|
||||
{
|
||||
sample_counter++;
|
||||
if(sample_counter < decimation) continue;
|
||||
sample_counter = 0;
|
||||
}
|
||||
//Averaging
|
||||
if(averaging && decimation > 1) {
|
||||
sample = sample_sum / decimation;
|
||||
sample_sum =0;
|
||||
}
|
||||
//Store the sample
|
||||
sample_total_saved ++;
|
||||
if(bits_per_sample == 8){
|
||||
dest[sample_total_saved-1] = sample;
|
||||
data.numbits = sample_total_saved << 3;//Get the return value correct
|
||||
if(sample_total_saved >= bufsize) break;
|
||||
}
|
||||
else{
|
||||
pushBit(&data, sample & 0x80);
|
||||
if(bits_per_sample > 1) pushBit(&data, sample & 0x40);
|
||||
if(bits_per_sample > 2) pushBit(&data, sample & 0x20);
|
||||
if(bits_per_sample > 3) pushBit(&data, sample & 0x10);
|
||||
if(bits_per_sample > 4) pushBit(&data, sample & 0x08);
|
||||
if(bits_per_sample > 5) pushBit(&data, sample & 0x04);
|
||||
if(bits_per_sample > 6) pushBit(&data, sample & 0x02);
|
||||
//Not needed, 8bps is covered above
|
||||
//if(bits_per_sample > 7) pushBit(&data, sample & 0x01);
|
||||
if((data.numbits >> 3) +1 >= bufsize) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!silent)
|
||||
{
|
||||
Dbprintf("Done, saved %d out of %d seen samples at %d bits/sample",sample_total_saved, sample_total_numbers,bits_per_sample);
|
||||
Dbprintf("buffer samples: %02x %02x %02x %02x %02x %02x %02x %02x ...",
|
||||
dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]);
|
||||
}
|
||||
return data.numbits;
|
||||
}
|
||||
/**
|
||||
* @brief Does sample acquisition, ignoring the config values set in the sample_config.
|
||||
* This method is typically used by tag-specific readers who just wants to read the samples
|
||||
* the normal way
|
||||
* @param trigger_threshold
|
||||
* @param silent
|
||||
* @return number of bits sampled
|
||||
*/
|
||||
uint32_t DoAcquisition_default(int trigger_threshold, bool silent)
|
||||
{
|
||||
return DoAcquisition(1,8,0,trigger_threshold,silent);
|
||||
}
|
||||
uint32_t DoAcquisition_config( bool silent)
|
||||
{
|
||||
return DoAcquisition(config.decimation
|
||||
,config.bits_per_sample
|
||||
,config.averaging
|
||||
,config.trigger_threshold
|
||||
,silent);
|
||||
}
|
||||
|
||||
uint32_t ReadLF(bool activeField)
|
||||
{
|
||||
printConfig();
|
||||
LFSetupFPGAForADC(config.divisor, activeField);
|
||||
// Now call the acquisition routine
|
||||
return DoAcquisition_config(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the FPGA for reader-mode (field on), and acquires the samples.
|
||||
* @return number of bits sampled
|
||||
**/
|
||||
uint32_t SampleLF()
|
||||
{
|
||||
return ReadLF(true);
|
||||
}
|
||||
/**
|
||||
* Initializes the FPGA for snoop-mode (field off), and acquires the samples.
|
||||
* @return number of bits sampled
|
||||
**/
|
||||
|
||||
uint32_t SnoopLF()
|
||||
{
|
||||
return ReadLF(false);
|
||||
}
|
||||
59
armsrc/lfsampling.h
Normal file
59
armsrc/lfsampling.h
Normal file
@@ -0,0 +1,59 @@
|
||||
#ifndef LFSAMPLING_H
|
||||
#define LFSAMPLING_H
|
||||
|
||||
/**
|
||||
* Initializes the FPGA for reader-mode (field on), and acquires the samples.
|
||||
* @return number of bits sampled
|
||||
**/
|
||||
uint32_t SampleLF();
|
||||
|
||||
/**
|
||||
* Initializes the FPGA for snoop-mode (field off), and acquires the samples.
|
||||
* @return number of bits sampled
|
||||
**/
|
||||
|
||||
uint32_t SnoopLF();
|
||||
|
||||
/**
|
||||
* @brief Does sample acquisition, ignoring the config values set in the sample_config.
|
||||
* This method is typically used by tag-specific readers who just wants to read the samples
|
||||
* the normal way
|
||||
* @param trigger_threshold
|
||||
* @param silent
|
||||
* @return number of bits sampled
|
||||
*/
|
||||
uint32_t DoAcquisition_default(int trigger_threshold, bool silent);
|
||||
/**
|
||||
* @brief Does sample acquisition, using the config values set in the sample_config.
|
||||
* @param trigger_threshold
|
||||
* @param silent
|
||||
* @return number of bits sampled
|
||||
*/
|
||||
|
||||
uint32_t DoAcquisition_config( bool silent);
|
||||
|
||||
/**
|
||||
* Setup the FPGA to listen for samples. This method downloads the FPGA bitstream
|
||||
* if not already loaded, sets divisor and starts up the antenna.
|
||||
* @param divisor : 1, 88> 255 or negative ==> 134.8 KHz
|
||||
* 0 or 95 ==> 125 KHz
|
||||
*
|
||||
**/
|
||||
void LFSetupFPGAForADC(int divisor, bool lf_field);
|
||||
|
||||
|
||||
/**
|
||||
* Called from the USB-handler to set the sampling configuration
|
||||
* The sampling config is used for std reading and snooping.
|
||||
*
|
||||
* Other functions may read samples and ignore the sampling config,
|
||||
* such as functions to read the UID from a prox tag or similar.
|
||||
*
|
||||
* Values set to '0' implies no change (except for averaging)
|
||||
* @brief setSamplingConfig
|
||||
* @param sc
|
||||
*/
|
||||
void setSamplingConfig(sample_config *sc);
|
||||
|
||||
sample_config * getSamplingConfig();
|
||||
#endif // LFSAMPLING_H
|
||||
@@ -17,6 +17,8 @@
|
||||
#include "apps.h"
|
||||
#include "util.h"
|
||||
|
||||
#include "crc.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Select, Authenticate, Read a MIFARE tag.
|
||||
// read block
|
||||
@@ -80,7 +82,71 @@ void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
|
||||
cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,16);
|
||||
LED_B_OFF();
|
||||
|
||||
// Thats it...
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
LEDsoff();
|
||||
}
|
||||
|
||||
|
||||
void MifareUC_Auth1(uint8_t arg0, uint8_t *datain){
|
||||
|
||||
byte_t isOK = 0;
|
||||
byte_t dataoutbuf[16] = {0x00};
|
||||
uint8_t uid[10] = {0x00};
|
||||
uint32_t cuid;
|
||||
|
||||
LED_A_ON();
|
||||
LED_B_OFF();
|
||||
LED_C_OFF();
|
||||
|
||||
iso14a_clear_trace();
|
||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||
|
||||
if(!iso14443a_select_card(uid, NULL, &cuid)) {
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR)
|
||||
Dbprintf("Can't select card");
|
||||
//OnError(0);
|
||||
return;
|
||||
};
|
||||
|
||||
if(mifare_ultra_auth1(cuid, dataoutbuf)){
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR)
|
||||
Dbprintf("Authentication part1: Fail.");
|
||||
//OnError(1);
|
||||
return;
|
||||
}
|
||||
|
||||
isOK = 1;
|
||||
if (MF_DBGLEVEL >= MF_DBG_EXTENDED)
|
||||
DbpString("AUTH 1 FINISHED");
|
||||
|
||||
cmd_send(CMD_ACK,isOK,cuid,0,dataoutbuf,11);
|
||||
LEDsoff();
|
||||
}
|
||||
void MifareUC_Auth2(uint32_t arg0, uint8_t *datain){
|
||||
|
||||
uint32_t cuid = arg0;
|
||||
uint8_t key[16] = {0x00};
|
||||
byte_t isOK = 0;
|
||||
byte_t dataoutbuf[16] = {0x00};
|
||||
|
||||
memcpy(key, datain, 16);
|
||||
|
||||
LED_A_ON();
|
||||
LED_B_OFF();
|
||||
LED_C_OFF();
|
||||
|
||||
if(mifare_ultra_auth2(cuid, key, dataoutbuf)){
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR)
|
||||
Dbprintf("Authentication part2: Fail...");
|
||||
//OnError(1);
|
||||
return;
|
||||
}
|
||||
|
||||
isOK = 1;
|
||||
if (MF_DBGLEVEL >= MF_DBG_EXTENDED)
|
||||
DbpString("AUTH 2 FINISHED");
|
||||
|
||||
cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,11);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
LEDsoff();
|
||||
}
|
||||
@@ -463,11 +529,13 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat
|
||||
struct Crypto1State mpcs = {0, 0};
|
||||
struct Crypto1State *pcs;
|
||||
pcs = &mpcs;
|
||||
uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf();
|
||||
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
|
||||
|
||||
uint32_t auth1_time, auth2_time;
|
||||
static uint16_t delta_time;
|
||||
|
||||
// free eventually allocated BigBuf memory
|
||||
BigBuf_free();
|
||||
// clear trace
|
||||
iso14a_clear_trace();
|
||||
iso14a_set_tracing(false);
|
||||
@@ -854,8 +922,8 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
|
||||
uint8_t d_block[18] = {0x00};
|
||||
uint32_t cuid;
|
||||
|
||||
uint8_t *receivedAnswer = get_bigbufptr_recvrespbuf();
|
||||
uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
|
||||
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
|
||||
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
|
||||
|
||||
// reset FPGA and LED
|
||||
if (workFlags & 0x08) {
|
||||
@@ -973,8 +1041,8 @@ void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
|
||||
uint8_t data[18] = {0x00};
|
||||
uint32_t cuid = 0;
|
||||
|
||||
uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf();
|
||||
uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
|
||||
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
|
||||
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
|
||||
|
||||
if (workFlags & 0x08) {
|
||||
LED_A_ON();
|
||||
@@ -1038,8 +1106,8 @@ void MifareCIdent(){
|
||||
// variables
|
||||
byte_t isOK = 1;
|
||||
|
||||
uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf();
|
||||
uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
|
||||
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
|
||||
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
|
||||
|
||||
ReaderTransmitBitsPar(wupC1,7,0, NULL);
|
||||
if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
|
||||
@@ -1061,3 +1129,58 @@ void MifareCIdent(){
|
||||
//
|
||||
// DESFIRE
|
||||
//
|
||||
|
||||
void Mifare_DES_Auth1(uint8_t arg0, uint8_t *datain){
|
||||
|
||||
byte_t dataout[11] = {0x00};
|
||||
uint8_t uid[10] = {0x00};
|
||||
uint32_t cuid;
|
||||
|
||||
iso14a_clear_trace();
|
||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||
|
||||
int len = iso14443a_select_card(uid, NULL, &cuid);
|
||||
if(!len) {
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR)
|
||||
Dbprintf("Can't select card");
|
||||
//OnError(1);
|
||||
return;
|
||||
};
|
||||
|
||||
if(mifare_desfire_des_auth1(cuid, dataout)){
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR)
|
||||
Dbprintf("Authentication part1: Fail.");
|
||||
//OnError(4);
|
||||
return;
|
||||
}
|
||||
|
||||
if (MF_DBGLEVEL >= MF_DBG_EXTENDED) DbpString("AUTH 1 FINISHED");
|
||||
|
||||
cmd_send(CMD_ACK,1,cuid,0,dataout, sizeof(dataout));
|
||||
}
|
||||
|
||||
void Mifare_DES_Auth2(uint32_t arg0, uint8_t *datain){
|
||||
|
||||
uint32_t cuid = arg0;
|
||||
uint8_t key[16] = {0x00};
|
||||
byte_t isOK = 0;
|
||||
byte_t dataout[12] = {0x00};
|
||||
|
||||
memcpy(key, datain, 16);
|
||||
|
||||
isOK = mifare_desfire_des_auth2(cuid, key, dataout);
|
||||
|
||||
if( isOK) {
|
||||
if (MF_DBGLEVEL >= MF_DBG_EXTENDED)
|
||||
Dbprintf("Authentication part2: Failed");
|
||||
//OnError(4);
|
||||
return;
|
||||
}
|
||||
|
||||
if (MF_DBGLEVEL >= MF_DBG_EXTENDED)
|
||||
DbpString("AUTH 2 FINISHED");
|
||||
|
||||
cmd_send(CMD_ACK, isOK, 0, 0, dataout, sizeof(dataout));
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
LEDsoff();
|
||||
}
|
||||
|
||||
@@ -13,10 +13,10 @@
|
||||
|
||||
static int sniffState = SNF_INIT;
|
||||
static uint8_t sniffUIDType;
|
||||
static uint8_t sniffUID[8];
|
||||
static uint8_t sniffATQA[2];
|
||||
static uint8_t sniffUID[8] = {0x00};
|
||||
static uint8_t sniffATQA[2] = {0x00};
|
||||
static uint8_t sniffSAK;
|
||||
static uint8_t sniffBuf[16];
|
||||
static uint8_t sniffBuf[16] = {0x00};
|
||||
static uint32_t timerData = 0;
|
||||
|
||||
|
||||
@@ -151,12 +151,13 @@ bool intMfSniffSend() {
|
||||
int pckSize = 0;
|
||||
int pckLen = traceLen;
|
||||
int pckNum = 0;
|
||||
|
||||
uint8_t *trace = BigBuf_get_addr();
|
||||
|
||||
FpgaDisableSscDma();
|
||||
while (pckLen > 0) {
|
||||
pckSize = MIN(USB_CMD_DATA_SIZE, pckLen);
|
||||
LED_B_ON();
|
||||
cmd_send(CMD_ACK, 1, pckSize, pckNum, trace + traceLen - pckLen, pckSize);
|
||||
cmd_send(CMD_ACK, 1, traceLen, pckSize, trace + traceLen - pckLen, pckSize);
|
||||
LED_B_OFF();
|
||||
|
||||
pckLen -= pckSize;
|
||||
|
||||
@@ -21,17 +21,6 @@
|
||||
|
||||
int MF_DBGLEVEL = MF_DBG_ALL;
|
||||
|
||||
// memory management
|
||||
uint8_t* get_bigbufptr_recvrespbuf(void) {
|
||||
return (((uint8_t *)BigBuf) + RECV_RESP_OFFSET);
|
||||
}
|
||||
uint8_t* get_bigbufptr_recvcmdbuf(void) {
|
||||
return (((uint8_t *)BigBuf) + RECV_CMD_OFFSET);
|
||||
}
|
||||
uint8_t* get_bigbufptr_emlcardmem(void) {
|
||||
return (((uint8_t *)BigBuf) + CARD_MEMORY_OFFSET);
|
||||
}
|
||||
|
||||
// crypto1 helpers
|
||||
void mf_crypto1_decrypt(struct Crypto1State *pcs, uint8_t *data, int len){
|
||||
uint8_t bt = 0;
|
||||
@@ -93,10 +82,30 @@ int mifare_sendcmd_short_special(struct Crypto1State *pcs, uint8_t crypted, uint
|
||||
AppendCrc14443a(dcmd, 6);
|
||||
ReaderTransmit(dcmd, sizeof(dcmd), NULL);
|
||||
int len = ReaderReceive(answer, answer_parity);
|
||||
if(!len)
|
||||
{
|
||||
if(!len) {
|
||||
if (MF_DBGLEVEL >= 1) Dbprintf("Authentication failed. Card timeout.");
|
||||
return 2;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
int mifare_sendcmd_short_mfucauth(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t *data, uint8_t *answer, uint8_t *answer_parity, uint32_t *timing)
|
||||
{
|
||||
uint8_t dcmd[19];
|
||||
int len;
|
||||
dcmd[0] = cmd;
|
||||
memcpy(dcmd+1,data,16);
|
||||
AppendCrc14443a(dcmd, 17);
|
||||
|
||||
ReaderTransmit(dcmd, sizeof(dcmd), timing);
|
||||
len = ReaderReceive(answer, answer_parity);
|
||||
if(!len) {
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Authentication failed. Card timeout.");
|
||||
len = ReaderReceive(answer,answer_parity);
|
||||
}
|
||||
if(len==1) {
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("NAK - Authentication failed.");
|
||||
return 1;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
@@ -166,8 +175,8 @@ int mifare_classic_authex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockN
|
||||
uint32_t nt, ntpp; // Supplied tag nonce
|
||||
|
||||
uint8_t mf_nr_ar[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
|
||||
uint8_t *receivedAnswer = get_bigbufptr_recvrespbuf();
|
||||
uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
|
||||
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
|
||||
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
|
||||
|
||||
// Transmit MIFARE_CLASSIC_AUTH
|
||||
len = mifare_sendcmd_short(pcs, isNested, 0x60 + (keyType & 0x01), blockNo, receivedAnswer, receivedAnswerPar, timing);
|
||||
@@ -253,8 +262,8 @@ int mifare_classic_readblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blo
|
||||
int len;
|
||||
uint8_t bt[2];
|
||||
|
||||
uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf();
|
||||
uint8_t* receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
|
||||
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
|
||||
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
|
||||
|
||||
// command MIFARE_CLASSIC_READBLOCK
|
||||
len = mifare_sendcmd_short(pcs, 1, 0x30, blockNo, receivedAnswer, receivedAnswerPar, NULL);
|
||||
@@ -278,12 +287,63 @@ int mifare_classic_readblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blo
|
||||
return 0;
|
||||
}
|
||||
|
||||
// mifare ultralight commands
|
||||
int mifare_ultra_auth1(uint32_t uid, uint8_t *blockData){
|
||||
|
||||
uint16_t len;
|
||||
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
|
||||
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
|
||||
|
||||
len = mifare_sendcmd_short(NULL, 1, 0x1A, 0x00, receivedAnswer,receivedAnswerPar ,NULL);
|
||||
if (len == 1) {
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR)
|
||||
Dbprintf("Cmd Error: %02x", receivedAnswer[0]);
|
||||
return 1;
|
||||
}
|
||||
if (len != 11)
|
||||
return 1;
|
||||
|
||||
if (MF_DBGLEVEL >= MF_DBG_EXTENDED) {
|
||||
Dbprintf("Auth1 Resp: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
|
||||
receivedAnswer[0],receivedAnswer[1],receivedAnswer[2],receivedAnswer[3],receivedAnswer[4],
|
||||
receivedAnswer[5],receivedAnswer[6],receivedAnswer[7],receivedAnswer[8],receivedAnswer[9],
|
||||
receivedAnswer[10]);
|
||||
}
|
||||
memcpy(blockData, receivedAnswer, 11);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mifare_ultra_auth2(uint32_t uid, uint8_t *key, uint8_t *blockData){
|
||||
|
||||
uint16_t len;
|
||||
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
|
||||
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
|
||||
|
||||
len = mifare_sendcmd_short_mfucauth(NULL, 1, 0xAF, key, receivedAnswer, receivedAnswerPar, NULL);
|
||||
if (len == 1) {
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR)
|
||||
Dbprintf("Cmd Error: %02x", receivedAnswer[0]);
|
||||
return 1;
|
||||
}
|
||||
if (len != 11)
|
||||
return 1;
|
||||
|
||||
if (MF_DBGLEVEL >= MF_DBG_EXTENDED) {
|
||||
Dbprintf("Auth2 Resp: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
|
||||
receivedAnswer[0],receivedAnswer[1],receivedAnswer[2],receivedAnswer[3],receivedAnswer[4],
|
||||
receivedAnswer[5],receivedAnswer[6],receivedAnswer[7],receivedAnswer[8],receivedAnswer[9],
|
||||
receivedAnswer[10]);
|
||||
}
|
||||
memcpy(blockData, receivedAnswer, 11);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mifare_ultra_readblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData)
|
||||
{
|
||||
uint16_t len;
|
||||
uint8_t bt[2];
|
||||
uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf();
|
||||
uint8_t* receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
|
||||
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
|
||||
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
|
||||
|
||||
|
||||
// command MIFARE_CLASSIC_READBLOCK
|
||||
@@ -321,8 +381,8 @@ int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t bl
|
||||
byte_t res;
|
||||
|
||||
uint8_t d_block[18], d_block_enc[18];
|
||||
uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf();
|
||||
uint8_t* receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
|
||||
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
|
||||
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
|
||||
|
||||
// command MIFARE_CLASSIC_WRITEBLOCK
|
||||
len = mifare_sendcmd_short(pcs, 1, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL);
|
||||
@@ -364,8 +424,8 @@ int mifare_ultra_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData)
|
||||
uint16_t len;
|
||||
uint8_t par[3] = {0}; // enough for 18 parity bits
|
||||
uint8_t d_block[18] = {0x00};
|
||||
uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf();
|
||||
uint8_t* receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
|
||||
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
|
||||
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
|
||||
|
||||
// command MIFARE_CLASSIC_WRITEBLOCK
|
||||
len = mifare_sendcmd_short(NULL, true, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL);
|
||||
@@ -395,8 +455,8 @@ int mifare_ultra_special_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *bloc
|
||||
{
|
||||
uint16_t len;
|
||||
uint8_t d_block[8] = {0x00};
|
||||
uint8_t *receivedAnswer = get_bigbufptr_recvrespbuf();
|
||||
uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
|
||||
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
|
||||
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
|
||||
|
||||
// command MIFARE_CLASSIC_WRITEBLOCK
|
||||
d_block[0]= blockNo;
|
||||
@@ -416,8 +476,8 @@ int mifare_ultra_special_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *bloc
|
||||
|
||||
int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid)
|
||||
{
|
||||
uint16_t len;
|
||||
uint8_t *receivedAnswer = get_bigbufptr_recvrespbuf();
|
||||
uint16_t len;
|
||||
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
|
||||
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
|
||||
|
||||
len = mifare_sendcmd_short(pcs, pcs == NULL ? false:true, 0x50, 0x00, receivedAnswer, receivedAnswerPar, NULL);
|
||||
@@ -432,8 +492,8 @@ int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid)
|
||||
|
||||
int mifare_ultra_halt(uint32_t uid)
|
||||
{
|
||||
uint16_t len;
|
||||
uint8_t *receivedAnswer = get_bigbufptr_recvrespbuf();
|
||||
uint16_t len;
|
||||
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
|
||||
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
|
||||
|
||||
len = mifare_sendcmd_short(NULL, true, 0x50, 0x00, receivedAnswer, receivedAnswerPar, NULL);
|
||||
@@ -467,22 +527,22 @@ uint8_t FirstBlockOfSector(uint8_t sectorNo)
|
||||
|
||||
|
||||
// work with emulator memory
|
||||
void emlSetMem(uint8_t *data, int blockNum, int blocksCount) {
|
||||
void emlSetMem(uint8_t *data, int blockNum, int blocksCount) {
|
||||
uint8_t* emCARD = BigBuf_get_EM_addr();
|
||||
memcpy(emCARD + blockNum * 16, data, blocksCount * 16);
|
||||
}
|
||||
|
||||
void emlGetMem(uint8_t *data, int blockNum, int blocksCount) {
|
||||
void emlGetMem(uint8_t *data, int blockNum, int blocksCount) {
|
||||
uint8_t* emCARD = BigBuf_get_EM_addr();
|
||||
memcpy(data, emCARD + blockNum * 16, blocksCount * 16);
|
||||
}
|
||||
|
||||
void emlGetMemBt(uint8_t *data, int bytePtr, int byteCount) {
|
||||
void emlGetMemBt(uint8_t *data, int bytePtr, int byteCount) {
|
||||
uint8_t* emCARD = BigBuf_get_EM_addr();
|
||||
memcpy(data, emCARD + bytePtr, byteCount);
|
||||
}
|
||||
|
||||
int emlCheckValBl(int blockNum) {
|
||||
int emlCheckValBl(int blockNum) {
|
||||
uint8_t* emCARD = BigBuf_get_EM_addr();
|
||||
uint8_t* data = emCARD + blockNum * 16;
|
||||
|
||||
@@ -497,7 +557,7 @@ int emlCheckValBl(int blockNum) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int emlGetValBl(uint32_t *blReg, uint8_t *blBlock, int blockNum) {
|
||||
int emlGetValBl(uint32_t *blReg, uint8_t *blBlock, int blockNum) {
|
||||
uint8_t* emCARD = BigBuf_get_EM_addr();
|
||||
uint8_t* data = emCARD + blockNum * 16;
|
||||
|
||||
@@ -510,7 +570,7 @@ int emlGetValBl(uint32_t *blReg, uint8_t *blBlock, int blockNum) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int emlSetValBl(uint32_t blReg, uint8_t blBlock, int blockNum) {
|
||||
int emlSetValBl(uint32_t blReg, uint8_t blBlock, int blockNum) {
|
||||
uint8_t* emCARD = BigBuf_get_EM_addr();
|
||||
uint8_t* data = emCARD + blockNum * 16;
|
||||
|
||||
@@ -528,7 +588,7 @@ int emlSetValBl(uint32_t blReg, uint8_t blBlock, int blockNum) {
|
||||
}
|
||||
|
||||
uint64_t emlGetKey(int sectorNum, int keyType) {
|
||||
uint8_t key[6];
|
||||
uint8_t key[6];
|
||||
uint8_t* emCARD = BigBuf_get_EM_addr();
|
||||
|
||||
memcpy(key, emCARD + 16 * (FirstBlockOfSector(sectorNum) + NumBlocksPerSector(sectorNum) - 1) + keyType * 10, 6);
|
||||
@@ -539,7 +599,7 @@ void emlClearMem(void) {
|
||||
int b;
|
||||
|
||||
const uint8_t trailer[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x80, 0x69, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
|
||||
const uint8_t uid[] = {0xe6, 0x84, 0x87, 0xf3, 0x16, 0x88, 0x04, 0x00, 0x46, 0x8e, 0x45, 0x55, 0x4d, 0x70, 0x41, 0x04};
|
||||
const uint8_t uid[] = {0xe6, 0x84, 0x87, 0xf3, 0x16, 0x88, 0x04, 0x00, 0x46, 0x8e, 0x45, 0x55, 0x4d, 0x70, 0x41, 0x04};
|
||||
uint8_t* emCARD = BigBuf_get_EM_addr();
|
||||
|
||||
memset(emCARD, 0, CARD_MEMORY_SIZE);
|
||||
@@ -552,3 +612,98 @@ void emlClearMem(void) {
|
||||
// uid
|
||||
emlSetMem((uint8_t *)uid, 0, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Mifare desfire commands
|
||||
int mifare_sendcmd_special(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t* data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing)
|
||||
{
|
||||
uint8_t dcmd[5] = {0x00};
|
||||
dcmd[0] = cmd;
|
||||
memcpy(dcmd+1,data,2);
|
||||
AppendCrc14443a(dcmd, 3);
|
||||
|
||||
ReaderTransmit(dcmd, sizeof(dcmd), NULL);
|
||||
int len = ReaderReceive(answer, answer_parity);
|
||||
if(!len) {
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR)
|
||||
Dbprintf("Authentication failed. Card timeout.");
|
||||
return 1;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
int mifare_sendcmd_special2(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t* data, uint8_t* answer,uint8_t *answer_parity, uint32_t *timing)
|
||||
{
|
||||
uint8_t dcmd[20] = {0x00};
|
||||
dcmd[0] = cmd;
|
||||
memcpy(dcmd+1,data,17);
|
||||
AppendCrc14443a(dcmd, 18);
|
||||
|
||||
ReaderTransmit(dcmd, sizeof(dcmd), NULL);
|
||||
int len = ReaderReceive(answer, answer_parity);
|
||||
if(!len){
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR)
|
||||
Dbprintf("Authentication failed. Card timeout.");
|
||||
return 1;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
int mifare_desfire_des_auth1(uint32_t uid, uint8_t *blockData){
|
||||
|
||||
int len;
|
||||
// load key, keynumber
|
||||
uint8_t data[2]={0x0a, 0x00};
|
||||
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
|
||||
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
|
||||
|
||||
len = mifare_sendcmd_special(NULL, 1, 0x02, data, receivedAnswer,receivedAnswerPar,NULL);
|
||||
if (len == 1) {
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR)
|
||||
Dbprintf("Cmd Error: %02x", receivedAnswer[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (len == 12) {
|
||||
if (MF_DBGLEVEL >= MF_DBG_EXTENDED) {
|
||||
Dbprintf("Auth1 Resp: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
|
||||
receivedAnswer[0],receivedAnswer[1],receivedAnswer[2],receivedAnswer[3],receivedAnswer[4],
|
||||
receivedAnswer[5],receivedAnswer[6],receivedAnswer[7],receivedAnswer[8],receivedAnswer[9],
|
||||
receivedAnswer[10],receivedAnswer[11]);
|
||||
}
|
||||
memcpy(blockData, receivedAnswer, 12);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int mifare_desfire_des_auth2(uint32_t uid, uint8_t *key, uint8_t *blockData){
|
||||
|
||||
int len;
|
||||
uint8_t data[17] = {0x00};
|
||||
data[0] = 0xAF;
|
||||
memcpy(data+1,key,16);
|
||||
|
||||
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
|
||||
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
|
||||
|
||||
len = mifare_sendcmd_special2(NULL, 1, 0x03, data, receivedAnswer, receivedAnswerPar ,NULL);
|
||||
|
||||
if ((receivedAnswer[0] == 0x03) && (receivedAnswer[1] == 0xae)) {
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR)
|
||||
Dbprintf("Auth Error: %02x %02x", receivedAnswer[0], receivedAnswer[1]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (len == 12){
|
||||
if (MF_DBGLEVEL >= MF_DBG_EXTENDED) {
|
||||
Dbprintf("Auth2 Resp: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
|
||||
receivedAnswer[0],receivedAnswer[1],receivedAnswer[2],receivedAnswer[3],receivedAnswer[4],
|
||||
receivedAnswer[5],receivedAnswer[6],receivedAnswer[7],receivedAnswer[8],receivedAnswer[9],
|
||||
receivedAnswer[10],receivedAnswer[11]);
|
||||
}
|
||||
memcpy(blockData, receivedAnswer, 12);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
|
||||
@@ -53,31 +53,35 @@ extern int MF_DBGLEVEL;
|
||||
#define cardSTATE_TO_IDLE() cardSTATE = MFEMUL_IDLE; LED_B_OFF(); LED_C_OFF();
|
||||
|
||||
//functions
|
||||
uint8_t* mifare_get_bigbufptr(void);
|
||||
int mifare_sendcmd_short(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing);
|
||||
int mifare_sendcmd_short_special(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t *data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing);
|
||||
|
||||
int mifare_sendcmd_short_mfucauth(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t *data, uint8_t *answer, uint8_t *answer_parity, uint32_t *timing);
|
||||
int mifare_sendcmd_shortex(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing);
|
||||
|
||||
int mifare_classic_auth(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested);
|
||||
int mifare_classic_authex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested, uint32_t * ntptr, uint32_t *timing);
|
||||
int mifare_classic_readblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData);
|
||||
int mifare_ultra_auth1(uint32_t cuid, uint8_t *blockData);
|
||||
int mifare_ultra_auth2(uint32_t cuid, uint8_t *key, uint8_t *blockData);
|
||||
int mifare_ultra_readblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData);
|
||||
int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData);
|
||||
int mifare_ultra_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData);
|
||||
int mifare_ultra_special_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData);
|
||||
int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid);
|
||||
int mifare_ultra_halt(uint32_t uid);
|
||||
|
||||
// desfire
|
||||
int mifare_sendcmd_special(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t* data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing);
|
||||
int mifare_sendcmd_special2(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t* data, uint8_t* answer,uint8_t *answer_parity, uint32_t *timing);
|
||||
int mifare_desfire_des_auth1(uint32_t uid, uint8_t *blockData);
|
||||
int mifare_desfire_des_auth2(uint32_t uid, uint8_t *key, uint8_t *blockData);
|
||||
|
||||
// crypto functions
|
||||
void mf_crypto1_decrypt(struct Crypto1State *pcs, uint8_t *receivedCmd, int len);
|
||||
void mf_crypto1_encrypt(struct Crypto1State *pcs, uint8_t *data, uint16_t len, uint8_t *par);
|
||||
uint8_t mf_crypto1_encrypt4bit(struct Crypto1State *pcs, uint8_t data);
|
||||
|
||||
// memory management
|
||||
uint8_t* get_bigbufptr_recvrespbuf(void);
|
||||
uint8_t* get_bigbufptr_recvcmdbuf(void);
|
||||
uint8_t* get_bigbufptr_emlcardmem(void);
|
||||
|
||||
// Mifare memory structure
|
||||
uint8_t NumBlocksPerSector(uint8_t sectorNo);
|
||||
uint8_t FirstBlockOfSector(uint8_t sectorNo);
|
||||
|
||||
@@ -12,9 +12,8 @@
|
||||
#include "util.h"
|
||||
#include "string.h"
|
||||
#include "apps.h"
|
||||
#include "BigBuf.h"
|
||||
|
||||
uint8_t *trace = (uint8_t *) BigBuf+TRACE_OFFSET;
|
||||
int traceLen = 0;
|
||||
int tracing = TRUE;
|
||||
|
||||
|
||||
@@ -439,7 +438,9 @@ void iso14a_set_tracing(bool enable) {
|
||||
}
|
||||
|
||||
void clear_trace() {
|
||||
memset(trace, 0x44, TRACE_SIZE);
|
||||
uint8_t *trace = BigBuf_get_addr();
|
||||
uint16_t max_traceLen = BigBuf_max_traceLen();
|
||||
memset(trace, 0x44, max_traceLen);
|
||||
traceLen = 0;
|
||||
}
|
||||
|
||||
@@ -458,11 +459,15 @@ bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_
|
||||
{
|
||||
if (!tracing) return FALSE;
|
||||
|
||||
uint8_t *trace = BigBuf_get_addr();
|
||||
|
||||
uint16_t num_paritybytes = (iLen-1)/8 + 1; // number of valid paritybytes in *parity
|
||||
uint16_t duration = timestamp_end - timestamp_start;
|
||||
|
||||
// Return when trace is full
|
||||
if (traceLen + sizeof(iLen) + sizeof(timestamp_start) + sizeof(duration) + num_paritybytes + iLen >= TRACE_SIZE) {
|
||||
uint16_t max_traceLen = BigBuf_max_traceLen();
|
||||
|
||||
if (traceLen + sizeof(iLen) + sizeof(timestamp_start) + sizeof(duration) + num_paritybytes + iLen >= max_traceLen) {
|
||||
tracing = FALSE; // don't trace any more
|
||||
return FALSE;
|
||||
}
|
||||
@@ -504,7 +509,7 @@ bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_
|
||||
}
|
||||
traceLen += num_paritybytes;
|
||||
|
||||
if(traceLen +4 < TRACE_SIZE)
|
||||
if(traceLen +4 < max_traceLen)
|
||||
{ //If it hadn't been cleared, for whatever reason..
|
||||
memset(trace+traceLen,0x44, 4);
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <common.h>
|
||||
#include "common.h"
|
||||
|
||||
#define BYTEx(x, n) (((x) >> (n * 8)) & 0xff )
|
||||
|
||||
|
||||
Reference in New Issue
Block a user