mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-14 18:48:13 -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:
parent
f3cfe428f8
commit
e98572a1e2
34 changed files with 2085 additions and 519 deletions
14
CHANGELOG.md
14
CHANGELOG.md
|
@ -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)
|
||||
|
|
65
README.txt
65
README.txt
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
276
armsrc/iclass.c
276
armsrc/iclass.c
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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
armsrc/lfops.c
257
armsrc/lfops.c
|
@ -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;
|
||||
}
|
|
@ -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){
|
||||
|
|
1530
client/cmdhficlass.c
1530
client/cmdhficlass.c
File diff suppressed because it is too large
Load diff
|
@ -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
|
||||
|
|
|
@ -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}
|
||||
};
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"},
|
||||
|
|
|
@ -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)"},
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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){
|
||||
|
||||
|
|
|
@ -20,13 +20,14 @@
|
|||
// FDXB requires data inversion and BiPhase 57 is simply BipHase 50 inverted, so we can either do it using the modulation scheme or the inversion flag
|
||||
// we've done both below to prove that it works either way, and the modulation value for BiPhase 50 in the Atmel data sheet of binary "10001" (17) is a typo,
|
||||
// and it should actually be "10000" (16)
|
||||
// #define T55X7_FDXB_CONFIG_BLOCK 903F8080 // emulate fdx-b - xtended mode, BiPhase ('57), data rate 32, 4 data blocks
|
||||
#define T55X7_FDXB_CONFIG_BLOCK 0x903F0082 // emulate fdx-b - xtended mode, BiPhase ('50), invert data, data rate 32, 4 data blocks
|
||||
#define T55X7_HID_26_CONFIG_BLOCK 0x00107060 // hid 26 bit - compat mode, FSK2a, data rate 50, 3 data blocks
|
||||
#define T55X7_INDALA_64_CONFIG_BLOCK 0x00081040 // emulate indala 64 bit - compat mode, PSK1, psk carrier FC * 2, data rate 32, maxblock 2
|
||||
#define T55X7_INDALA_224_CONFIG_BLOCK 0x000810E0 // emulate indala 224 bit - compat mode, PSK1, psk carrier FC * 2, data rate 32, maxblock 7
|
||||
#define T55X7_GUARDPROXII_CONFIG_BLOCK 0x00150060 // bitrate 64pcb, Direct modulation, Biphase, 3 data blocks
|
||||
#define T55X7_VIKING_CONFIG_BLOCK 0x00088040 // compat mode, data rate 32, Manchester, 2 data blocks
|
||||
// #define T55X7_FDXB_CONFIG_BLOCK 903F8080 // emulate fdx-b - xtended mode, BiPhase ('57), data rate 32, 4 data blocks
|
||||
#define T55X7_FDXB_CONFIG_BLOCK 0x903F0082 // emulate fdx-b - xtended mode, BiPhase ('50), invert data, data rate 32, 4 data blocks
|
||||
#define T55X7_HID_26_CONFIG_BLOCK 0x00107060 // hid 26 bit - compat mode, FSK2a, data rate 50, 3 data blocks
|
||||
#define T55X7_INDALA_64_CONFIG_BLOCK 0x00081040 // emulate indala 64 bit - compat mode, PSK1, psk carrier FC * 2, data rate 32, maxblock 2
|
||||
#define T55X7_INDALA_224_CONFIG_BLOCK 0x000810E0 // emulate indala 224 bit - compat mode, PSK1, psk carrier FC * 2, data rate 32, maxblock 7
|
||||
#define T55X7_GUARDPROXII_CONFIG_BLOCK 0x00150060 // bitrate 64pcb, Direct modulation, Biphase, 3 data blocks
|
||||
#define T55X7_VIKING_CONFIG_BLOCK 0x00088040 // compat mode, data rate 32, Manchester, 2 data blocks
|
||||
#define T55X7_NORALYS_CONFIG_BLOCK 0x00088C6A // compat mode, (NORALYS - KCP3000)
|
||||
#define T55X7_bin 0b0010
|
||||
|
||||
|
||||
|
|
|
@ -91,4 +91,6 @@ fc0001877bf7,--RKFÖstgötaTrafikenKeyA
|
|||
314B49474956,--VIGIK1KeyA
|
||||
564c505f4d41,--VIGIK1KeyB
|
||||
f4a9ef2afc6d,--BCARD KeyB
|
||||
a9f953def0a3,--
|
||||
a9f953def0a3,--
|
||||
75ccb59c9bed,-- mystery KeyA Mifare 1k EV1 (S50) Sector 17!
|
||||
4b791bea7bcc,-- mystery KeyB Mifare 1k EV1 (S50) Sector 17!
|
|
@ -241,6 +241,27 @@ void doMAC(uint8_t *cc_nr_p, uint8_t *div_key_p, uint8_t mac[4])
|
|||
//free(cc_nr);
|
||||
return;
|
||||
}
|
||||
void doMAC_N(uint8_t *address_data_p, uint8_t address_data_size, uint8_t *div_key_p, uint8_t mac[4])
|
||||
{
|
||||
uint8_t *address_data;
|
||||
uint8_t div_key[8];
|
||||
address_data = (uint8_t*) malloc(address_data_size);
|
||||
|
||||
memcpy(address_data, address_data_p, address_data_size);
|
||||
memcpy(div_key, div_key_p, 8);
|
||||
|
||||
reverse_arraybytes(address_data, address_data_size);
|
||||
BitstreamIn bitstream = {address_data, address_data_size * 8, 0};
|
||||
uint8_t dest []= {0,0,0,0,0,0,0,0};
|
||||
BitstreamOut out = { dest, sizeof(dest)*8, 0 };
|
||||
MAC(div_key, bitstream, out);
|
||||
//The output MAC must also be reversed
|
||||
reverse_arraybytes(dest, sizeof(dest));
|
||||
memcpy(mac, dest, 4);
|
||||
free(address_data);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifndef ON_DEVICE
|
||||
int testMAC()
|
||||
{
|
||||
|
|
|
@ -42,6 +42,8 @@
|
|||
#include <stdint.h>
|
||||
|
||||
void doMAC(uint8_t *cc_nr_p, uint8_t *div_key_p, uint8_t mac[4]);
|
||||
void doMAC_N(uint8_t *address_data_p,uint8_t address_data_size, uint8_t *div_key_p, uint8_t mac[4]);
|
||||
|
||||
#ifndef ON_DEVICE
|
||||
int testMAC();
|
||||
#endif
|
||||
|
|
|
@ -91,11 +91,17 @@ local _commands = {
|
|||
CMD_EPA_PACE_COLLECT_NONCE = 0x038A,
|
||||
CMD_EPA_PACE_REPLAY = 0x038B,
|
||||
|
||||
CMD_ICLASS_READCHECK = 0x038F,
|
||||
CMD_ICLASS_CLONE = 0x0390,
|
||||
CMD_ICLASS_DUMP = 0x0391,
|
||||
CMD_SNOOP_ICLASS = 0x0392,
|
||||
CMD_SIMULATE_TAG_ICLASS = 0x0393,
|
||||
CMD_READER_ICLASS = 0x0394,
|
||||
CMD_READER_ICLASS_REPLAY = 0x0395,
|
||||
CMD_ICLASS_ISO14443A_WRITE = 0x0397,
|
||||
CMD_ICLASS_READBLOCK = 0x0396,
|
||||
CMD_ICLASS_WRITEBLOCK = 0x0397,
|
||||
CMD_ICLASS_EML_MEMSET = 0x0398,
|
||||
CMD_ICLASS_AUTHENTICATION = 0x0399,
|
||||
|
||||
--// For measurements of the antenna tuning
|
||||
CMD_MEASURE_ANTENNA_TUNING = 0x0400,
|
||||
|
|
|
@ -181,6 +181,12 @@ local _keys = {
|
|||
--[[
|
||||
--]]
|
||||
'a9f953def0a3',
|
||||
|
||||
--[[
|
||||
mystery Key A and B for Mifare 1k EV1 (S50) Sector 17!
|
||||
--]]
|
||||
'75ccb59c9bed',
|
||||
'4b791bea7bcc',
|
||||
}
|
||||
|
||||
---
|
||||
|
|
|
@ -630,3 +630,23 @@ int mfTraceDecode(uint8_t *data_src, int len, bool wantSaveToEmlFile) {
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tryDecryptWord(uint32_t nt, uint32_t ar_enc, uint32_t at_enc, uint8_t *data, int len){
|
||||
/*
|
||||
uint32_t nt; // tag challenge
|
||||
uint32_t ar_enc; // encrypted reader response
|
||||
uint32_t at_enc; // encrypted tag response
|
||||
*/
|
||||
if (traceCrypto1) {
|
||||
crypto1_destroy(traceCrypto1);
|
||||
}
|
||||
ks2 = ar_enc ^ prng_successor(nt, 64);
|
||||
ks3 = at_enc ^ prng_successor(nt, 96);
|
||||
traceCrypto1 = lfsr_recovery64(ks2, ks3);
|
||||
|
||||
mf_crypto1_decrypt(traceCrypto1, data, len, 0);
|
||||
|
||||
PrintAndLog("Decrypted data: [%s]", sprint_hex(data,len) );
|
||||
crypto1_destroy(traceCrypto1);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -68,3 +68,4 @@ int isBlockEmpty(int blockN);
|
|||
int isBlockTrailer(int blockN);
|
||||
int loadTraceCard(uint8_t *tuid);
|
||||
int saveTraceCard(void);
|
||||
int tryDecryptWord(uint32_t nt, uint32_t ar_enc, uint32_t at_enc, uint8_t *data, int len);
|
||||
|
|
|
@ -288,4 +288,4 @@ int tryMfk64(uint64_t myuid, uint8_t *data, uint8_t *outputkey ){
|
|||
crypto1_destroy(revstate);
|
||||
crypto1_destroy(pcs);
|
||||
return 0;
|
||||
}
|
||||
}
|
|
@ -333,7 +333,28 @@ int param_gethex(const char *line, int paramnum, uint8_t * data, int hexcnt)
|
|||
|
||||
return 0;
|
||||
}
|
||||
int param_gethex_ex(const char *line, int paramnum, uint8_t * data, int *hexcnt)
|
||||
{
|
||||
int bg, en, temp, i;
|
||||
|
||||
//if (hexcnt % 2)
|
||||
// return 1;
|
||||
|
||||
if (param_getptr(line, &bg, &en, paramnum)) return 1;
|
||||
|
||||
*hexcnt = en - bg + 1;
|
||||
if (*hexcnt % 2) //error if not complete hex bytes
|
||||
return 1;
|
||||
|
||||
for(i = 0; i < *hexcnt; i += 2) {
|
||||
if (!(isxdigit(line[bg + i]) && isxdigit(line[bg + i + 1])) ) return 1;
|
||||
|
||||
sscanf((char[]){line[bg + i], line[bg + i + 1], 0}, "%X", &temp);
|
||||
data[i / 2] = temp & 0xff;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
int param_getstr(const char *line, int paramnum, char * str)
|
||||
{
|
||||
int bg, en;
|
||||
|
|
|
@ -55,6 +55,7 @@ uint64_t param_get64ex(const char *line, int paramnum, int deflt, int base);
|
|||
uint8_t param_getdec(const char *line, int paramnum, uint8_t *destination);
|
||||
uint8_t param_isdec(const char *line, int paramnum);
|
||||
int param_gethex(const char *line, int paramnum, uint8_t * data, int hexcnt);
|
||||
int param_gethex_ex(const char *line, int paramnum, uint8_t * data, int *hexcnt);
|
||||
int param_getstr(const char *line, int paramnum, char * str);
|
||||
|
||||
int hextobinarray( char *target, char *source);
|
||||
|
|
|
@ -11,13 +11,13 @@
|
|||
|
||||
|
||||
typedef struct {
|
||||
uint8_t app_limit;
|
||||
uint8_t otp[2];
|
||||
uint8_t block_writelock;
|
||||
uint8_t chip_config;
|
||||
uint8_t mem_config;
|
||||
uint8_t eas;
|
||||
uint8_t fuses;
|
||||
uint8_t app_limit; //[8]
|
||||
uint8_t otp[2]; //[9-10]
|
||||
uint8_t block_writelock;//[11]
|
||||
uint8_t chip_config; //[12]
|
||||
uint8_t mem_config; //[13]
|
||||
uint8_t eas; //[14]
|
||||
uint8_t fuses; //[15]
|
||||
}picopass_conf_block;
|
||||
|
||||
|
||||
|
@ -74,24 +74,54 @@ void fuse_config(const picopass_hdr *hdr)
|
|||
if( isset( fuses, FUSE_RA)) prnt(" RA: Read access enabled");
|
||||
else prnt(" RA: Read access not enabled");
|
||||
}
|
||||
void mem_config(const picopass_hdr *hdr)
|
||||
|
||||
void getMemConfig(uint8_t mem_cfg, uint8_t chip_cfg, uint8_t *max_blk, uint8_t *app_areas, uint8_t *kb) {
|
||||
// mem-bit 5, mem-bit 7, chip-bit 4: defines chip type
|
||||
if(isset(chip_cfg, 0x10) && notset(mem_cfg, 0x80) && notset(mem_cfg, 0x20)) {
|
||||
*kb = 2;
|
||||
*app_areas = 2;
|
||||
*max_blk = 31;
|
||||
} else if(isset(chip_cfg, 0x10) && isset(mem_cfg, 0x80) && notset(mem_cfg, 0x20)) {
|
||||
*kb = 16;
|
||||
*app_areas = 2;
|
||||
*max_blk = 255; //16kb
|
||||
} else if(notset(chip_cfg, 0x10) && notset(mem_cfg, 0x80) && notset(mem_cfg, 0x20)) {
|
||||
*kb = 16;
|
||||
*app_areas = 16;
|
||||
*max_blk = 255; //16kb
|
||||
} else if(isset(chip_cfg, 0x10) && isset(mem_cfg, 0x80) && isset(mem_cfg, 0x20)) {
|
||||
*kb = 32;
|
||||
*app_areas = 3;
|
||||
*max_blk = 255; //16kb
|
||||
} else if(notset(chip_cfg, 0x10) && notset(mem_cfg, 0x80) && isset(mem_cfg, 0x20)) {
|
||||
*kb = 32;
|
||||
*app_areas = 17;
|
||||
*max_blk = 255; //16kb
|
||||
} else {
|
||||
*kb = 32;
|
||||
*app_areas = 2;
|
||||
*max_blk = 255;
|
||||
}
|
||||
}
|
||||
|
||||
void mem_app_config(const picopass_hdr *hdr)
|
||||
{
|
||||
uint8_t mem = hdr->conf.mem_config;
|
||||
if( isset (mem, 0x80)) prnt(" Mem: 16KBits (255 * 8 bytes)");
|
||||
else prnt(" Mem: 2 KBits ( 32 * 8 bytes)");
|
||||
|
||||
}
|
||||
void applimit_config(const picopass_hdr *hdr)
|
||||
{
|
||||
uint8_t chip = hdr->conf.chip_config;
|
||||
uint8_t applimit = hdr->conf.app_limit;
|
||||
prnt(" AA1: blocks 6-%d", applimit);
|
||||
prnt(" AA2: blocks %d-", (applimit+1));
|
||||
if (applimit < 6) applimit = 26;
|
||||
uint8_t kb = 2;
|
||||
uint8_t app_areas = 2;
|
||||
uint8_t max_blk = 31;
|
||||
getMemConfig(mem, chip, &max_blk, &app_areas, &kb);
|
||||
prnt(" Mem: %u KBits/%u App Areas (%u * 8 bytes) [%02X]", kb, app_areas, max_blk, mem);
|
||||
prnt(" AA1: blocks 06-%02X", applimit);
|
||||
prnt(" AA2: blocks %02X-%02X", applimit+1, max_blk);
|
||||
}
|
||||
void print_picopass_info(const picopass_hdr *hdr)
|
||||
{
|
||||
fuse_config(hdr);
|
||||
mem_config(hdr);
|
||||
applimit_config(hdr);
|
||||
mem_app_config(hdr);
|
||||
}
|
||||
void printIclassDumpInfo(uint8_t* iclass_dump)
|
||||
{
|
||||
|
|
|
@ -148,6 +148,10 @@ ISO 7816-4 Basic interindustry commands. For command APDU's.
|
|||
#define MIFARE_CMD_RESTORE 0xC2
|
||||
#define MIFARE_CMD_TRANSFER 0xB0
|
||||
|
||||
#define MIFARE_EV1_PERSONAL_UID 0x40
|
||||
#define MIFARE_EV1_SETMODE 0x43
|
||||
|
||||
|
||||
#define MIFARE_ULC_WRITE 0xA2
|
||||
//#define MIFARE_ULC__COMP_WRITE 0xA0
|
||||
#define MIFARE_ULC_AUTH_1 0x1A
|
||||
|
@ -162,6 +166,8 @@ ISO 7816-4 Basic interindustry commands. For command APDU's.
|
|||
#define MIFARE_ULEV1_CHECKTEAR 0x3E
|
||||
#define MIFARE_ULEV1_VCSL 0x4B
|
||||
|
||||
|
||||
|
||||
/**
|
||||
06 00 = INITIATE
|
||||
0E xx = SELECT ID (xx = Chip-ID)
|
||||
|
@ -259,5 +265,6 @@ ISO 7816-4 Basic interindustry commands. For command APDU's.
|
|||
// 6x xx = ERROR
|
||||
|
||||
void printIclassDumpInfo(uint8_t* iclass_dump);
|
||||
void getMemConfig(uint8_t mem_cfg, uint8_t chip_cfg, uint8_t *max_blk, uint8_t *app_areas, uint8_t *kb);
|
||||
|
||||
#endif // PROTOCOLS_H
|
||||
|
|
|
@ -87,6 +87,7 @@ typedef struct{
|
|||
#define CMD_T55XX_WRITE_BLOCK 0x0215
|
||||
#define CMD_T55XX_READ_TRACE 0x0216
|
||||
#define CMD_PCF7931_READ 0x0217
|
||||
#define CMD_PCF7931_WRITE 0x0223
|
||||
#define CMD_EM4X_READ_WORD 0x0218
|
||||
#define CMD_EM4X_WRITE_WORD 0x0219
|
||||
#define CMD_IO_DEMOD_FSK 0x021A
|
||||
|
@ -133,12 +134,17 @@ typedef struct{
|
|||
#define CMD_EPA_PACE_COLLECT_NONCE 0x038A
|
||||
#define CMD_EPA_PACE_REPLAY 0x038B
|
||||
|
||||
#define CMD_ICLASS_READCHECK 0x038F
|
||||
#define CMD_ICLASS_CLONE 0x0390
|
||||
#define CMD_ICLASS_DUMP 0x0391
|
||||
#define CMD_SNOOP_ICLASS 0x0392
|
||||
#define CMD_SIMULATE_TAG_ICLASS 0x0393
|
||||
#define CMD_READER_ICLASS 0x0394
|
||||
#define CMD_READER_ICLASS_REPLAY 0x0395
|
||||
#define CMD_ICLASS_ISO14443A_WRITE 0x0397
|
||||
#define CMD_ICLASS_READBLOCK 0x0396
|
||||
#define CMD_ICLASS_WRITEBLOCK 0x0397
|
||||
#define CMD_ICLASS_EML_MEMSET 0x0398
|
||||
#define CMD_ICLASS_AUTHENTICATION 0x0399
|
||||
|
||||
// For measurements of the antenna tuning
|
||||
#define CMD_MEASURE_ANTENNA_TUNING 0x0400
|
||||
|
@ -211,6 +217,7 @@ typedef struct{
|
|||
#define FLAG_ICLASS_READER_CONF 0x08
|
||||
#define FLAG_ICLASS_READER_AA 0x10
|
||||
#define FLAG_ICLASS_READER_ONE_TRY 0x20
|
||||
#define FLAG_ICLASS_READER_CEDITKEY 0x40
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue