Merged with master

This commit is contained in:
Martin Holst Swende 2015-01-31 18:21:38 +01:00
commit 0644d5e3a3
77 changed files with 441269 additions and 1214 deletions

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

@ -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,7 +10,7 @@ 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
@ -18,7 +18,8 @@ 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

File diff suppressed because it is too large Load Diff

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);

@ -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;
}
}
@ -802,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;
@ -859,6 +865,7 @@ void UsbPacketReceived(uint8_t *packet, int len)
case CMD_MIFARE_SNIFFER:
SniffMifare(c->arg[0]);
break;
#endif
#ifdef WITH_ICLASS
@ -882,7 +889,7 @@ void UsbPacketReceived(uint8_t *packet, int len)
break;
case CMD_BUFF_CLEAR:
BufferClear();
BigBuf_Clear();
break;
case CMD_MEASURE_ANTENNA_TUNING:
@ -906,18 +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
// We put a 1 in arg[0] to alert the host we're also sending sample_config
cmd_send(CMD_ACK,1,0,0,getSamplingConfig(),sizeof(sample_config));
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;
@ -83,7 +45,6 @@ void ToSendReset(void);
void ListenReaderField(int limit);
extern int ToSendMax;
extern uint8_t ToSend[];
extern uint32_t BigBuf[];
/// fpga.h
void FpgaSendCommand(uint16_t cmd, uint16_t v);
@ -199,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);
@ -216,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

@ -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

@ -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 */

@ -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;
}

@ -339,10 +339,10 @@ void SimulateIso14443Tag(void)
uint8_t *resp;
int respLen;
uint8_t *resp1 = (((uint8_t *)BigBuf) + 800);
uint8_t *resp1 = BigBuf_get_addr() + 800;
int resp1Len;
uint8_t *receivedCmd = (uint8_t *)BigBuf;
uint8_t *receivedCmd = BigBuf_get_addr();
int len;
int i;
@ -629,31 +629,32 @@ static void GetSamplesFor14443Demod(int weTx, int n, int quiet)
int gotFrame = FALSE;
//# define DMA_BUFFER_SIZE 8
int8_t *dmaBuf;
uint8_t *dmaBuf;
int lastRxCounter;
int8_t *upTo;
uint8_t *upTo;
int ci, cq;
int samples = 0;
// Clear out the state of the "UART" that receives from the tag.
uint8_t *BigBuf = BigBuf_get_addr();
memset(BigBuf, 0x00, 400);
Demod.output = (uint8_t *)BigBuf;
Demod.output = BigBuf;
Demod.len = 0;
Demod.state = DEMOD_UNSYNCD;
// And the UART that receives from the reader
Uart.output = (((uint8_t *)BigBuf) + 1024);
Uart.output = BigBuf + 1024;
Uart.byteCntMax = 100;
Uart.state = STATE_UNSYNCD;
// Setup for the DMA.
dmaBuf = (int8_t *)(BigBuf + 32);
dmaBuf = BigBuf + 32;
upTo = dmaBuf;
lastRxCounter = DEMOD_DMA_BUFFER_SIZE;
FpgaSetupSscDma((uint8_t *)dmaBuf, DEMOD_DMA_BUFFER_SIZE);
FpgaSetupSscDma(dmaBuf, DEMOD_DMA_BUFFER_SIZE);
// Signal field is ON with the appropriate LED:
if (weTx) LED_D_ON(); else LED_D_OFF();
@ -1012,20 +1013,21 @@ void RAMFUNC SnoopIso14443(void)
int triggered = TRUE;
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
BigBuf_free();
// The command (reader -> tag) that we're working on receiving.
uint8_t *receivedCmd = (uint8_t *)(BigBuf) + DEMOD_TRACE_SIZE;
uint8_t *receivedCmd = BigBuf_malloc(READER_TAG_BUFFER_SIZE);
// The response (tag -> reader) that we're working on receiving.
uint8_t *receivedResponse = (uint8_t *)(BigBuf) + DEMOD_TRACE_SIZE + READER_TAG_BUFFER_SIZE;
uint8_t *receivedResponse = BigBuf_malloc(TAG_READER_BUFFER_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;
int traceLen = 0;
uint8_t *trace = BigBuf_get_addr();
traceLen = 0;
// The DMA buffer, used to stream samples from the FPGA.
int8_t *dmaBuf = (int8_t *)(BigBuf) + DEMOD_TRACE_SIZE + READER_TAG_BUFFER_SIZE + TAG_READER_BUFFER_SIZE;
uint8_t *dmaBuf = BigBuf_malloc(DEMOD_DMA_BUFFER_SIZE);
int lastRxCounter;
int8_t *upTo;
uint8_t *upTo;
int ci, cq;
int maxBehindBy = 0;
@ -1034,7 +1036,7 @@ void RAMFUNC SnoopIso14443(void)
int samples = 0;
// Initialize the trace buffer
memset(trace, 0x44, DEMOD_TRACE_SIZE);
memset(trace, 0x44, BigBuf_max_traceLen());
// Set up the demodulator for tag -> reader responses.
Demod.output = receivedResponse;
@ -1049,7 +1051,7 @@ void RAMFUNC SnoopIso14443(void)
// Print some debug information about the buffer sizes
Dbprintf("Snooping buffers initialized:");
Dbprintf(" Trace: %i bytes", DEMOD_TRACE_SIZE);
Dbprintf(" Trace: %i bytes", BigBuf_max_traceLen());
Dbprintf(" Reader -> tag: %i bytes", READER_TAG_BUFFER_SIZE);
Dbprintf(" tag -> Reader: %i bytes", TAG_READER_BUFFER_SIZE);
Dbprintf(" DMA: %i bytes", DEMOD_DMA_BUFFER_SIZE);
@ -1076,7 +1078,7 @@ void RAMFUNC SnoopIso14443(void)
(DEMOD_DMA_BUFFER_SIZE-1);
if(behindBy > maxBehindBy) {
maxBehindBy = behindBy;
if(behindBy > (DEMOD_DMA_BUFFER_SIZE-2)) { // TODO: understand whether we can increase/decrease as we want or not?
if(behindBy > (9*DEMOD_DMA_BUFFER_SIZE/10)) { // TODO: understand whether we can increase/decrease as we want or not?
Dbprintf("blew circular buffer! behindBy=0x%x", behindBy);
goto done;
}
@ -1147,7 +1149,7 @@ void RAMFUNC SnoopIso14443(void)
trace[traceLen++] = Demod.len;
memcpy(trace+traceLen, receivedResponse, Demod.len);
traceLen += Demod.len;
if(traceLen > DEMOD_TRACE_SIZE) {
if(traceLen > BigBuf_max_traceLen()) {
DbpString("Reached trace limit");
goto done;
}
@ -1173,9 +1175,9 @@ done:
LED_A_OFF();
LED_B_OFF();
LED_C_OFF();
AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS;
AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS;
DbpString("Snoop statistics:");
Dbprintf(" Max behind by: %i", maxBehindBy);
Dbprintf(" Max behind by: %i", maxBehindBy);
Dbprintf(" Uart State: %x", Uart.state);
Dbprintf(" Uart ByteCnt: %i", Uart.byteCnt);
Dbprintf(" Uart ByteCntMax: %i", Uart.byteCntMax);

@ -22,9 +22,7 @@
#include "mifareutil.h"
static uint32_t iso14a_timeout;
uint8_t *trace = (uint8_t *) BigBuf+TRACE_OFFSET;
int rsamples = 0;
int traceLen = 0;
int tracing = TRUE;
uint8_t trigger = 0;
// the block number for the ISO14443-4 PCB
@ -149,7 +147,9 @@ void iso14a_set_trigger(bool enable) {
}
void iso14a_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;
}
@ -204,11 +204,13 @@ 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;
}
@ -591,9 +593,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
@ -601,22 +600,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;
@ -656,7 +658,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;
}
@ -885,7 +887,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;
@ -895,10 +897,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
@ -910,7 +908,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);
@ -931,15 +930,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;
@ -954,10 +960,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).
@ -1001,10 +1003,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);
@ -1025,12 +1028,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]);
@ -1066,9 +1069,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++) {
@ -1089,10 +1100,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;
@ -1253,6 +1260,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();
}
@ -1726,8 +1734,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;
@ -2019,9 +2027,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);
@ -2231,10 +2242,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};
@ -2251,6 +2262,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);
@ -2721,18 +2734,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;
@ -2791,7 +2806,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);
}
}

@ -93,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;
@ -246,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;
@ -294,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--) {
@ -383,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);
@ -443,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
@ -547,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);
@ -562,11 +563,10 @@ void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol)
DoAcquisition_default(-1,true);
// FSK demodulator
size = HIDdemodFSK(dest, sizeof(BigBuf), &hi2, &hi, &lo);
WDT_HIT();
if (size>0 && lo>0){
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
@ -622,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
@ -635,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
@ -649,7 +651,7 @@ void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol)
if (ledcontrol) LED_A_ON();
DoAcquisition_default(-1,true);
size = sizeof(BigBuf);
size = BigBuf_max_traceLen();
//Dbprintf("DEBUG: Buffer got");
//askdemod and manchester decode
errCnt = askmandemod(dest, &size, &clk, &invert);
@ -657,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)",
@ -669,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{
@ -687,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;
@ -702,7 +706,7 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol)
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
@ -735,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;
@ -874,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.
@ -939,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.
@ -1293,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;
@ -1713,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
@ -1723,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.

