mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2026-05-12 11:18:11 -07:00
I just merged @marshmellow's branch "iclass" and that was a lot of new functionality. *great work*
Things like the ICLASS, tryDecryptWord, -- My other stuff like default keys, some new Mifare EV1 commands 0x40, 0x43 for the logging annotation, start of the T55x7 configblock helper functionality (ripped from Adam Lauries RFIdler code) Changes to the PCF7931 functions written, which has a lousy input check..
This commit is contained in:
+12
-2
@@ -3,8 +3,18 @@ All notable changes to this project will be documented in this file.
|
||||
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
|
||||
|
||||
## [unreleased][unreleased]
|
||||
--trying to fix "hf 14b" command to be able to read CALYPSO card. (iceman)
|
||||
--trying to fix "t55x7" read with password bug. (iceman)
|
||||
--
|
||||
|
||||
### Added
|
||||
- `hf mf eload u` added an ultralight/ntag option. (marshmellow)
|
||||
- `hf iclass managekeys` to save, load and manage iclass keys. (adjusted most commands to accept a loaded key in memory) (marshmellow)
|
||||
- `hf iclass readblk` to select, authenticate, and read 1 block from an iclass card (marshmellow)
|
||||
- `hf iclass writeblk` to select, authenticate, and write 1 block to an iclass card (or picopass) (marshmellow + others)
|
||||
- `hf iclass clone` to take a saved dump file and clone selected blocks to a new tag (marshmellow + others)
|
||||
- `hf iclass calcnewkey` - to calculate the div_key change to change a key - (experimental) (marshmellow + others)
|
||||
- `hf iclass encryptblk` - to encrypt a data block hex to prep for writing that block (marshmellow)
|
||||
- ISO14443a stand-alone operation with ARM CFLAG="WITH_ISO14443a_StandAlone". This code can read & emulate two banks of 14a tag UIDs and write to "magic" cards (Craig Young)
|
||||
- AWID26 command context added as 'lf awid' containing realtime demodulation as well as cloning/simulation based on tag numbers (Craig Young)
|
||||
- Added 'hw status'. This command makes the ARM print out some runtime information. (holiman)
|
||||
@@ -12,8 +22,9 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
|
||||
- Added `data hex2bin` and `data bin2hex` for command line conversion between binary and hexadecimal (holiman)
|
||||
|
||||
### Changed
|
||||
- changed `lf config t <threshold>` to be 0 - 128 and will trigger on + or - threshold value (marshmellow)
|
||||
- `hf iclass dump` cli options - can now dump AA1 and AA2 with different keys in one run (does not go to muliple pages for the larger tags yet)
|
||||
- Revised workflow for StandAloneMode14a (Craig Young)
|
||||
- Changed lf config's `threshold` to a graph (signed) metric and it will trigger on + or - value set to. (example: set to 50 and recording would begin at first graphed value of >= 50 or <= -50) (marshmellow)
|
||||
- EPA functions (`hf epa`) now support both ISO 14443-A and 14443-B cards (frederikmoellers)
|
||||
- 'hw version' only talks to ARM at startup, after that the info is cached. (pwpiwi)
|
||||
|
||||
@@ -26,7 +37,6 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
|
||||
- Added compression of fpga config and data, *BOOTROM REFLASH REQUIRED* (piwi)
|
||||
- Implemented better detection of mifare-tags that are not vulnerable to classic attacks (`hf mf mifare`, `hf mf nested`) (piwi)
|
||||
|
||||
|
||||
### Added
|
||||
- Add `hf 14b reader` to find and print general info about known 14b tags (marshmellow)
|
||||
- Add `hf 14b info` to find and print full info about std 14b tags and sri tags (using 14b raw commands in the client) (marshmellow)
|
||||
|
||||
+59
-6
@@ -1,24 +1,32 @@
|
||||
The iceman fork.
|
||||
|
||||
The iceman fork
|
||||
---------------
|
||||
NOTICE:
|
||||
|
||||
The official Proxmark repository is found here: https://github.com/Proxmark/proxmark3
|
||||
|
||||
NEWS:
|
||||
|
||||
::THIS FORK IS HIGHLY EXPERIMENTAL::
|
||||
|
||||
NEWS:
|
||||
|
||||
Whats in this fork? I have scraped the web for different enhancements to the PM3 source code and not all of them ever found their way to the master branch.
|
||||
Among the stuff is
|
||||
|
||||
* Jonor's hf 14a raw timing patch
|
||||
* Piwi's updates. (usually gets into the master)
|
||||
* Piwi's "topaz" branch (not merged)
|
||||
* Holiman's iclass, (usually gets into the master)
|
||||
* Marshmellow's LF fixes
|
||||
* Marshmellow's fixes (usually gets into the master)
|
||||
* Midnitesnake's Ultralight, Ultralight-c enhancements
|
||||
* Izsh's lf peak modification / iir-filtering
|
||||
* Aspers's tips and tricks from inside the PM3-gui-tool, settings.xml and other stuff.
|
||||
* My own desfire, Ultralight extras, LF T55xx enhancements, bugs fixes (filelength, hf mf commands ), TNP3xxx lua scripts, Awid26, skidata scripts (will come)
|
||||
* other obscure patches like for the sammy-mode, (offline you know), tagidentifications, defaultkeys.
|
||||
* Minor textual changes here and there.
|
||||
* Simulation of Ultralight/Ntag.
|
||||
* Marshmellow's and my "RevEng" addon for the client. Ref: http://reveng.sourceforge.net/
|
||||
* Someone's alterantive bruteforce Mifare changes.. (you need the two other exe to make it work)
|
||||
*
|
||||
|
||||
Give me a hint, and I'll see if I can't merge in the stuff you have.
|
||||
|
||||
@@ -28,6 +36,7 @@ PM3 GUI:
|
||||
|
||||
I do tend to rename and move stuff around, the official PM3-GUI from Gaucho will not work so well. *sorry*
|
||||
|
||||
|
||||
|
||||
DEVELOPMENT:
|
||||
|
||||
@@ -78,10 +87,54 @@ Solution
|
||||
|
||||
|
||||
An old Qt4 version makefile is found here: http://www.icesql.se/proxmark3/code/linuxmakefile.txt but this one doesn't have all new files in it. So I don't recommend it.
|
||||
|
||||
|
||||
January 2015, Sweden
|
||||
iceman at host iuse.se
|
||||
|
||||
|
||||
The Proxmark 3 is available for purchase (assembled and tested) from the
|
||||
following locations:
|
||||
|
||||
* http://proxmark3.com/
|
||||
* http://www.xfpga.com/
|
||||
|
||||
January 2015, Sweden
|
||||
iceman at host iuse.se
|
||||
Most of the ultra-low-volume contract assemblers could put
|
||||
something like this together with a reasonable yield. A run of around
|
||||
a dozen units is probably cost-effective. The BOM includes (possibly-
|
||||
outdated) component pricing, and everything is available from Digikey
|
||||
and the usual distributors.
|
||||
|
||||
If you've never assembled a modern circuit board by hand, then this is
|
||||
not a good place to start. Some of the components (e.g. the crystals)
|
||||
must not be assembled with a soldering iron, and require hot air.
|
||||
|
||||
The schematics are included; the component values given are not
|
||||
necessarily correct for all situations, but it should be possible to do
|
||||
nearly anything you would want with appropriate population options.
|
||||
|
||||
The printed circuit board artwork is also available, as Gerbers and an
|
||||
Excellon drill file.
|
||||
|
||||
|
||||
LICENSING:
|
||||
|
||||
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 2 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, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
|
||||
Jonathan Westhues
|
||||
user jwesthues, at host cq.cx
|
||||
|
||||
May 2007, Cambridge MA
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
// LCD code
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "../include/proxmark3.h"
|
||||
#include "proxmark3.h"
|
||||
#include "apps.h"
|
||||
#include "LCD.h"
|
||||
#include "fonts.h"
|
||||
|
||||
@@ -992,6 +992,9 @@ void UsbPacketReceived(uint8_t *packet, int len)
|
||||
ReadPCF7931();
|
||||
cmd_send(CMD_ACK,0,0,0,0,0);
|
||||
break;
|
||||
case CMD_PCF7931_WRITE:
|
||||
WritePCF7931(c->d.asDwords[0],c->d.asDwords[1],c->d.asDwords[2],c->d.asDwords[3],c->d.asDwords[4],c->d.asDwords[5],c->d.asDwords[6], c->d.asDwords[9], c->d.asDwords[7]-128,c->d.asDwords[8]-128, c->arg[0], c->arg[1], c->arg[2]);
|
||||
break;
|
||||
case CMD_EM4X_READ_WORD:
|
||||
EM4xReadWord(c->arg[1], c->arg[2],c->d.asBytes[0]);
|
||||
break;
|
||||
@@ -1212,6 +1215,24 @@ void UsbPacketReceived(uint8_t *packet, int len)
|
||||
case CMD_ICLASS_EML_MEMSET:
|
||||
emlSet(c->d.asBytes,c->arg[0], c->arg[1]);
|
||||
break;
|
||||
case CMD_ICLASS_WRITEBLOCK:
|
||||
iClass_WriteBlock(c->arg[0], c->d.asBytes);
|
||||
break;
|
||||
case CMD_ICLASS_READCHECK: // auth step 1
|
||||
iClass_ReadCheck(c->arg[0], c->arg[1]);
|
||||
break;
|
||||
case CMD_ICLASS_READBLOCK:
|
||||
iClass_ReadBlk(c->arg[0]);
|
||||
break;
|
||||
case CMD_ICLASS_AUTHENTICATION: //check
|
||||
iClass_Authentication(c->d.asBytes);
|
||||
break;
|
||||
case CMD_ICLASS_DUMP:
|
||||
iClass_Dump(c->arg[0], c->arg[1]);
|
||||
break;
|
||||
case CMD_ICLASS_CLONE:
|
||||
iClass_Clone(c->arg[0], c->arg[1], c->d.asBytes);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case CMD_BUFF_CLEAR:
|
||||
|
||||
@@ -94,6 +94,11 @@ int DemodPCF7931(uint8_t **outBlocks);
|
||||
int IsBlock0PCF7931(uint8_t *Block);
|
||||
int IsBlock1PCF7931(uint8_t *Block);
|
||||
void ReadPCF7931();
|
||||
void SendCmdPCF7931(uint32_t * tab);
|
||||
bool AddBytePCF7931(uint8_t byte, uint32_t * tab, int32_t l, int32_t p);
|
||||
bool AddBitPCF7931(bool b, uint32_t * tab, int32_t l, int32_t p);
|
||||
bool AddPatternPCF7931(uint32_t a, uint32_t b, uint32_t c, uint32_t * tab);
|
||||
void WritePCF7931(uint8_t pass1, uint8_t pass2, uint8_t pass3, uint8_t pass4, uint8_t pass5, uint8_t pass6, uint8_t pass7, uint16_t init_delay, int32_t l, int32_t p, uint8_t address, uint8_t byte, uint8_t data);
|
||||
void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode);
|
||||
void EM4xWriteWord(uint32_t Data, uint8_t Address, uint32_t Pwd, uint8_t PwdMode);
|
||||
|
||||
@@ -190,6 +195,13 @@ void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain
|
||||
void ReaderIClass(uint8_t arg0);
|
||||
void ReaderIClass_Replay(uint8_t arg0,uint8_t *MAC);
|
||||
void IClass_iso14443A_GetPublic(uint8_t arg0);
|
||||
void iClass_Authentication(uint8_t *MAC);
|
||||
void iClass_WriteBlock(uint8_t blockNo, uint8_t *data);
|
||||
void iClass_ReadBlk(uint8_t blockNo);
|
||||
bool iClass_ReadBlock(uint8_t blockNo, uint8_t *readdata);
|
||||
void iClass_Dump(uint8_t blockno, uint8_t numblks);
|
||||
void iClass_Clone(uint8_t startblock, uint8_t endblock, uint8_t *data);
|
||||
void iClass_ReadCheck(uint8_t blockNo, uint8_t keyType);
|
||||
|
||||
void CopyViKingtoT55x7(uint32_t block1,uint32_t block2);
|
||||
// hitag2.h
|
||||
|
||||
+141
-135
@@ -1601,16 +1601,16 @@ void setupIclassReader()
|
||||
|
||||
}
|
||||
|
||||
size_t sendCmdGetResponseWithRetries(uint8_t* command, size_t cmdsize, uint8_t* resp, uint8_t expected_size, uint8_t retries)
|
||||
bool sendCmdGetResponseWithRetries(uint8_t* command, size_t cmdsize, uint8_t* resp, uint8_t expected_size, uint8_t retries)
|
||||
{
|
||||
while(retries-- > 0)
|
||||
{
|
||||
ReaderTransmitIClass(command, cmdsize);
|
||||
if(expected_size == ReaderReceiveIClass(resp)){
|
||||
return 0;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return 1;//Error
|
||||
return false;//Error
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1620,14 +1620,17 @@ size_t sendCmdGetResponseWithRetries(uint8_t* command, size_t cmdsize, uint8_t*
|
||||
* 1 = Got CSN
|
||||
* 2 = Got CSN and CC
|
||||
*/
|
||||
uint8_t handshakeIclassTag(uint8_t *card_data)
|
||||
uint8_t handshakeIclassTag_ext(uint8_t *card_data, bool use_credit_key)
|
||||
{
|
||||
static uint8_t act_all[] = { 0x0a };
|
||||
static uint8_t identify[] = { 0x0c };
|
||||
//static uint8_t identify[] = { 0x0c };
|
||||
static uint8_t identify[] = { 0x0c, 0x00, 0x73, 0x33 };
|
||||
static uint8_t select[] = { 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
|
||||
|
||||
static uint8_t readcheck_cc[]= { 0x88, 0x02,};
|
||||
static uint8_t readcheck_cc[]= { 0x88, 0x02 };
|
||||
if (use_credit_key)
|
||||
readcheck_cc[0] = 0x18;
|
||||
else
|
||||
readcheck_cc[0] = 0x88;
|
||||
|
||||
uint8_t resp[ICLASS_BUFFER_SIZE];
|
||||
|
||||
@@ -1668,6 +1671,9 @@ uint8_t handshakeIclassTag(uint8_t *card_data)
|
||||
|
||||
return read_status;
|
||||
}
|
||||
uint8_t handshakeIclassTag(uint8_t *card_data){
|
||||
return handshakeIclassTag_ext(card_data, false);
|
||||
}
|
||||
|
||||
|
||||
// Reader iClass Anticollission
|
||||
@@ -1687,6 +1693,9 @@ void ReaderIClass(uint8_t arg0) {
|
||||
uint8_t result_status = 0;
|
||||
bool abort_after_read = arg0 & FLAG_ICLASS_READER_ONLY_ONCE;
|
||||
bool try_once = arg0 & FLAG_ICLASS_READER_ONE_TRY;
|
||||
bool use_credit_key = false;
|
||||
if (arg0 & FLAG_ICLASS_READER_CEDITKEY)
|
||||
use_credit_key = true;
|
||||
set_tracing(TRUE);
|
||||
setupIclassReader();
|
||||
|
||||
@@ -1701,7 +1710,7 @@ void ReaderIClass(uint8_t arg0) {
|
||||
}
|
||||
WDT_HIT();
|
||||
|
||||
read_status = handshakeIclassTag(card_data);
|
||||
read_status = handshakeIclassTag_ext(card_data, use_credit_key);
|
||||
|
||||
if(read_status == 0) continue;
|
||||
if(read_status == 1) result_status = FLAG_ICLASS_READER_CSN;
|
||||
@@ -1715,11 +1724,10 @@ void ReaderIClass(uint8_t arg0) {
|
||||
if(arg0 & FLAG_ICLASS_READER_CONF)
|
||||
{
|
||||
if(sendCmdGetResponseWithRetries(readConf, sizeof(readConf),card_data+8, 10, 10))
|
||||
{
|
||||
Dbprintf("Failed to dump config block");
|
||||
}else
|
||||
{
|
||||
result_status |= FLAG_ICLASS_READER_CONF;
|
||||
} else {
|
||||
Dbprintf("Failed to dump config block");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1727,10 +1735,9 @@ void ReaderIClass(uint8_t arg0) {
|
||||
if(arg0 & FLAG_ICLASS_READER_AA){
|
||||
if(sendCmdGetResponseWithRetries(readAA, sizeof(readAA),card_data+(8*4), 10, 10))
|
||||
{
|
||||
// Dbprintf("Failed to dump AA block");
|
||||
}else
|
||||
{
|
||||
result_status |= FLAG_ICLASS_READER_AA;
|
||||
} else {
|
||||
//Dbprintf("Failed to dump AA block");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1814,7 +1821,7 @@ void ReaderIClass_Replay(uint8_t arg0, uint8_t *MAC) {
|
||||
//for now replay captured auth (as cc not updated)
|
||||
memcpy(check+5,MAC,4);
|
||||
|
||||
if(sendCmdGetResponseWithRetries(check, sizeof(check),resp, 4, 5))
|
||||
if(!sendCmdGetResponseWithRetries(check, sizeof(check),resp, 4, 5))
|
||||
{
|
||||
Dbprintf("Error: Authentication Fail!");
|
||||
continue;
|
||||
@@ -1826,7 +1833,7 @@ void ReaderIClass_Replay(uint8_t arg0, uint8_t *MAC) {
|
||||
read[2] = crc >> 8;
|
||||
read[3] = crc & 0xff;
|
||||
|
||||
if(sendCmdGetResponseWithRetries(read, sizeof(read),resp, 10, 10))
|
||||
if(!sendCmdGetResponseWithRetries(read, sizeof(read),resp, 10, 10))
|
||||
{
|
||||
Dbprintf("Dump config (block 1) failed");
|
||||
continue;
|
||||
@@ -1853,7 +1860,7 @@ void ReaderIClass_Replay(uint8_t arg0, uint8_t *MAC) {
|
||||
read[2] = crc >> 8;
|
||||
read[3] = crc & 0xff;
|
||||
|
||||
if(!sendCmdGetResponseWithRetries(read, sizeof(read), resp, 10, 10))
|
||||
if(sendCmdGetResponseWithRetries(read, sizeof(read), resp, 10, 10))
|
||||
{
|
||||
Dbprintf(" %02x: %02x %02x %02x %02x %02x %02x %02x %02x",
|
||||
block, resp[0], resp[1], resp[2],
|
||||
@@ -1904,130 +1911,129 @@ void ReaderIClass_Replay(uint8_t arg0, uint8_t *MAC) {
|
||||
LED_A_OFF();
|
||||
}
|
||||
|
||||
//2. Create Read method (cut-down from above) based off responses from 1.
|
||||
// Since we have the MAC could continue to use replay function.
|
||||
//3. Create Write method
|
||||
/*
|
||||
void IClass_iso14443A_write(uint8_t arg0, uint8_t blockNo, uint8_t *data, uint8_t *MAC) {
|
||||
uint8_t act_all[] = { 0x0a };
|
||||
uint8_t identify[] = { 0x0c };
|
||||
uint8_t select[] = { 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
uint8_t readcheck_cc[]= { 0x88, 0x02 };
|
||||
uint8_t check[] = { 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
uint8_t read[] = { 0x0c, 0x00, 0x00, 0x00 };
|
||||
uint8_t write[] = { 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
|
||||
uint16_t crc = 0;
|
||||
|
||||
uint8_t* resp = (((uint8_t *)BigBuf) + 3560);
|
||||
void iClass_ReadCheck(uint8_t blockNo, uint8_t keyType) {
|
||||
uint8_t readcheck[] = { keyType, blockNo };
|
||||
uint8_t resp[] = {0,0,0,0,0,0,0,0};
|
||||
size_t isOK = 0;
|
||||
isOK = sendCmdGetResponseWithRetries(readcheck, sizeof(readcheck), resp, sizeof(resp), 6);
|
||||
cmd_send(CMD_ACK,isOK,0,0,0,0);
|
||||
}
|
||||
|
||||
// Reset trace buffer
|
||||
memset(trace, 0x44, RECV_CMD_OFFSET);
|
||||
traceLen = 0;
|
||||
void iClass_Authentication(uint8_t *MAC) {
|
||||
uint8_t check[] = { ICLASS_CMD_CHECK, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
uint8_t resp[ICLASS_BUFFER_SIZE];
|
||||
memcpy(check+5,MAC,4);
|
||||
bool isOK;
|
||||
isOK = sendCmdGetResponseWithRetries(check, sizeof(check), resp, 4, 6);
|
||||
cmd_send(CMD_ACK,isOK,0,0,0,0);
|
||||
}
|
||||
bool iClass_ReadBlock(uint8_t blockNo, uint8_t *readdata) {
|
||||
uint8_t readcmd[] = {ICLASS_CMD_READ_OR_IDENTIFY, blockNo, 0x00, 0x00}; //0x88, 0x00 // can i use 0C?
|
||||
char bl = blockNo;
|
||||
uint16_t rdCrc = iclass_crc16(&bl, 1);
|
||||
readcmd[2] = rdCrc >> 8;
|
||||
readcmd[3] = rdCrc & 0xff;
|
||||
uint8_t resp[] = {0,0,0,0,0,0,0,0,0,0};
|
||||
bool isOK = false;
|
||||
|
||||
// Setup SSC
|
||||
FpgaSetupSsc();
|
||||
// Start from off (no field generated)
|
||||
// Signal field is off with the appropriate LED
|
||||
LED_D_OFF();
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
SpinDelay(200);
|
||||
//readcmd[1] = blockNo;
|
||||
isOK = sendCmdGetResponseWithRetries(readcmd, sizeof(readcmd), resp, 10, 10);
|
||||
memcpy(readdata, resp, sizeof(resp));
|
||||
|
||||
SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
|
||||
return isOK;
|
||||
}
|
||||
|
||||
// Now give it time to spin up.
|
||||
// Signal field is on with the appropriate LED
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);
|
||||
SpinDelay(200);
|
||||
void iClass_ReadBlk(uint8_t blockno) {
|
||||
uint8_t readblockdata[] = {0,0,0,0,0,0,0,0,0,0};
|
||||
bool isOK = false;
|
||||
isOK = iClass_ReadBlock(blockno, readblockdata);
|
||||
cmd_send(CMD_ACK, isOK, 0, 0, readblockdata, 8);
|
||||
}
|
||||
|
||||
LED_A_ON();
|
||||
void iClass_Dump(uint8_t blockno, uint8_t numblks) {
|
||||
uint8_t readblockdata[] = {0,0,0,0,0,0,0,0,0,0};
|
||||
bool isOK = false;
|
||||
uint8_t blkCnt = 0;
|
||||
|
||||
for(int i=0;i<1;i++) {
|
||||
|
||||
if(traceLen > TRACE_SIZE) {
|
||||
DbpString("Trace full");
|
||||
BigBuf_free();
|
||||
uint8_t *dataout = BigBuf_malloc(255*8);
|
||||
if (dataout == NULL){
|
||||
Dbprintf("out of memory");
|
||||
OnError(1);
|
||||
return;
|
||||
}
|
||||
memset(dataout,0xFF,255*8);
|
||||
|
||||
for (;blkCnt < numblks; blkCnt++) {
|
||||
isOK = iClass_ReadBlock(blockno+blkCnt, readblockdata);
|
||||
if (!isOK || (readblockdata[0] == 0xBB || readblockdata[7] == 0xBB || readblockdata[2] == 0xBB)) { //try again
|
||||
isOK = iClass_ReadBlock(blockno+blkCnt, readblockdata);
|
||||
if (!isOK) {
|
||||
Dbprintf("Block %02X failed to read", blkCnt+blockno);
|
||||
break;
|
||||
}
|
||||
|
||||
if (BUTTON_PRESS()) break;
|
||||
|
||||
// Send act_all
|
||||
ReaderTransmitIClass(act_all, 1);
|
||||
// Card present?
|
||||
if(ReaderReceiveIClass(resp)) {
|
||||
ReaderTransmitIClass(identify, 1);
|
||||
if(ReaderReceiveIClass(resp) == 10) {
|
||||
// Select card
|
||||
memcpy(&select[1],resp,8);
|
||||
ReaderTransmitIClass(select, sizeof(select));
|
||||
|
||||
if(ReaderReceiveIClass(resp) == 10) {
|
||||
Dbprintf(" Selected CSN: %02x %02x %02x %02x %02x %02x %02x %02x",
|
||||
resp[0], resp[1], resp[2],
|
||||
resp[3], resp[4], resp[5],
|
||||
resp[6], resp[7]);
|
||||
}
|
||||
// Card selected
|
||||
Dbprintf("Readcheck on Sector 2");
|
||||
ReaderTransmitIClass(readcheck_cc, sizeof(readcheck_cc));
|
||||
if(ReaderReceiveIClass(resp) == 8) {
|
||||
Dbprintf(" CC: %02x %02x %02x %02x %02x %02x %02x %02x",
|
||||
resp[0], resp[1], resp[2],
|
||||
resp[3], resp[4], resp[5],
|
||||
resp[6], resp[7]);
|
||||
}else return;
|
||||
Dbprintf("Authenticate");
|
||||
//for now replay captured auth (as cc not updated)
|
||||
memcpy(check+5,MAC,4);
|
||||
Dbprintf(" AA: %02x %02x %02x %02x",
|
||||
check[5], check[6], check[7],check[8]);
|
||||
ReaderTransmitIClass(check, sizeof(check));
|
||||
if(ReaderReceiveIClass(resp) == 4) {
|
||||
Dbprintf(" AR: %02x %02x %02x %02x",
|
||||
resp[0], resp[1], resp[2],resp[3]);
|
||||
}else {
|
||||
Dbprintf("Error: Authentication Fail!");
|
||||
return;
|
||||
}
|
||||
Dbprintf("Write Block");
|
||||
|
||||
//read configuration for max block number
|
||||
read_success=false;
|
||||
read[1]=1;
|
||||
uint8_t *blockno=&read[1];
|
||||
crc = iclass_crc16((char *)blockno,1);
|
||||
read[2] = crc >> 8;
|
||||
read[3] = crc & 0xff;
|
||||
while(!read_success){
|
||||
ReaderTransmitIClass(read, sizeof(read));
|
||||
if(ReaderReceiveIClass(resp) == 10) {
|
||||
read_success=true;
|
||||
mem=resp[5];
|
||||
memory.k16= (mem & 0x80);
|
||||
memory.book= (mem & 0x20);
|
||||
memory.k2= (mem & 0x8);
|
||||
memory.lockauth= (mem & 0x2);
|
||||
memory.keyaccess= (mem & 0x1);
|
||||
|
||||
}
|
||||
}
|
||||
if (memory.k16){
|
||||
cardsize=255;
|
||||
}else cardsize=32;
|
||||
//check card_size
|
||||
|
||||
memcpy(write+1,blockNo,1);
|
||||
memcpy(write+2,data,8);
|
||||
memcpy(write+10,mac,4);
|
||||
while(!send_success){
|
||||
ReaderTransmitIClass(write, sizeof(write));
|
||||
if(ReaderReceiveIClass(resp) == 10) {
|
||||
write_success=true;
|
||||
}
|
||||
}//
|
||||
}
|
||||
WDT_HIT();
|
||||
memcpy(dataout+(blkCnt*8),readblockdata,8);
|
||||
}
|
||||
|
||||
LED_A_OFF();
|
||||
}*/
|
||||
//return pointer to dump memory in arg3
|
||||
cmd_send(CMD_ACK,isOK,blkCnt,BigBuf_max_traceLen(),0,0);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
LEDsoff();
|
||||
BigBuf_free();
|
||||
}
|
||||
|
||||
bool iClass_WriteBlock_ext(uint8_t blockNo, uint8_t *data) {
|
||||
uint8_t write[] = { ICLASS_CMD_UPDATE, blockNo, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
//uint8_t readblockdata[10];
|
||||
//write[1] = blockNo;
|
||||
memcpy(write+2, data, 12); // data + mac
|
||||
uint8_t resp[] = {0,0,0,0,0,0,0,0,0,0};
|
||||
bool isOK;
|
||||
isOK = sendCmdGetResponseWithRetries(write,sizeof(write),resp,sizeof(resp),10);
|
||||
if (isOK) {
|
||||
//Dbprintf("WriteResp: %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",resp[0],resp[1],resp[2],resp[3],resp[4],resp[5],resp[6],resp[7],resp[8],resp[9]);
|
||||
if (memcmp(write+2,resp,8)) {
|
||||
//error try again
|
||||
isOK = sendCmdGetResponseWithRetries(write,sizeof(write),resp,sizeof(resp),10);
|
||||
}
|
||||
}
|
||||
return isOK;
|
||||
}
|
||||
|
||||
void iClass_WriteBlock(uint8_t blockNo, uint8_t *data) {
|
||||
bool isOK = iClass_WriteBlock_ext(blockNo, data);
|
||||
if (isOK){
|
||||
Dbprintf("Write block [%02x] successful",blockNo);
|
||||
}else {
|
||||
Dbprintf("Write block [%02x] failed",blockNo);
|
||||
}
|
||||
cmd_send(CMD_ACK,isOK,0,0,0,0);
|
||||
}
|
||||
|
||||
void iClass_Clone(uint8_t startblock, uint8_t endblock, uint8_t *data) {
|
||||
int i;
|
||||
int written = 0;
|
||||
int total_block = (endblock - startblock) + 1;
|
||||
for (i = 0; i < total_block;i++){
|
||||
// block number
|
||||
if (iClass_WriteBlock_ext(i+startblock, data+(i*12))){
|
||||
Dbprintf("Write block [%02x] successful",i + startblock);
|
||||
written++;
|
||||
} else {
|
||||
if (iClass_WriteBlock_ext(i+startblock, data+(i*12))){
|
||||
Dbprintf("Write block [%02x] successful",i + startblock);
|
||||
written++;
|
||||
} else {
|
||||
Dbprintf("Write block [%02x] failed",i + startblock);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (written == total_block)
|
||||
Dbprintf("Clone complete");
|
||||
else
|
||||
Dbprintf("Clone incomplete");
|
||||
|
||||
cmd_send(CMD_ACK,1,0,0,0,0);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
LEDsoff();
|
||||
}
|
||||
|
||||
+4
-25
@@ -947,10 +947,10 @@ void SimulateIso14443aTag(int tagType, int flags, byte_t* data)
|
||||
uint8_t sak;
|
||||
|
||||
// PACK response to PWD AUTH for EV1/NTAG
|
||||
uint8_t response8[4];
|
||||
uint8_t response8[4] = {0,0,0,0};
|
||||
|
||||
// The first response contains the ATQA (note: bytes are transmitted in reverse order).
|
||||
uint8_t response1[2];
|
||||
uint8_t response1[2] = {0,0};
|
||||
|
||||
switch (tagType) {
|
||||
case 1: { // MIFARE Classic
|
||||
@@ -1299,7 +1299,8 @@ void SimulateIso14443aTag(int tagType, int flags, byte_t* data)
|
||||
if ( tagType == 7 ) {
|
||||
p_response = &responses[8]; // PACK response
|
||||
uint32_t pwd = bytes_to_num(receivedCmd+1,4);
|
||||
Dbprintf("Auth attempt: %08x", pwd);
|
||||
|
||||
if ( MF_DBGLEVEL >= 3) Dbprintf("Auth attempt: %08x", pwd);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -2206,28 +2207,6 @@ int32_t dist_nt(uint32_t nt1, uint32_t nt2) {
|
||||
return(-99999); // either nt1 or nt2 are invalid nonces
|
||||
}
|
||||
|
||||
int32_t dist_nt_ex32(uint32_t nt1, uint32_t nt2, bool *result) {
|
||||
|
||||
uint16_t i;
|
||||
uint32_t nttmp1, nttmp2;
|
||||
|
||||
if (nt1 == nt2) return 0;
|
||||
|
||||
nttmp1 = nt1;
|
||||
nttmp2 = nt2;
|
||||
|
||||
*result = true;
|
||||
for (i = 1; i < 0xFFFFFFFF; i++) {
|
||||
nttmp1 = prng_successor(nttmp1, 1);
|
||||
if (nttmp1 == nt2) return i;
|
||||
|
||||
nttmp2 = prng_successor(nttmp2, 1);
|
||||
if (nttmp2 == nt1) return -i;
|
||||
}
|
||||
|
||||
*result = false;
|
||||
return(-99999); // either nt1 or nt2 are invalid nonces
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Recover several bits of the cypher stream. This implements (first stages of)
|
||||
|
||||
+257
@@ -2125,3 +2125,260 @@ void CopyViKingtoT55x7(uint32_t block1,uint32_t block2)
|
||||
DbpString("DONE!");
|
||||
}
|
||||
|
||||
|
||||
#define T0_PCF 8 //period for the pcf7931 in us
|
||||
|
||||
/* Write on a byte of a PCF7931 tag
|
||||
* @param address : address of the block to write
|
||||
@param byte : address of the byte to write
|
||||
@param data : data to write
|
||||
*/
|
||||
void WritePCF7931(uint8_t pass1, uint8_t pass2, uint8_t pass3, uint8_t pass4, uint8_t pass5, uint8_t pass6, uint8_t pass7, uint16_t init_delay, int32_t l, int32_t p, uint8_t address, uint8_t byte, uint8_t data)
|
||||
{
|
||||
|
||||
uint32_t tab[1024]={0}; // data times frame
|
||||
uint32_t u = 0;
|
||||
uint8_t parity = 0;
|
||||
bool comp = 0;
|
||||
|
||||
|
||||
//BUILD OF THE DATA FRAME
|
||||
|
||||
//alimentation of the tag (time for initializing)
|
||||
AddPatternPCF7931(init_delay, 0, 8192/2*T0_PCF, tab);
|
||||
|
||||
//PMC
|
||||
Dbprintf("Initialization delay : %d us", init_delay);
|
||||
AddPatternPCF7931(8192/2*T0_PCF + 319*T0_PCF+70, 3*T0_PCF, 29*T0_PCF, tab);
|
||||
|
||||
Dbprintf("Offsets : %d us on the low pulses width, %d us on the low pulses positions", l, p);
|
||||
|
||||
//password indication bit
|
||||
AddBitPCF7931(1, tab, l, p);
|
||||
|
||||
|
||||
//password (on 56 bits)
|
||||
Dbprintf("Password (LSB first on each byte) : %02x %02x %02x %02x %02x %02x %02x", pass1,pass2,pass3,pass4,pass5,pass6,pass7);
|
||||
AddBytePCF7931(pass1, tab, l, p);
|
||||
AddBytePCF7931(pass2, tab, l, p);
|
||||
AddBytePCF7931(pass3, tab, l, p);
|
||||
AddBytePCF7931(pass4, tab, l, p);
|
||||
AddBytePCF7931(pass5, tab, l, p);
|
||||
AddBytePCF7931(pass6, tab, l, p);
|
||||
AddBytePCF7931(pass7, tab, l, p);
|
||||
|
||||
|
||||
//programming mode (0 or 1)
|
||||
AddBitPCF7931(0, tab, l, p);
|
||||
|
||||
//block adress on 6 bits
|
||||
Dbprintf("Block address : %02x", address);
|
||||
for (u=0; u<6; u++)
|
||||
{
|
||||
if (address&(1<<u)) { // bit 1
|
||||
parity++;
|
||||
AddBitPCF7931(1, tab, l, p);
|
||||
} else{ // bit 0
|
||||
AddBitPCF7931(0, tab, l, p);
|
||||
}
|
||||
}
|
||||
|
||||
//byte address on 4 bits
|
||||
Dbprintf("Byte address : %02x", byte);
|
||||
for (u=0; u<4; u++)
|
||||
{
|
||||
if (byte&(1<<u)) { // bit 1
|
||||
parity++;
|
||||
AddBitPCF7931(1, tab, l, p);
|
||||
} else{ // bit 0
|
||||
AddBitPCF7931(0, tab, l, p);
|
||||
}
|
||||
}
|
||||
|
||||
//data on 8 bits
|
||||
Dbprintf("Data : %02x", data);
|
||||
for (u=0; u<8; u++)
|
||||
{
|
||||
if (data&(1<<u)) { // bit 1
|
||||
parity++;
|
||||
AddBitPCF7931(1, tab, l, p);
|
||||
} else{ //bit 0
|
||||
AddBitPCF7931(0, tab, l, p);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//parity bit
|
||||
if((parity%2)==0){
|
||||
AddBitPCF7931(0, tab, l, p); //even parity
|
||||
}else{
|
||||
AddBitPCF7931(1, tab, l, p);//odd parity
|
||||
}
|
||||
|
||||
//time access memory
|
||||
AddPatternPCF7931(5120+2680, 0, 0, tab);
|
||||
|
||||
//conversion of the scale time
|
||||
for(u=0;u<500;u++){
|
||||
tab[u]=(tab[u] * 3)/2;
|
||||
}
|
||||
|
||||
|
||||
//compennsation of the counter reload
|
||||
while (!comp){
|
||||
comp = 1;
|
||||
for(u=0;tab[u]!=0;u++){
|
||||
if(tab[u] > 0xFFFF){
|
||||
tab[u] -= 0xFFFF;
|
||||
comp = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SendCmdPCF7931(tab);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Send a trame to a PCF7931 tags
|
||||
* @param tab : array of the data frame
|
||||
*/
|
||||
|
||||
void SendCmdPCF7931(uint32_t * tab){
|
||||
uint16_t u=0;
|
||||
uint16_t tempo=0;
|
||||
|
||||
Dbprintf("SENDING DATA FRAME...");
|
||||
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
||||
|
||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
|
||||
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU );
|
||||
|
||||
LED_A_ON();
|
||||
|
||||
// steal this pin from the SSP and use it to control the modulation
|
||||
AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT;
|
||||
AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT;
|
||||
|
||||
//initialization of the timer
|
||||
AT91C_BASE_PMC->PMC_PCER |= (0x1 << 12) | (0x1 << 13) | (0x1 << 14);
|
||||
AT91C_BASE_TCB->TCB_BMR = AT91C_TCB_TC0XC0S_NONE | AT91C_TCB_TC1XC1S_TIOA0 | AT91C_TCB_TC2XC2S_NONE;
|
||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; // timer disable
|
||||
AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_TIMER_DIV3_CLOCK; //clock at 48/32 MHz
|
||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN;
|
||||
AT91C_BASE_TCB->TCB_BCR = 1;
|
||||
|
||||
|
||||
tempo = AT91C_BASE_TC0->TC_CV;
|
||||
for(u=0;tab[u]!= 0;u+=3){
|
||||
|
||||
|
||||
// modulate antenna
|
||||
HIGH(GPIO_SSC_DOUT);
|
||||
while(tempo != tab[u]){
|
||||
tempo = AT91C_BASE_TC0->TC_CV;
|
||||
}
|
||||
|
||||
// stop modulating antenna
|
||||
LOW(GPIO_SSC_DOUT);
|
||||
while(tempo != tab[u+1]){
|
||||
tempo = AT91C_BASE_TC0->TC_CV;
|
||||
}
|
||||
|
||||
|
||||
// modulate antenna
|
||||
HIGH(GPIO_SSC_DOUT);
|
||||
while(tempo != tab[u+2]){
|
||||
tempo = AT91C_BASE_TC0->TC_CV;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
LED_A_OFF();
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
SpinDelay(200);
|
||||
|
||||
|
||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; // timer disable
|
||||
DbpString("FINISH !");
|
||||
DbpString("(Could be usefull to send the same trame many times)");
|
||||
LED(0xFFFF, 1000);
|
||||
}
|
||||
|
||||
|
||||
/* Add a byte for building the data frame of PCF7931 tags
|
||||
* @param b : byte to add
|
||||
* @param tab : array of the data frame
|
||||
* @param l : offset on low pulse width
|
||||
* @param p : offset on low pulse positioning
|
||||
*/
|
||||
|
||||
bool AddBytePCF7931(uint8_t byte, uint32_t * tab, int32_t l, int32_t p){
|
||||
|
||||
uint32_t u;
|
||||
for (u=0; u<8; u++)
|
||||
{
|
||||
if (byte&(1<<u)) { //bit à 1
|
||||
if(AddBitPCF7931(1, tab, l, p)==1)return 1;
|
||||
} else { //bit à 0
|
||||
if(AddBitPCF7931(0, tab, l, p)==1)return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Add a bits for building the data frame of PCF7931 tags
|
||||
* @param b : bit to add
|
||||
* @param tab : array of the data frame
|
||||
* @param l : offset on low pulse width
|
||||
* @param p : offset on low pulse positioning
|
||||
*/
|
||||
bool AddBitPCF7931(bool b, uint32_t * tab, int32_t l, int32_t p){
|
||||
uint8_t u = 0;
|
||||
|
||||
for(u=0;tab[u]!=0;u+=3){} //we put the cursor at the last value of the array
|
||||
|
||||
|
||||
if(b==1){ //add a bit 1
|
||||
if(u==0) tab[u] = 34*T0_PCF+p;
|
||||
else tab[u] = 34*T0_PCF+tab[u-1]+p;
|
||||
|
||||
tab[u+1] = 6*T0_PCF+tab[u]+l;
|
||||
tab[u+2] = 88*T0_PCF+tab[u+1]-l-p;
|
||||
return 0;
|
||||
}else{ //add a bit 0
|
||||
|
||||
if(u==0) tab[u] = 98*T0_PCF+p;
|
||||
else tab[u] = 98*T0_PCF+tab[u-1]+p;
|
||||
|
||||
tab[u+1] = 6*T0_PCF+tab[u]+l;
|
||||
tab[u+2] = 24*T0_PCF+tab[u+1]-l-p;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Add a custom pattern in the data frame
|
||||
* @param a : delay of the first high pulse
|
||||
* @param b : delay of the low pulse
|
||||
* @param c : delay of the last high pulse
|
||||
* @param tab : array of the data frame
|
||||
*/
|
||||
bool AddPatternPCF7931(uint32_t a, uint32_t b, uint32_t c, uint32_t * tab){
|
||||
uint32_t u = 0;
|
||||
for(u=0;tab[u]!=0;u+=3){} //we put the cursor at the last value of the array
|
||||
|
||||
if(u==0) tab[u] = a;
|
||||
else tab[u] = a + tab[u-1];
|
||||
|
||||
tab[u+1] = b+tab[u];
|
||||
tab[u+2] = c+tab[u+1];
|
||||
|
||||
return 0;
|
||||
}
|
||||
+1
-1
@@ -602,7 +602,7 @@ int CmdHF14ACmdRaw(const char *cmd) {
|
||||
uint32_t temp;
|
||||
|
||||
if (strlen(cmd)<2) {
|
||||
PrintAndLog("Usage: hf 14a raw [-r] [-c] [-p] [-a] [-t] <milliseconds> [-b] <number of bits> <0A 0B 0C ... hex>");
|
||||
PrintAndLog("Usage: hf 14a raw [-r] [-c] [-p] [-a] [-T] [-t] <milliseconds> [-b] <number of bits> <0A 0B 0C ... hex>");
|
||||
PrintAndLog(" -r do not read response");
|
||||
PrintAndLog(" -c calculate and append CRC");
|
||||
PrintAndLog(" -p leave the signal field ON after receive");
|
||||
|
||||
@@ -73,10 +73,14 @@ int CmdSrix4kRead(const char *Cmd)
|
||||
}
|
||||
|
||||
int rawClose(void){
|
||||
UsbCommand resp;
|
||||
UsbCommand c = {CMD_ISO_14443B_COMMAND, {0, 0, 0}};
|
||||
clearCommandBuffer();
|
||||
SendCommand(&c);
|
||||
if (!WaitForResponseTimeout(CMD_ACK,&resp,1000)) {
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int HF14BCmdRaw(bool reply, bool *crc, bool power, uint8_t *data, uint8_t *datalen, bool verbose){
|
||||
|
||||
+1237
-293
File diff suppressed because it is too large
Load Diff
+18
-3
@@ -14,11 +14,26 @@
|
||||
|
||||
int CmdHFiClass(const char *Cmd);
|
||||
|
||||
int CmdHFiClassSnoop(const char *Cmd);
|
||||
int CmdHFiClassSim(const char *Cmd);
|
||||
int CmdHFiClassCalcNewKey(const char *Cmd);
|
||||
int CmdHFiClassCloneTag(const char *Cmd);
|
||||
int CmdHFiClassDecrypt(const char *Cmd);
|
||||
int CmdHFiClassEncryptBlk(const char *Cmd);
|
||||
int CmdHFiClassELoad(const char *Cmd);
|
||||
int CmdHFiClassList(const char *Cmd);
|
||||
int HFiClassReader(const char *Cmd, bool loop, bool verbose);
|
||||
int CmdHFiClassReader(const char *Cmd);
|
||||
int CmdHFiClassReader_Dump(const char *Cmd);
|
||||
int CmdHFiClassReader_Replay(const char *Cmd);
|
||||
|
||||
int CmdHFiClassReadKeyFile(const char *filename);
|
||||
int CmdHFiClassReadTagFile(const char *Cmd);
|
||||
int CmdHFiClass_ReadBlock(const char *Cmd);
|
||||
int CmdHFiClass_TestMac(const char *Cmd);
|
||||
int CmdHFiClassManageKeys(const char *Cmd);
|
||||
int CmdHFiClass_loclass(const char *Cmd);
|
||||
int CmdHFiClassSnoop(const char *Cmd);
|
||||
int CmdHFiClassSim(const char *Cmd);
|
||||
int CmdHFiClassWriteKeyFile(const char *Cmd);
|
||||
int CmdHFiClass_WriteBlock(const char *Cmd);
|
||||
void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t endblock, size_t filesize);
|
||||
void HFiClassCalcDivKey(uint8_t *CSN, uint8_t *KEY, uint8_t *div_key, bool elite);
|
||||
#endif
|
||||
|
||||
+10
-2
@@ -1230,8 +1230,8 @@ int CmdHF14AMfELoad(const char *Cmd)
|
||||
case '\0': numBlocks = 16*4; break;
|
||||
case '2' : numBlocks = 32*4; break;
|
||||
case '4' : numBlocks = 256; break;
|
||||
case 'U' : // fall through
|
||||
case 'u' : numBlocks = 255; blockWidth = 8; break;
|
||||
case 'U' : // fall through , NTAG 215 has 135blocks a 540 bytes.
|
||||
case 'u' : numBlocks = 135; blockWidth = 8; break;
|
||||
default: {
|
||||
numBlocks = 16*4;
|
||||
nameParamNo = 0;
|
||||
@@ -1980,6 +1980,13 @@ int CmdHF14AMfSniff(const char *Cmd){
|
||||
return 0;
|
||||
}
|
||||
|
||||
//needs nt, ar, at, Data to decrypt
|
||||
int CmdDecryptTraceCmds(const char *Cmd){
|
||||
uint8_t data[50];
|
||||
int len = 0;
|
||||
param_gethex_ex(Cmd,3,data,&len);
|
||||
return tryDecryptWord(param_get32ex(Cmd,0,0,16),param_get32ex(Cmd,1,0,16),param_get32ex(Cmd,2,0,16),data,len/2);
|
||||
}
|
||||
|
||||
static command_t CommandTable[] =
|
||||
{
|
||||
@@ -2008,6 +2015,7 @@ static command_t CommandTable[] =
|
||||
{"cgetsc", CmdHF14AMfCGetSc, 0, "Read sector - Magic Chinese card"},
|
||||
{"cload", CmdHF14AMfCLoad, 0, "Load dump into magic Chinese card"},
|
||||
{"csave", CmdHF14AMfCSave, 0, "Save dump from magic Chinese card into file or emulator"},
|
||||
{"decrypt", CmdDecryptTraceCmds, 1, "[nt] [ar_enc] [at_enc] [data] - to decrypt snoop or trace"},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
|
||||
+2
-2
@@ -16,11 +16,11 @@
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include "proxmark3.h"
|
||||
#include "../common/iso14443crc.h"
|
||||
#include "iso14443crc.h"
|
||||
#include "data.h"
|
||||
#include "ui.h"
|
||||
#include "cmdparser.h"
|
||||
#include "../include/common.h"
|
||||
#include "common.h"
|
||||
#include "util.h"
|
||||
#include "mifarehost.h"
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
//#include <openssl/des.h>
|
||||
#include "loclass/des.h"
|
||||
#include "cmdmain.h"
|
||||
#include "proxmark3.h"
|
||||
|
||||
+1
-1
@@ -1924,7 +1924,7 @@ static command_t CommandTable[] =
|
||||
{"dump", CmdHF14AMfUDump, 0, "Dump Ultralight / Ultralight-C / NTAG tag to binary file"},
|
||||
{"rdbl", CmdHF14AMfURdBl, 0, "Read block"},
|
||||
{"wrbl", CmdHF14AMfUWrBl, 0, "Write block"},
|
||||
{"eload", CmdHF14AMfuELoad, 0, "Load from file emulator dump"},
|
||||
{"eload", CmdHF14AMfuELoad, 0, "<not implemented> Load from file emulator dump"},
|
||||
{"cauth", CmdHF14AMfucAuth, 0, "Authentication - Ultralight C"},
|
||||
{"setpwd", CmdHF14AMfucSetPwd, 1, "Set 3des password - Ultralight-C"},
|
||||
{"setuid", CmdHF14AMfucSetUid, 1, "Set UID - MAGIC tags only"},
|
||||
|
||||
+5
-3
@@ -85,7 +85,9 @@ int CmdLFCommandRead(const char *Cmd)
|
||||
if(errors) return usage_lf_cmdread();
|
||||
|
||||
UsbCommand c = {CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K};
|
||||
|
||||
sscanf(Cmd, "%"lli" %"lli" %"lli" %s %s", &c.arg[0], &c.arg[1], &c.arg[2],(char*)(&c.d.asBytes),(char*)(&dummy+1));
|
||||
|
||||
// in case they specified 'h'
|
||||
strcpy((char *)&c.d.asBytes + strlen((char *)c.d.asBytes), dummy);
|
||||
|
||||
@@ -1212,7 +1214,7 @@ static command_t CommandTable[] =
|
||||
{"pcf7931", CmdLFPCF7931, 1, "{ PCF7931 RFIDs... }"},
|
||||
{"ti", CmdLFTI, 1, "{ TI RFIDs... }"},
|
||||
{"t55xx", CmdLFT55XX, 1, "{ T55X7 RFIDs... }"},
|
||||
{"viking", CmdLFViking, 1, "{ Viking RFIDs... }"},
|
||||
{"viking", CmdLFViking, 1, "{ Viking RFIDs... }"},
|
||||
{"config", CmdLFSetConfig, 0, "Set config for LF sampling, bit/sample, decimation, frequency"},
|
||||
|
||||
{"cmdread", CmdLFCommandRead, 0, "<off period> <'0' period> <'1' period> <command> ['h' 134] \n\t\t-- Modulate LF reader field to send command before read (all periods in microseconds)"},
|
||||
@@ -1220,9 +1222,9 @@ static command_t CommandTable[] =
|
||||
{"indalademod", CmdIndalaDemod, 1, "['224'] -- Demodulate samples for Indala 64 bit UID (option '224' for 224 bit)"},
|
||||
{"indalaclone", CmdIndalaClone, 0, "<UID> ['l']-- Clone Indala to T55x7 (tag must be in antenna)(UID in HEX)(option 'l' for 224 UID"},
|
||||
{"read", CmdLFRead, 0, "['s' silent] Read 125/134 kHz LF ID-only tag. Do 'lf read h' for help"},
|
||||
{"search", CmdLFfind, 1, "[offline] ['u'] Read and Search for valid known tag (in offline mode it you can load first then search) \n\t\t- 'u' to search for unknown tags"},
|
||||
{"search", CmdLFfind, 1, "[offline] ['u'] Read and Search for valid known tag (in offline mode it you can load first then search) \n\t\t-- 'u' to search for unknown tags"},
|
||||
{"sim", CmdLFSim, 0, "[GAP] -- Simulate LF tag from buffer with optional GAP (in microseconds)"},
|
||||
{"simask", CmdLFaskSim, 0, "[clock] [invert <1|0>] [manchester/raw <'m'|'r'>] [msg separator 's'] [d <hexdata>] \n\t\t-- Simulate LF ASK tag from demodbuffer or input"},
|
||||
{"simask", CmdLFaskSim, 0, "[clock] [invert <1|0>] [biphase/manchester/raw <'b'|'m'|'r'>] [msg separator 's'] [d <hexdata>] \n\t\t-- Simulate LF ASK tag from demodbuffer or input"},
|
||||
{"simfsk", CmdLFfskSim, 0, "[c <clock>] [i] [H <fcHigh>] [L <fcLow>] [d <hexdata>] \n\t\t-- Simulate LF FSK tag from demodbuffer or input"},
|
||||
{"simpsk", CmdLFpskSim, 0, "[1|2|3] [c <clock>] [i] [r <carrier>] [d <raw hex to sim>] \n\t\t-- Simulate LF PSK tag from demodbuffer or input"},
|
||||
{"simbidir", CmdLFSimBidir, 0, "Simulate LF tag (with bidirectional data transmission between reader and tag)"},
|
||||
|
||||
+127
-13
@@ -1,13 +1,13 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2012 Chalk <chalk.secu at gmail.com>
|
||||
//
|
||||
// 2015 Dake <thomas.cayrou at gmail.com>
|
||||
|
||||
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
||||
// at your option, any later version. See the LICENSE.txt file for the text of
|
||||
// the license.
|
||||
//-----------------------------------------------------------------------------
|
||||
// Low frequency PCF7931 commands
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "proxmark3.h"
|
||||
@@ -21,30 +21,144 @@
|
||||
|
||||
static int CmdHelp(const char *Cmd);
|
||||
|
||||
struct pcf7931_config configPcf = {{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},17500,{0,0}};
|
||||
|
||||
int usage_pcf7931_read()
|
||||
{
|
||||
PrintAndLog("Usage: lf pcf7931 read [h] ");
|
||||
PrintAndLog("This command tries to read a PCF7931 tag.");
|
||||
PrintAndLog("Options: ");
|
||||
PrintAndLog(" h This help");
|
||||
PrintAndLog("Examples:");
|
||||
PrintAndLog(" lf pcf7931 read");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CmdLFPCF7931Read(const char *Cmd)
|
||||
{
|
||||
UsbCommand c = {CMD_PCF7931_READ};
|
||||
SendCommand(&c);
|
||||
UsbCommand resp;
|
||||
WaitForResponse(CMD_ACK,&resp);
|
||||
uint8_t cmdp = 0;
|
||||
|
||||
if (param_getchar(Cmd, cmdp) == 'H' || param_getchar(Cmd, cmdp) == 'h')
|
||||
return usage_pcf7931_read();
|
||||
|
||||
UsbCommand c = {CMD_PCF7931_READ};
|
||||
clearCommandBuffer();
|
||||
SendCommand(&c);
|
||||
UsbCommand resp;
|
||||
WaitForResponse(CMD_ACK,&resp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CmdLFPCF7931Config(const char *Cmd)
|
||||
{
|
||||
int res = 0;
|
||||
// res = sscanf(Cmd,
|
||||
// "%02x %02x %hu %hu %hu %hu %hu %hhu %hd %hd",
|
||||
// &configPcf.password[0],
|
||||
// &configPcf.password[1],
|
||||
// &configPcf.password[2],
|
||||
// &configPcf.password[3],
|
||||
// &configPcf.password[4],
|
||||
// &configPcf.password[5],
|
||||
// &configPcf.password[6],
|
||||
// &configPcf.init_delay,
|
||||
// &configPcf.offset[0],
|
||||
// &configPcf.offset[1]);
|
||||
|
||||
if (res >= 7 || res < 1){
|
||||
if(res == 7) configPcf.init_delay = 17500; //default value
|
||||
|
||||
if(res<=8){
|
||||
configPcf.offset[0] = 0; //default value
|
||||
configPcf.offset[1] = 0; //default value
|
||||
}
|
||||
|
||||
if(res < 1){
|
||||
PrintAndLog("Usage: <password byte 1 (in hex, lsb first)> <password byte 2 (in hex, lsb first)> [...] <password byte 7 (in hex, lsb first)> <tag initialization delay (in us)> <optional : offset on the low pulses width (in us)> <optional : offset on the low pulses position (in us)>");
|
||||
PrintAndLog("The time offsets could be usefull to correct slew rate generated by the antenna.");
|
||||
}
|
||||
|
||||
PrintAndLog("Current configuration :");
|
||||
PrintAndLog("Password (LSB first on each byte) : %02x %02x %02x %02x %02x %02x %02x", configPcf.password[0], configPcf.password[1], configPcf.password[2], configPcf.password[3], configPcf.password[4], configPcf.password[5], configPcf.password[6]);
|
||||
PrintAndLog("Tag initialization delay : %d us", configPcf.init_delay);
|
||||
PrintAndLog("Offsets : %d us on the low pulses width, %d us on the low pulses positions", configPcf.offset[0], configPcf.offset[1]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//default values
|
||||
configPcf.password[0] = 0xFF;
|
||||
configPcf.password[1] = 0xFF;
|
||||
configPcf.password[2] = 0xFF;
|
||||
configPcf.password[3] = 0xFF;
|
||||
configPcf.password[4] = 0xFF;
|
||||
configPcf.password[5] = 0xFF;
|
||||
configPcf.password[6] = 0xFF;
|
||||
|
||||
configPcf.init_delay = 17500;
|
||||
configPcf.offset[0] = 0;
|
||||
configPcf.offset[1] = 0;
|
||||
|
||||
PrintAndLog("Incorrect format");
|
||||
PrintAndLog("Examples of right usage : lf pcf7931 config 11 22 33 44 55 66 77 20000");
|
||||
PrintAndLog(" lf pcf7931 config FF FF FF FF FF FF FF 17500 -10 30");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CmdLFPCF7931Write(const char *Cmd)
|
||||
{
|
||||
UsbCommand c = {CMD_PCF7931_WRITE};
|
||||
|
||||
int res = 0;
|
||||
res = sscanf(Cmd, "%" SCNu64 " %" SCNu64 " %" SCNu64 , &c.arg[0], &c.arg[1], &c.arg[2]);
|
||||
|
||||
if(res < 1) {
|
||||
PrintAndLog("Please specify the block address in hex");
|
||||
return 1;
|
||||
}
|
||||
if (res == 1){
|
||||
PrintAndLog("Please specify the byte address in hex");
|
||||
return 2;
|
||||
}
|
||||
if(res == 2) {
|
||||
PrintAndLog("Please specify the data in hex (1 byte)");
|
||||
return 3;
|
||||
}
|
||||
if(res == 3) {
|
||||
|
||||
memcpy(c.d.asDwords, configPcf.password, 7);
|
||||
|
||||
c.d.asDwords[7] = (configPcf.offset[0]+128);
|
||||
c.d.asDwords[8] = (configPcf.offset[1]+128);
|
||||
c.d.asDwords[9] = configPcf.init_delay;
|
||||
|
||||
clearCommandBuffer();
|
||||
SendCommand(&c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
PrintAndLog("INCORRECT FORMAT");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static command_t CommandTable[] =
|
||||
{
|
||||
{"help", CmdHelp, 1, "This help"},
|
||||
{"read", CmdLFPCF7931Read, 1, "Read content of a PCF7931 transponder"},
|
||||
{NULL, NULL, 0, NULL}
|
||||
{"help", CmdHelp, 1, "This help"},
|
||||
{"read", CmdLFPCF7931Read, 1, "Read content of a PCF7931 transponder"},
|
||||
{"write", CmdLFPCF7931Write, 1, "Write data on a PCF7931 transponder. Usage : lf pcf7931 write <bloc address> <byte address> <data>"},
|
||||
{"config", CmdLFPCF7931Config, 1, "Configure the password, the tags initialization delay and time offsets (optional)"},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
int CmdLFPCF7931(const char *Cmd)
|
||||
{
|
||||
CmdsParse(CommandTable, Cmd);
|
||||
return 0;
|
||||
CmdsParse(CommandTable, Cmd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CmdHelp(const char *Cmd)
|
||||
{
|
||||
CmdsHelp(CommandTable);
|
||||
return 0;
|
||||
CmdsHelp(CommandTable);
|
||||
return 0;
|
||||
}
|
||||
|
||||
+12
-1
@@ -1,6 +1,7 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2012 Chalk <chalk.secu at gmail.com>
|
||||
//
|
||||
// 2015 Dake <thomas.cayrou at gmail.com>
|
||||
|
||||
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
||||
// at your option, any later version. See the LICENSE.txt file for the text of
|
||||
// the license.
|
||||
@@ -11,8 +12,18 @@
|
||||
#ifndef CMDLFPCF7931_H__
|
||||
#define CMDLFPCF7931_H__
|
||||
|
||||
struct pcf7931_config{
|
||||
uint8_t password[7];
|
||||
uint16_t init_delay;
|
||||
int16_t offset[2];
|
||||
};
|
||||
|
||||
int CmdLFPCF7931(const char *Cmd);
|
||||
|
||||
int CmdLFPCF7931Read(const char *Cmd);
|
||||
|
||||
int CmdLFPCF7931Write(const char *Cmd);
|
||||
|
||||
int CmdLFPCF7931Config(const char *Cmd);
|
||||
|
||||
#endif
|
||||
|
||||
+7
-1
@@ -37,7 +37,7 @@ int usage_t55xx_config(){
|
||||
PrintAndLog("Options: ");
|
||||
PrintAndLog(" h This help");
|
||||
PrintAndLog(" b <8|16|32|40|50|64|100|128> Set bitrate");
|
||||
PrintAndLog(" d <FSK|FSK1|FSK1a|FSK2|FSK2a|ASK|PSK1|PSK2|NRZ|BI|BIa> Set demodulation FSK / ASK / PSK / NZ / Biphase / Biphase A");
|
||||
PrintAndLog(" d <FSK|FSK1|FSK1a|FSK2|FSK2a|ASK|PSK1|PSK2|NRZ|BI|BIa> Set demodulation FSK / ASK / PSK / NRZ / Biphase / Biphase A");
|
||||
PrintAndLog(" i [1] Invert data signal, defaults to normal");
|
||||
PrintAndLog(" o [offset] Set offset, where data should start decode in bitstream");
|
||||
PrintAndLog("");
|
||||
@@ -1059,6 +1059,12 @@ char * GetSelectedModulationStr( uint8_t id){
|
||||
return buf;
|
||||
}
|
||||
|
||||
void t55x7_create_config_block( int tagtype ){
|
||||
//switch?
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
uint32_t PackBits(uint8_t start, uint8_t len, uint8_t* bits){
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user