@ -124,8 +124,9 @@ void LFSetupFPGAForADC(int divisor, bool lf_field)
uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averaging, int trigger_threshold,bool silent)
{
//.
uint8_t *dest = (uint8_t *)BigBuf;
int bufsize = BIGBUF_SIZE;
uint8_t *dest = BigBuf_get_addr();
int bufsize = BigBuf_max_traceLen();
memset(dest, 0, bufsize);
if(bits_per_sample < 1) bits_per_sample = 1;

@ -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();
uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
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);
if (len != 0) {
@ -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();
uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
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);
if (len != 0) {
@ -467,22 +527,22 @@ uint8_t FirstBlockOfSector(uint8_t sectorNo)
// work with emulator memory
void emlSetMem(uint8_t *data, int blockNum, int blocksCount) {
uint8_t* emCARD = get_bigbufptr_emlcardmem();
uint8_t* emCARD = BigBuf_get_EM_addr();
memcpy(emCARD + blockNum * 16, data, blocksCount * 16);
}
void emlGetMem(uint8_t *data, int blockNum, int blocksCount) {
uint8_t* emCARD = get_bigbufptr_emlcardmem();
uint8_t* emCARD = BigBuf_get_EM_addr();
memcpy(data, emCARD + blockNum * 16, blocksCount * 16);
}
void emlGetMemBt(uint8_t *data, int bytePtr, int byteCount) {
uint8_t* emCARD = get_bigbufptr_emlcardmem();
uint8_t* emCARD = BigBuf_get_EM_addr();
memcpy(data, emCARD + bytePtr, byteCount);
}
int emlCheckValBl(int blockNum) {
uint8_t* emCARD = get_bigbufptr_emlcardmem();
uint8_t* emCARD = BigBuf_get_EM_addr();
uint8_t* data = emCARD + blockNum * 16;
if ((data[0] != (data[4] ^ 0xff)) || (data[0] != data[8]) ||
@ -497,7 +557,7 @@ int emlCheckValBl(int blockNum) {
}
int emlGetValBl(uint32_t *blReg, uint8_t *blBlock, int blockNum) {
uint8_t* emCARD = get_bigbufptr_emlcardmem();
uint8_t* emCARD = BigBuf_get_EM_addr();
uint8_t* data = emCARD + blockNum * 16;
if (emlCheckValBl(blockNum)) {
@ -510,7 +570,7 @@ int emlGetValBl(uint32_t *blReg, uint8_t *blBlock, int blockNum) {
}
int emlSetValBl(uint32_t blReg, uint8_t blBlock, int blockNum) {
uint8_t* emCARD = get_bigbufptr_emlcardmem();
uint8_t* emCARD = BigBuf_get_EM_addr();
uint8_t* data = emCARD + blockNum * 16;
memcpy(data + 0, &blReg, 4);
@ -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* emCARD = get_bigbufptr_emlcardmem();
uint8_t* emCARD = BigBuf_get_EM_addr();
memcpy(key, emCARD + 16 * (FirstBlockOfSector(sectorNum) + NumBlocksPerSector(sectorNum) - 1) + keyType * 10, 6);
return bytes_to_num(key, 6);
@ -539,7 +599,7 @@ void emlClearMem(void) {
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};
uint8_t* emCARD = get_bigbufptr_emlcardmem();
uint8_t* emCARD = BigBuf_get_EM_addr();
memset(emCARD, 0, CARD_MEMORY_SIZE);
@ -552,3 +612,98 @@ void emlClearMem(void) {
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);

@ -13,7 +13,7 @@
#include <stddef.h>
#include <stdint.h>
#include <common.h>
#include "common.h"
#define BYTEx(x, n) (((x) >> (n * 8)) & 0xff )

@ -9,15 +9,13 @@ include ../common/Makefile.common
CC=gcc
CXX=g++
#COMMON_FLAGS = -m32
VPATH = ../common
OBJDIR = obj
LDLIBS = -L/opt/local/lib -L/usr/local/lib ../liblua/liblua.a -lreadline -lpthread -lm
LDFLAGS = $(COMMON_FLAGS)
CFLAGS = -std=c99 -I. -I../include -I../common -I/opt/local/include -I../liblua -Wall $(COMMON_FLAGS) -g -O4
CFLAGS = -std=c99 -I. -I../include -I../common -I/opt/local/include -I../liblua -Wall $(COMMON_FLAGS) -g -O4
LUAPLATFORM = generic
ifneq (,$(findstring MINGW,$(platform)))
CXXFLAGS = -I$(QTDIR)/include -I$(QTDIR)/include/QtCore -I$(QTDIR)/include/QtGui
QTLDLIBS = -L$(QTDIR)/lib -lQtCore4 -lQtGui4
@ -79,6 +77,7 @@ CMDSRCS = nonce2key/crapto1.c\
cmdhflegic.c \
cmdhficlass.c \
cmdhfmf.c \
cmdhfmfu.c \
cmdhw.c \
cmdlf.c \
cmdlfio.c \

File diff suppressed because it is too large Load Diff

@ -26,9 +26,12 @@ int CmdBitstream(const char *Cmd);
int CmdBuffClear(const char *Cmd);
int CmdDec(const char *Cmd);
int CmdDetectClockRate(const char *Cmd);
int CmdFSKdemodAWID(const char *Cmd);
int CmdFSKdemod(const char *Cmd);
int CmdFSKdemodHID(const char *Cmd);
int CmdFSKdemodIO(const char *Cmd);
int CmdFSKdemodParadox(const char *Cmd);
int CmdFSKdemodPyramid(const char *Cmd);
int CmdFSKrawdemod(const char *Cmd);
int CmdDetectNRZpskClockRate(const char *Cmd);
int CmdpskNRZrawDemod(const char *Cmd);
@ -57,4 +60,6 @@ int CmdIndalaDecode(const char *Cmd);
extern uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN];
extern int DemodBufferLen;
#define BIGBUF_SIZE 40000
#endif

@ -22,6 +22,7 @@
#include "cmdhflegic.h"
#include "cmdhficlass.h"
#include "cmdhfmf.h"
#include "cmdhfmfu.h"
static int CmdHelp(const char *Cmd);
@ -31,8 +32,6 @@ int CmdHFTune(const char *Cmd)
SendCommand(&c);
return 0;
}
// for the time being. Need better Bigbuf handling.
#define TRACE_SIZE 3000
//The following data is taken from http://www.proxmark.org/forum/viewtopic.php?pid=13501#p13501
/*
@ -193,7 +192,7 @@ void annotateIso14443a(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize)
case ISO14443A_CMD_ANTICOLL_OR_SELECT:{
// 93 20 = Anticollision (usage: 9320 - answer: 4bytes UID+1byte UID-bytes-xor)
// 93 70 = Select (usage: 9370+5bytes 9320 answer - answer: 1byte SAK)
if(cmd[2] == 0x70)
if(cmd[1] == 0x70)
{
snprintf(exp,size,"SELECT_UID"); break;
}else
@ -221,8 +220,8 @@ void annotateIso14443a(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize)
case MIFARE_CMD_DEC: snprintf(exp,size,"DEC(%d)",cmd[1]); break;
case MIFARE_CMD_RESTORE: snprintf(exp,size,"RESTORE(%d)",cmd[1]); break;
case MIFARE_CMD_TRANSFER: snprintf(exp,size,"TRANSFER(%d)",cmd[1]); break;
case MIFARE_AUTH_KEYA: snprintf(exp,size,"AUTH-A"); break;
case MIFARE_AUTH_KEYB: snprintf(exp,size,"AUTH-B"); break;
case MIFARE_AUTH_KEYA: snprintf(exp,size,"AUTH-A(%d)",cmd[1]); break;
case MIFARE_AUTH_KEYB: snprintf(exp,size,"AUTH-B(%d)",cmd[1]); break;
case MIFARE_MAGICMODE: snprintf(exp,size,"MAGIC"); break;
default: snprintf(exp,size,"?"); break;
}
@ -383,18 +382,18 @@ uint8_t iclass_CRC_check(bool isResponse, uint8_t* data, uint8_t len)
}
}
uint16_t printTraceLine(uint16_t tracepos, uint8_t* trace, uint8_t protocol, bool showWaitCycles)
uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, uint8_t protocol, bool showWaitCycles)
{
bool isResponse;
uint16_t duration, data_len,parity_len;
uint16_t duration, data_len, parity_len;
uint32_t timestamp, first_timestamp, EndOfTransmissionTimestamp;
char explanation[30] = {0};
if (tracepos + sizeof(uint32_t) + sizeof(uint16_t) + sizeof(uint16_t) > traceLen) return traceLen;
first_timestamp = *((uint32_t *)(trace));
timestamp = *((uint32_t *)(trace + tracepos));
// Break and stick with current result if buffer was not completely full
if (timestamp == 0x44444444) return TRACE_SIZE;
tracepos += 4;
duration = *((uint16_t *)(trace + tracepos));
@ -410,8 +409,8 @@ uint16_t printTraceLine(uint16_t tracepos, uint8_t* trace, uint8_t protocol, boo
}
parity_len = (data_len-1)/8 + 1;
if (tracepos + data_len + parity_len >= TRACE_SIZE) {
return TRACE_SIZE;
if (tracepos + data_len + parity_len > traceLen) {
return traceLen;
}
uint8_t *frame = trace + tracepos;
@ -497,6 +496,8 @@ uint16_t printTraceLine(uint16_t tracepos, uint8_t* trace, uint8_t protocol, boo
}
}
if (tracepos + sizeof(uint32_t) + sizeof(uint16_t) + sizeof(uint16_t) > traceLen) return traceLen;
bool next_isResponse = *((uint16_t *)(trace + tracepos + 6)) & 0x8000;
if (showWaitCycles && !isResponse && next_isResponse) {
@ -509,9 +510,11 @@ uint16_t printTraceLine(uint16_t tracepos, uint8_t* trace, uint8_t protocol, boo
(next_timestamp - EndOfTransmissionTimestamp));
}
}
return tracepos;
}
int CmdHFList(const char *Cmd)
{
bool showWaitCycles = false;
@ -551,12 +554,13 @@ int CmdHFList(const char *Cmd)
if (errors) {
PrintAndLog("List protocol data in trace buffer.");
PrintAndLog("Usage: hf list [14a|14b|iclass] [f]");
PrintAndLog("Usage: hf list <protocol> [f]");
PrintAndLog(" f - show frame delay times as well");
PrintAndLog("Supported <protocol> values:");
PrintAndLog(" raw - just show raw data without annotations");
PrintAndLog(" 14a - interpret data as iso14443a communications");
PrintAndLog(" 14b - interpret data as iso14443b communications");
PrintAndLog(" iclass - interpret data as iclass communications");
PrintAndLog(" raw - just show raw data");
PrintAndLog(" f - show frame delay times as well");
PrintAndLog("");
PrintAndLog("example: hf list 14a f");
PrintAndLog("example: hf list iclass");
@ -569,12 +573,28 @@ int CmdHFList(const char *Cmd)
}
uint8_t trace[TRACE_SIZE];
uint8_t *trace;
uint16_t tracepos = 0;
GetFromBigBuf(trace, TRACE_SIZE, 0);
WaitForResponse(CMD_ACK, NULL);
trace = malloc(USB_CMD_DATA_SIZE);
PrintAndLog("Recorded Activity");
// Query for the size of the trace
UsbCommand response;
GetFromBigBuf(trace, USB_CMD_DATA_SIZE, 0);
WaitForResponse(CMD_ACK, &response);
uint16_t traceLen = response.arg[2];
if (traceLen > USB_CMD_DATA_SIZE) {
uint8_t *p = realloc(trace, traceLen);
if (p == NULL) {
PrintAndLog("Cannot allocate memory for trace");
free(trace);
return 2;
}
trace = p;
GetFromBigBuf(trace, traceLen, 0);
WaitForResponse(CMD_ACK, NULL);
}
PrintAndLog("Recorded Activity (TraceLen = %d bytes)", traceLen);
PrintAndLog("");
PrintAndLog("Start = Start of Start Bit, End = End of last modulation. Src = Source of Transfer");
PrintAndLog("iso14443a - All times are in carrier periods (1/13.56Mhz)");
@ -583,10 +603,12 @@ int CmdHFList(const char *Cmd)
PrintAndLog(" Start | End | Src | Data (! denotes parity error) | CRC | Annotation |");
PrintAndLog("-----------|-----------|-----|-----------------------------------------------------------------|-----|--------------------|");
while(tracepos < TRACE_SIZE)
while(tracepos < traceLen)
{
tracepos = printTraceLine(tracepos, trace, protocol, showWaitCycles);
tracepos = printTraceLine(tracepos, traceLen, trace, protocol, showWaitCycles);
}
free(trace);
return 0;
}
@ -601,6 +623,7 @@ static command_t CommandTable[] =
{"legic", CmdHFLegic, 0, "{ LEGIC RFIDs... }"},
{"iclass", CmdHFiClass, 1, "{ ICLASS RFIDs... }"},
{"mf", CmdHFMF, 1, "{ MIFARE RFIDs... }"},
{"mfu", CmdHFMFUltra, 1, "{ MIFARE Ultralight RFIDs... }"},
{"tune", CmdHFTune, 0, "Continuously measure HF antenna tuning"},
{"list", CmdHFList, 1, "List protocol data in trace buffer"},
{NULL, NULL, 0, NULL}

@ -412,9 +412,9 @@ int CmdHF14ASim(const char *Cmd)
PrintAndLog(" syntax: hf 14a sim <type> <uid>");
PrintAndLog(" types: 1 = MIFARE Classic");
PrintAndLog(" 2 = MIFARE Ultralight");
PrintAndLog(" 3 = MIFARE DESFIRE");
PrintAndLog(" 3 = MIFARE Desfire");
PrintAndLog(" 4 = ISO/IEC 14443-4");
PrintAndLog(" 5 = MIFARE TNP3XXX");
PrintAndLog(" 5 = MIFARE Tnp3xxx");
PrintAndLog("");
return 1;
}
@ -480,7 +480,8 @@ int CmdHF14ASim(const char *Cmd)
int CmdHF14ASnoop(const char *Cmd) {
int param = 0;
if (param_getchar(Cmd, 0) == 'h') {
uint8_t ctmp = param_getchar(Cmd, 0) ;
if (ctmp == 'h' || ctmp == 'H') {
PrintAndLog("It get data from the field and saves it into command buffer.");
PrintAndLog("Buffer accessible from command hf list 14a.");
PrintAndLog("Usage: hf 14a snoop [c][r]");
@ -491,7 +492,7 @@ int CmdHF14ASnoop(const char *Cmd) {
}
for (int i = 0; i < 2; i++) {
char ctmp = param_getchar(Cmd, i);
ctmp = param_getchar(Cmd, i);
if (ctmp == 'c' || ctmp == 'C') param |= 0x01;
if (ctmp == 'r' || ctmp == 'R') param |= 0x02;
}
@ -670,7 +671,7 @@ static command_t CommandTable[] =
{"list", CmdHF14AList, 0, "[Deprecated] List ISO 14443a history"},
{"reader", CmdHF14AReader, 0, "Act like an ISO14443 Type A reader"},
{"cuids", CmdHF14ACUIDs, 0, "<n> Collect n>0 ISO14443 Type A UIDs in one go"},
{"sim", CmdHF14ASim, 0, "<UID> -- Fake ISO 14443a tag"},
{"sim", CmdHF14ASim, 0, "<UID> -- Simulate ISO 14443a tag"},
{"snoop", CmdHF14ASnoop, 0, "Eavesdrop ISO 14443 Type A"},
{"raw", CmdHF14ACmdRaw, 0, "Send raw hex data to tag"},
{NULL, NULL, 0, NULL}

@ -145,11 +145,25 @@ demodError:
int CmdHF14BList(const char *Cmd)
{
uint8_t got[TRACE_BUFFER_SIZE];
GetFromBigBuf(got,sizeof(got),0);
WaitForResponse(CMD_ACK,NULL);
uint8_t *got = malloc(USB_CMD_DATA_SIZE);
PrintAndLog("recorded activity:");
// Query for the actual size of the trace
UsbCommand response;
GetFromBigBuf(got, USB_CMD_DATA_SIZE, 0);
WaitForResponse(CMD_ACK, &response);
uint16_t traceLen = response.arg[2];
if (traceLen > USB_CMD_DATA_SIZE) {
uint8_t *p = realloc(got, traceLen);
if (p == NULL) {
PrintAndLog("Cannot allocate memory for trace");
free(got);
return 2;
}
got = p;
GetFromBigBuf(got, traceLen, 0);
WaitForResponse(CMD_ACK,NULL);
}
PrintAndLog("recorded activity: (TraceLen = %d bytes)", traceLen);
PrintAndLog(" time :rssi: who bytes");
PrintAndLog("---------+----+----+-----------");
@ -158,7 +172,7 @@ int CmdHF14BList(const char *Cmd)
for(;;) {
if(i >= TRACE_BUFFER_SIZE) { break; }
if(i >= traceLen) { break; }
bool isResponse;
int timestamp = *((uint32_t *)(got+i));
@ -175,7 +189,7 @@ int CmdHF14BList(const char *Cmd)
if(len > 100) {
break;
}
if(i + len >= TRACE_BUFFER_SIZE) {
if(i + len >= traceLen) {
break;
}
@ -218,6 +232,7 @@ int CmdHF14BList(const char *Cmd)
prev = timestamp;
i += (len + 9);
}
free(got);
return 0;
}
@ -280,7 +295,7 @@ int CmdHF14BCmdRaw (const char *cmd) {
uint8_t power=0;
char buf[5]="";
int i=0;
uint8_t data[100];
uint8_t data[100] = {0x00};
unsigned int datalen=0, temp;
char *hexout;
@ -334,7 +349,7 @@ int CmdHF14BCmdRaw (const char *cmd) {
continue;
}
PrintAndLog("Invalid char on input");
return 0;
return 1;
}
if (datalen == 0)
{
@ -448,7 +463,7 @@ int CmdHF14BWrite( const char *Cmd){
else
PrintAndLog("[%s] Write block %02X [ %s ]", (isSrix4k)?"SRIX4K":"SRI512", blockno, sprint_hex(data,4) );
sprintf(str, "-c -p 09 %02x %02x%02x%02x%02x", blockno, data[0], data[1], data[2], data[3]);
sprintf(str, "-c 09 %02x %02x%02x%02x%02x", blockno, data[0], data[1], data[2], data[3]);
CmdHF14BCmdRaw(str);
return 0;

@ -140,117 +140,6 @@ int CmdHF14AMfWrBl(const char *Cmd)
return 0;
}
int CmdHF14AMfUWrBl(const char *Cmd)
{
uint8_t blockNo = 0;
bool chinese_card=0;
uint8_t bldata[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
UsbCommand resp;
if (strlen(Cmd)<3) {
PrintAndLog("Usage: hf mf uwrbl <block number> <block data (8 hex symbols)> <w>");
PrintAndLog(" sample: hf mf uwrbl 0 01020304");
return 0;
}
blockNo = param_get8(Cmd, 0);
if (param_gethex(Cmd, 1, bldata, 8)) {
PrintAndLog("Block data must include 8 HEX symbols");
return 1;
}
if (strchr(Cmd,'w') != 0) {
chinese_card=1;
}
switch(blockNo){
case 0:
if (!chinese_card){
PrintAndLog("Access Denied");
}else{
PrintAndLog("--specialblock no:%d", blockNo);
PrintAndLog("--data: %s", sprint_hex(bldata, 4));
UsbCommand d = {CMD_MIFAREU_WRITEBL, {blockNo}};
memcpy(d.d.asBytes,bldata, 4);
SendCommand(&d);
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
uint8_t isOK = resp.arg[0] & 0xff;
PrintAndLog("isOk:%02x", isOK);
} else {
PrintAndLog("Command execute timeout");
}
}
break;
case 1:
if (!chinese_card){
PrintAndLog("Access Denied");
}else{
PrintAndLog("--specialblock no:%d", blockNo);
PrintAndLog("--data: %s", sprint_hex(bldata, 4));
UsbCommand d = {CMD_MIFAREU_WRITEBL, {blockNo}};
memcpy(d.d.asBytes,bldata, 4);
SendCommand(&d);
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
uint8_t isOK = resp.arg[0] & 0xff;
PrintAndLog("isOk:%02x", isOK);
} else {
PrintAndLog("Command execute timeout");
}
}
break;
case 2:
if (!chinese_card){
PrintAndLog("Access Denied");
}else{
PrintAndLog("--specialblock no:%d", blockNo);
PrintAndLog("--data: %s", sprint_hex(bldata, 4));
UsbCommand c = {CMD_MIFAREU_WRITEBL, {blockNo}};
memcpy(c.d.asBytes, bldata, 4);
SendCommand(&c);
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
uint8_t isOK = resp.arg[0] & 0xff;
PrintAndLog("isOk:%02x", isOK);
} else {
PrintAndLog("Command execute timeout");
}
}
break;
case 3:
PrintAndLog("--specialblock no:%d", blockNo);
PrintAndLog("--data: %s", sprint_hex(bldata, 4));
UsbCommand d = {CMD_MIFAREU_WRITEBL, {blockNo}};
memcpy(d.d.asBytes,bldata, 4);
SendCommand(&d);
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
uint8_t isOK = resp.arg[0] & 0xff;
PrintAndLog("isOk:%02x", isOK);
} else {
PrintAndLog("Command execute timeout");
}
break;
default:
PrintAndLog("--block no:%d", blockNo);
PrintAndLog("--data: %s", sprint_hex(bldata, 4));
UsbCommand e = {CMD_MIFAREU_WRITEBL, {blockNo}};
memcpy(e.d.asBytes,bldata, 4);
SendCommand(&e);
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
uint8_t isOK = resp.arg[0] & 0xff;
PrintAndLog("isOk:%02x", isOK);
} else {
PrintAndLog("Command execute timeout");
}
break;
}
return 0;
}
int CmdHF14AMfRdBl(const char *Cmd)
{
uint8_t blockNo = 0;
@ -299,87 +188,6 @@ int CmdHF14AMfRdBl(const char *Cmd)
return 0;
}
int CmdHF14AMfURdBl(const char *Cmd)
{
uint8_t blockNo = 0;
if (strlen(Cmd)<1) {
PrintAndLog("Usage: hf mf urdbl <block number>");
PrintAndLog(" sample: hf mf urdbl 0");
return 0;
}
blockNo = param_get8(Cmd, 0);
PrintAndLog("--block no:%d", blockNo);
UsbCommand c = {CMD_MIFAREU_READBL, {blockNo}};
SendCommand(&c);
UsbCommand resp;
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
uint8_t isOK = resp.arg[0] & 0xff;
uint8_t *data = resp.d.asBytes;
if (isOK)
PrintAndLog("isOk:%02x data:%s", isOK, sprint_hex(data, 4));
else
PrintAndLog("isOk:%02x", isOK);
} else {
PrintAndLog("Command execute timeout");
}
return 0;
}
int CmdHF14AMfURdCard(const char *Cmd)
{
int i;
uint8_t sectorNo = 0;
uint8_t *lockbytes_t=NULL;
uint8_t lockbytes[2]={0,0};
bool bit[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
uint8_t isOK = 0;
uint8_t * data = NULL;
PrintAndLog("Attempting to Read Ultralight... ");
UsbCommand c = {CMD_MIFAREU_READCARD, {sectorNo}};
SendCommand(&c);
UsbCommand resp;
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
isOK = resp.arg[0] & 0xff;
data = resp.d.asBytes;
PrintAndLog("isOk:%02x", isOK);
if (isOK)
{ // bit 0 and 1
PrintAndLog("Block %3d:%s ", 0,sprint_hex(data + 0 * 4, 4));
PrintAndLog("Block %3d:%s ", 1,sprint_hex(data + 1 * 4, 4));
// bit 2
//process lock bytes
lockbytes_t=data+(2*4);
lockbytes[0]=lockbytes_t[2];
lockbytes[1]=lockbytes_t[3];
for(int j=0; j<16; j++){
bit[j]=lockbytes[j/8] & ( 1 <<(7-j%8));
}
//remaining
for (i = 3; i < 16; i++) {
int bitnum = (23-i) % 16;
PrintAndLog("Block %3d:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[bitnum]);
}
}
} else {
PrintAndLog("Command execute timeout");
}
return 0;
}
int CmdHF14AMfRdSc(const char *Cmd)
{
int i;
@ -970,12 +778,14 @@ int CmdHF14AMfNested(const char *Cmd)
int CmdHF14AMfChk(const char *Cmd)
{
if (strlen(Cmd)<3) {
PrintAndLog("Usage: hf mf chk <block number>|<*card memory> <key type (A/B/?)> [t] [<key (12 hex symbols)>] [<dic (*.dic)>]");
PrintAndLog("Usage: hf mf chk <block number>|<*card memory> <key type (A/B/?)> [t|d] [<key (12 hex symbols)>] [<dic (*.dic)>]");
PrintAndLog(" * - all sectors");
PrintAndLog("card memory - 0 - MINI(320 bytes), 1 - 1K, 2 - 2K, 4 - 4K, <other> - 1K");
PrintAndLog("d - write keys to binary file\n");
PrintAndLog("t - write keys to emulator memory");
PrintAndLog(" sample: hf mf chk 0 A 1234567890ab keys.dic");
PrintAndLog(" hf mf chk *1 ? t");
PrintAndLog(" hf mf chk *1 ? d");
return 0;
}
@ -1202,12 +1012,16 @@ int CmdHF14AMf1kSim(const char *Cmd)
uint8_t exitAfterNReads = 0;
uint8_t flags = 0;
if (param_getchar(Cmd, 0) == 'h') {
uint8_t cmdp = param_getchar(Cmd, 0);
if (cmdp == 'h' || cmdp == 'H') {
PrintAndLog("Usage: hf mf sim u <uid (8 hex symbols)> n <numreads> i x");
PrintAndLog(" h this help");
PrintAndLog(" u (Optional) UID. If not specified, the UID from emulator memory will be used");
PrintAndLog(" n (Optional) Automatically exit simulation after <numreads> blocks have been read by reader. 0 = infinite");
PrintAndLog(" i (Optional) Interactive, means that console will not be returned until simulation finishes or is aborted");
PrintAndLog(" x (Optional) Crack, performs the 'reader attack', nr/ar attack against a legitimate reader, fishes out the key(s)");
PrintAndLog("");
PrintAndLog(" sample: hf mf sim u 0a0a0a0a ");
return 0;
}
@ -1288,7 +1102,7 @@ int CmdHF14AMfDbg(const char *Cmd)
int CmdHF14AMfEGet(const char *Cmd)
{
uint8_t blockNo = 0;
uint8_t data[16];
uint8_t data[16] = {0x00};
if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') {
PrintAndLog("Usage: hf mf eget <block number>");
@ -1355,14 +1169,11 @@ int CmdHF14AMfELoad(const char *Cmd)
FILE * f;
char filename[FILE_PATH_SIZE];
char *fnameptr = filename;
char buf[64];
uint8_t buf8[64];
char buf[64] = {0x00};
uint8_t buf8[64] = {0x00};
int i, len, blockNum, numBlocks;
int nameParamNo = 1;
memset(filename, 0, sizeof(filename));
memset(buf, 0, sizeof(buf));
char ctmp = param_getchar(Cmd, 0);
if ( ctmp == 'h' || ctmp == 0x00) {
@ -1432,11 +1243,13 @@ int CmdHF14AMfELoad(const char *Cmd)
fclose(f);
return 3;
}
printf(".");
blockNum++;
if (blockNum >= numBlocks) break;
}
fclose(f);
printf("\n");
if ((blockNum != numBlocks)) {
PrintAndLog("File content error. Got %d must be %d blocks.",blockNum, numBlocks);
@ -1638,7 +1451,7 @@ int CmdHF14AMfCSetUID(const char *Cmd)
char ctmp = param_getchar(Cmd, 1);
if (ctmp == 'w' || ctmp == 'W') wipeCard = 1;
PrintAndLog("--wipe card:%02x uid:%s", wipeCard, sprint_hex(uid, 4));
PrintAndLog("--wipe card:%s uid:%s", (wipeCard)?"YES":"NO", sprint_hex(uid, 4));
res = mfCSetUID(uid, oldUid, wipeCard);
if (res) {
@ -1653,11 +1466,10 @@ int CmdHF14AMfCSetUID(const char *Cmd)
int CmdHF14AMfCSetBlk(const char *Cmd)
{
uint8_t uid[8];
uint8_t memBlock[16];
uint8_t uid[8] = {0x00};
uint8_t memBlock[16] = {0x00};
uint8_t blockNo = 0;
int res;
memset(memBlock, 0x00, sizeof(memBlock));
if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') {
PrintAndLog("Usage: hf mf csetblk <block number> <block data (32 hex symbols)>");
@ -1682,7 +1494,6 @@ int CmdHF14AMfCSetBlk(const char *Cmd)
return 1;
}
PrintAndLog("UID:%s", sprint_hex(uid, 4));
return 0;
}
@ -1697,11 +1508,8 @@ int CmdHF14AMfCLoad(const char *Cmd)
uint8_t fillFromEmulator = 0;
int i, len, blockNum, flags;
// memset(filename, 0, sizeof(filename));
// memset(buf, 0, sizeof(buf));
if (param_getchar(Cmd, 0) == 'h' || param_getchar(Cmd, 0)== 0x00) {
PrintAndLog("It loads magic Chinese card (only works with!!!) from the file `filename.eml`");
PrintAndLog("It loads magic Chinese card from the file `filename.eml`");
PrintAndLog("or from emulator memory (option `e`)");
PrintAndLog("Usage: hf mf cload <file name w/o `.eml`>");
PrintAndLog(" or: hf mf cload e ");
@ -1748,7 +1556,9 @@ int CmdHF14AMfCLoad(const char *Cmd)
blockNum = 0;
flags = CSETBLOCK_INIT_FIELD + CSETBLOCK_WUPC;
while(!feof(f)){
memset(buf, 0, sizeof(buf));
if (fgets(buf, sizeof(buf), f) == NULL) {
PrintAndLog("File reading error.");
return 2;
@ -1783,6 +1593,7 @@ int CmdHF14AMfCLoad(const char *Cmd)
PrintAndLog("Loaded from file: %s", filename);
return 0;
}
return 0;
}
int CmdHF14AMfCGetBlk(const char *Cmd) {
@ -1814,10 +1625,9 @@ int CmdHF14AMfCGetBlk(const char *Cmd) {
int CmdHF14AMfCGetSc(const char *Cmd) {
uint8_t memBlock[16];
uint8_t memBlock[16] = {0x00};
uint8_t sectorNo = 0;
int i, res, flags;
memset(memBlock, 0x00, sizeof(memBlock));
if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') {
PrintAndLog("Usage: hf mf cgetsc <sector number>");
@ -1955,18 +1765,19 @@ int CmdHF14AMfSniff(const char *Cmd){
int res = 0;
int len = 0;
int blockLen = 0;
int num = 0;
int pckNum = 0;
int num = 0;
uint8_t uid[7];
uint8_t uid_len;
uint8_t atqa[2];
uint8_t atqa[2] = {0x00};
uint8_t sak;
bool isTag;
uint8_t buf[3000];
uint8_t * bufPtr = buf;
memset(buf, 0x00, 3000);
uint8_t *buf = NULL;
uint16_t bufsize = 0;
uint8_t *bufPtr = NULL;
if (param_getchar(Cmd, 0) == 'h') {
char ctmp = param_getchar(Cmd, 0);
if ( ctmp == 'h' || ctmp == 'H' ) {
PrintAndLog("It continuously gets data from the field and saves it to: log, emulator, emulator file.");
PrintAndLog("You can specify:");
PrintAndLog(" l - save encrypted sequence to logfile `uid.log`");
@ -1979,7 +1790,7 @@ int CmdHF14AMfSniff(const char *Cmd){
}
for (int i = 0; i < 4; i++) {
char ctmp = param_getchar(Cmd, i);
ctmp = param_getchar(Cmd, i);
if (ctmp == 'l' || ctmp == 'L') wantLogToFile = true;
if (ctmp == 'd' || ctmp == 'D') wantDecrypt = true;
//if (ctmp == 'e' || ctmp == 'E') wantSaveToEml = true; TODO
@ -2006,32 +1817,47 @@ int CmdHF14AMfSniff(const char *Cmd){
break;
}
UsbCommand resp;
if (WaitForResponseTimeout(CMD_ACK,&resp,2000)) {
UsbCommand resp;
if (WaitForResponseTimeout(CMD_ACK,&resp,2000)) {
res = resp.arg[0] & 0xff;
len = resp.arg[1];
num = resp.arg[2];
if (res == 0) return 0;
if (res == 1) {
if (num ==0) {
uint16_t traceLen = resp.arg[1];
len = resp.arg[2];
if (res == 0) return 0; // we are done
if (res == 1) { // there is (more) data to be transferred
if (pckNum == 0) { // first packet, (re)allocate necessary buffer
if (traceLen > bufsize) {
uint8_t *p;
if (buf == NULL) { // not yet allocated
p = malloc(traceLen);
} else { // need more memory
p = realloc(buf, traceLen);
}
if (p == NULL) {
PrintAndLog("Cannot allocate memory for trace");
free(buf);
return 2;
}
buf = p;
}
bufPtr = buf;
memset(buf, 0x00, 3000);
bufsize = traceLen;
memset(buf, 0x00, traceLen);
}
memcpy(bufPtr, resp.d.asBytes, len);
bufPtr += len;
pckNum++;
}
if (res == 2) {
if (res == 2) { // received all data, start displaying
blockLen = bufPtr - buf;
bufPtr = buf;
printf(">\n");
PrintAndLog("received trace len: %d packages: %d", blockLen, pckNum);
num = 0;
while (bufPtr - buf < blockLen) {
bufPtr += 6;
bufPtr += 6; // skip (void) timing information
len = *((uint16_t *)bufPtr);
if(len & 0x8000) {
isTag = true;
len &= 0x7fff;
@ -2040,12 +1866,10 @@ int CmdHF14AMfSniff(const char *Cmd){
}
bufPtr += 2;
if ((len == 14) && (bufPtr[0] == 0xff) && (bufPtr[1] == 0xff) && (bufPtr[12] == 0xff) && (bufPtr[13] == 0xff)) {
memcpy(uid, bufPtr + 2, 7);
memcpy(atqa, bufPtr + 2 + 7, 2);
uid_len = (atqa[0] & 0xC0) == 0x40 ? 7 : 4;
sak = bufPtr[11];
PrintAndLog("tag select uid:%s atqa:0x%02x%02x sak:0x%02x",
sprint_hex(uid + (7 - uid_len), uid_len),
atqa[1],
@ -2063,26 +1887,26 @@ int CmdHF14AMfSniff(const char *Cmd){
AddLogHex(logHexFileName, isTag ? "TAG: ":"RDR: ", bufPtr, len);
if (wantDecrypt)
mfTraceDecode(bufPtr, len, wantSaveToEmlFile);
num++;
}
bufPtr += len;
bufPtr += ((len-1)/8+1); // ignore parity
num++;
}
pckNum = 0;
}
} // resp not NULL
} // while (true)
free(buf);
return 0;
}
static command_t CommandTable[] =
{
{"help", CmdHelp, 1, "This help"},
{"dbg", CmdHF14AMfDbg, 0, "Set default debug mode"},
{"rdbl", CmdHF14AMfRdBl, 0, "Read MIFARE classic block"},
{"urdbl", CmdHF14AMfURdBl, 0, "Read MIFARE Ultralight block"},
{"urdcard", CmdHF14AMfURdCard, 0,"Read MIFARE Ultralight Card"},
{"uwrbl", CmdHF14AMfUWrBl, 0,"Write MIFARE Ultralight block"},
{"rdsc", CmdHF14AMfRdSc, 0, "Read MIFARE classic sector"},
{"dump", CmdHF14AMfDump, 0, "Dump MIFARE classic tag to binary file"},
{"restore", CmdHF14AMfRestore, 0, "Restore MIFARE classic binary file to BLANK tag"},

741
client/cmdhfmfu.c Normal file

@ -0,0 +1,741 @@
//-----------------------------------------------------------------------------
// Ultralight Code (c) 2013,2014 Midnitesnake & Andy Davies of Pentura
//
// 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.
//-----------------------------------------------------------------------------
// High frequency MIFARE ULTRALIGHT (C) commands
//-----------------------------------------------------------------------------
//#include <openssl/des.h>
#include "loclass/des.h"
#include "cmdhfmfu.h"
#include "cmdhfmf.h"
#include "cmdhf14a.h"
#define MAX_ULTRA_BLOCKS 0x0f
#define MAX_ULTRAC_BLOCKS 0x2f
//#define MAX_ULTRAC_BLOCKS 0x2c
static int CmdHelp(const char *Cmd);
int CmdHF14AMfUInfo(const char *Cmd){
uint8_t datatemp[7] = {0x00};
uint8_t isOK = 0;
uint8_t *data = NULL;
UsbCommand c = {CMD_MIFAREU_READCARD, {0, 4}};
SendCommand(&c);
UsbCommand resp;
if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
isOK = resp.arg[0] & 0xff;
data = resp.d.asBytes;
if (!isOK) {
PrintAndLog("Error reading from tag");
return -1;
}
} else {
PrintAndLog("Command execute timed out");
return -1;
}
PrintAndLog("");
PrintAndLog("-- Mifare Ultralight / Ultralight-C Tag Information ---------");
PrintAndLog("-------------------------------------------------------------");
// UID
memcpy( datatemp, data, 3);
memcpy( datatemp+3, data+4, 4);
PrintAndLog("MANUFACTURER : %s", getTagInfo(datatemp[0]));
PrintAndLog(" UID : %s ", sprint_hex(datatemp, 7));
// BBC
// CT (cascade tag byte) 0x88 xor SN0 xor SN1 xor SN2
int crc0 = 0x88 ^ data[0] ^ data[1] ^data[2];
if ( data[3] == crc0 )
PrintAndLog(" BCC0 : %02x - Ok", data[3]);
else
PrintAndLog(" BCC0 : %02x - crc should be %02x", data[3], crc0);
int crc1 = data[4] ^ data[5] ^ data[6] ^data[7];
if ( data[8] == crc1 )
PrintAndLog(" BCC1 : %02x - Ok", data[8]);
else
PrintAndLog(" BCC1 : %02x - crc should be %02x", data[8], crc1 );
PrintAndLog(" Internal : %s ", sprint_hex(data + 9, 1));
memcpy(datatemp, data+10, 2);
PrintAndLog(" Lock : %s - %s", sprint_hex(datatemp, 2),printBits( 2, &datatemp) );
PrintAndLog(" OneTimePad : %s ", sprint_hex(data + 3*4, 4));
PrintAndLog("");
int len = CmdHF14AMfucAuth("K 0");
// PrintAndLog("CODE: %d",len);
PrintAndLog("Seems to be a Ultralight %s", (len==0) ? "-C" :"");
return 0;
}
//
// Mifare Ultralight Write Single Block
//
int CmdHF14AMfUWrBl(const char *Cmd){
uint8_t blockNo = -1;
bool chinese_card = FALSE;
uint8_t bldata[16] = {0x00};
UsbCommand resp;
char cmdp = param_getchar(Cmd, 0);
if (strlen(Cmd) < 3 || cmdp == 'h' || cmdp == 'H') {
PrintAndLog("Usage: hf mfu wrbl <block number> <block data (8 hex symbols)> [w]");
PrintAndLog(" [block number]");
PrintAndLog(" [block data] - (8 hex symbols)");
PrintAndLog(" [w] - Chinese magic ultralight tag");
PrintAndLog("");
PrintAndLog(" sample: hf mfu wrbl 0 01020304");
PrintAndLog("");
return 0;
}
blockNo = param_get8(Cmd, 0);
if (blockNo > MAX_ULTRA_BLOCKS){
PrintAndLog("Error: Maximum number of blocks is 15 for Ultralight Cards!");
return 1;
}
if (param_gethex(Cmd, 1, bldata, 8)) {
PrintAndLog("Block data must include 8 HEX symbols");
return 1;
}
if (strchr(Cmd,'w') != 0 || strchr(Cmd,'W') != 0 ) {
chinese_card = TRUE;
}
if ( blockNo <= 3) {
if (!chinese_card){
PrintAndLog("Access Denied");
} else {
PrintAndLog("--specialblock no:%02x", blockNo);
PrintAndLog("--data: %s", sprint_hex(bldata, 4));
UsbCommand d = {CMD_MIFAREU_WRITEBL, {blockNo}};
memcpy(d.d.asBytes,bldata, 4);
SendCommand(&d);
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
uint8_t isOK = resp.arg[0] & 0xff;
PrintAndLog("isOk:%02x", isOK);
} else {
PrintAndLog("Command execute timeout");
}
}
} else {
PrintAndLog("--block no:%02x", blockNo);
PrintAndLog("--data: %s", sprint_hex(bldata, 4));
UsbCommand e = {CMD_MIFAREU_WRITEBL, {blockNo}};
memcpy(e.d.asBytes,bldata, 4);
SendCommand(&e);
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
uint8_t isOK = resp.arg[0] & 0xff;
PrintAndLog("isOk:%02x", isOK);
} else {
PrintAndLog("Command execute timeout");
}
}
return 0;
}
//
// Mifare Ultralight Read Single Block
//
int CmdHF14AMfURdBl(const char *Cmd){
uint8_t blockNo = -1;
char cmdp = param_getchar(Cmd, 0);
if (strlen(Cmd) < 1 || cmdp == 'h' || cmdp == 'H') {
PrintAndLog("Usage: hf mfu rdbl <block number>");
PrintAndLog(" sample: hfu mfu rdbl 0");
return 0;
}
blockNo = param_get8(Cmd, 0);
if (blockNo > MAX_ULTRA_BLOCKS){
PrintAndLog("Error: Maximum number of blocks is 15 for Ultralight Cards!");
return 1;
}
PrintAndLog("--block no:0x%02X (%d)", (int)blockNo, blockNo);
UsbCommand c = {CMD_MIFAREU_READBL, {blockNo}};
SendCommand(&c);
UsbCommand resp;
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
uint8_t isOK = resp.arg[0] & 0xff;
uint8_t * data = resp.d.asBytes;
PrintAndLog("isOk: %02x", isOK);
if (isOK)
PrintAndLog("Data: %s", sprint_hex(data, 4));
} else {
PrintAndLog("Command execute timeout");
}
return 0;
}
//
// Mifare Ultralight / Ultralight-C; Read and Dump Card Contents
//
int CmdHF14AMfUDump(const char *Cmd){
FILE *fout;
char filename[FILE_PATH_SIZE] = {0x00};
char * fnameptr = filename;
uint8_t *lockbytes_t = NULL;
uint8_t lockbytes[2] = {0x00};
uint8_t *lockbytes_t2 = NULL;
uint8_t lockbytes2[2] = {0x00};
bool bit[16] = {0x00};
bool bit2[16] = {0x00};
int i;
uint8_t BlockNo = 0;
int Pages = 16;
bool tmplockbit = false;
uint8_t isOK = 0;
uint8_t *data = NULL;
char cmdp = param_getchar(Cmd, 0);
if (cmdp == 'h' || cmdp == 'H') {
PrintAndLog("Reads all pages from Mifare Ultralight or Ultralight-C tag.");
PrintAndLog("It saves binary dump into the file `filename.bin` or `cardUID.bin`");
PrintAndLog("Usage: hf mfu dump <c> <filename w/o .bin>");
PrintAndLog(" <c> optional cardtype c == Ultralight-C, if not defaults to Ultralight");
PrintAndLog(" sample: hf mfu dump");
PrintAndLog(" : hf mfu dump myfile");
PrintAndLog(" : hf mfu dump c myfile");
return 0;
}
// UL or UL-C?
Pages = (cmdp == 'c' || cmdp == 'C') ? 44 : 16;
PrintAndLog("Dumping Ultralight%s Card Data...", (Pages ==16)?"":"-C");
UsbCommand c = {CMD_MIFAREU_READCARD, {BlockNo,Pages}};
SendCommand(&c);
UsbCommand resp;
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
isOK = resp.arg[0] & 0xff;
if (!isOK) {
PrintAndLog("Command error");
return 0;
}
data = resp.d.asBytes;
} else {
PrintAndLog("Command execute timeout");
return 0;
}
// Load lock bytes.
int j = 0;
lockbytes_t = data + 8;
lockbytes[0] = lockbytes_t[2];
lockbytes[1] = lockbytes_t[3];
for(j = 0; j < 16; j++){
bit[j] = lockbytes[j/8] & ( 1 <<(7-j%8));
}
// Load bottom lockbytes if available
if ( Pages == 44 ) {
lockbytes_t2 = data + (40*4);
lockbytes2[0] = lockbytes_t2[2];
lockbytes2[1] = lockbytes_t2[3];
for (j = 0; j < 16; j++) {
bit2[j] = lockbytes2[j/8] & ( 1 <<(7-j%8));
}
}
for (i = 0; i < Pages; ++i) {
if ( i < 3 ) {
PrintAndLog("Block %02x:%s ", i,sprint_hex(data + i * 4, 4));
continue;
}
switch(i){
case 3: tmplockbit = bit[4]; break;
case 4: tmplockbit = bit[3]; break;
case 5: tmplockbit = bit[2]; break;
case 6: tmplockbit = bit[1]; break;
case 7: tmplockbit = bit[0]; break;
case 8: tmplockbit = bit[15]; break;
case 9: tmplockbit = bit[14]; break;
case 10: tmplockbit = bit[13]; break;
case 11: tmplockbit = bit[12]; break;
case 12: tmplockbit = bit[11]; break;
case 13: tmplockbit = bit[10]; break;
case 14: tmplockbit = bit[9]; break;
case 15: tmplockbit = bit[8]; break;
case 16:
case 17:
case 18:
case 19: tmplockbit = bit2[6]; break;
case 20:
case 21:
case 22:
case 23: tmplockbit = bit2[5]; break;
case 24:
case 25:
case 26:
case 27: tmplockbit = bit2[4]; break;
case 28:
case 29:
case 30:
case 31: tmplockbit = bit2[2]; break;
case 32:
case 33:
case 34:
case 35: tmplockbit = bit2[1]; break;
case 36:
case 37:
case 38:
case 39: tmplockbit = bit2[0]; break;
case 40: tmplockbit = bit2[12]; break;
case 41: tmplockbit = bit2[11]; break;
case 42: tmplockbit = bit2[10]; break; //auth0
case 43: tmplockbit = bit2[9]; break; //auth1
default: break;
}
PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),tmplockbit);
}
int len = 0;
if ( Pages == 16 )
len = param_getstr(Cmd,0,filename);
else
len = param_getstr(Cmd,1,filename);
if (len > FILE_PATH_SIZE-5) len = FILE_PATH_SIZE-5;
// user supplied filename?
if (len < 1) {
// UID = data 0-1-2 4-5-6-7 (skips a beat)
sprintf(fnameptr,"%02X%02X%02X%02X%02X%02X%02X.bin",
data[0],data[1], data[2], data[4],data[5],data[6], data[7]);
} else {
sprintf(fnameptr + len," .bin");
}
if ((fout = fopen(filename,"wb")) == NULL) {
PrintAndLog("Could not create file name %s", filename);
return 1;
}
fwrite( data, 1, Pages*4, fout );
fclose(fout);
PrintAndLog("Dumped %d pages, wrote %d bytes to %s", Pages, Pages*4, filename);
return 0;
}
// Needed to Authenticate to Ultralight C tags
void rol (uint8_t *data, const size_t len){
uint8_t first = data[0];
for (size_t i = 0; i < len-1; i++) {
data[i] = data[i+1];
}
data[len-1] = first;
}
//-------------------------------------------------------------------------------
// Ultralight C Methods
//-------------------------------------------------------------------------------
//
// Ultralight C Authentication Demo {currently uses hard-coded key}
//
int CmdHF14AMfucAuth(const char *Cmd){
uint8_t default_keys[5][16] = {
{ 0x42,0x52,0x45,0x41,0x4b,0x4d,0x45,0x49,0x46,0x59,0x4f,0x55,0x43,0x41,0x4e,0x21 },// 3des std key
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },// all zeroes
{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f },// 0x00-0x0F
{ 0x49,0x45,0x4D,0x4B,0x41,0x45,0x52,0x42,0x21,0x4E,0x41,0x43,0x55,0x4F,0x59,0x46 },// NFC-key
{ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01 } // all ones
};
char cmdp = param_getchar(Cmd, 0);
uint8_t keyNo = 0;
bool errors = false;
//Change key to user defined one
if (cmdp == 'k' || cmdp == 'K'){
keyNo = param_get8(Cmd, 1);
if(keyNo >= 4) errors = true;
}
if (cmdp == 'h' || cmdp == 'H') {
errors = true;
}
if (errors) {
PrintAndLog("Usage: hf mfu cauth k <key number>");
PrintAndLog(" 0 (default): 3DES standard key");
PrintAndLog(" 1 : all zeros key");
PrintAndLog(" 2 : 0x00-0x0F key");
PrintAndLog(" 3 : nfc key");
PrintAndLog(" 4 : all ones key");
PrintAndLog(" sample : hf mfu cauth k");
PrintAndLog(" : hf mfu cauth k 3");
return 0;
}
uint8_t random_a[8] = { 1,1,1,1,1,1,1,1 };
//uint8_t enc_random_a[8] = { 0 };
uint8_t random_b[8] = { 0 };
uint8_t enc_random_b[8] = { 0 };
uint8_t random_a_and_b[16] = { 0 };
des3_context ctx = { 0 };
uint8_t *key = default_keys[keyNo];
uint8_t blockNo = 0;
uint32_t cuid = 0;
//Auth1
UsbCommand c = {CMD_MIFAREUC_AUTH1, {blockNo}};
SendCommand(&c);
UsbCommand resp;
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
uint8_t isOK = resp.arg[0] & 0xff;
cuid = resp.arg[1];
uint8_t * data= resp.d.asBytes;
if (isOK){
PrintAndLog("enc(RndB):%s", sprint_hex(data+1, 8));
memcpy(enc_random_b,data+1,8);
} else {
PrintAndLog("Auth failed");
return 2; // auth failed.
}
} else {
PrintAndLog("Command execute timeout");
return 1;
}
uint8_t iv[8] = { 0 };
// Do we need random ? Right now we use all ones, is that random enough ?
// DES_random_key(&RndA);
PrintAndLog(" RndA :%s",sprint_hex(random_a, 8));
PrintAndLog(" e_RndB:%s",sprint_hex(enc_random_b, 8));
des3_set2key_dec(&ctx, key);
des3_crypt_cbc(&ctx // des3_context *ctx
, DES_DECRYPT // int mode
, sizeof(random_b) // size_t length
, iv // unsigned char iv[8]
, enc_random_b // const unsigned char *input
, random_b // unsigned char *output
);
PrintAndLog(" RndB:%s",sprint_hex(random_b, 8));
rol(random_b,8);
memcpy(random_a_and_b ,random_a,8);
memcpy(random_a_and_b+8,random_b,8);
PrintAndLog(" RA+B:%s",sprint_hex(random_a_and_b, 16));
des3_set2key_enc(&ctx, key);
des3_crypt_cbc(&ctx // des3_context *ctx
, DES_ENCRYPT // int mode
, sizeof(random_a_and_b) // size_t length
, enc_random_b // unsigned char iv[8]
, random_a_and_b // const unsigned char *input
, random_a_and_b // unsigned char *output
);
PrintAndLog("enc(RA+B):%s",sprint_hex(random_a_and_b, 16));
//Auth2
UsbCommand d = {CMD_MIFAREUC_AUTH2, {cuid}};
memcpy(d.d.asBytes,random_a_and_b, 16);
SendCommand(&d);
UsbCommand respb;
if (WaitForResponseTimeout(CMD_ACK,&respb,1500)) {
uint8_t isOK = respb.arg[0] & 0xff;
uint8_t * data2= respb.d.asBytes;
if (isOK){
PrintAndLog("enc(RndA'):%s", sprint_hex(data2+1, 8));
} else {
return 2;
}
} else {
PrintAndLog("Command execute timeout");
return 1;
}
return 0;
}
/**
A test function to validate that the polarssl-function works the same
was as the openssl-implementation.
Commented out, since it requires openssl
int CmdTestDES(const char * cmd)
{
uint8_t key[16] = {0x00};
memcpy(key,key3_3des_data,16);
DES_cblock RndA, RndB;
PrintAndLog("----------OpenSSL DES implementation----------");
{
uint8_t e_RndB[8] = {0x00};
unsigned char RndARndB[16] = {0x00};
DES_cblock iv = { 0 };
DES_key_schedule ks1,ks2;
DES_cblock key1,key2;
memcpy(key,key3_3des_data,16);
memcpy(key1,key,8);
memcpy(key2,key+8,8);
DES_set_key((DES_cblock *)key1,&ks1);
DES_set_key((DES_cblock *)key2,&ks2);
DES_random_key(&RndA);
PrintAndLog(" RndA:%s",sprint_hex(RndA, 8));
PrintAndLog(" e_RndB:%s",sprint_hex(e_RndB, 8));
//void DES_ede2_cbc_encrypt(const unsigned char *input,
// unsigned char *output, long length, DES_key_schedule *ks1,
// DES_key_schedule *ks2, DES_cblock *ivec, int enc);
DES_ede2_cbc_encrypt(e_RndB,RndB,sizeof(e_RndB),&ks1,&ks2,&iv,0);
PrintAndLog(" RndB:%s",sprint_hex(RndB, 8));
rol(RndB,8);
memcpy(RndARndB,RndA,8);
memcpy(RndARndB+8,RndB,8);
PrintAndLog(" RA+B:%s",sprint_hex(RndARndB, 16));
DES_ede2_cbc_encrypt(RndARndB,RndARndB,sizeof(RndARndB),&ks1,&ks2,&e_RndB,1);
PrintAndLog("enc(RA+B):%s",sprint_hex(RndARndB, 16));
}
PrintAndLog("----------PolarSSL implementation----------");
{
uint8_t random_a[8] = { 0 };
uint8_t enc_random_a[8] = { 0 };
uint8_t random_b[8] = { 0 };
uint8_t enc_random_b[8] = { 0 };
uint8_t random_a_and_b[16] = { 0 };
des3_context ctx = { 0 };
memcpy(random_a, RndA,8);
uint8_t output[8] = { 0 };
uint8_t iv[8] = { 0 };
PrintAndLog(" RndA :%s",sprint_hex(random_a, 8));
PrintAndLog(" e_RndB:%s",sprint_hex(enc_random_b, 8));
des3_set2key_dec(&ctx, key);
des3_crypt_cbc(&ctx // des3_context *ctx
, DES_DECRYPT // int mode
, sizeof(random_b) // size_t length
, iv // unsigned char iv[8]
, enc_random_b // const unsigned char *input
, random_b // unsigned char *output
);
PrintAndLog(" RndB:%s",sprint_hex(random_b, 8));
rol(random_b,8);
memcpy(random_a_and_b ,random_a,8);
memcpy(random_a_and_b+8,random_b,8);
PrintAndLog(" RA+B:%s",sprint_hex(random_a_and_b, 16));
des3_set2key_enc(&ctx, key);
des3_crypt_cbc(&ctx // des3_context *ctx
, DES_ENCRYPT // int mode
, sizeof(random_a_and_b) // size_t length
, enc_random_b // unsigned char iv[8]
, random_a_and_b // const unsigned char *input
, random_a_and_b // unsigned char *output
);
PrintAndLog("enc(RA+B):%s",sprint_hex(random_a_and_b, 16));
}
return 0;
}
**/
//
// Ultralight C Read Single Block
//
int CmdHF14AMfUCRdBl(const char *Cmd)
{
uint8_t blockNo = -1;
char cmdp = param_getchar(Cmd, 0);
if (strlen(Cmd) < 1 || cmdp == 'h' || cmdp == 'H') {
PrintAndLog("Usage: hf mfu crdbl <block number>");
PrintAndLog(" sample: hf mfu crdbl 0");
return 0;
}
blockNo = param_get8(Cmd, 0);
if (blockNo < 0) {
PrintAndLog("Wrong block number");
return 1;
}
if (blockNo > MAX_ULTRAC_BLOCKS ){
PrintAndLog("Error: Maximum number of readable blocks is 47 for Ultralight-C Cards!");
return 1;
}
PrintAndLog("--block no: 0x%02X (%d)", (int)blockNo, blockNo);
//Read Block
UsbCommand e = {CMD_MIFAREU_READBL, {blockNo}};
SendCommand(&e);
UsbCommand resp_c;
if (WaitForResponseTimeout(CMD_ACK,&resp_c,1500)) {
uint8_t isOK = resp_c.arg[0] & 0xff;
uint8_t *data = resp_c.d.asBytes;
PrintAndLog("isOk: %02x", isOK);
if (isOK)
PrintAndLog("Data: %s", sprint_hex(data, 4));
} else {
PrintAndLog("Command execute timeout");
}
return 0;
}
//
// Mifare Ultralight C Write Single Block
//
int CmdHF14AMfUCWrBl(const char *Cmd){
uint8_t blockNo = -1;
bool chinese_card = FALSE;
uint8_t bldata[16] = {0x00};
UsbCommand resp;
char cmdp = param_getchar(Cmd, 0);
if (strlen(Cmd) < 3 || cmdp == 'h' || cmdp == 'H') {
PrintAndLog("Usage: hf mfu cwrbl <block number> <block data (8 hex symbols)> [w]");
PrintAndLog(" [block number]");
PrintAndLog(" [block data] - (8 hex symbols)");
PrintAndLog(" [w] - Chinese magic ultralight tag");
PrintAndLog("");
PrintAndLog(" sample: hf mfu cwrbl 0 01020304");
PrintAndLog("");
return 0;
}
blockNo = param_get8(Cmd, 0);
if (blockNo > MAX_ULTRAC_BLOCKS ){
PrintAndLog("Error: Maximum number of blocks is 47 for Ultralight-C Cards!");
return 1;
}
if (param_gethex(Cmd, 1, bldata, 8)) {
PrintAndLog("Block data must include 8 HEX symbols");
return 1;
}
if (strchr(Cmd,'w') != 0 || strchr(Cmd,'W') != 0 ) {
chinese_card = TRUE;
}
if ( blockNo <= 3 ) {
if (!chinese_card){
PrintAndLog("Access Denied");
} else {
PrintAndLog("--Special block no: 0x%02x", blockNo);
PrintAndLog("--Data: %s", sprint_hex(bldata, 4));
UsbCommand d = {CMD_MIFAREU_WRITEBL, {blockNo}};
memcpy(d.d.asBytes,bldata, 4);
SendCommand(&d);
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
uint8_t isOK = resp.arg[0] & 0xff;
PrintAndLog("isOk:%02x", isOK);
} else {
PrintAndLog("Command execute timeout");
}
}
} else {
PrintAndLog("--Block no : 0x%02x", blockNo);
PrintAndLog("--Data: %s", sprint_hex(bldata, 4));
UsbCommand e = {CMD_MIFAREU_WRITEBL, {blockNo}};
memcpy(e.d.asBytes,bldata, 4);
SendCommand(&e);
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
uint8_t isOK = resp.arg[0] & 0xff;
PrintAndLog("isOk : %02x", isOK);
} else {
PrintAndLog("Command execute timeout");
}
}
return 0;
}
//------------------------------------
// Menu Stuff
//------------------------------------
static command_t CommandTable[] =
{
{"help", CmdHelp, 1,"This help"},
{"dbg", CmdHF14AMfDbg, 0,"Set default debug mode"},
{"info", CmdHF14AMfUInfo, 0,"Taginfo"},
{"dump", CmdHF14AMfUDump, 0,"Dump MIFARE Ultralight / Ultralight-C tag to binary file"},
{"rdbl", CmdHF14AMfURdBl, 0,"Read block - MIFARE Ultralight"},
{"wrbl", CmdHF14AMfUWrBl, 0,"Write block - MIFARE Ultralight"},
{"crdbl", CmdHF14AMfUCRdBl, 0,"Read block - MIFARE Ultralight C"},
{"cwrbl", CmdHF14AMfUCWrBl, 0,"Write MIFARE Ultralight C block"},
{"cauth", CmdHF14AMfucAuth, 0,"try a Ultralight C Authentication"},
//{"testdes", CmdTestDES , 1, "Test DES"},
{NULL, NULL, 0, NULL}
};
int CmdHFMFUltra(const char *Cmd){
WaitForResponseTimeout(CMD_ACK,NULL,100);
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd){
CmdsHelp(CommandTable);
return 0;
}

19
client/cmdhfmfu.h Normal file

@ -0,0 +1,19 @@
#include "cmdhfmf.h"
#include "cmdhf14a.h"
//standard ultralight
int CmdHF14AMfUWrBl(const char *Cmd);
int CmdHF14AMfURdBl(const char *Cmd);
//Crypto Cards
int CmdHF14AMfUCRdBl(const char *Cmd);
int CmdHF14AMfUCRdCard(const char *Cmd);
int CmdHF14AMfucAuth(const char *Cmd);
//general stuff
int CmdHF14AMfUDump(const char *Cmd);
void rol (uint8_t *data, const size_t len);
int CmdHFMFUltra(const char *Cmd);
int CmdHF14AMfUInfo(const char *Cmd);

@ -519,7 +519,7 @@ static void ChkBitstream(const char *str)
}
}
}
//appears to attempt to simulate manchester
int CmdLFSim(const char *Cmd)
{
int i,j;
@ -682,26 +682,41 @@ int CmdLFfind(const char *Cmd)
}
PrintAndLog("NOTE: some demods output possible binary\n if it finds something that looks like a tag");
PrintAndLog("Checking for known tags:");
PrintAndLog("\nChecking for known tags:\n");
ans=CmdFSKdemodIO("");
if (ans>0) {
PrintAndLog("Valid IO Prox ID Found!");
PrintAndLog("\nValid IO Prox ID Found!");
return 1;
}
ans=CmdFSKdemodPyramid("");
if (ans>0) {
PrintAndLog("\nValid Pyramid ID Found!");
return 1;
}
ans=CmdFSKdemodParadox("");
if (ans>0) {
PrintAndLog("\nValid Paradox ID Found!");
return 1;
}
ans=CmdFSKdemodAWID("");
if (ans>0) {
PrintAndLog("\nValid AWID ID Found!");
return 1;
}
ans=CmdFSKdemodHID("");
if (ans>0) {
PrintAndLog("Valid HID Prox ID Found!");
PrintAndLog("\nValid HID Prox ID Found!");
return 1;
}
//add psk and indala
ans=CmdIndalaDecode("0");
ans=CmdIndalaDecode("");
if (ans>0) {
PrintAndLog("Valid Indala ID Found!");
PrintAndLog("\nValid Indala ID Found!");
return 1;
}
ans=Cmdaskmandemod("");
if (ans>0) {
PrintAndLog("Valid EM410x ID Found!");
PrintAndLog("\nValid EM410x ID Found!");
return 1;
}
PrintAndLog("No Known Tags Found!\n");

@ -29,110 +29,125 @@ size_t nbytes(size_t nbits) {
int CmdLFHitagList(const char *Cmd)
{
uint8_t got[TRACE_BUFFER_SIZE];
GetFromBigBuf(got,sizeof(got),0);
WaitForResponse(CMD_ACK,NULL);
uint8_t *got = malloc(USB_CMD_DATA_SIZE);
PrintAndLog("recorded activity:");
PrintAndLog(" ETU :nbits: who bytes");
PrintAndLog("---------+-----+----+-----------");
int i = 0;
int prev = -1;
int len = strlen(Cmd);
char filename[FILE_PATH_SIZE] = { 0x00 };
FILE* pf = NULL;
if (len > FILE_PATH_SIZE)
len = FILE_PATH_SIZE;
memcpy(filename, Cmd, len);
if (strlen(filename) > 0) {
if ((pf = fopen(filename,"wb")) == NULL) {
PrintAndLog("Error: Could not open file [%s]",filename);
return 1;
// Query for the actual size of the trace
UsbCommand response;
GetFromBigBuf(got, USB_CMD_DATA_SIZE, 0);
WaitForResponse(CMD_ACK, &response);
uint16_t traceLen = response.arg[2];
if (traceLen > USB_CMD_DATA_SIZE) {
uint8_t *p = realloc(got, traceLen);
if (p == NULL) {
PrintAndLog("Cannot allocate memory for trace");
free(got);
return 2;
}
got = p;
GetFromBigBuf(got, traceLen, 0);
WaitForResponse(CMD_ACK,NULL);
}
}
for (;;) {
if(i >= TRACE_BUFFER_SIZE) { break; }
bool isResponse;
int timestamp = *((uint32_t *)(got+i));
if (timestamp & 0x80000000) {
timestamp &= 0x7fffffff;
isResponse = 1;
} else {
isResponse = 0;
}
int parityBits = *((uint32_t *)(got+i+4));
// 4 bytes of additional information...
// maximum of 32 additional parity bit information
//
// TODO:
// at each quarter bit period we can send power level (16 levels)
// or each half bit period in 256 levels.
int bits = got[i+8];
int len = nbytes(got[i+8]);
if (len > 100) {
break;
}
if (i + len >= TRACE_BUFFER_SIZE) { break;}
uint8_t *frame = (got+i+9);
// Break and stick with current result if buffer was not completely full
if (frame[0] == 0x44 && frame[1] == 0x44 && frame[3] == 0x44) { break; }
char line[1000] = "";
int j;
for (j = 0; j < len; j++) {
int oddparity = 0x01;
int k;
for (k=0;k<8;k++) {
oddparity ^= (((frame[j] & 0xFF) >> k) & 0x01);
}
//if((parityBits >> (len - j - 1)) & 0x01) {
if (isResponse && (oddparity != ((parityBits >> (len - j - 1)) & 0x01))) {
sprintf(line+(j*4), "%02x! ", frame[j]);
}
else {
sprintf(line+(j*4), "%02x ", frame[j]);
}
}
PrintAndLog(" +%7d: %3d: %s %s",
(prev < 0 ? 0 : (timestamp - prev)),
bits,
(isResponse ? "TAG" : " "),
line);
if (pf) {
fprintf(pf," +%7d: %3d: %s %s\n",
(prev < 0 ? 0 : (timestamp - prev)),
bits,
(isResponse ? "TAG" : " "),
line);
}
prev = timestamp;
i += (len + 9);
}
if (pf) {
fclose(pf);
PrintAndLog("Recorded activity succesfully written to file: %s", filename);
}
PrintAndLog("recorded activity (TraceLen = %d bytes):");
PrintAndLog(" ETU :nbits: who bytes");
PrintAndLog("---------+-----+----+-----------");
return 0;
int i = 0;
int prev = -1;
int len = strlen(Cmd);
char filename[FILE_PATH_SIZE] = { 0x00 };
FILE* pf = NULL;
if (len > FILE_PATH_SIZE)
len = FILE_PATH_SIZE;
memcpy(filename, Cmd, len);
if (strlen(filename) > 0) {
if ((pf = fopen(filename,"wb")) == NULL) {
PrintAndLog("Error: Could not open file [%s]",filename);
return 1;
}
}
for (;;) {
if(i > traceLen) { break; }
bool isResponse;
int timestamp = *((uint32_t *)(got+i));
if (timestamp & 0x80000000) {
timestamp &= 0x7fffffff;
isResponse = 1;
} else {
isResponse = 0;
}
int parityBits = *((uint32_t *)(got+i+4));
// 4 bytes of additional information...
// maximum of 32 additional parity bit information
//
// TODO:
// at each quarter bit period we can send power level (16 levels)
// or each half bit period in 256 levels.
int bits = got[i+8];
int len = nbytes(got[i+8]);
if (len > 100) {
break;
}
if (i + len > traceLen) { break;}
uint8_t *frame = (got+i+9);
// Break and stick with current result if buffer was not completely full
if (frame[0] == 0x44 && frame[1] == 0x44 && frame[3] == 0x44) { break; }
char line[1000] = "";
int j;
for (j = 0; j < len; j++) {
int oddparity = 0x01;
int k;
for (k=0;k<8;k++) {
oddparity ^= (((frame[j] & 0xFF) >> k) & 0x01);
}
//if((parityBits >> (len - j - 1)) & 0x01) {
if (isResponse && (oddparity != ((parityBits >> (len - j - 1)) & 0x01))) {
sprintf(line+(j*4), "%02x! ", frame[j]);
}
else {
sprintf(line+(j*4), "%02x ", frame[j]);
}
}
PrintAndLog(" +%7d: %3d: %s %s",
(prev < 0 ? 0 : (timestamp - prev)),
bits,
(isResponse ? "TAG" : " "),
line);
if (pf) {
fprintf(pf," +%7d: %3d: %s %s\n",
(prev < 0 ? 0 : (timestamp - prev)),
bits,
(isResponse ? "TAG" : " "),
line);
}
prev = timestamp;
i += (len + 9);
}
if (pf) {
fclose(pf);
PrintAndLog("Recorded activity succesfully written to file: %s", filename);
}
free(got);
return 0;
}
int CmdLFHitagSnoop(const char *Cmd) {

@ -188,7 +188,6 @@ void UsbCommandReceived(UsbCommand *UC)
} break;
case CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K: {
sample_buf_len += UC->arg[1];
memcpy(sample_buf+(UC->arg[0]),UC->d.asBytes,UC->arg[1]);
} break;

@ -16,11 +16,9 @@
#include "cmdmain.h"
uint8_t* sample_buf;
size_t sample_buf_len;
void GetFromBigBuf(uint8_t *dest, int bytes, int start_index)
{
sample_buf_len = 0;
sample_buf = dest;
UsbCommand c = {CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K, {start_index, bytes, 0}};
SendCommand(&c);

@ -13,13 +13,9 @@
#include <stdint.h>
//trace buffer size as defined in armsrc/apps.h TRACE_SIZE
#define TRACE_BUFFER_SIZE 4096
#define FILE_PATH_SIZE 1000
#define SAMPLE_BUFFER_SIZE 64
extern uint8_t* sample_buf;
extern size_t sample_buf_len;
#define arraylen(x) (sizeof(x)/sizeof((x)[0]))
void GetFromBigBuf(uint8_t *dest, int bytes, int start_index);

@ -9,6 +9,7 @@
//-----------------------------------------------------------------------------
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include "ui.h"
#include "graph.h"
@ -50,7 +51,11 @@ int ClearGraph(int redraw)
void setGraphBuf(uint8_t *buff, size_t size)
{
int i=0;
if ( buff == NULL ) return;
uint16_t i = 0;
if ( size > MAX_GRAPH_TRACE_LEN )
size = MAX_GRAPH_TRACE_LEN;
ClearGraph(0);
for (; i < size; ++i){
GraphBuffer[i]=buff[i]-128;
@ -61,6 +66,8 @@ void setGraphBuf(uint8_t *buff, size_t size)
}
size_t getFromGraphBuf(uint8_t *buff)
{
if ( buff == NULL ) return 0;
uint32_t i;
for (i=0;i<GraphTraceLen;++i){
if (GraphBuffer[i]>127) GraphBuffer[i]=127; //trim
@ -69,27 +76,64 @@ size_t getFromGraphBuf(uint8_t *buff)
}
return i;
}
// Get or auto-detect clock rate
int GetClock(const char *str, int peak, int verbose)
{
int clock;
sscanf(str, "%i", &clock);
if (!strcmp(str, ""))
clock = 0;
int clock;
sscanf(str, "%i", &clock);
if (!strcmp(str, ""))
clock = 0;
// Auto-detect clock
if (!clock)
{
uint8_t grph[MAX_GRAPH_TRACE_LEN]={0};
if (!clock)
{
uint8_t grph[MAX_GRAPH_TRACE_LEN]={0};
size_t size = getFromGraphBuf(grph);
clock = DetectASKClock(grph,size,0);
if ( size == 0 ) {
PrintAndLog("Failed to copy from graphbuffer");
return -1;
}
clock = DetectASKClock(grph,size,0);
// Only print this message if we're not looping something
if (!verbose){
PrintAndLog("Auto-detected clock rate: %d", clock);
}
}
if (!verbose){
PrintAndLog("Auto-detected clock rate: %d", clock);
}
}
return clock;
}
return clock;
// A simple test to see if there is any data inside Graphbuffer.
bool HasGraphData(){
if ( GraphTraceLen <= 0) {
PrintAndLog("No data available, try reading something first");
return false;
}
return true;
}
// Detect high and lows in Grapbuffer.
// Only loops the first 256 values.
void DetectHighLowInGraph(int *high, int *low, bool addFuzz) {
uint8_t loopMax = 255;
if ( loopMax > GraphTraceLen)
loopMax = GraphTraceLen;
for (uint8_t i = 0; i < loopMax; ++i) {
if (GraphBuffer[i] > *high)
*high = GraphBuffer[i];
else if (GraphBuffer[i] < *low)
*low = GraphBuffer[i];
}
//12% fuzz in case highs and lows aren't clipped
if (addFuzz) {
*high = (int)(*high * .88);
*low = (int)(*low * .88);
}
}
int GetNRZpskClock(const char *str, int peak, int verbose)
@ -104,6 +148,10 @@ int GetNRZpskClock(const char *str, int peak, int verbose)
{
uint8_t grph[MAX_GRAPH_TRACE_LEN]={0};
size_t size = getFromGraphBuf(grph);
if ( size == 0 ) {
PrintAndLog("Failed to copy from graphbuffer");
return -1;
}
clock = DetectpskNRZClock(grph,size,0);
// Only print this message if we're not looping something
if (!verbose){

@ -20,9 +20,12 @@ int GetClock(const char *str, int peak, int verbose);
int GetNRZpskClock(const char *str, int peak, int verbose);
void setGraphBuf(uint8_t *buff, size_t size);
bool HasGraphData();
void DetectHighLowInGraph(int *high, int *low, bool addFuzz);
// Max graph trace len: 40000 (bigbuf) * 8 (at 1 bit per sample)
#define MAX_GRAPH_TRACE_LEN (40000 * 8 )
extern int GraphBuffer[MAX_GRAPH_TRACE_LEN];
extern int GraphTraceLen;
#endif

@ -28,7 +28,13 @@
#define POLARSSL_DES_H
//#include "config.h"
/**
* \def POLARSSL_CIPHER_MODE_CBC
*
* Enable Cipher Block Chaining mode (CBC) for symmetric ciphers.
*/
#define POLARSSL_CIPHER_MODE_CBC
#include <string.h>
#if defined(_MSC_VER) && !defined(EFIX64) && !defined(EFI32)

@ -49,7 +49,7 @@ local _commands = {
CMD_EM4X_WRITE_WORD = 0x0219,
CMD_IO_DEMOD_FSK = 0x021A,
CMD_IO_CLONE_TAG = 0x021B,
CMD_EM410X_DEMOD = 0x021C,
CMD_EM410X_DEMOD = 0x021c,
--/* CMD_SET_ADC_MUX: ext1 is 0 for lopkd, 1 for loraw, 2 for hipkd, 3 for hiraw */
--// For the 13.56 MHz tags

@ -108,6 +108,24 @@ local Utils =
return retval
end,
-- input parameter is a string
-- Swaps the endianess and returns a string,
-- IE: 'cd7a' -> '7acd' -> 0x7acd
SwapEndiannessStr = function(s, len)
if s == nil then return nil end
if #s == 0 then return '' end
if type(s) ~= 'string' then return nil end
local retval
if len == 16 then
retval = s:sub(3,4)..s:sub(1,2)
elseif len == 24 then
retval = s:sub(5,6)..s:sub(3,4)..s:sub(1,2)
elseif len == 32 then
retval = s:sub(7,8)..s:sub(5,6)..s:sub(3,4)..s:sub(1,2)
end
return retval
end,
------------ CONVERSIONS
--
@ -116,7 +134,7 @@ local Utils =
local B,K,OUT,I,D=16,"0123456789ABCDEF","",0
while IN>0 do
I=I+1
IN,D=math.floor(IN/B),math.mod(IN,B)+1
IN , D = math.floor(IN/B), math.modf(IN,B)+1
OUT=string.sub(K,D,D)..OUT
end
return OUT

@ -232,14 +232,27 @@ int mfEmlSetMem(uint8_t *data, int blockNum, int blocksCount) {
// "MAGIC" CARD
int mfCSetUID(uint8_t *uid, uint8_t *oldUID, bool wantWipe) {
uint8_t oldblock0[16] = {0x00};
uint8_t block0[16] = {0x00};
memcpy(block0, uid, 4);
block0[4] = block0[0]^block0[1]^block0[2]^block0[3]; // Mifare UID BCC
// mifare classic SAK(byte 5) and ATQA(byte 6 and 7)
block0[5] = 0x08;
block0[6] = 0x04;
block0[7] = 0x00;
//block0[5] = 0x08;
//block0[6] = 0x04;
//block0[7] = 0x00;
block0[5] = 0x01; //sak
block0[6] = 0x01;
block0[7] = 0x0f;
int old = mfCGetBlock(0, oldblock0, CSETBLOCK_SINGLE_OPER);
if ( old == 0) {
memcpy(block0+8, oldblock0+8, 8);
PrintAndLog("block 0: %s", sprint_hex(block0,16));
} else {
PrintAndLog("Couldn't get olddata. Will write over the last bytes of Block 0.");
}
return mfCSetBlock(0, block0, oldUID, wantWipe, CSETBLOCK_SINGLE_OPER);
}
@ -253,8 +266,10 @@ int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, bool wantWipe, uin
UsbCommand resp;
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
isOK = resp.arg[0] & 0xff;
if (uid != NULL) memcpy(uid, resp.d.asBytes, 4);
if (!isOK) return 2;
if (uid != NULL)
memcpy(uid, resp.d.asBytes, 4);
if (!isOK)
return 2;
} else {
PrintAndLog("Command execute timeout");
return 1;
@ -286,9 +301,9 @@ int mfCGetBlock(uint8_t blockNo, uint8_t *data, uint8_t params) {
static uint8_t trailerAccessBytes[4] = {0x08, 0x77, 0x8F, 0x00};
// variables
char logHexFileName[200] = {0x00};
char logHexFileName[FILE_PATH_SIZE] = {0x00};
static uint8_t traceCard[4096] = {0x00};
static char traceFileName[200] = {0x00};
static char traceFileName[FILE_PATH_SIZE] = {0x00};
static int traceState = TRACE_IDLE;
static uint8_t traceCurBlock = 0;
static uint8_t traceCurKey = 0;
@ -323,20 +338,28 @@ int isBlockTrailer(int blockN) {
int loadTraceCard(uint8_t *tuid) {
FILE * f;
char buf[64];
uint8_t buf8[64];
char buf[64] = {0x00};
uint8_t buf8[64] = {0x00};
int i, blockNum;
if (!isTraceCardEmpty()) saveTraceCard();
if (!isTraceCardEmpty())
saveTraceCard();
memset(traceCard, 0x00, 4096);
memcpy(traceCard, tuid + 3, 4);
FillFileNameByUID(traceFileName, tuid, ".eml", 7);
f = fopen(traceFileName, "r");
if (!f) return 1;
if (!f) {
fclose(f);
return 1;
}
blockNum = 0;
while(!feof(f)){
memset(buf, 0, sizeof(buf));
if (fgets(buf, sizeof(buf), f) == NULL) {
PrintAndLog("File reading error.");
@ -368,22 +391,30 @@ int saveTraceCard(void) {
if ((!strlen(traceFileName)) || (isTraceCardEmpty())) return 0;
f = fopen(traceFileName, "w+");
if ( !f ) {
fclose(f);
return 1;
}
for (int i = 0; i < 64; i++) { // blocks
for (int j = 0; j < 16; j++) // bytes
fprintf(f, "%02x", *(traceCard + i * 16 + j));
fprintf(f,"\n");
}
fclose(f);
return 0;
}
int mfTraceInit(uint8_t *tuid, uint8_t *atqa, uint8_t sak, bool wantSaveToEmlFile) {
if (traceCrypto1) crypto1_destroy(traceCrypto1);
if (traceCrypto1)
crypto1_destroy(traceCrypto1);
traceCrypto1 = NULL;
if (wantSaveToEmlFile) loadTraceCard(tuid);
if (wantSaveToEmlFile)
loadTraceCard(tuid);
traceCard[4] = traceCard[0] ^ traceCard[1] ^ traceCard[2] ^ traceCard[3];
traceCard[5] = sak;
memcpy(&traceCard[6], atqa, 2);

@ -47,7 +47,7 @@ typedef struct {
int foundKey[2];
} sector;
extern char logHexFileName[200];
extern char logHexFileName[FILE_PATH_SIZE];
int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t * key, uint8_t trgBlockNo, uint8_t trgKeyType, uint8_t * ResultKeys, bool calibrate);
int mfCheckKeys (uint8_t blockNo, uint8_t keyType, uint8_t keycnt, uint8_t * keyBlock, uint64_t * key);

@ -0,0 +1,63 @@
local getopt = require('getopt')
example = "script run remagic"
author = "Iceman"
desc =
[[
This is a script that tries to bring back a chinese magic card (1k generation1)
from the dead when it's block 0 has been written with bad values.
Arguments:
-h this help
]]
---
-- A debug printout-function
function dbg(args)
if DEBUG then
print("###", args)
end
end
---
-- This is only meant to be used when errors occur
function oops(err)
print("ERROR: ",err)
end
---
-- Usage help
function help()
print(desc)
print("Example usage")
print(example)
end
---
-- The main entry point
function main(args)
-- Read the parameters
for o, a in getopt.getopt(args, 'h') do
if o == "h" then help() return end
end
local _cmds = {
--[[
--]]
[0] = "hf 14a raw -p -a -b 7 40",
[1] = "hf 14a raw -p -a 43",
[2] = "hf 14a raw -c -p -a A000",
[3] = "hf 14a raw -c -p -a 01 02 03 04 04 98 02 00 00 00 00 00 00 00 10 01",
}
core.clearCommandBuffer()
local i
--for _,c in pairs(_cmds) do
for i = 0, 3 do
print ( _cmds[i] )
core.console( _cmds[i] )
end
end
main(args)

@ -0,0 +1,173 @@
local cmds = require('commands')
local getopt = require('getopt')
local bin = require('bin')
local utils = require('utils')
local dumplib = require('html_dumplib')
example =[[
1. script run tracetest
2. script run tracetest -o
]]
author = "Iceman"
usage = "script run test_t55x7_psk -o <filename>"
desc =[[
This script will program a T55x7 TAG with the configuration: block 0x00 data 0x00088040
The outlined procedure is as following:
"lf t55xx write 0 00088040"
"lf read"
"data samples"
"data pskdet"
"data psknrz"
"data pskindala"
"data psknrzraw"
Loop OUTER:
change the configuretion block 0 with:
-xxxx8xxx = PSK RF/2 with Manchester modulation
-xxxx1xxx = PSK RF/2 with PSK1 modulation (phase change when input changes)
-xxxx2xxx = PSK RF/2 with PSk2 modulation (phase change on bitclk if input high)
-xxxx3xxx = PSK RF/2 with PSk3 modulation (phase change on rising edge of input)
Loop INNER
for each outer configuration, also do
XXXXX0XX = PSK RF/2
XXXXX4XX = PSK RF/4
XXXXX8XX = PSK RF/8
In all 12 individual test for the PSK demod
Arguments:
-h : this help
-o : logfile name
]]
local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds
local DEBUG = true -- the debug flag
--BLOCK 0 = 00088040
local config1 = '0008'
local config2 = '40'
local procedurecmds = {
[1] = '%s%s%s%s',
[2] = 'lf read',
--[3] = '',
[3] = 'data samples',
[4] = 'data pskdetectclock',
[5] = 'data psknrzrawdemod',
[6] = 'data pskindalademod',
}
---
-- A debug printout-function
function dbg(args)
if not DEBUG then
return
end
if type(args) == "table" then
local i = 1
while args[i] do
dbg(args[i])
i = i+1
end
else
print("###", args)
end
end
---
-- This is only meant to be used when errors occur
function oops(err)
print("ERROR: ",err)
end
---
-- Usage help
function help()
print(desc)
print("Example usage")
print(example)
end
--
-- Exit message
function ExitMsg(msg)
print( string.rep('--',20) )
print( string.rep('--',20) )
print(msg)
print()
end
function pskTest(modulation)
local y
for y = 0, 8, 4 do
for _ = 1, #procedurecmds do
local cmd = procedurecmds[_]
if #cmd == 0 then
elseif _ == 1 then
dbg("Writing to T55x7 TAG")
local configdata = cmd:format( config1, modulation , y, config2)
dbg( configdata)
local writecommand = Command:new{cmd = cmds.CMD_T55XX_WRITE_BLOCK, arg1 = configdata ,arg2 = 0, arg3 = 0}
local err = core.SendCommand(writecommand:getBytes())
if err then return oops(err) end
local response = core.WaitForResponseTimeout(cmds.CMD_ACK,TIMEOUT)
if response then
local count,cmd,arg0 = bin.unpack('LL',response)
if(arg0==1) then
dbg("Writing success")
else
return nil, "Couldn't read block.."
end
end
else
dbg(cmd)
core.console( cmd )
end
end
core.clearCommandBuffer()
end
print( string.rep('--',20) )
end
local function main(args)
print( string.rep('--',20) )
print( string.rep('--',20) )
local outputTemplate = os.date("testpsk_%Y-%m-%d_%H%M%S")
-- Arguments for the script
for o, arg in getopt.getopt(args, 'ho:') do
if o == "h" then return help() end
if o == "o" then outputTemplate = arg end
end
core.clearCommandBuffer()
pskTest(1)
pskTest(2)
pskTest(3)
pskTest(8)
print( string.rep('--',20) )
end
main(args)
-- Where it iterates over
-- xxxx8xxx = PSK RF/2 with Manchester modulation
-- xxxx1xxx = PSK RF/2 with PSK1 modulation (phase change when input changes)
-- xxxx2xxx = PSK RF/2 with PSk2 modulation (phase change on bitclk if input high)
-- xxxx3xxx = PSK RF/2 with PSk3 modulation (phase change on rising edge of input)
-- XXXXX0XX = PSK RF/2
-- XXXXX4XX = PSK RF/4
-- XXXXX8XX = PSK RF/8

@ -249,17 +249,18 @@ local function main(args)
end
end
-- Write dump to files
if not DEBUG then
local foo = dumplib.SaveAsBinary(bindata, outputTemplate..'.bin')
print(("Wrote a BIN dump to the file %s"):format(foo))
local bar = dumplib.SaveAsText(emldata, outputTemplate..'.eml')
print(("Wrote a EML dump to the file %s"):format(bar))
end
local uid = block0:sub(1,8)
local itemtype = block1:sub(1,4)
local cardid = block1:sub(9,24)
-- Write dump to files
if not DEBUG then
local foo = dumplib.SaveAsBinary(bindata, outputTemplate..'_uid_'..uid..'.bin')
print(("Wrote a BIN dump to the file %s"):format(foo))
local bar = dumplib.SaveAsText(emldata, outputTemplate..'_uid_'..uid..'.eml')
print(("Wrote a EML dump to the file %s"):format(bar))
end
-- Show info
print( string.rep('--',20) )

@ -241,18 +241,20 @@ local function main(args)
local cmdSetDbgOff = "hf mf dbg 0"
core.console( cmdSetDbgOff)
-- Look for tag present on reader,
result, err = lib14a.read1443a(false)
if not result then return oops(err) end
-- if not loadFromDump then
-- -- Look for tag present on reader,
-- result, err = lib14a.read1443a(false)
-- if not result then return oops(err) end
core.clearCommandBuffer()
-- core.clearCommandBuffer()
if 0x01 ~= result.sak then -- NXP MIFARE TNP3xxx
return oops('This is not a TNP3xxx tag. aborting.')
end
-- if 0x01 ~= result.sak then -- NXP MIFARE TNP3xxx
-- return oops('This is not a TNP3xxx tag. aborting.')
-- end
-- Show tag info
print((' Found tag : %s'):format(result.name))
-- -- Show tag info
-- print((' Found tag : %s'):format(result.name))
-- end
-- Load dump.bin file
print( (' Load data from %s'):format(inputTemplate))
@ -349,7 +351,7 @@ local function main(args)
err = LoadEmulator(blocks)
if err then return oops(err) end
core.clearCommandBuffer()
print('The simulation is now prepared.\n --> run \"hf mf sim 5 '..uid..'\" <--')
print('The simulation is now prepared.\n --> run \"hf mf sim u '..uid..' x\" <--')
end
end
main(args)

@ -0,0 +1,132 @@
local cmds = require('commands')
local getopt = require('getopt')
local bin = require('bin')
local utils = require('utils')
local dumplib = require('html_dumplib')
example =[[
1. script run tracetest
2. script run tracetest -o
]]
author = "Iceman"
usage = "script run tracetest -o <filename>"
desc =[[
This script will load several traces files in ../traces/ folder and do
"data load"
"lf search"
Arguments:
-h : this help
-o : logfile name
]]
local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds
local DEBUG = true -- the debug flag
---
-- A debug printout-function
function dbg(args)
if not DEBUG then
return
end
if type(args) == "table" then
local i = 1
while result[i] do
dbg(result[i])
i = i+1
end
else
print("###", args)
end
end
---
-- This is only meant to be used when errors occur
function oops(err)
print("ERROR: ",err)
end
---
-- Usage help
function help()
print(desc)
print("Example usage")
print(example)
end
--
-- Exit message
function ExitMsg(msg)
print( string.rep('--',20) )
print( string.rep('--',20) )
print(msg)
print()
end
local function main(args)
print( string.rep('--',20) )
print( string.rep('--',20) )
local cmdDataLoad = 'data load %s';
local tracesEM = "find '../traces/' -iname 'em*.pm3' -type f"
local tracesMOD = "find '../traces/' -iname 'm*.pm3' -type f"
local outputTemplate = os.date("testtest_%Y-%m-%d_%H%M%S")
-- Arguments for the script
for o, arg in getopt.getopt(args, 'ho:') do
if o == "h" then return help() end
if o == "o" then outputTemplate = arg end
end
core.clearCommandBuffer()
local files = {}
-- Find a set of traces staring with EM
local p = assert( io.popen(tracesEM))
for file in p:lines() do
table.insert(files, file)
end
p.close();
-- Find a set of traces staring with MOD
p = assert( io.popen(tracesMOD) )
for file in p:lines() do
table.insert(files, file)
end
p.close();
local cmdLFSEARCH = "lf search 1"
-- main loop
io.write('Starting to test traces > ')
for _,file in pairs(files) do
local x = "data load "..file
dbg(x)
core.console(x)
dbg(cmdLFSEARCH)
core.console(cmdLFSEARCH)
core.clearCommandBuffer()
if core.ukbhit() then
print("aborted by user")
break
end
end
io.write('\n')
-- Write dump to files
if not DEBUG then
local bar = dumplib.SaveAsText(emldata, outputTemplate..'.txt')
print(("Wrote output to: %s"):format(bar))
end
-- Show info
print( string.rep('--',20) )
end
main(args)

@ -33,8 +33,8 @@
#ifndef _PROXMARK_CMD_H_
#define _PROXMARK_CMD_H_
#include <common.h>
#include <usb_cmd.h>
#include "common.h"
#include "usb_cmd.h"
#include "usb_cdc.h"
bool cmd_receive(UsbCommand* cmd);

File diff suppressed because it is too large Load Diff

@ -4,7 +4,11 @@
// at your option, any later version. See the LICENSE.txt file for the text of
// the license.
//-----------------------------------------------------------------------------
// Low frequency commands
// Low frequency demod related commands
// marshmellow
// note that many of these demods are not the slickest code and they often rely
// on peaks and clock instead of converting to clean signal.
//
//-----------------------------------------------------------------------------
#ifndef LFDEMOD_H__
@ -13,17 +17,29 @@
int DetectASKClock(uint8_t dest[], size_t size, int clock);
int askmandemod(uint8_t *BinStream, size_t *size, int *clk, int *invert);
uint64_t Em410xDecode(uint8_t *BitStream,size_t size);
uint64_t Em410xDecode(uint8_t *BitStream, size_t *size, size_t *startIdx);
int ManchesterEncode(uint8_t *BitStream, size_t size);
int manrawdecode(uint8_t *BitStream, size_t *size);
int BiphaseRawDecode(uint8_t * BitStream, size_t *size, int offset);
int BiphaseRawDecode(uint8_t * BitStream, size_t *size, int offset, int invert);
int askrawdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert);
int HIDdemodFSK(uint8_t *dest, size_t size, uint32_t *hi2, uint32_t *hi, uint32_t *lo);
int HIDdemodFSK(uint8_t *dest, size_t *size, uint32_t *hi2, uint32_t *hi, uint32_t *lo);
int IOdemodFSK(uint8_t *dest, size_t size);
int fskdemod(uint8_t *dest, size_t size, uint8_t rfLen, uint8_t invert, uint8_t fchigh, uint8_t fclow);
uint32_t bytebits_to_byte(uint8_t* src, size_t numbits);
int pskNRZrawDemod(uint8_t *dest, size_t *size, int *clk, int *invert);
void psk1TOpsk2(uint8_t *BitStream, size_t size);
int DetectpskNRZClock(uint8_t dest[], size_t size, int clock);
int indala26decode(uint8_t *bitStream, size_t *size, uint8_t *invert);
void pskCleanWave(uint8_t *bitStream, size_t size);
int PyramiddemodFSK(uint8_t *dest, size_t *size);
int AWIDdemodFSK(uint8_t *dest, size_t *size);
size_t removeParity(uint8_t *BitStream, size_t startIdx, uint8_t pLen, uint8_t pType, size_t bLen);
uint16_t countFC(uint8_t *BitStream, size_t size);
uint8_t detectFSKClk(uint8_t *BitStream, size_t size, uint8_t fcHigh, uint8_t fcLow);
int getHiLo(uint8_t *BitStream, size_t size, int *high, int *low, uint8_t fuzzHi, uint8_t fuzzLo);
int ParadoxdemodFSK(uint8_t *dest, size_t *size, uint32_t *hi2, uint32_t *hi, uint32_t *lo);
uint8_t preambleSearch(uint8_t *BitStream, uint8_t *preamble, size_t pLen, size_t *size, size_t *startIdx);
uint8_t parityTest(uint32_t bits, uint8_t bitLen, uint8_t pType);
uint8_t justNoise(uint8_t *BitStream, size_t size);
#endif

@ -370,7 +370,7 @@ uint32_t usb_write(const byte_t* data, const size_t len) {
//* \fn AT91F_USB_SendData
//* \brief Send Data through the control endpoint
//*----------------------------------------------------------------------------
unsigned int csrTab[100];
unsigned int csrTab[100] = {0x00};
unsigned char csrIdx = 0;
static void AT91F_USB_SendData(AT91PS_UDP pUdp, const char *pData, uint32_t length) {

@ -35,7 +35,7 @@
#ifndef _USB_CDC_H_
#define _USB_CDC_H_
#include <common.h>
#include "common.h"
void usb_disable();
void usb_enable();

@ -14,8 +14,8 @@
typedef enum {
RHT2F_PASSWORD = 21,
RHT2F_AUTHENTICATE = 22,
RHT2F_CRYPTO = 23,
RHT2F_TEST_AUTH_ATTEMPTS = 25,
RHT2F_CRYPTO = 23,
RHT2F_TEST_AUTH_ATTEMPTS = 25,
} hitag_function;
typedef struct {
@ -33,7 +33,7 @@ typedef struct {
typedef union {
rht2d_password pwd;
rht2d_authenticate auth;
rht2d_crypto crypto;
rht2d_crypto crypto;
} hitag_data;
#endif

20000
traces/AWID-15-259.pm3 Normal file

File diff suppressed because it is too large Load Diff

20000
traces/HID-weak-fob-11647.pm3 Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -21,4 +21,6 @@ casi-12ed825c29.pm3: casi rusco 40 bit (EM410x ID: 12ed825c29)
EM4102-Fob.pm3: (ID: 0400193cbe)
ioprox-XSF-01-3B-44725.pm3: IO Prox FSK RF/64 ID in name
ioprox-XSF-01-BE-03011.pm3: IO Prox FSK RF/64 ID in name
indala-504278295.pm3: PSK 26 bit indala
indala-504278295.pm3: PSK 26 bit indala
AWID-15-259.pm3: AWID FSK RF/50 FC: 15 Card: 259
HID-weak-fob-11647.pm3: HID 32bit Prox Card#: 11647. very weak tag/read but just readable.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

20000
traces/modulation-fsk1-50.pm3 Normal file

File diff suppressed because it is too large Load Diff

20000
traces/modulation-fsk1a-50.pm3 Normal file

File diff suppressed because it is too large Load Diff

20000
traces/modulation-fsk2-50.pm3 Normal file

File diff suppressed because it is too large Load Diff

20000
traces/modulation-fsk2a-40.pm3 Normal file

File diff suppressed because it is too large Load Diff

20000
traces/modulation-fsk2a-50.pm3 Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff