mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-07-05 20:41:34 -07:00
initial commit to be in sync the-soon-defunct repo pm3rdv40.
This commit is contained in:
parent
905df58cc3
commit
5f77121694
34 changed files with 709 additions and 508 deletions
31
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
31
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
|
@ -0,0 +1,31 @@
|
|||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Desktop (please complete the following information):**
|
||||
- OS: [e.g. iOS]
|
||||
- inside proxmark3 client run the following commands and paste the output here.
|
||||
- hw version
|
||||
- hw status
|
||||
- data tune
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
|
@ -1,4 +1,4 @@
|
|||
# Travis-CI Build for IcemanFork/Proxmark3
|
||||
# Travis-CI Build for RfidResearchGroup/Proxmark3
|
||||
language: c
|
||||
|
||||
#default linux build env is: Ubuntu 14.04 trusty
|
||||
|
@ -28,7 +28,7 @@ before_install:
|
|||
sudo apt-get install -y gcc-arm-none-eabi;
|
||||
elif [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
|
||||
brew update;
|
||||
brew tap iceman1001/proxmark3;
|
||||
brew tap RfidResearchGroup/proxmark3;
|
||||
fi
|
||||
|
||||
install:
|
||||
|
|
11
CHANGELOG.md
11
CHANGELOG.md
|
@ -2,7 +2,16 @@
|
|||
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]
|
||||
## [unreleased][unreleased]
|
||||
- Fix 'hf legic' enhancement of rx / tx in legic commands (@drandreas)
|
||||
- Fix 'data buffclear' - now frees bigbuff also (@iceman)
|
||||
- Fix GET_TICKS and signess while shifting (@drandreas)
|
||||
- Added 'hf 14b dump' - now dumps to file (bin & eml) (@iceman)
|
||||
- Fix fixed xcorrelation for strong signal (@drandreas)
|
||||
- Fix 'hf mf chk' - keytype was reversed (@TomHarkness)
|
||||
- Added strange vid/pid found in wild. Could be pm3 easy clones. (@iceman)
|
||||
- Fix 'make udev' - udev filename could be in conflict, renamed. (@blshkv)
|
||||
- Fix 'lf t55xx config' - wrong sized array disabled FSK1a/FSK2a as options (@grauerfuchs)
|
||||
- Added more default keys (@j8048188) (@iceman)
|
||||
- Added 'sc list/info/raw/reader/upgrade' - (RDV40) smart card module functionality (@iceman)
|
||||
- Fix 'download eml buffer' (@drandreas)
|
||||
|
|
|
@ -30,64 +30,6 @@ Links
|
|||
https://github.com/Gator96100/ProxSpace/archive/master.zip
|
||||
|
||||
|
||||
-- OR --
|
||||
|
||||
Use the following list of packages required to setup the compile environment yourself.
|
||||
|
||||
1 - Install QT SDK for Windows [1]
|
||||
|
||||
In the following instructions, we'll assume you installed it to C:\QT
|
||||
|
||||
2 - MSYS-1.0.11 [2]
|
||||
|
||||
Just follow the installation procedure.
|
||||
When asked if you have MinGW installed and for its path, provide:
|
||||
C:/QT/mingw
|
||||
|
||||
3 - readline-5.0-1-bin [5]
|
||||
|
||||
From this archive, copy:
|
||||
bin/* to C:\QT\mingw\bin
|
||||
include/* to C:\QT\mingw\include
|
||||
lib/*.a to C:\QT\mingw\lib
|
||||
|
||||
4 - libusb-win32-device-bin-0.1.12.2 [6]
|
||||
|
||||
Be careful here, it is *NOT* working with the filter version!
|
||||
Likewise copy:
|
||||
include/usb.h to C:\QT\mingw\include
|
||||
lib/gcc/libusb.a to C:\QT\mingw\lib
|
||||
|
||||
|
||||
5 - Install DevkitPro [5]
|
||||
|
||||
You'll need it to compile the firmware (ARM) side.
|
||||
You only need devkitARM, nothing more (no extra lib or anything else)
|
||||
Assuming you installed it to C:\devkitpro, make sure you set
|
||||
the DEVKITARM environment variable to /c/devkitPro/devkitARM :
|
||||
export DEVKITARM=/c/devkitPro/devkitARM
|
||||
Also, add its bin to your PATH:
|
||||
export PATH=$PATH:$DEVKITARM/bin
|
||||
|
||||
6 - Install Strawberry Perl [6]
|
||||
|
||||
7 - Setup a few variables
|
||||
|
||||
In your shell from MSYS, make sure you set QTDIR to your QT installation:
|
||||
export QTDIR=/c/QT/qt
|
||||
And add its bin to your path as well:
|
||||
export PATH=$PATH:$QTDIR/bin
|
||||
|
||||
Download links:
|
||||
|
||||
[1] http://qt.nokia.com/downloads/sdk-windows-cpp
|
||||
[2] http://downloads.sourceforge.net/mingw/MSYS-1.0.11.exe
|
||||
[3] http://sourceforge.net/projects/gnuwin32/files/readline/5.0-1/readline-5.0-1-bin.zip/download
|
||||
[4] http://sourceforge.net/projects/libusb-win32/files/libusb-win32-releases/0.1.12.2/libusb-win32-device-bin-0.1.12.2.tar.gz/download
|
||||
[5] http://sourceforge.net/projects/devkitpro/files/Automated%20Installer/devkitProUpdater-1.5.0.exe/download
|
||||
[6] http://strawberry-perl.googlecode.com/files/strawberry-perl-5.10.1.1.msi
|
||||
|
||||
|
||||
============
|
||||
= Mac OS X =
|
||||
============
|
||||
|
|
2
Makefile
2
Makefile
|
@ -77,7 +77,7 @@ tarbin: newtarbin client/tarbin armsrc/tarbin bootrom/tarbin
|
|||
# you may need to logout, relogin to get this access right correct.
|
||||
# Finally, you might need to run the proxmark3 client under SUDO on some systems
|
||||
udev:
|
||||
sudo cp -rf driver/77-mm-usb-device-blacklist.rules /etc/udev/rules.d/77-mm-usb-device-blacklist.rules
|
||||
sudo cp -rf driver/77-pm3-usb-device-blacklist.rules /etc/udev/rules.d/77-pm3-usb-device-blacklist.rules
|
||||
sudo udevadm control --reload-rules
|
||||
ifneq ($(wildcard /etc/arch-release),) #If user is running ArchLinux
|
||||
sudo usermod -aG uucp $(USER) #Use specific command and group
|
||||
|
|
87
README.md
87
README.md
|
@ -1,25 +1,11 @@
|
|||
Iceman fork
|
||||
===============
|
||||
[](https://travis-ci.org/iceman1001/proxmark3)[](https://scan.coverity.com/project/proxmark3_iceman_fork)[](https://github.com/iceman1001/proxmark3/releases/latest)
|
||||
[](https://github.com/RfidResearchGroup/proxmark3/releases/latest)
|
||||
|
||||
## This fork is HIGHLY experimental and bleeding edge
|
||||
|
||||
|
||||
The kickstarter for the latest revision of proxmark is out.
|
||||
[proxmark3 rdv4.0](https://www.kickstarter.com/projects/1408815241/proxmark3-rdv-40)
|
||||
|
||||
That one is a beauty!
|
||||
|
||||
|
||||
|
||||
|
||||
## Nothing says thank you as much as a donation
|
||||
https://paypal.me/iceman1001/ Feel free to donate. All support is welcome.
|
||||
|
||||
monereo: 43mNJLpgBVaTvyZmX9ajcohpvVkaRy1kbZPm8tqAb7itZgfuYecgkRF36rXrKFUkwEGeZedPsASRxgv4HPBHvJwyJdyvQuP
|
||||
## Proxmark3 RDV40 dedicated
|
||||
|
||||
## Notice
|
||||
There is so much in this fork, with all fixes and additions its basically the most enhanced fork to this day for the Proxmark3 device. Which makes it so awesum to play with. Do please play with it. Get excited and experiment. As a side note with all coverity scan fixes this client is much more stable than PM3 Master even if I tend to break it sometimes. I'll try to make a release when this fork becomes stable between my experiments.
|
||||
This repo is based on iceman fork for proxmark3. It is dedicated to bring the most out of the new features for proxmark3 RDV40 device.
|
||||
|
||||
## Coverity Scan Config & Run
|
||||
Download the Coverity Scan Self-buld and install it.
|
||||
|
@ -41,40 +27,20 @@ You will need to configure ARM-NON-EABI- Compiler for it to use:
|
|||
|
||||
|
||||
## Whats changed?
|
||||
Whats so special with 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
|
||||
* Piwi's "hardnested" branch
|
||||
* Holiman's iclass, (usually gets into the master)
|
||||
* 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/ Now using reveng1.44
|
||||
* J-Run alternative bruteforce Mifare nested auths.. (you need one other exe to make it work)
|
||||
* A Bruteforce for T55XX passwords against tag.
|
||||
* A Bruteforce for AWID 26, starting w a facilitycode then trying all 0xFFFF cardnumbers via simulation. To be used against a AWID Reader.
|
||||
* A Bruteforce for HID, starting w a facilitycode then trying all 0xFFFF cardnumbers via simulation. To be used against a HID Reader.
|
||||
* Blaposts Crapto1 v3.3
|
||||
* Icsom's legic script and legic enhancements
|
||||
* Aczid's bitsliced bruteforce solver in 'hf mf hardnested'
|
||||
* added flash memory 256kb.
|
||||
* added smart card module
|
||||
* added FPC connector
|
||||
|
||||
---
|
||||
## Why don't you merged with offical PM3 Master?
|
||||
Me fiddling with the code so much, there is a nightmare in merging a PR. I will never find time to do PR because of it. Much of what you find here is not in the interest for offical PM3. However and luckily I have @marshmellow42 who takes some stuff and push PR's back. The separation from offical pm3 repo gives me very much freedom to create a firmware/client in the way I want to use the PM3.
|
||||
## Why didn't you based it on offical PM3 Master?
|
||||
The separation from offical pm3 repo gives us very much freedom to create a firmware/client that suits the RDV40 features. We don't want to mess up the offical pm3 repo with RDV40 specific code.
|
||||
|
||||
## Why don't you add this or that functionality?
|
||||
Give me a hint, and I'll see if I can't merge in the stuff you have.
|
||||
Give us a hint, and we'll see if we can't merge in the stuff you have.
|
||||
|
||||
## PM3 GUI
|
||||
I do tend to rename and move stuff around, the official PM3-GUI from Gaucho will not work so well. *sorry*
|
||||
The official PM3-GUI from Gaucho will not work.
|
||||
The new universial GUI will work.
|
||||
|
||||
## Development
|
||||
This fork now compiles just fine on
|
||||
|
@ -90,13 +56,13 @@ See https://github.com/Proxmark/proxmark3/wiki/Ubuntu%20Linux
|
|||
A nice and cool install script made by @daveio is found here:
|
||||
https://github.com/daveio/attacksurface/blob/master/proxmark3/pm3-setup.sh
|
||||
I have also added this script to the fork.
|
||||
https://github.com/iceman1001/proxmark3/blob/master/install.sh
|
||||
https://github.com/RfidResearchGroup/proxmark3/blob/master/install.sh
|
||||
|
||||
- Run
|
||||
`sudo apt-get install p7zip git build-essential libreadline5 libreadline-dev libusb-0.1-4 libusb-dev libqt4-dev perl pkg-config wget libncurses5-dev gcc-arm-none-eabi`
|
||||
|
||||
- Clone iceman fork
|
||||
`git clone https://github.com/iceman1001/proxmark3.git`
|
||||
- Clone fork
|
||||
`git clone https://github.com/RfidResearchGroup/proxmark3.git`
|
||||
|
||||
- Get the latest commits
|
||||
`git pull`
|
||||
|
@ -121,8 +87,8 @@ https://github.com/iceman1001/proxmark3/blob/master/install.sh
|
|||
`sudo pacman -Sy base-devel p7zip libusb readline ncurses arm-none-eabi-newlib --needed`
|
||||
`yaourt -S termcap`
|
||||
|
||||
- Clone iceman fork
|
||||
`git clone https://github.com/iceman1001/proxmark3.git`
|
||||
- Clone fork
|
||||
`git clone https://github.com/RfidResearchGroup/proxmark3.git`
|
||||
|
||||
- Get the latest commits
|
||||
`git pull`
|
||||
|
@ -148,7 +114,7 @@ Further questions about Mac & Homebrew, contact @Chrisfu (https://github.com/c
|
|||
|
||||
1. Install homebrew if you haven't yet already done so: http://brew.sh/
|
||||
|
||||
2. Tap this repo: `brew tap iceman1001/proxmark3`
|
||||
2. Tap this repo: `brew tap RfidResearchGroup/proxmark3`
|
||||
|
||||
3. Install Proxmark3: `brew install proxmark3` for stable release or `brew install --HEAD proxmark3` for latest non-stable from GitHub.
|
||||
|
||||
|
@ -161,7 +127,7 @@ Tested on macOS High Sierra 10.13.2
|
|||
*Note: This assumes you have already installed iceman's fork from HomeBrew as mentioned above*
|
||||
|
||||
1. Force HomeBrew to pull the latest source from github
|
||||
`brew upgrade --fetch-HEAD iceman1001/proxmark3/proxmark3`
|
||||
`brew upgrade --fetch-HEAD RfidResearchGroup/proxmark3`
|
||||
|
||||
2. Flash the bootloader & fullimage.elf
|
||||
* With your Proxmark3 unplugged from your machine, press and hold the button on your Proxmark 3 as you plug it into a USB port. Continue to hold the button until after this step is complete and the `proxmark3-flasher` command outputs "Have a nice day!"*
|
||||
|
@ -172,16 +138,6 @@ Tested on macOS High Sierra 10.13.2
|
|||
|
||||
4. Enjoy the update
|
||||
|
||||
## Docker container
|
||||
I recently added a docker container on Docker HUB. You find it here: https://hub.docker.com/r/iceman1001/proxmark3/
|
||||
Follow those instructions to get it up and running. No need for the old proxspace-environment anymore.
|
||||
|
||||
-[1.6.0] How to start: https://www.youtube.com/watch?v=b5Zta89Cf6Q
|
||||
-[1.6.0] How to connect: https://youtu.be/0ZS2t5C-caI
|
||||
-[1.6.1] How to flash: https://www.youtube.com/watch?v=WXouhuGYEiw
|
||||
|
||||
Recommendations: Use only latest container.
|
||||
|
||||
|
||||
## Building on Windows
|
||||
|
||||
|
@ -196,13 +152,12 @@ Read instructions on @Gator96100 repo page. (https://github.com/Gator96100/ProxS
|
|||
Links
|
||||
- https://github.com/Gator96100/ProxSpace/archive/master.zip
|
||||
- https://github.com/Gator96100/ProxSpace/releases/tag/v2.2 (release v2.2 with gcc v5.3.0 arm-none-eabi-gcc v7.1.0)
|
||||
- https://github.com/Gator96100/ProxSpace/releases/tag/v2.1 (release v2.1 with gcc v5.3.0)
|
||||
|
||||
|
||||
### 7. Build and run
|
||||
|
||||
- Clone iceman fork
|
||||
`git clone https://github.com/iceman1001/proxmark3.git`
|
||||
- Clone fork
|
||||
`git clone https://github.com/RfidResearchGroup/proxmark3.git`
|
||||
|
||||
- Get the latest commits
|
||||
`git pull`
|
||||
|
@ -222,4 +177,4 @@ Assuming you have Proxmark3 Windows drivers installed you can run the Proxmark s
|
|||
`proxmark3.exe comX`
|
||||
|
||||
iceman at host iuse.se
|
||||
January 2015, Sweden
|
||||
July 2018, Sweden
|
||||
|
|
|
@ -1070,6 +1070,7 @@ void UsbPacketReceived(uint8_t *packet, int len) {
|
|||
#endif
|
||||
case CMD_BUFF_CLEAR:
|
||||
BigBuf_Clear();
|
||||
BigBuf_free();
|
||||
break;
|
||||
|
||||
case CMD_MEASURE_ANTENNA_TUNING:
|
||||
|
|
|
@ -320,7 +320,6 @@ static void BuildFliteRdblk(uint8_t* idm, int blocknum, uint16_t *blocks ) {
|
|||
|
||||
static void TransmitFor18092_AsReader(uint8_t * frame, int len, uint32_t *timing, uint8_t power, uint8_t highspeed) {
|
||||
|
||||
volatile uint16_t b;
|
||||
uint8_t flags = FPGA_MAJOR_MODE_ISO18092;
|
||||
|
||||
if ( power )
|
||||
|
@ -340,25 +339,23 @@ static void TransmitFor18092_AsReader(uint8_t * frame, int len, uint32_t *timing
|
|||
// sending 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
uint16_t c = 0;
|
||||
while (c < 6) {
|
||||
|
||||
// keep tx buffer in a defined state anyway.
|
||||
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
|
||||
AT91C_BASE_SSC->SSC_THR = 0x00;
|
||||
c++;
|
||||
}
|
||||
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
|
||||
b = (uint16_t)(AT91C_BASE_SSC->SSC_RHR); (void)b;
|
||||
}
|
||||
}
|
||||
// sending sync code
|
||||
|
||||
// sending data
|
||||
c = 0;
|
||||
while (c < len) {
|
||||
|
||||
// Put byte into tx holding register as soon as it is ready
|
||||
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
|
||||
AT91C_BASE_SSC->SSC_THR = frame[c++];
|
||||
}
|
||||
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
|
||||
b = (uint16_t)(AT91C_BASE_SSC->SSC_RHR); (void)b;
|
||||
}
|
||||
}
|
||||
|
||||
/**/
|
||||
|
@ -436,7 +433,7 @@ bool WaitForFelicaReply(uint16_t maxbytes) {
|
|||
// Set up FeliCa communication (similar to iso14443a_setup)
|
||||
// field is setup for "Sending as Reader"
|
||||
static void felica_setup(uint8_t fpga_minor_mode) {
|
||||
if (MF_DBGLEVEL > 3) Dbprintf("FeliCa_setup Enter");
|
||||
|
||||
LEDsoff();
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
|
||||
|
||||
|
@ -471,7 +468,6 @@ static void felica_setup(uint8_t fpga_minor_mode) {
|
|||
StartCountSspClk();
|
||||
|
||||
LED_D_ON();
|
||||
if (MF_DBGLEVEL > 3) Dbprintf("FeliCa_setup Exit");
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// RAW FeliCa commands. Send out commands and store answers.
|
||||
|
|
|
@ -29,28 +29,31 @@ void HfSnoop(int samplesToSkip, int triggersToSkip)
|
|||
BigBuf_free(); BigBuf_Clear();
|
||||
|
||||
Dbprintf("Skipping first %d sample pairs, Skipping %d triggers.\n", samplesToSkip, triggersToSkip);
|
||||
int trigger_cnt;
|
||||
int trigger_cnt = 0;
|
||||
|
||||
LED_D_ON();
|
||||
// Select correct configs
|
||||
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
|
||||
|
||||
SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
|
||||
|
||||
// Set up the synchronous serial port
|
||||
FpgaSetupSsc();
|
||||
// connect Demodulated Signal to ADC:
|
||||
SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
|
||||
|
||||
// Setting Frame Mode For better performance on high speed data transfer.
|
||||
AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(16);
|
||||
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SNOOP);
|
||||
SpinDelay(100);
|
||||
|
||||
AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(16); // Setting Frame Mode For better performance on high speed data transfer.
|
||||
|
||||
trigger_cnt = 0;
|
||||
uint16_t r = 0;
|
||||
while (!BUTTON_PRESS() && !usb_poll_validate_length() ) {
|
||||
WDT_HIT();
|
||||
|
||||
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
|
||||
r = (uint16_t)AT91C_BASE_SSC->SSC_RHR;
|
||||
r = MAX(r & 0xff, r >> 8);
|
||||
if (r >= 180) {
|
||||
if (r >= 180) { // 0xB4 ??
|
||||
if (++trigger_cnt > triggersToSkip)
|
||||
break;
|
||||
}
|
||||
|
@ -75,4 +78,3 @@ void HfSnoop(int samplesToSkip, int triggersToSkip)
|
|||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
LED_D_OFF();
|
||||
}
|
||||
|
||||
|
|
|
@ -38,9 +38,9 @@ struct hitag2_tag {
|
|||
TAG_STATE_WRITING = 0x04, // In write command, awaiting sector contents to be written
|
||||
} state;
|
||||
unsigned int active_sector;
|
||||
byte_t crypto_active;
|
||||
uint8_t crypto_active;
|
||||
uint64_t cs;
|
||||
byte_t sectors[12][4];
|
||||
uint8_t sectors[12][4];
|
||||
};
|
||||
|
||||
static struct hitag2_tag tag = {
|
||||
|
@ -71,14 +71,14 @@ static enum {
|
|||
// ToDo: define a meaningful maximum size for auth_table. The bigger this is, the lower will be the available memory for traces.
|
||||
// Historically it used to be FREE_BUFFER_SIZE, which was 2744.
|
||||
#define AUTH_TABLE_LENGTH 2744
|
||||
static byte_t* auth_table;
|
||||
static uint8_t* auth_table;
|
||||
static size_t auth_table_pos = 0;
|
||||
static size_t auth_table_len = AUTH_TABLE_LENGTH;
|
||||
|
||||
static byte_t password[4];
|
||||
static byte_t NrAr[8];
|
||||
static byte_t key[8];
|
||||
static byte_t writedata[4];
|
||||
static uint8_t password[4];
|
||||
static uint8_t NrAr[8];
|
||||
static uint8_t key[8];
|
||||
static uint8_t writedata[4];
|
||||
static uint64_t cipher_state;
|
||||
|
||||
/* Following is a modified version of cryptolib.com/ciphers/hitag2/ */
|
||||
|
@ -177,7 +177,7 @@ static int hitag2_init(void) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void hitag2_cipher_reset(struct hitag2_tag *tag, const byte_t *iv)
|
||||
static void hitag2_cipher_reset(struct hitag2_tag *tag, const uint8_t *iv)
|
||||
{
|
||||
uint64_t key = ((uint64_t)tag->sectors[2][2]) |
|
||||
((uint64_t)tag->sectors[2][3] << 8) |
|
||||
|
@ -196,9 +196,9 @@ static void hitag2_cipher_reset(struct hitag2_tag *tag, const byte_t *iv)
|
|||
tag->cs = _hitag2_init(rev64(key), rev32(uid), rev32(iv_));
|
||||
}
|
||||
|
||||
static int hitag2_cipher_authenticate(uint64_t* cs, const byte_t *authenticator_is)
|
||||
static int hitag2_cipher_authenticate(uint64_t* cs, const uint8_t *authenticator_is)
|
||||
{
|
||||
byte_t authenticator_should[4];
|
||||
uint8_t authenticator_should[4];
|
||||
authenticator_should[0] = ~_hitag2_byte(cs);
|
||||
authenticator_should[1] = ~_hitag2_byte(cs);
|
||||
authenticator_should[2] = ~_hitag2_byte(cs);
|
||||
|
@ -206,7 +206,7 @@ static int hitag2_cipher_authenticate(uint64_t* cs, const byte_t *authenticator_
|
|||
return (memcmp(authenticator_should, authenticator_is, 4) == 0);
|
||||
}
|
||||
|
||||
static int hitag2_cipher_transcrypt(uint64_t* cs, byte_t *data, unsigned int bytes, unsigned int bits)
|
||||
static int hitag2_cipher_transcrypt(uint64_t* cs, uint8_t *data, unsigned int bytes, unsigned int bits)
|
||||
{
|
||||
int i;
|
||||
for(i=0; i<bytes; i++) data[i] ^= _hitag2_byte(cs);
|
||||
|
@ -271,7 +271,7 @@ static void hitag_send_bit(int bit) {
|
|||
LED_A_OFF();
|
||||
}
|
||||
|
||||
static void hitag_send_frame(const byte_t* frame, size_t frame_len)
|
||||
static void hitag_send_frame(const uint8_t* frame, size_t frame_len)
|
||||
{
|
||||
// Send start of frame
|
||||
for(size_t i=0; i<5; i++) {
|
||||
|
@ -288,9 +288,9 @@ static void hitag_send_frame(const byte_t* frame, size_t frame_len)
|
|||
}
|
||||
|
||||
|
||||
static void hitag2_handle_reader_command(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen)
|
||||
static void hitag2_handle_reader_command(uint8_t* rx, const size_t rxlen, uint8_t* tx, size_t* txlen)
|
||||
{
|
||||
byte_t rx_air[HITAG_FRAME_LEN];
|
||||
uint8_t rx_air[HITAG_FRAME_LEN];
|
||||
|
||||
// Copy the (original) received frame how it is send over the air
|
||||
memcpy(rx_air,rx,nbytes(rxlen));
|
||||
|
@ -435,17 +435,17 @@ static void hitag_reader_send_bit(int bit) {
|
|||
|
||||
if(bit == 0) {
|
||||
// Zero bit: |_-|
|
||||
while(AT91C_BASE_TC0->TC_CV < T0*22);
|
||||
while (AT91C_BASE_TC0->TC_CV < T0*22) {};
|
||||
|
||||
} else {
|
||||
// One bit: |_--|
|
||||
while(AT91C_BASE_TC0->TC_CV < T0*28);
|
||||
while (AT91C_BASE_TC0->TC_CV < T0*28) {};
|
||||
}
|
||||
LED_A_OFF();
|
||||
}
|
||||
|
||||
|
||||
static void hitag_reader_send_frame(const byte_t* frame, size_t frame_len)
|
||||
static void hitag_reader_send_frame(const uint8_t* frame, size_t frame_len)
|
||||
{
|
||||
// Send the content of the frame
|
||||
for(size_t i=0; i<frame_len; i++) {
|
||||
|
@ -463,7 +463,7 @@ static void hitag_reader_send_frame(const byte_t* frame, size_t frame_len)
|
|||
|
||||
size_t blocknr;
|
||||
|
||||
static bool hitag2_password(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen) {
|
||||
static bool hitag2_password(uint8_t* rx, const size_t rxlen, uint8_t* tx, size_t* txlen) {
|
||||
// Reset the transmission frame length
|
||||
*txlen = 0;
|
||||
|
||||
|
@ -518,7 +518,7 @@ static bool hitag2_password(byte_t* rx, const size_t rxlen, byte_t* tx, size_t*
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool hitag2_write_page(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen)
|
||||
static bool hitag2_write_page(uint8_t* rx, const size_t rxlen, uint8_t* tx, size_t* txlen)
|
||||
{
|
||||
switch (writestate) {
|
||||
case WRITE_STATE_START:
|
||||
|
@ -560,22 +560,19 @@ static bool hitag2_write_page(byte_t* rx, const size_t rxlen, byte_t* tx, size_t
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool hitag2_crypto(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen, bool write) {
|
||||
static bool hitag2_crypto(uint8_t* rx, const size_t rxlen, uint8_t* tx, size_t* txlen, bool write) {
|
||||
// Reset the transmission frame length
|
||||
*txlen = 0;
|
||||
|
||||
if(bCrypto) {
|
||||
hitag2_cipher_transcrypt(&cipher_state,rx,rxlen/8,rxlen%8);
|
||||
|
||||
}
|
||||
|
||||
if (bCrypto && !bAuthenticating && write) {
|
||||
if (!hitag2_write_page(rx, rxlen, tx, txlen)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
|
||||
// Try to find out which command was send by selecting on length (in bits)
|
||||
switch (rxlen) {
|
||||
|
@ -670,7 +667,7 @@ static bool hitag2_crypto(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* tx
|
|||
}
|
||||
|
||||
|
||||
static bool hitag2_authenticate(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen) {
|
||||
static bool hitag2_authenticate(uint8_t* rx, const size_t rxlen, uint8_t* tx, size_t* txlen) {
|
||||
// Reset the transmission frame length
|
||||
*txlen = 0;
|
||||
|
||||
|
@ -710,7 +707,7 @@ static bool hitag2_authenticate(byte_t* rx, const size_t rxlen, byte_t* tx, size
|
|||
}
|
||||
|
||||
|
||||
static bool hitag2_test_auth_attempts(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen) {
|
||||
static bool hitag2_test_auth_attempts(uint8_t* rx, const size_t rxlen, uint8_t* tx, size_t* txlen) {
|
||||
|
||||
// Reset the transmission frame length
|
||||
*txlen = 0;
|
||||
|
@ -766,7 +763,7 @@ static bool hitag2_test_auth_attempts(byte_t* rx, const size_t rxlen, byte_t* tx
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool hitag2_read_uid(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen) {
|
||||
static bool hitag2_read_uid(uint8_t* rx, const size_t rxlen, uint8_t* tx, size_t* txlen) {
|
||||
// Reset the transmission frame length
|
||||
*txlen = 0;
|
||||
|
||||
|
@ -812,7 +809,7 @@ void SnoopHitag(uint32_t type) {
|
|||
int lastbit;
|
||||
bool bSkip;
|
||||
int tag_sof;
|
||||
byte_t rx[HITAG_FRAME_LEN];
|
||||
uint8_t rx[HITAG_FRAME_LEN];
|
||||
size_t rxlen=0;
|
||||
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
||||
|
@ -827,7 +824,7 @@ void SnoopHitag(uint32_t type) {
|
|||
auth_table_len = 0;
|
||||
auth_table_pos = 0;
|
||||
|
||||
auth_table = (byte_t *)BigBuf_malloc(AUTH_TABLE_LENGTH);
|
||||
auth_table = (uint8_t *)BigBuf_malloc(AUTH_TABLE_LENGTH);
|
||||
memset(auth_table, 0x00, AUTH_TABLE_LENGTH);
|
||||
|
||||
DbpString("Starting Hitag2 snoop");
|
||||
|
@ -1020,13 +1017,13 @@ void SnoopHitag(uint32_t type) {
|
|||
// DbpString("All done");
|
||||
}
|
||||
|
||||
void SimulateHitagTag(bool tag_mem_supplied, byte_t* data) {
|
||||
void SimulateHitagTag(bool tag_mem_supplied, uint8_t* data) {
|
||||
int frame_count;
|
||||
int response;
|
||||
int overflow;
|
||||
byte_t rx[HITAG_FRAME_LEN];
|
||||
uint8_t rx[HITAG_FRAME_LEN];
|
||||
size_t rxlen=0;
|
||||
byte_t tx[HITAG_FRAME_LEN];
|
||||
uint8_t tx[HITAG_FRAME_LEN];
|
||||
size_t txlen=0;
|
||||
bool bQuitTraceFull = false;
|
||||
bQuiet = false;
|
||||
|
@ -1042,9 +1039,9 @@ void SimulateHitagTag(bool tag_mem_supplied, byte_t* data) {
|
|||
|
||||
auth_table_len = 0;
|
||||
auth_table_pos = 0;
|
||||
byte_t* auth_table;
|
||||
uint8_t* auth_table;
|
||||
|
||||
auth_table = (byte_t *)BigBuf_malloc(AUTH_TABLE_LENGTH);
|
||||
auth_table = (uint8_t *)BigBuf_malloc(AUTH_TABLE_LENGTH);
|
||||
memset(auth_table, 0x00, AUTH_TABLE_LENGTH);
|
||||
|
||||
DbpString("Starting Hitag2 simulation");
|
||||
|
@ -1053,7 +1050,7 @@ void SimulateHitagTag(bool tag_mem_supplied, byte_t* data) {
|
|||
|
||||
if (tag_mem_supplied) {
|
||||
DbpString("Loading hitag2 memory...");
|
||||
memcpy((byte_t*)tag.sectors,data,48);
|
||||
memcpy((uint8_t*)tag.sectors,data,48);
|
||||
}
|
||||
|
||||
uint32_t block = 0;
|
||||
|
@ -1213,10 +1210,10 @@ void SimulateHitagTag(bool tag_mem_supplied, byte_t* data) {
|
|||
void ReaderHitag(hitag_function htf, hitag_data* htd) {
|
||||
int frame_count = 0;
|
||||
int response = 0;
|
||||
byte_t rx[HITAG_FRAME_LEN];
|
||||
uint8_t rx[HITAG_FRAME_LEN];
|
||||
size_t rxlen = 0;
|
||||
byte_t txbuf[HITAG_FRAME_LEN];
|
||||
byte_t* tx = txbuf;
|
||||
uint8_t txbuf[HITAG_FRAME_LEN];
|
||||
uint8_t* tx = txbuf;
|
||||
size_t txlen = 0;
|
||||
int lastbit = 1;
|
||||
bool bSkip;
|
||||
|
@ -1349,6 +1346,7 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) {
|
|||
} else {
|
||||
Dbprintf("Error, unknown hitag reader type: %d",htf);
|
||||
set_tracing(false);
|
||||
LED_D_OFF();
|
||||
return;
|
||||
}
|
||||
uint8_t attempt_count=0;
|
||||
|
@ -1388,11 +1386,13 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) {
|
|||
case RHT2F_UID_ONLY: {
|
||||
bStop = !hitag2_read_uid(rx, rxlen, tx, &txlen);
|
||||
attempt_count++; //attempt 3 times to get uid then quit
|
||||
if (!bStop && attempt_count == 3) bStop = true;
|
||||
if (!bStop && attempt_count == 3)
|
||||
bStop = true;
|
||||
} break;
|
||||
default: {
|
||||
Dbprintf("Error, unknown function: %d",htf);
|
||||
set_tracing(false);
|
||||
LED_D_OFF();
|
||||
return;
|
||||
} break;
|
||||
}
|
||||
|
@ -1501,22 +1501,21 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) {
|
|||
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS;
|
||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS;
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
set_tracing(false);
|
||||
|
||||
if ( bSuccessful )
|
||||
cmd_send(CMD_ACK, bSuccessful, 0, 0, (byte_t*)tag.sectors, 48);
|
||||
cmd_send(CMD_ACK, bSuccessful, 0, 0, (uint8_t*)tag.sectors, 48);
|
||||
else
|
||||
cmd_send(CMD_ACK, bSuccessful, 0, 0, 0, 0);
|
||||
|
||||
set_tracing(false);
|
||||
}
|
||||
|
||||
void WriterHitag(hitag_function htf, hitag_data* htd, int page) {
|
||||
int frame_count;
|
||||
int response;
|
||||
byte_t rx[HITAG_FRAME_LEN];
|
||||
uint8_t rx[HITAG_FRAME_LEN];
|
||||
size_t rxlen=0;
|
||||
byte_t txbuf[HITAG_FRAME_LEN];
|
||||
byte_t* tx = txbuf;
|
||||
uint8_t txbuf[HITAG_FRAME_LEN];
|
||||
uint8_t* tx = txbuf;
|
||||
size_t txlen=0;
|
||||
int lastbit;
|
||||
bool bSkip;
|
||||
|
@ -1788,5 +1787,5 @@ void WriterHitag(hitag_function htf, hitag_data* htd, int page) {
|
|||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
// Dbprintf("frame received: %d",frame_count);
|
||||
// DbpString("All done");
|
||||
cmd_send(CMD_ACK,bSuccessful,0,0,(byte_t*)tag.sectors,48);
|
||||
cmd_send(CMD_ACK,bSuccessful,0,0,(uint8_t*)tag.sectors,48);
|
||||
}
|
||||
|
|
|
@ -990,9 +990,11 @@ static bool GetIClassCommandFromReader(uint8_t *received, int *len, int maxLen)
|
|||
while (!BUTTON_PRESS()) {
|
||||
WDT_HIT();
|
||||
|
||||
// keep tx buffer in a defined state anyway.
|
||||
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY))
|
||||
AT91C_BASE_SSC->SSC_THR = 0x00;
|
||||
|
||||
// wait for byte to become available in rx holding register
|
||||
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
|
||||
b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
||||
|
||||
|
@ -1127,13 +1129,10 @@ void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain
|
|||
LEDsoff();
|
||||
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
|
||||
// this will clear out bigbuf memory, the eload command must select this before!
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
|
||||
|
||||
SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
|
||||
|
||||
FpgaSetupSsc();
|
||||
SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
|
||||
|
||||
// Enable and clear the trace
|
||||
clear_trace();
|
||||
|
@ -1586,11 +1585,17 @@ static int SendIClassAnswer(uint8_t *resp, int respLen, uint16_t delay) {
|
|||
volatile uint8_t b = 0;
|
||||
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_MODULATE_424K_8BIT);
|
||||
|
||||
AT91C_BASE_SSC->SSC_THR = 0x00;
|
||||
|
||||
while (!BUTTON_PRESS()) {
|
||||
|
||||
// Prevent rx holding register from overflowing
|
||||
if ( (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY)){
|
||||
b = AT91C_BASE_SSC->SSC_RHR; (void) b;
|
||||
}
|
||||
|
||||
// Put byte into tx holding register as soon as it is ready
|
||||
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)){
|
||||
b = 0x00;
|
||||
if ( i < respLen){
|
||||
|
@ -1630,6 +1635,7 @@ static void TransmitIClassCommand(const uint8_t *cmd, int len, int *samples, int
|
|||
|
||||
WDT_HIT();
|
||||
|
||||
// Put byte into tx holding register as soon as it is ready
|
||||
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
|
||||
|
||||
// DOUBLE THE SAMPLES!
|
||||
|
@ -1649,6 +1655,7 @@ static void TransmitIClassCommand(const uint8_t *cmd, int len, int *samples, int
|
|||
if (c >= len) break;
|
||||
}
|
||||
|
||||
// Prevent rx holding register from overflowing
|
||||
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
|
||||
b = AT91C_BASE_SSC->SSC_RHR; (void)b;
|
||||
}
|
||||
|
@ -1750,12 +1757,14 @@ static int GetIClassAnswer(uint8_t* receivedResponse, int maxLen, int *samples,
|
|||
while (!BUTTON_PRESS()) {
|
||||
WDT_HIT();
|
||||
|
||||
// keep tx buffer in a defined state anyway.
|
||||
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
|
||||
AT91C_BASE_SSC->SSC_THR = 0x00;
|
||||
// To make use of exact timing of next command from reader!!
|
||||
if (elapsed) (*elapsed)++;
|
||||
}
|
||||
|
||||
// Wait for byte be become available in rx holding register
|
||||
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
|
||||
if (c >= timeout) return false;
|
||||
|
||||
|
@ -1802,10 +1811,10 @@ void setupIclassReader() {
|
|||
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
|
||||
|
||||
SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
|
||||
|
||||
FpgaSetupSsc();
|
||||
|
||||
SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
|
||||
|
||||
// Reset trace buffer
|
||||
clear_trace();
|
||||
set_tracing(true);
|
||||
|
|
|
@ -449,14 +449,12 @@ static int GetIso14443bCommandFromReader(uint8_t *received, uint16_t *len) {
|
|||
// loop is a wait/delay ?
|
||||
/*
|
||||
for(uint8_t c = 0; c < 10;) {
|
||||
|
||||
// keep tx buffer in a defined state anyway.
|
||||
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
|
||||
AT91C_BASE_SSC->SSC_THR = 0xFF;
|
||||
++c;
|
||||
}
|
||||
|
||||
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
|
||||
b = (uint16_t)(AT91C_BASE_SSC->SSC_RHR); (void)b;
|
||||
}
|
||||
}
|
||||
*/
|
||||
// Now run a `software UART' on the stream of incoming samples.
|
||||
|
@ -466,8 +464,16 @@ static int GetIso14443bCommandFromReader(uint8_t *received, uint16_t *len) {
|
|||
while( !BUTTON_PRESS() ) {
|
||||
WDT_HIT();
|
||||
|
||||
// keep tx buffer in a defined state anyway.
|
||||
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
|
||||
AT91C_BASE_SSC->SSC_THR = 0x00;
|
||||
}
|
||||
|
||||
// Wait for byte be become available in rx holding register
|
||||
if ( AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY ) {
|
||||
|
||||
b = (uint8_t) AT91C_BASE_SSC->SSC_RHR;
|
||||
|
||||
for ( mask = 0x80; mask != 0; mask >>= 1) {
|
||||
if ( Handle14443bReaderUartBit(b & mask)) {
|
||||
*len = Uart.byteCnt;
|
||||
|
@ -494,7 +500,7 @@ void ClearFpgaShiftingRegisters(void){
|
|||
|
||||
// wait for the FPGA to signal fdt_indicator == 1 (the FPGA is ready to queue new data in its delay line)
|
||||
for (uint8_t j = 0; j < 5; j++) { // allow timeout - better late than never
|
||||
while(!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY));
|
||||
while (!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY)) {};
|
||||
if (AT91C_BASE_SSC->SSC_RHR) break;
|
||||
}
|
||||
|
||||
|
@ -531,9 +537,13 @@ static void TransmitFor14443b_AsTag( uint8_t *response, uint16_t len) {
|
|||
|
||||
// Transmit the response.
|
||||
for(uint16_t i = 0; i < len;) {
|
||||
|
||||
// Put byte into tx holding register as soon as it is ready
|
||||
if(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
|
||||
AT91C_BASE_SSC->SSC_THR = response[++i];
|
||||
}
|
||||
|
||||
// Prevent rx holding register from overflowing
|
||||
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
|
||||
b = AT91C_BASE_SSC->SSC_RHR;(void)b;
|
||||
}
|
||||
|
@ -550,10 +560,10 @@ void SimulateIso14443bTag(uint32_t pupi) {
|
|||
|
||||
// setup device.
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
|
||||
// Set up the synchronous serial port
|
||||
FpgaSetupSsc();
|
||||
// connect Demodulated Signal to ADC:
|
||||
SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
|
||||
// Set up the synchronous serial port
|
||||
FpgaSetupSsc();
|
||||
|
||||
// allocate command receive buffer
|
||||
BigBuf_free(); BigBuf_Clear_ext(false);
|
||||
|
@ -786,6 +796,7 @@ static RAMFUNC int Handle14443bTagSamplesDemod(int ci, int cq) {
|
|||
CHECK_FOR_SUBCARRIER();
|
||||
|
||||
// subcarrier detected
|
||||
|
||||
if (v > SUBCARRIER_DETECT_THRESHOLD) {
|
||||
Demod.state = DEMOD_PHASE_REF_TRAINING;
|
||||
Demod.sumI = ci;
|
||||
|
@ -987,10 +998,6 @@ static void GetTagSamplesFor14443bDemod() {
|
|||
if ( upTo )
|
||||
upTo = NULL;
|
||||
|
||||
// print the last batch of IQ values from FPGA
|
||||
if (MF_DBGLEVEL == 4)
|
||||
Dbhexdump(ISO14443B_DMA_BUFFER_SIZE, (uint8_t *)dmaBuf, false);
|
||||
|
||||
if ( Demod.len > 0 )
|
||||
LogTrace(Demod.output, Demod.len, time_0, time_stop, NULL, false);
|
||||
}
|
||||
|
@ -999,20 +1006,10 @@ static void GetTagSamplesFor14443bDemod() {
|
|||
// Transmit the command (to the tag) that was placed in ToSend[].
|
||||
//-----------------------------------------------------------------------------
|
||||
static void TransmitFor14443b_AsReader(void) {
|
||||
|
||||
// we could been in following mode:
|
||||
// FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ
|
||||
// if its second call or more
|
||||
|
||||
// while(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
|
||||
// AT91C_BASE_SSC->SSC_THR = 0XFF;
|
||||
// }
|
||||
|
||||
int c;
|
||||
volatile uint32_t b;
|
||||
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX | FPGA_HF_READER_TX_SHALLOW_MOD);
|
||||
SpinDelay(40);
|
||||
SpinDelay(60);
|
||||
|
||||
// What does this loop do? Is it TR1?
|
||||
// 0xFF = 8 bits of 1. 1 bit == 1Etu,..
|
||||
|
@ -1020,27 +1017,21 @@ static void TransmitFor14443b_AsReader(void) {
|
|||
// 80*9 = 720us.
|
||||
|
||||
for(c = 0; c < 50;) {
|
||||
|
||||
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
|
||||
AT91C_BASE_SSC->SSC_THR = 0xFF;
|
||||
c++;
|
||||
}
|
||||
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
|
||||
b = AT91C_BASE_SSC->SSC_RHR; (void)b;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Send frame loop
|
||||
for(c = 0; c < ToSendMax;) {
|
||||
|
||||
// Put byte into tx holding register as soon as it is ready
|
||||
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
|
||||
AT91C_BASE_SSC->SSC_THR = ToSend[c++];
|
||||
}
|
||||
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
|
||||
b = AT91C_BASE_SSC->SSC_RHR; (void)b;
|
||||
}
|
||||
}
|
||||
//WaitForFpgaDelayQueueIsEmpty(delay);
|
||||
// We should wait here for the FPGA to send all bits.
|
||||
WDT_HIT();
|
||||
}
|
||||
|
||||
|
@ -1188,7 +1179,8 @@ uint8_t iso14443b_select_srx_card(iso14b_card_select_t *card ) {
|
|||
CodeAndTransmit14443bAsReader(init_srx, sizeof(init_srx));
|
||||
GetTagSamplesFor14443bDemod(); //no
|
||||
|
||||
if (Demod.len == 0) return 2;
|
||||
if (Demod.len == 0)
|
||||
return 2;
|
||||
|
||||
// Randomly generated Chip ID
|
||||
if (card) card->chipid = Demod.output[0];
|
||||
|
@ -1200,16 +1192,16 @@ uint8_t iso14443b_select_srx_card(iso14b_card_select_t *card ) {
|
|||
CodeAndTransmit14443bAsReader(select_srx, sizeof(select_srx));
|
||||
GetTagSamplesFor14443bDemod(); //no
|
||||
|
||||
if (Demod.len != 3) return 2;
|
||||
if (Demod.len != 3)
|
||||
return 2;
|
||||
|
||||
// Check the CRC of the answer:
|
||||
if (!check_crc(CRC_14443_B, Demod.output, Demod.len)) {
|
||||
if (MF_DBGLEVEL > 1) Dbprintf("crc fail ice2");
|
||||
if (!check_crc(CRC_14443_B, Demod.output, Demod.len))
|
||||
return 3;
|
||||
}
|
||||
|
||||
// Check response from the tag: should be the same UID as the command we just sent:
|
||||
if (select_srx[1] != Demod.output[0]) return 1;
|
||||
if (select_srx[1] != Demod.output[0])
|
||||
return 1;
|
||||
|
||||
// First get the tag's UID:
|
||||
select_srx[0] = ISO14443B_GET_UID;
|
||||
|
@ -1218,13 +1210,12 @@ uint8_t iso14443b_select_srx_card(iso14b_card_select_t *card ) {
|
|||
CodeAndTransmit14443bAsReader(select_srx, 3); // Only first three bytes for this one
|
||||
GetTagSamplesFor14443bDemod(); //no
|
||||
|
||||
if (Demod.len != 10) return 2;
|
||||
if (Demod.len != 10)
|
||||
return 2;
|
||||
|
||||
// The check the CRC of the answer
|
||||
if (!check_crc(CRC_14443_B, Demod.output, Demod.len)) {
|
||||
if (MF_DBGLEVEL > 1) Dbprintf("crc fail ice3");
|
||||
if (!check_crc(CRC_14443_B, Demod.output, Demod.len))
|
||||
return 3;
|
||||
}
|
||||
|
||||
if (card) {
|
||||
card->uidlen = 8;
|
||||
|
@ -1251,13 +1242,12 @@ uint8_t iso14443b_select_card(iso14b_card_select_t *card ) {
|
|||
GetTagSamplesFor14443bDemod(); //select_card
|
||||
|
||||
// ATQB too short?
|
||||
if (Demod.len < 14) return 2;
|
||||
if (Demod.len < 14)
|
||||
return 2;
|
||||
|
||||
// VALIDATE CRC
|
||||
if (!check_crc(CRC_14443_B, Demod.output, Demod.len)) {
|
||||
if (MF_DBGLEVEL > 3) Dbprintf("iso1443b_setup crc fail");
|
||||
if (!check_crc(CRC_14443_B, Demod.output, Demod.len))
|
||||
return 3;
|
||||
}
|
||||
|
||||
if (card) {
|
||||
card->uidlen = 4;
|
||||
|
@ -1276,13 +1266,12 @@ uint8_t iso14443b_select_card(iso14b_card_select_t *card ) {
|
|||
GetTagSamplesFor14443bDemod();//select_card
|
||||
|
||||
// Answer to ATTRIB too short?
|
||||
if(Demod.len < 3) return 2;
|
||||
if(Demod.len < 3)
|
||||
return 2;
|
||||
|
||||
// VALIDATE CRC
|
||||
if (!check_crc(CRC_14443_B, Demod.output, Demod.len) ) {
|
||||
if (MF_DBGLEVEL > 3) Dbprintf("iso1443b_setup crc2 fail");
|
||||
if (!check_crc(CRC_14443_B, Demod.output, Demod.len) )
|
||||
return 3;
|
||||
}
|
||||
|
||||
if (card) {
|
||||
|
||||
|
@ -1314,11 +1303,8 @@ uint8_t iso14443b_select_card(iso14b_card_select_t *card ) {
|
|||
// Set up ISO 14443 Type B communication (similar to iso14443a_setup)
|
||||
// field is setup for "Sending as Reader"
|
||||
void iso14443b_setup() {
|
||||
if (MF_DBGLEVEL > 3) Dbprintf("iso1443b_setup Enter");
|
||||
LEDsoff();
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
|
||||
//BigBuf_free();
|
||||
//BigBuf_Clear_ext(false);
|
||||
|
||||
// Initialize Demod and Uart structs
|
||||
DemodInit(BigBuf_malloc(MAX_FRAME_SIZE));
|
||||
|
@ -1332,13 +1318,12 @@ void iso14443b_setup() {
|
|||
|
||||
// Signal field is on with the appropriate LED
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX | FPGA_HF_READER_TX_SHALLOW_MOD);
|
||||
SpinDelay(300);
|
||||
SpinDelay(100);
|
||||
|
||||
// Start the timer
|
||||
StartCountSspClk();
|
||||
|
||||
LED_D_ON();
|
||||
if (MF_DBGLEVEL > 3) Dbprintf("iso1443b_setup Exit");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -1350,91 +1335,42 @@ void iso14443b_setup() {
|
|||
//
|
||||
// I tried to be systematic and check every answer of the tag, every CRC, etc...
|
||||
//-----------------------------------------------------------------------------
|
||||
static bool ReadSTBlock(uint8_t block) {
|
||||
uint8_t cmd[] = {ISO14443B_READ_BLK, block, 0x00, 0x00};
|
||||
AddCrc14B(cmd, 2);
|
||||
CodeAndTransmit14443bAsReader(cmd, sizeof(cmd));
|
||||
GetTagSamplesFor14443bDemod();
|
||||
|
||||
// Check if we got an answer from the tag
|
||||
if (Demod.len != 6) {
|
||||
DbpString("[!] expected 6 bytes from tag, got less...");
|
||||
return false;
|
||||
}
|
||||
// The check the CRC of the answer
|
||||
if (!check_crc(CRC_14443_B, Demod.output, Demod.len)) {
|
||||
DbpString("[!] CRC Error block!");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
void ReadSTMemoryIso14443b(uint8_t numofblocks) {
|
||||
// Make sure that we start from off, since the tags are stateful;
|
||||
// confusing things will happen if we don't reset them between reads.
|
||||
switch_off();
|
||||
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
|
||||
SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
|
||||
|
||||
FpgaSetupSsc();
|
||||
|
||||
set_tracing(true);
|
||||
|
||||
// Now give it time to spin up.
|
||||
// Signal field is on with the appropriate LED
|
||||
LED_D_ON();
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ);
|
||||
SpinDelay(100);
|
||||
//switch_off();
|
||||
|
||||
uint8_t i = 0x00;
|
||||
uint8_t *buf = BigBuf_malloc(sizeof(iso14b_card_select_t));
|
||||
|
||||
// First command: wake up the tag using the INITIATE command
|
||||
uint8_t cmd1[] = {ISO14443B_INITIATE, 0x00, 0x97, 0x5b};
|
||||
CodeAndTransmit14443bAsReader(cmd1, sizeof(cmd1)); //no
|
||||
GetTagSamplesFor14443bDemod(); // no
|
||||
|
||||
if (Demod.len == 0) {
|
||||
DbpString("[!] No response from tag");
|
||||
set_tracing(false);
|
||||
return;
|
||||
} else {
|
||||
Dbprintf("Randomly generated Chip ID (+ 2 byte CRC): %02x %02x %02x",
|
||||
Demod.output[0], Demod.output[1], Demod.output[2]);
|
||||
}
|
||||
|
||||
// There is a response, SELECT the uid
|
||||
DbpString("[!] SELECT tag:");
|
||||
cmd1[0] = ISO14443B_SELECT; // 0x0E is SELECT
|
||||
cmd1[1] = Demod.output[0];
|
||||
AddCrc14B(cmd1, 2);
|
||||
CodeAndTransmit14443bAsReader(cmd1, sizeof(cmd1)); //no
|
||||
GetTagSamplesFor14443bDemod(); //no
|
||||
if (Demod.len != 3) {
|
||||
Dbprintf("[!] expected 3 bytes from tag, got %d", Demod.len);
|
||||
set_tracing(false);
|
||||
return;
|
||||
}
|
||||
// Check the CRC of the answer:
|
||||
iso14443b_setup();
|
||||
|
||||
if (!check_crc(CRC_14443_B, Demod.output, Demod.len)) {
|
||||
DbpString("[!] CRC Error reading select response.");
|
||||
set_tracing(false);
|
||||
return;
|
||||
}
|
||||
// Check response from the tag: should be the same UID as the command we just sent:
|
||||
if (cmd1[1] != Demod.output[0]) {
|
||||
Dbprintf("[!] Bad response to SELECT from Tag, aborting: %02x %02x", cmd1[1], Demod.output[0]);
|
||||
set_tracing(false);
|
||||
return;
|
||||
}
|
||||
iso14b_card_select_t *card = (iso14b_card_select_t*)buf;
|
||||
uint8_t res = iso14443b_select_srx_card(card);
|
||||
|
||||
// Tag is now selected,
|
||||
// First get the tag's UID:
|
||||
cmd1[0] = ISO14443B_GET_UID;
|
||||
AddCrc14B(cmd1, 1);
|
||||
CodeAndTransmit14443bAsReader(cmd1, 3); // no -- Only first three bytes for this one
|
||||
GetTagSamplesFor14443bDemod(); //no
|
||||
if (Demod.len != 10) {
|
||||
Dbprintf("[!] expected 10 bytes from tag, got %d", Demod.len);
|
||||
set_tracing(false);
|
||||
return;
|
||||
}
|
||||
// The check the CRC of the answer (use cmd1 as temporary variable):
|
||||
// 0: OK 2: attrib fail, 3:crc fail,
|
||||
if ( res > 0 ) goto out;
|
||||
|
||||
if (!check_crc(CRC_14443_B, Demod.output, Demod.len)) {
|
||||
Dbprintf("[!] CRC Error reading block! Expected: %04x got: %04x", (cmd1[2]<<8)+cmd1[3], (Demod.output[8]<<8)+Demod.output[9]);
|
||||
// Do not return;, let's go on... (we should retry, maybe ?)
|
||||
}
|
||||
Dbprintf("[+] Tag UID (64 bits): %08x %08x",
|
||||
(Demod.output[7]<<24) + (Demod.output[6]<<16) + (Demod.output[5]<<8) + Demod.output[4],
|
||||
(Demod.output[3]<<24) + (Demod.output[2]<<16) + (Demod.output[1]<<8) + Demod.output[0]);
|
||||
|
||||
// Now loop to read all 16 blocks, address from 0 to last block
|
||||
Dbprintf("[+] Tag memory dump, block 0 to %d", numofblocks);
|
||||
cmd1[0] = 0x08;
|
||||
i = 0x00;
|
||||
|
||||
++numofblocks;
|
||||
|
||||
for (;;) {
|
||||
|
@ -1442,22 +1378,16 @@ void ReadSTMemoryIso14443b(uint8_t numofblocks) {
|
|||
DbpString("System area block (0xFF):");
|
||||
i = 0xff;
|
||||
}
|
||||
cmd1[1] = i;
|
||||
AddCrc14B(cmd1, 2);
|
||||
CodeAndTransmit14443bAsReader(cmd1, sizeof(cmd1)); //no
|
||||
GetTagSamplesFor14443bDemod(); //no
|
||||
|
||||
uint8_t retries = 3;
|
||||
do {
|
||||
res = ReadSTBlock(i);
|
||||
} while (!res && --retries);
|
||||
|
||||
if (Demod.len != 6) { // Check if we got an answer from the tag
|
||||
DbpString("[!] expected 6 bytes from tag, got less...");
|
||||
return;
|
||||
}
|
||||
// The check the CRC of the answer (use cmd1 as temporary variable):
|
||||
|
||||
if (!check_crc(CRC_14443_B, Demod.output, Demod.len)) {
|
||||
Dbprintf("[!] CRC Error reading block! Expected: %04x got: %04x",
|
||||
(cmd1[2]<<8)+cmd1[3], (Demod.output[4]<<8)+Demod.output[5]);
|
||||
// Do not return;, let's go on... (we should retry, maybe ?)
|
||||
if (!res && !retries) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
// Now print out the memory location:
|
||||
Dbprintf("Address=%02x, Contents=%08x, CRC=%04x", i,
|
||||
(Demod.output[3]<<24) + (Demod.output[2]<<16) + (Demod.output[1]<<8) + Demod.output[0],
|
||||
|
@ -1467,11 +1397,13 @@ void ReadSTMemoryIso14443b(uint8_t numofblocks) {
|
|||
++i;
|
||||
}
|
||||
|
||||
set_tracing(false);
|
||||
out:
|
||||
switch_off(); // disconnect raw
|
||||
SpinDelay(20);
|
||||
}
|
||||
|
||||
static void iso1444b_setup_sniff(void){
|
||||
if (MF_DBGLEVEL > 3) Dbprintf("iso1443b_setup_sniff Enter");
|
||||
|
||||
LEDsoff();
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
|
||||
BigBuf_free();
|
||||
|
@ -1504,8 +1436,6 @@ static void iso1444b_setup_sniff(void){
|
|||
|
||||
// Start the SSP timer
|
||||
StartCountSspClk();
|
||||
|
||||
if (MF_DBGLEVEL > 3) Dbprintf("iso1443b_setup_sniff Exit");
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
@ -1596,7 +1526,7 @@ void RAMFUNC SniffIso14443b(void) {
|
|||
|
||||
// is this | 0x01 the error? & 0xfe in https://github.com/Proxmark/proxmark3/issues/103
|
||||
// LSB is a fpga signal bit.
|
||||
if (Handle14443bTagSamplesDemod(ci >> 1, cq >> 1)) {
|
||||
if (Handle14443bTagSamplesDemod(ci, cq)) {
|
||||
time_stop = GetCountSspClk() - time_0;
|
||||
LogTrace(Demod.output, Demod.len, time_start, time_stop, NULL, false);
|
||||
UartReset();
|
||||
|
@ -1647,10 +1577,8 @@ void SendRawCommand14443B_Ex(UsbCommand *c) {
|
|||
iso14b_set_trigger(true);
|
||||
|
||||
if ((param & ISO14B_CONNECT) == ISO14B_CONNECT) {
|
||||
// Make sure that we start from off, since the tags are stateful;
|
||||
// confusing things will happen if we don't reset them between reads.
|
||||
//switch_off(); // before connect in raw
|
||||
iso14443b_setup();
|
||||
clear_trace();
|
||||
}
|
||||
|
||||
set_tracing(true);
|
||||
|
@ -1660,15 +1588,15 @@ void SendRawCommand14443B_Ex(UsbCommand *c) {
|
|||
status = iso14443b_select_card(card);
|
||||
cmd_send(CMD_ACK, status, sendlen, 0, buf, sendlen);
|
||||
// 0: OK 2: attrib fail, 3:crc fail,
|
||||
if ( status > 0 ) return;
|
||||
if ( status > 0 ) goto out;
|
||||
}
|
||||
|
||||
if ((param & ISO14B_SELECT_SR) == ISO14B_SELECT_SR) {
|
||||
iso14b_card_select_t *card = (iso14b_card_select_t*)buf;
|
||||
status = iso14443b_select_srx_card(card);
|
||||
cmd_send(CMD_ACK, status, sendlen, 0, buf, sendlen);
|
||||
// 0: OK 2: attrib fail, 3:crc fail,
|
||||
if ( status > 0 ) return;
|
||||
// 0: OK 2: demod fail, 3:crc fail,
|
||||
if ( status > 0 ) goto out;
|
||||
}
|
||||
|
||||
if ((param & ISO14B_APDU) == ISO14B_APDU) {
|
||||
|
@ -1690,6 +1618,7 @@ void SendRawCommand14443B_Ex(UsbCommand *c) {
|
|||
cmd_send(CMD_ACK, status, sendlen, 0, Demod.output, sendlen);
|
||||
}
|
||||
|
||||
out:
|
||||
// turn off trigger (LED_A)
|
||||
if ((param & ISO14B_REQUEST_TRIGGER) == ISO14B_REQUEST_TRIGGER)
|
||||
iso14b_set_trigger(false);
|
||||
|
@ -1697,11 +1626,7 @@ void SendRawCommand14443B_Ex(UsbCommand *c) {
|
|||
// turn off antenna et al
|
||||
// we don't send a HALT command.
|
||||
if ((param & ISO14B_DISCONNECT) == ISO14B_DISCONNECT) {
|
||||
if (MF_DBGLEVEL > 2) Dbprintf("disconnect");
|
||||
switch_off(); // disconnect raw
|
||||
SpinDelay(20);
|
||||
} else {
|
||||
//FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX | FPGA_HF_READER_TX_SHALLOW_MOD);
|
||||
}
|
||||
|
||||
}
|
|
@ -1930,7 +1930,7 @@ void Cotag(uint32_t arg0) {
|
|||
// Turn the field off
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
|
||||
cmd_send(CMD_ACK,0,0,0,0,0);
|
||||
LED_A_OFF();
|
||||
LEDsoff();
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -399,8 +399,9 @@ uint32_t doCotagAcquisitionManchester() {
|
|||
uint8_t sample = 0, firsthigh = 0, firstlow = 0;
|
||||
uint16_t sample_counter = 0, period = 0;
|
||||
uint8_t curr = 0, prev = 0;
|
||||
uint16_t noise_counter = 0;
|
||||
|
||||
while (!BUTTON_PRESS() && !usb_poll_validate_length() && (sample_counter < bufsize) ) {
|
||||
while (!BUTTON_PRESS() && !usb_poll_validate_length() && (sample_counter < bufsize) && (noise_counter < (COTAG_T1 << 1)) ) {
|
||||
WDT_HIT();
|
||||
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
|
||||
AT91C_BASE_SSC->SSC_THR = 0x43;
|
||||
|
@ -413,14 +414,20 @@ uint32_t doCotagAcquisitionManchester() {
|
|||
|
||||
// find first peak
|
||||
if ( !firsthigh ) {
|
||||
if (sample < COTAG_ONE_THRESHOLD)
|
||||
if (sample < COTAG_ONE_THRESHOLD) {
|
||||
noise_counter++;
|
||||
continue;
|
||||
}
|
||||
noise_counter = 0;
|
||||
firsthigh = 1;
|
||||
}
|
||||
|
||||
if ( !firstlow ){
|
||||
if (sample > COTAG_ZERO_THRESHOLD )
|
||||
if (sample > COTAG_ZERO_THRESHOLD ) {
|
||||
noise_counter++;
|
||||
continue;
|
||||
}
|
||||
noise_counter = 0;
|
||||
firstlow = 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -37,10 +37,11 @@ void StartCountSspClk();
|
|||
void ResetSspClk(void);
|
||||
uint32_t RAMFUNC GetCountSspClk();
|
||||
|
||||
void StartTicks(void);
|
||||
uint32_t GetTicks(void);
|
||||
void WaitTicks(uint32_t ticks);
|
||||
void WaitUS(uint16_t us);
|
||||
void WaitMS(uint16_t ms);
|
||||
void StopTicks(void);
|
||||
extern void StartTicks(void);
|
||||
extern uint32_t GetTicks(void);
|
||||
extern void WaitTicks(uint32_t ticks);
|
||||
extern void WaitUS(uint16_t us);
|
||||
extern void WaitMS(uint16_t ms);
|
||||
|
||||
extern void StopTicks(void);
|
||||
#endif
|
|
@ -66,7 +66,7 @@ int usage_analyse_nuid(void){
|
|||
return 0;
|
||||
}
|
||||
int usage_analyse_a(void) {
|
||||
PrintAndLogEx(NORMAL, "my personal garbage test command");
|
||||
PrintAndLogEx(NORMAL, "Iceman's personal garbage test command");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(NORMAL, "Usage: analyse a [h] d <bytes>");
|
||||
PrintAndLogEx(NORMAL, "Options:");
|
||||
|
@ -248,9 +248,17 @@ int CmdAnalyseLCR(const char *Cmd) {
|
|||
if (strlen(Cmd) == 0|| cmdp == 'h' || cmdp == 'H') return usage_analyse_lcr();
|
||||
|
||||
int len = 0;
|
||||
param_gethex_ex(Cmd, 0, data, &len);
|
||||
if ( len%2 ) return usage_analyse_lcr();
|
||||
len >>= 1;
|
||||
switch (param_gethex_to_eol(Cmd, 0, data, sizeof(data), &len)) {
|
||||
case 1:
|
||||
PrintAndLogEx(WARNING, "Invalid HEX value.");
|
||||
return 1;
|
||||
case 2:
|
||||
PrintAndLogEx(WARNING, "Too many bytes. Max %d bytes", sizeof(data));
|
||||
return 1;
|
||||
case 3:
|
||||
PrintAndLogEx(WARNING, "Hex must have even number of digits.");
|
||||
return 1;
|
||||
}
|
||||
uint8_t finalXor = calculateLRC(data, len);
|
||||
PrintAndLogEx(NORMAL, "Target [%02X] requires final LRC XOR byte value: 0x%02X",data[len-1] ,finalXor);
|
||||
return 0;
|
||||
|
|
|
@ -150,6 +150,7 @@ int GetModels(char *Models[], int *count, uint8_t *width){
|
|||
if (pset.flags & P_REFOUT)
|
||||
prev(&apoly);
|
||||
|
||||
|
||||
for (qptr = apolys; qptr < pptr; ++qptr) {
|
||||
crc = pcrc(*qptr, pset.spoly, pset.init, apoly, 0);
|
||||
if (ptst(crc)) {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2010 iZsh <izsh at fail0verflow.com>
|
||||
// Modified 2018 iceman
|
||||
//
|
||||
// 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
|
||||
|
@ -89,12 +90,28 @@ int usage_hf_14b_write_srx(void){
|
|||
PrintAndLogEx(NORMAL, " hf 14b sriwrite 2 FF 11223344");
|
||||
return 0;
|
||||
}
|
||||
int usage_hf_14b_dump(void){
|
||||
PrintAndLogEx(NORMAL, "This command dumps the contents of a ISO-14443-B tag and save it to file\n"
|
||||
"\n"
|
||||
"Usage: hf 14b dump [h] [card memory] <f filname> \n"
|
||||
"Options:\n"
|
||||
"\th this help\n"
|
||||
"\t[card memory] 1 = SRIX4K (default), 2 = SRI512"
|
||||
"\tf <name> filename, if no <name> UID will be used as filename\n"
|
||||
"\n"
|
||||
"Example:\n"
|
||||
"\thf 14b dump f\n"
|
||||
"\thf 14b dump 2 f mydump");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
static void switch_on_field_14b(void) {
|
||||
UsbCommand c = {CMD_ISO_14443B_COMMAND, {ISO14B_CONNECT, 0, 0}};
|
||||
clearCommandBuffer();
|
||||
SendCommand(&c);
|
||||
}
|
||||
*/
|
||||
|
||||
static int switch_off_field_14b(void) {
|
||||
UsbCommand c = {CMD_ISO_14443B_COMMAND, {ISO14B_DISCONNECT, 0, 0}};
|
||||
|
@ -109,11 +126,11 @@ int CmdHF14BList(const char *Cmd) {
|
|||
}
|
||||
|
||||
int CmdHF14BSim(const char *Cmd) {
|
||||
char cmdp = param_getchar(Cmd, 0);
|
||||
if (cmdp == 'h' || cmdp == 'H') return usage_hf_14b_sim();
|
||||
char cmdp = tolower(param_getchar(Cmd, 0));
|
||||
if (cmdp == 'h') return usage_hf_14b_sim();
|
||||
|
||||
uint32_t pupi = 0;
|
||||
if (cmdp == 'u' || cmdp == 'U') {
|
||||
if (cmdp == 'u') {
|
||||
pupi = param_get32ex(Cmd, 1, 0, 16);
|
||||
}
|
||||
|
||||
|
@ -125,8 +142,8 @@ int CmdHF14BSim(const char *Cmd) {
|
|||
|
||||
int CmdHF14BSniff(const char *Cmd) {
|
||||
|
||||
char cmdp = param_getchar(Cmd, 0);
|
||||
if (cmdp == 'h' || cmdp == 'H') return usage_hf_14b_sniff();
|
||||
char cmdp = tolower(param_getchar(Cmd, 0));
|
||||
if (cmdp == 'h') return usage_hf_14b_sniff();
|
||||
|
||||
UsbCommand c = {CMD_SNOOP_ISO_14443B, {0, 0, 0}};
|
||||
clearCommandBuffer();
|
||||
|
@ -151,26 +168,21 @@ int CmdHF14BCmdRaw (const char *Cmd) {
|
|||
while (Cmd[i]!='\0') {
|
||||
if (Cmd[i]==' ' || Cmd[i]=='\t') { ++i; continue; }
|
||||
if (Cmd[i]=='-') {
|
||||
switch (Cmd[i+1]) {
|
||||
switch (tolower(Cmd[i+1])) {
|
||||
case 'h':
|
||||
case 'H':
|
||||
return usage_hf_14b_raw();
|
||||
case 'r':
|
||||
case 'R':
|
||||
reply = false;
|
||||
break;
|
||||
case 'c':
|
||||
case 'C':
|
||||
flags |= ISO14B_APPEND_CRC;
|
||||
break;
|
||||
case 'p':
|
||||
case 'P':
|
||||
power = true;
|
||||
break;
|
||||
case 's':
|
||||
case 'S':
|
||||
select = true;
|
||||
if (Cmd[i+2]=='s' || Cmd[i+2]=='S') {
|
||||
if (tolower(Cmd[i+2]) == 's') {
|
||||
flags |= ISO14B_SELECT_SR;
|
||||
++i;
|
||||
} else {
|
||||
|
@ -229,6 +241,54 @@ int CmdHF14BCmdRaw (const char *Cmd) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
static bool get_14b_UID(iso14b_card_select_t *card) {
|
||||
|
||||
if (!card)
|
||||
return false;
|
||||
|
||||
uint8_t retry = 3;
|
||||
UsbCommand resp;
|
||||
UsbCommand c = {CMD_ISO_14443B_COMMAND, {ISO14B_CONNECT | ISO14B_SELECT_SR | ISO14B_DISCONNECT, 0, 0}};
|
||||
|
||||
// test for 14b SR
|
||||
while (retry--) {
|
||||
|
||||
clearCommandBuffer();
|
||||
SendCommand(&c);
|
||||
if (WaitForResponseTimeout(CMD_ACK, &resp, TIMEOUT)) {
|
||||
|
||||
uint8_t status = resp.arg[0];
|
||||
if ( status == 0) {
|
||||
memcpy(card, (iso14b_card_select_t *)resp.d.asBytes, sizeof(iso14b_card_select_t));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} // retry
|
||||
|
||||
// test 14b standard
|
||||
c.arg[0] = ISO14B_CONNECT | ISO14B_SELECT_STD | ISO14B_DISCONNECT;
|
||||
retry = 3;
|
||||
while (retry--) {
|
||||
|
||||
|
||||
clearCommandBuffer();
|
||||
SendCommand(&c);
|
||||
if (WaitForResponseTimeout(CMD_ACK, &resp, TIMEOUT)) {
|
||||
|
||||
uint8_t status = resp.arg[0];
|
||||
if ( status == 0) {
|
||||
memcpy(card, (iso14b_card_select_t *)resp.d.asBytes, sizeof(iso14b_card_select_t));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} // retry
|
||||
|
||||
if ( !retry )
|
||||
PrintAndLogEx(WARNING, "timeout while waiting for reply.");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// print full atqb info
|
||||
// bytes
|
||||
// 0,1,2,3 = application data
|
||||
|
@ -374,8 +434,45 @@ static void print_st_general_info(uint8_t *data, uint8_t len){
|
|||
|
||||
// 14b get and print Full Info (as much as we know)
|
||||
bool HF14B_Std_Info(bool verbose){
|
||||
//add more info here
|
||||
|
||||
bool isSuccess = false;
|
||||
|
||||
// 14b get and print UID only (general info)
|
||||
UsbCommand c = {CMD_ISO_14443B_COMMAND, {ISO14B_CONNECT | ISO14B_SELECT_STD | ISO14B_DISCONNECT, 0, 0}};
|
||||
clearCommandBuffer();
|
||||
SendCommand(&c);
|
||||
UsbCommand resp;
|
||||
|
||||
if (!WaitForResponseTimeout(CMD_ACK, &resp, TIMEOUT)) {
|
||||
if (verbose) PrintAndLogEx(WARNING, "command execution timeout");
|
||||
switch_off_field_14b();
|
||||
return false;
|
||||
}
|
||||
|
||||
iso14b_card_select_t card;
|
||||
memcpy(&card, (iso14b_card_select_t *)resp.d.asBytes, sizeof(iso14b_card_select_t));
|
||||
|
||||
uint64_t status = resp.arg[0];
|
||||
|
||||
switch( status ){
|
||||
case 0:
|
||||
PrintAndLogEx(NORMAL, " UID : %s", sprint_hex(card.uid, card.uidlen));
|
||||
PrintAndLogEx(NORMAL, " ATQB : %s", sprint_hex(card.atqb, sizeof(card.atqb)));
|
||||
PrintAndLogEx(NORMAL, " CHIPID : %02X", card.chipid);
|
||||
print_atqb_resp(card.atqb, card.cid);
|
||||
isSuccess = true;
|
||||
case 2:
|
||||
if (verbose) PrintAndLogEx(FAILED, "ISO 14443-3 ATTRIB fail");
|
||||
break;
|
||||
case 3:
|
||||
if (verbose) PrintAndLogEx(FAILED, "ISO 14443-3 CRC fail");
|
||||
break;
|
||||
default:
|
||||
if (verbose) PrintAndLogEx(FAILED, "ISO 14443-b card select failed");
|
||||
break;
|
||||
}
|
||||
|
||||
return isSuccess;
|
||||
}
|
||||
|
||||
// SRx get and print full info (needs more info...)
|
||||
|
@ -395,7 +492,10 @@ bool HF14B_ST_Info(bool verbose){
|
|||
memcpy(&card, (iso14b_card_select_t *)resp.d.asBytes, sizeof(iso14b_card_select_t));
|
||||
|
||||
uint64_t status = resp.arg[0];
|
||||
if ( status > 0 ) return switch_off_field_14b();
|
||||
if ( status > 0 )
|
||||
return false;
|
||||
|
||||
print_st_general_info(card.uid, card.uidlen);
|
||||
|
||||
//add locking bit information here. uint8_t data[16] = {0x00};
|
||||
// uint8_t datalen = 2;
|
||||
|
@ -418,7 +518,6 @@ bool HF14B_ST_Info(bool verbose){
|
|||
|
||||
// if (datalen != resplen || !crc) return rawClose();
|
||||
//print_ST_Lock_info(data[5]>>2);
|
||||
switch_off_field_14b();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -428,7 +527,7 @@ bool HF14BInfo(bool verbose){
|
|||
// try std 14b (atqb)
|
||||
if (HF14B_Std_Info(verbose)) return true;
|
||||
|
||||
// try st 14b
|
||||
// try ST 14b
|
||||
if (HF14B_ST_Info(verbose)) return true;
|
||||
|
||||
// try unknown 14b read commands (to be identified later)
|
||||
|
@ -439,10 +538,10 @@ bool HF14BInfo(bool verbose){
|
|||
|
||||
// menu command to get and print all info known about any known 14b tag
|
||||
int CmdHF14Binfo(const char *Cmd){
|
||||
char cmdp = param_getchar(Cmd, 0);
|
||||
if (cmdp == 'h' || cmdp == 'H') return usage_hf_14b_info();
|
||||
char cmdp = tolower(param_getchar(Cmd, 0));
|
||||
if (cmdp == 'h') return usage_hf_14b_info();
|
||||
|
||||
bool verbose = !((cmdp == 's') || (cmdp == 'S'));
|
||||
bool verbose = !(cmdp == 's');
|
||||
return HF14BInfo(verbose);
|
||||
}
|
||||
|
||||
|
@ -450,16 +549,13 @@ bool HF14B_ST_Reader(bool verbose){
|
|||
|
||||
bool isSuccess = false;
|
||||
|
||||
switch_on_field_14b();
|
||||
|
||||
// SRx get and print general info about SRx chip from UID
|
||||
UsbCommand c = {CMD_ISO_14443B_COMMAND, {ISO14B_SELECT_SR, 0, 0}};
|
||||
UsbCommand c = {CMD_ISO_14443B_COMMAND, {ISO14B_CONNECT | ISO14B_SELECT_SR | ISO14B_DISCONNECT, 0, 0}};
|
||||
clearCommandBuffer();
|
||||
SendCommand(&c);
|
||||
UsbCommand resp;
|
||||
if (!WaitForResponseTimeout(CMD_ACK, &resp, TIMEOUT)) {
|
||||
if (verbose) PrintAndLogEx(WARNING, "command execution timeout");
|
||||
switch_off_field_14b();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -486,8 +582,6 @@ bool HF14B_ST_Reader(bool verbose){
|
|||
if (verbose) PrintAndLogEx(FAILED, "ISO 14443-b card select SRx failed");
|
||||
break;
|
||||
}
|
||||
|
||||
switch_off_field_14b();
|
||||
return isSuccess;
|
||||
}
|
||||
|
||||
|
@ -503,7 +597,6 @@ bool HF14B_Std_Reader(bool verbose){
|
|||
|
||||
if (!WaitForResponseTimeout(CMD_ACK, &resp, TIMEOUT)) {
|
||||
if (verbose) PrintAndLogEx(WARNING, "command execution timeout");
|
||||
switch_off_field_14b();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -530,8 +623,6 @@ bool HF14B_Std_Reader(bool verbose){
|
|||
if (verbose) PrintAndLogEx(FAILED, "ISO 14443-b card select failed");
|
||||
break;
|
||||
}
|
||||
|
||||
switch_off_field_14b();
|
||||
return isSuccess;
|
||||
}
|
||||
|
||||
|
@ -613,10 +704,10 @@ bool HF14BReader(bool verbose){
|
|||
|
||||
// menu command to get and print general info about all known 14b chips
|
||||
int CmdHF14BReader(const char *Cmd){
|
||||
char cmdp = param_getchar(Cmd, 0);
|
||||
if (cmdp == 'h' || cmdp == 'H') return usage_hf_14b_reader();
|
||||
char cmdp = tolower(param_getchar(Cmd, 0));
|
||||
if (cmdp == 'h') return usage_hf_14b_reader();
|
||||
|
||||
bool verbose = !((cmdp == 's') || (cmdp == 'S'));
|
||||
bool verbose = !(cmdp == 's');
|
||||
return HF14BReader(verbose);
|
||||
}
|
||||
|
||||
|
@ -625,8 +716,8 @@ int CmdHF14BReader(const char *Cmd){
|
|||
* this command just dumps the contents of the memory/
|
||||
*/
|
||||
int CmdHF14BReadSri(const char *Cmd){
|
||||
char cmdp = param_getchar(Cmd, 0);
|
||||
if (strlen(Cmd) < 1 || cmdp == 'h' || cmdp == 'H') return usage_hf_14b_read_srx();
|
||||
char cmdp = tolower(param_getchar(Cmd, 0));
|
||||
if (strlen(Cmd) < 1 || cmdp == 'h') return usage_hf_14b_read_srx();
|
||||
|
||||
uint8_t tagtype = param_get8(Cmd, 0);
|
||||
uint8_t blocks = (tagtype == 1) ? 0x7F : 0x0F;
|
||||
|
@ -648,14 +739,14 @@ int CmdHF14BWriteSri(const char *Cmd){
|
|||
* Special block FF = otp_lock_reg block.
|
||||
* Data len 4 bytes-
|
||||
*/
|
||||
char cmdp = param_getchar(Cmd, 0);
|
||||
char cmdp = tolower(param_getchar(Cmd, 0));
|
||||
uint8_t blockno = -1;
|
||||
uint8_t data[4] = {0x00};
|
||||
bool isSrix4k = true;
|
||||
char str[30];
|
||||
memset(str, 0x00, sizeof(str));
|
||||
|
||||
if (strlen(Cmd) < 1 || cmdp == 'h' || cmdp == 'H') return usage_hf_14b_write_srx();
|
||||
if (strlen(Cmd) < 1 || cmdp == 'h') return usage_hf_14b_write_srx();
|
||||
|
||||
if ( cmdp == '2' )
|
||||
isSrix4k = false;
|
||||
|
@ -703,6 +794,162 @@ int CmdHF14BWriteSri(const char *Cmd){
|
|||
return 0;
|
||||
}
|
||||
|
||||
// need to write to file
|
||||
int CmdHF14BDump(const char*Cmd) {
|
||||
|
||||
uint8_t fileNameLen = 0;
|
||||
char filename[FILE_PATH_SIZE] = {0};
|
||||
char * fptr = filename;
|
||||
bool errors = false;
|
||||
uint8_t cmdp = 0, cardtype = 1;
|
||||
uint16_t cardsize = 0;
|
||||
uint8_t blocks = 0;
|
||||
iso14b_card_select_t card;
|
||||
|
||||
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
||||
switch (tolower(param_getchar(Cmd, cmdp))) {
|
||||
case 'h':
|
||||
return usage_hf_14b_dump();
|
||||
case 'f':
|
||||
fileNameLen = param_getstr(Cmd, cmdp+1, filename, FILE_PATH_SIZE);
|
||||
cmdp += 2;
|
||||
break;
|
||||
default:
|
||||
if (cmdp == 0) {
|
||||
cardtype = param_get8ex(Cmd, cmdp, 1, 10);
|
||||
cmdp++;
|
||||
} else {
|
||||
PrintAndLogEx(WARNING, "Unknown parameter '%c'\n", param_getchar(Cmd, cmdp));
|
||||
errors = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Validations
|
||||
if (errors) return usage_hf_14b_dump();
|
||||
|
||||
switch (cardtype){
|
||||
case 2:
|
||||
cardsize = (512/8) + 4;
|
||||
blocks = 0x0F;
|
||||
break;
|
||||
case 1:
|
||||
default:
|
||||
cardsize = (4096/8) + 4;
|
||||
blocks = 0x7F;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!get_14b_UID(&card)) {
|
||||
PrintAndLogEx(WARNING, "No tag found.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (fileNameLen < 1) {
|
||||
PrintAndLogEx(INFO, "Using UID as filename");
|
||||
fptr += sprintf(fptr, "hf-14b-");
|
||||
FillFileNameByUID(fptr, card.uid, "-dump", card.uidlen);
|
||||
}
|
||||
|
||||
// detect blocksize from card :)
|
||||
PrintAndLogEx(NORMAL, "Reading memory from tag UID %s", sprint_hex(card.uid, card.uidlen));
|
||||
|
||||
uint8_t data[cardsize];
|
||||
memset(data, 0, sizeof(data));
|
||||
|
||||
int blocknum = 0;
|
||||
uint8_t *recv = NULL;
|
||||
|
||||
UsbCommand resp;
|
||||
UsbCommand c = {CMD_ISO_14443B_COMMAND, { ISO14B_CONNECT | ISO14B_SELECT_SR, 0, 0}};
|
||||
clearCommandBuffer();
|
||||
SendCommand(&c);
|
||||
|
||||
//select
|
||||
if (WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
|
||||
if (resp.arg[0]) {
|
||||
PrintAndLogEx(INFO, "failed to select %d | %d", resp.arg[0], resp.arg[1]);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
c.arg[0] = ISO14B_APPEND_CRC | ISO14B_RAW;
|
||||
c.arg[1] = 2;
|
||||
|
||||
uint8_t *req = c.d.asBytes;
|
||||
req[0] = ISO14443B_READ_BLK;
|
||||
|
||||
for (int retry = 0; retry < 5; retry++) {
|
||||
|
||||
req[1] = blocknum;
|
||||
|
||||
clearCommandBuffer();
|
||||
SendCommand(&c);
|
||||
|
||||
if (WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
|
||||
|
||||
uint8_t status = resp.arg[0] & 0xFF;
|
||||
if ( status > 0 ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
uint16_t len = (resp.arg[1] & 0xFFFF);
|
||||
recv = resp.d.asBytes;
|
||||
|
||||
if ( !check_crc(CRC_14443_B, recv, len) ) {
|
||||
PrintAndLogEx(FAILED, "crc fail, retrying one more time");
|
||||
continue;
|
||||
}
|
||||
|
||||
memcpy(data + (blocknum * 4), resp.d.asBytes, 4);
|
||||
|
||||
if ( blocknum == 0xFF) {
|
||||
//last read.
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
retry = 0;
|
||||
blocknum++;
|
||||
if ( blocknum > blocks ) {
|
||||
// read config block
|
||||
blocknum = 0xFF;
|
||||
}
|
||||
|
||||
printf("."); fflush(stdout);
|
||||
}
|
||||
}
|
||||
|
||||
if ( blocknum != 0xFF) {
|
||||
PrintAndLogEx(NORMAL, "\n Dump failed");
|
||||
goto out;
|
||||
}
|
||||
|
||||
PrintAndLogEx(NORMAL, "\n");
|
||||
PrintAndLogEx(NORMAL, "block# | data | ascii");
|
||||
PrintAndLogEx(NORMAL, "---------+--------------+----------");
|
||||
|
||||
for (int i = 0; i <= blocks; i++) {
|
||||
PrintAndLogEx(NORMAL,
|
||||
"%3d/0x%02X | %s | %s",
|
||||
i,
|
||||
i,
|
||||
sprint_hex(data + (i*4), 4 ),
|
||||
sprint_ascii(data + (i*4), 4)
|
||||
);
|
||||
}
|
||||
|
||||
PrintAndLogEx(NORMAL, "\n");
|
||||
|
||||
|
||||
size_t datalen = (blocks+1) * 4;
|
||||
saveFileEML(filename, "eml", data, datalen, 4);
|
||||
saveFile(filename, "bin", data, datalen);
|
||||
out:
|
||||
return switch_off_field_14b();
|
||||
}
|
||||
|
||||
uint32_t srix4kEncode(uint32_t value) {
|
||||
/*
|
||||
// vv = value
|
||||
|
@ -844,6 +1091,7 @@ bool waitCmd14b(bool verbose) {
|
|||
|
||||
static command_t CommandTable[] = {
|
||||
{"help", CmdHelp, 1, "This help"},
|
||||
{"dump", CmdHF14BDump, 0, "Read all memory pages of an ISO14443-B tag, save to file"},
|
||||
{"info", CmdHF14Binfo, 0, "Tag information"},
|
||||
{"list", CmdHF14BList, 0, "[Deprecated] List ISO 14443B history"},
|
||||
{"raw", CmdHF14BCmdRaw, 0, "Send raw hex data to tag"},
|
||||
|
|
|
@ -45,6 +45,8 @@ extern int CmdHF14BSniff(const char *Cmd);
|
|||
extern int CmdHF14BWrite( const char *cmd);
|
||||
extern int CmdHF14BReader(const char *Cmd);
|
||||
|
||||
extern int CmdHF14BDump(const char *Cmd);
|
||||
|
||||
extern bool HF14BInfo(bool verbose);
|
||||
extern bool HF14BReader(bool verbose);
|
||||
extern int CmdHF14BCmdRaw (const char *Cmd);
|
||||
|
|
|
@ -658,12 +658,10 @@ int CmdHF15Dump(const char*Cmd) {
|
|||
uint8_t uid[8] = {0,0,0,0,0,0,0,0};
|
||||
|
||||
while(param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
||||
switch(param_getchar(Cmd, cmdp)) {
|
||||
switch (tolower(param_getchar(Cmd, cmdp))) {
|
||||
case 'h':
|
||||
case 'H':
|
||||
return usage_15_dump();
|
||||
case 'f':
|
||||
case 'F':
|
||||
fileNameLen = param_getstr(Cmd, cmdp+1, filename, FILE_PATH_SIZE);
|
||||
cmdp += 2;
|
||||
break;
|
||||
|
|
|
@ -166,8 +166,8 @@ int usage_legic_wipe(void){
|
|||
*/
|
||||
int CmdLegicInfo(const char *Cmd) {
|
||||
|
||||
char cmdp = param_getchar(Cmd, 0);
|
||||
if ( cmdp == 'H' || cmdp == 'h' ) return usage_legic_info();
|
||||
char cmdp = tolower(param_getchar(Cmd, 0));
|
||||
if ( cmdp == 'h' ) return usage_legic_info();
|
||||
|
||||
int i = 0, k = 0, segmentNum = 0, segment_len = 0, segment_flag = 0;
|
||||
int crc = 0, wrp = 0, wrc = 0;
|
||||
|
@ -477,8 +477,8 @@ out:
|
|||
// number of bytes to read
|
||||
int CmdLegicRdmem(const char *Cmd) {
|
||||
|
||||
char cmdp = param_getchar(Cmd, 0);
|
||||
if ( cmdp == 'H' || cmdp == 'h' ) return usage_legic_rdmem();
|
||||
char cmdp = tolower(param_getchar(Cmd, 0));
|
||||
if ( cmdp == 'h' ) return usage_legic_rdmem();
|
||||
|
||||
uint32_t offset = 0, len = 0, iv = 1;
|
||||
uint16_t datalen = 0;
|
||||
|
@ -524,9 +524,8 @@ int CmdLegicRfWrite(const char *Cmd) {
|
|||
uint32_t offset = 0, IV = 0x55;
|
||||
|
||||
while(param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
||||
switch(param_getchar(Cmd, cmdp)) {
|
||||
switch (tolower(param_getchar(Cmd, cmdp))) {
|
||||
case 'd':
|
||||
case 'D':
|
||||
// peek at length of the input string so we can
|
||||
// figure out how many elements to malloc in "data"
|
||||
bg=en=0;
|
||||
|
@ -571,12 +570,10 @@ int CmdLegicRfWrite(const char *Cmd) {
|
|||
cmdp += 2;
|
||||
break;
|
||||
case 'o':
|
||||
case 'O':
|
||||
offset = param_get32ex(Cmd, cmdp+1, 4, 16);
|
||||
cmdp += 2;
|
||||
break;
|
||||
case 'h':
|
||||
case 'H':
|
||||
errors = true;
|
||||
break;
|
||||
default:
|
||||
|
@ -658,9 +655,8 @@ int CmdLegicCalcCrc(const char *Cmd){
|
|||
int bg, en;
|
||||
|
||||
while(param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
||||
switch(param_getchar(Cmd, cmdp)) {
|
||||
switch (tolower(param_getchar(Cmd, cmdp))) {
|
||||
case 'd':
|
||||
case 'D':
|
||||
// peek at length of the input string so we can
|
||||
// figure out how many elements to malloc in "data"
|
||||
bg=en=0;
|
||||
|
@ -696,17 +692,14 @@ int CmdLegicCalcCrc(const char *Cmd){
|
|||
cmdp += 2;
|
||||
break;
|
||||
case 'u':
|
||||
case 'U':
|
||||
uidcrc = param_get8ex(Cmd, cmdp+1, 0, 16);
|
||||
cmdp += 2;
|
||||
break;
|
||||
case 'c':
|
||||
case 'C':
|
||||
type = param_get8ex(Cmd, cmdp+1, 0, 10);
|
||||
cmdp += 2;
|
||||
break;
|
||||
case 'h':
|
||||
case 'H':
|
||||
errors = true;
|
||||
break;
|
||||
default:
|
||||
|
@ -789,7 +782,7 @@ int legic_get_type(legic_card_select_t *card){
|
|||
clearCommandBuffer();
|
||||
SendCommand(&c);
|
||||
UsbCommand resp;
|
||||
if (!WaitForResponseTimeout(CMD_ACK, &resp, 500))
|
||||
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500))
|
||||
return 2;
|
||||
|
||||
uint8_t isOK = resp.arg[0] & 0xFF;
|
||||
|
@ -825,11 +818,10 @@ void legic_seteml(uint8_t *src, uint32_t offset, uint32_t numofbytes) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
int HFLegicReader(const char *Cmd, bool verbose) {
|
||||
|
||||
char cmdp = param_getchar(Cmd, 0);
|
||||
if ( cmdp == 'H' || cmdp == 'h' ) return usage_legic_reader();
|
||||
char cmdp = tolower(param_getchar(Cmd, 0));
|
||||
if ( cmdp == 'h' ) return usage_legic_reader();
|
||||
|
||||
legic_card_select_t card;
|
||||
switch(legic_get_type(&card)){
|
||||
|
@ -864,12 +856,10 @@ int CmdLegicDump(const char *Cmd){
|
|||
memset(filename, 0, sizeof(filename));
|
||||
|
||||
while(param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
||||
switch(param_getchar(Cmd, cmdp)) {
|
||||
switch (tolower(param_getchar(Cmd, cmdp))) {
|
||||
case 'h':
|
||||
case 'H':
|
||||
return usage_legic_dump();
|
||||
case 'o':
|
||||
case 'O':
|
||||
fileNlen = param_getstr(Cmd, cmdp+1, filename, FILE_PATH_SIZE);
|
||||
if (!fileNlen)
|
||||
errors = true;
|
||||
|
@ -964,13 +954,11 @@ int CmdLegicRestore(const char *Cmd){
|
|||
memset(filename, 0, sizeof(filename));
|
||||
|
||||
while(param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
||||
switch(param_getchar(Cmd, cmdp)) {
|
||||
switch (tolower(param_getchar(Cmd, cmdp))) {
|
||||
case 'h':
|
||||
case 'H':
|
||||
errors = true;
|
||||
break;
|
||||
case 'i':
|
||||
case 'I':
|
||||
fileNlen = param_getstr(Cmd, cmdp+1, filename, FILE_PATH_SIZE);
|
||||
if (!fileNlen)
|
||||
errors = true;
|
||||
|
@ -1079,8 +1067,8 @@ int CmdLegicELoad(const char *Cmd) {
|
|||
int len, numofbytes;
|
||||
int nameParamNo = 1;
|
||||
|
||||
char cmdp = param_getchar(Cmd, 0);
|
||||
if ( cmdp == 'h' || cmdp == 'H' || cmdp == 0x00)
|
||||
char cmdp = tolower(param_getchar(Cmd, 0));
|
||||
if ( cmdp == 'h' || cmdp == 0x00)
|
||||
return usage_legic_eload();
|
||||
|
||||
switch (cmdp) {
|
||||
|
@ -1142,9 +1130,9 @@ int CmdLegicESave(const char *Cmd) {
|
|||
|
||||
memset(filename, 0, sizeof(filename));
|
||||
|
||||
char cmdp = param_getchar(Cmd, 0);
|
||||
char cmdp = tolower(param_getchar(Cmd, 0));
|
||||
|
||||
if ( cmdp == 'h' || cmdp == 'H' || cmdp == 0x00)
|
||||
if ( cmdp == 'h' || cmdp == 0x00)
|
||||
return usage_legic_esave();
|
||||
|
||||
switch (cmdp) {
|
||||
|
@ -1198,9 +1186,9 @@ int CmdLegicESave(const char *Cmd) {
|
|||
|
||||
int CmdLegicWipe(const char *Cmd){
|
||||
|
||||
char cmdp = param_getchar(Cmd, 0);
|
||||
char cmdp = tolower(param_getchar(Cmd, 0));
|
||||
|
||||
if ( cmdp == 'h' || cmdp == 'H') return usage_legic_wipe();
|
||||
if ( cmdp == 'h') return usage_legic_wipe();
|
||||
|
||||
// tagtype
|
||||
legic_card_select_t card;
|
||||
|
|
|
@ -652,29 +652,22 @@ int CmdHF14AMfDump(const char *Cmd) {
|
|||
UsbCommand resp;
|
||||
|
||||
while(param_getchar(Cmd, cmdp) != 0x00) {
|
||||
switch(param_getchar(Cmd, cmdp)) {
|
||||
switch (tolower(param_getchar(Cmd, cmdp))) {
|
||||
case 'h':
|
||||
case 'H':
|
||||
return usage_hf14_dump();
|
||||
case 'k':
|
||||
case 'K':
|
||||
param_getstr(Cmd, cmdp+1, keyFilename, FILE_PATH_SIZE);
|
||||
cmdp += 2;
|
||||
break;
|
||||
case 'f':
|
||||
case 'F':
|
||||
param_getstr(Cmd, cmdp+1, dataFilename, FILE_PATH_SIZE);
|
||||
cmdp += 2;
|
||||
break;
|
||||
default:
|
||||
if (cmdp==0)
|
||||
{
|
||||
if (cmdp == 0) {
|
||||
numSectors = NumOfSectors(param_getchar(Cmd, cmdp));
|
||||
cmdp++;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
} else {
|
||||
PrintAndLogEx(WARNING, "Unknown parameter '%c'\n", param_getchar(Cmd, cmdp));
|
||||
return usage_hf14_dump();
|
||||
}
|
||||
|
@ -1662,10 +1655,12 @@ int CmdHF14AMfChk(const char *Cmd) {
|
|||
clen = param_getlength(Cmd, 1);
|
||||
if (clen == 1) {
|
||||
switch (ctmp) {
|
||||
case 'a': case 'A':
|
||||
case 'a':
|
||||
case 'A':
|
||||
keyType = 0;
|
||||
break;
|
||||
case 'b': case 'B':
|
||||
case 'b':
|
||||
case 'B':
|
||||
keyType = 1;
|
||||
break;
|
||||
case '?':
|
||||
|
|
|
@ -262,15 +262,17 @@ int CmdVersion(const char *Cmd) {
|
|||
PrintAndLogEx(NORMAL, "\n\e[34mProxmark3 RFID instrument\e[0m\n");
|
||||
#endif
|
||||
char s[50] = {0};
|
||||
#if defined(WITH_FLASH) || defined(WITH_SMARTCARD)
|
||||
#if defined(WITH_FLASH) || defined(WITH_SMARTCARD) || defined(WITH_FPC)
|
||||
strncat(s, "build for RDV40 with ", sizeof(s) - strlen(s) - 1);
|
||||
#endif
|
||||
|
||||
#ifdef WITH_FLASH
|
||||
strncat(s, "flashmem; ", sizeof(s) - strlen(s) - 1);
|
||||
#endif
|
||||
#ifdef WITH_SMARTCARD
|
||||
strncat(s, "smartcard; ", sizeof(s) - strlen(s) - 1);
|
||||
#endif
|
||||
#ifdef WITH_FPC
|
||||
strncat(s, "fpc; ", sizeof(s) - strlen(s) - 1);
|
||||
#endif
|
||||
PrintAndLogEx(NORMAL, "\n [ CLIENT ]");
|
||||
PrintAndLogEx(NORMAL, " client: iceman %s \n", s);
|
||||
|
|
|
@ -837,12 +837,12 @@ int CheckChipType(bool getDeviceData) {
|
|||
int CmdLFfind(const char *Cmd) {
|
||||
int ans = 0;
|
||||
size_t minLength = 2000;
|
||||
char cmdp = param_getchar(Cmd, 0);
|
||||
char cmdp = tolower(param_getchar(Cmd, 0));
|
||||
char testRaw = param_getchar(Cmd, 1);
|
||||
|
||||
if (strlen(Cmd) > 3 || cmdp == 'h' || cmdp == 'H') return usage_lf_find();
|
||||
if (strlen(Cmd) > 3 || cmdp == 'h') return usage_lf_find();
|
||||
|
||||
if (cmdp == 'u' || cmdp == 'U') testRaw = 'u';
|
||||
if (cmdp == 'u') testRaw = 'u';
|
||||
|
||||
bool isOnline = (!offline && (cmdp != '1') );
|
||||
|
||||
|
@ -902,7 +902,7 @@ int CmdLFfind(const char *Cmd) {
|
|||
|
||||
PrintAndLogEx(FAILED, "\nNo known 125/134 KHz tags Found!\n");
|
||||
|
||||
if (testRaw=='u' || testRaw=='U'){
|
||||
if (testRaw == 'u'){
|
||||
//test unknown tag formats (raw mode)
|
||||
PrintAndLogEx(INFO, "\nChecking for Unknown tags:\n");
|
||||
ans = AutoCorrelate(GraphBuffer, GraphBuffer, GraphTraceLen, 4000, false, false);
|
||||
|
|
|
@ -47,7 +47,7 @@ int usage_trace_load(){
|
|||
PrintAndLogEx(NORMAL, "Load protocol data from file to trace buffer.");
|
||||
PrintAndLogEx(NORMAL, "Usage: trace load <filename>");
|
||||
PrintAndLogEx(NORMAL, "Examples:");
|
||||
PrintAndLogEx(NORMAL, " trace lload mytracefile.bin");
|
||||
PrintAndLogEx(NORMAL, " trace load mytracefile.bin");
|
||||
return 0;
|
||||
}
|
||||
int usage_trace_save(){
|
||||
|
@ -396,6 +396,7 @@ void printFelica(uint16_t traceLen, uint8_t *trace) {
|
|||
}
|
||||
|
||||
// sanity check. Don't use proxmark if it is offline and you didn't specify useTraceBuffer
|
||||
/*
|
||||
static int SanityOfflineCheck( bool useTraceBuffer ){
|
||||
if ( !useTraceBuffer && offline) {
|
||||
PrintAndLogEx(NORMAL, "Your proxmark3 device is offline. Specify [1] to use TraceBuffer data instead");
|
||||
|
@ -403,6 +404,7 @@ static int SanityOfflineCheck( bool useTraceBuffer ){
|
|||
}
|
||||
return 1;
|
||||
}
|
||||
*/
|
||||
|
||||
int CmdTraceList(const char *Cmd) {
|
||||
|
||||
|
@ -478,11 +480,10 @@ int CmdTraceList(const char *Cmd) {
|
|||
if (errors) return usage_trace_list();
|
||||
|
||||
uint16_t tracepos = 0;
|
||||
|
||||
// reserv some space.
|
||||
if (!trace) {
|
||||
printf("trace pointer not allocated\n");
|
||||
if (!trace)
|
||||
trace = calloc(USB_CMD_DATA_SIZE, sizeof(uint8_t));
|
||||
}
|
||||
|
||||
if ( isOnline ) {
|
||||
// Query for the size of the trace, downloading USB_CMD_DATA_SIZE
|
||||
|
|
10
common/cmd.c
10
common/cmd.c
|
@ -33,14 +33,6 @@
|
|||
|
||||
bool cmd_receive(UsbCommand* cmd) {
|
||||
|
||||
// check if there is a FPC USART1 message?
|
||||
/*
|
||||
size_t fpc_rxlen = usart_read((uint8_t*)cmd, sizeof(UsbCommand));
|
||||
if ( fpc_rxlen )
|
||||
return true;
|
||||
|
||||
*/
|
||||
|
||||
// Check if there is a usb packet available
|
||||
if (!usb_poll_validate_length()) return false;
|
||||
|
||||
|
@ -78,8 +70,6 @@ bool cmd_send(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void* d
|
|||
txcmd.d.asBytes[i] = ((uint8_t*)data)[i];
|
||||
}
|
||||
}
|
||||
|
||||
//usart_send( (uint8_t*)&txcmd, sizeof(UsbCommand));
|
||||
|
||||
// Send frame and make sure all bytes are transmitted
|
||||
if ( usb_write( (uint8_t*)&txcmd, sizeof(UsbCommand)) != 0)
|
||||
|
|
144
common/i2c.c
144
common/i2c.c
|
@ -119,14 +119,29 @@ bool WaitSCL_H_delay(uint32_t delay) {
|
|||
}
|
||||
|
||||
// 5000 * 3.07us = 15350us. 15.35ms
|
||||
// 15000 * 3.07us = 46050us. 46.05ms
|
||||
bool WaitSCL_H(void) {
|
||||
return WaitSCL_H_delay(5000);
|
||||
return WaitSCL_H_delay(15000);
|
||||
}
|
||||
|
||||
bool WaitSCL_L_delay(uint32_t delay) {
|
||||
while (delay--) {
|
||||
if (!SCL_read) {
|
||||
return true;
|
||||
}
|
||||
I2C_DELAY_1CLK;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// 5000 * 3.07us = 15350us. 15.35ms
|
||||
bool WaitSCL_L(void) {
|
||||
return WaitSCL_L_delay(15000);
|
||||
}
|
||||
|
||||
// Wait max 300ms or until SCL goes LOW.
|
||||
// Which ever comes first
|
||||
bool WaitSCL_L_300ms(void){
|
||||
volatile uint16_t delay = 300;
|
||||
volatile uint16_t delay = 310;
|
||||
while ( delay-- ) {
|
||||
// exit on SCL LOW
|
||||
if (!SCL_read)
|
||||
|
@ -160,8 +175,8 @@ bool I2C_WaitForSim() {
|
|||
|
||||
// 8051 speaks with smart card.
|
||||
// 1000*50*3.07 = 153.5ms
|
||||
// 1byte transfer == 1ms
|
||||
if (!WaitSCL_H_delay(2000*50) )
|
||||
// 1byte transfer == 1ms with max frame being 256bytes
|
||||
if (!WaitSCL_H_delay(10 * 1000 * 50) )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
@ -182,6 +197,7 @@ void I2C_Ack(void) {
|
|||
SCL_L; I2C_DELAY_2CLK;
|
||||
SDA_L; I2C_DELAY_2CLK;
|
||||
SCL_H; I2C_DELAY_2CLK;
|
||||
if (!WaitSCL_H()) return;
|
||||
SCL_L; I2C_DELAY_2CLK;
|
||||
}
|
||||
|
||||
|
@ -190,6 +206,7 @@ void I2C_NoAck(void) {
|
|||
SCL_L; I2C_DELAY_2CLK;
|
||||
SDA_H; I2C_DELAY_2CLK;
|
||||
SCL_H; I2C_DELAY_2CLK;
|
||||
if (!WaitSCL_H()) return;
|
||||
SCL_L; I2C_DELAY_2CLK;
|
||||
}
|
||||
|
||||
|
@ -200,6 +217,7 @@ bool I2C_WaitAck(void) {
|
|||
if (!WaitSCL_H())
|
||||
return false;
|
||||
|
||||
I2C_DELAY_2CLK;
|
||||
I2C_DELAY_2CLK;
|
||||
if (SDA_read) {
|
||||
SCL_L;
|
||||
|
@ -210,10 +228,12 @@ bool I2C_WaitAck(void) {
|
|||
}
|
||||
|
||||
void I2C_SendByte(uint8_t data) {
|
||||
uint8_t i = 8;
|
||||
uint8_t bits = 8;
|
||||
|
||||
while (i--) {
|
||||
SCL_L; I2C_DELAY_1CLK;
|
||||
while (bits--) {
|
||||
SCL_L;
|
||||
|
||||
I2C_DELAY_1CLK;
|
||||
|
||||
if (data & 0x80)
|
||||
SDA_H;
|
||||
|
@ -221,6 +241,7 @@ void I2C_SendByte(uint8_t data) {
|
|||
SDA_L;
|
||||
|
||||
data <<= 1;
|
||||
|
||||
I2C_DELAY_1CLK;
|
||||
|
||||
SCL_H;
|
||||
|
@ -232,18 +253,21 @@ void I2C_SendByte(uint8_t data) {
|
|||
SCL_L;
|
||||
}
|
||||
|
||||
uint8_t I2C_ReadByte(void) {
|
||||
uint8_t i = 8, b = 0;
|
||||
int16_t I2C_ReadByte(void) {
|
||||
uint8_t bits = 8, b = 0;
|
||||
|
||||
SDA_H;
|
||||
while (i--) {
|
||||
while (bits--) {
|
||||
b <<= 1;
|
||||
SCL_L; I2C_DELAY_2CLK;
|
||||
SCL_L;
|
||||
if (!WaitSCL_L()) return -2;
|
||||
|
||||
I2C_DELAY_1CLK;
|
||||
|
||||
SCL_H;
|
||||
if (!WaitSCL_H())
|
||||
return 0;
|
||||
if (!WaitSCL_H()) return -1;
|
||||
|
||||
I2C_DELAY_2CLK;
|
||||
I2C_DELAY_1CLK;
|
||||
if (SDA_read)
|
||||
b |= 0x01;
|
||||
}
|
||||
|
@ -350,16 +374,16 @@ bool I2C_BufferWrite(uint8_t *data, uint8_t len, uint8_t device_cmd, uint8_t dev
|
|||
// 读出1串数据(存放读出数据,待读出长度,带读出地址,器件类型)
|
||||
// read 1 strings of data (Data array, Readout length, command to be written , SlaveDevice address ).
|
||||
// len = uint8 (max buffer to read 256bytes)
|
||||
uint8_t I2C_BufferRead(uint8_t *data, uint8_t len, uint8_t device_cmd, uint8_t device_address) {
|
||||
int16_t I2C_BufferRead(uint8_t *data, uint8_t len, uint8_t device_cmd, uint8_t device_address) {
|
||||
|
||||
if ( !data || len == 0 )
|
||||
return 0;
|
||||
|
||||
// extra wait 500us (514us measured)
|
||||
// 200us (xx measured)
|
||||
SpinDelayUs(200);
|
||||
SpinDelayUs(600);
|
||||
bool bBreak = true;
|
||||
uint8_t readcount = 0;
|
||||
uint16_t readcount = 0;
|
||||
|
||||
do {
|
||||
if (!I2C_Start())
|
||||
|
@ -389,10 +413,13 @@ uint8_t I2C_BufferRead(uint8_t *data, uint8_t len, uint8_t device_cmd, uint8_t d
|
|||
return 0;
|
||||
}
|
||||
|
||||
// reading
|
||||
while (len) {
|
||||
|
||||
*data = I2C_ReadByte();
|
||||
int16_t tmp = I2C_ReadByte();
|
||||
if ( tmp < 0 )
|
||||
return tmp;
|
||||
|
||||
*data = (uint8_t)tmp & 0xFF;
|
||||
|
||||
len--;
|
||||
|
||||
|
@ -413,11 +440,12 @@ uint8_t I2C_BufferRead(uint8_t *data, uint8_t len, uint8_t device_cmd, uint8_t d
|
|||
}
|
||||
|
||||
I2C_Stop();
|
||||
|
||||
// return bytecount - first byte (which is length byte)
|
||||
return (readcount) ? --readcount : 0;
|
||||
}
|
||||
|
||||
uint8_t I2C_ReadFW(uint8_t *data, uint8_t len, uint8_t msb, uint8_t lsb, uint8_t device_address) {
|
||||
int16_t I2C_ReadFW(uint8_t *data, uint8_t len, uint8_t msb, uint8_t lsb, uint8_t device_address) {
|
||||
//START, 0xB0, 0x00, 0x00, START, 0xB1, xx, yy, zz, ......, STOP
|
||||
bool bBreak = true;
|
||||
uint8_t readcount = 0;
|
||||
|
@ -459,7 +487,12 @@ uint8_t I2C_ReadFW(uint8_t *data, uint8_t len, uint8_t msb, uint8_t lsb, uint8_t
|
|||
|
||||
// reading
|
||||
while (len) {
|
||||
*data = I2C_ReadByte();
|
||||
|
||||
int16_t tmp = I2C_ReadByte();
|
||||
if ( tmp < 0 )
|
||||
return tmp;
|
||||
|
||||
*data = (uint8_t)tmp & 0xFF;
|
||||
|
||||
data++;
|
||||
readcount++;
|
||||
|
@ -532,6 +565,34 @@ void I2C_print_status(void) {
|
|||
DbpString(" version.................FAILED");
|
||||
}
|
||||
|
||||
// Will read response from smart card module, retries 3 times to get the data.
|
||||
bool sc_rx_bytes(uint8_t* dest, uint8_t *destlen) {
|
||||
|
||||
uint8_t i = 3;
|
||||
int16_t len = 0;
|
||||
while (i--) {
|
||||
|
||||
I2C_WaitForSim();
|
||||
|
||||
len = I2C_BufferRead(dest, *destlen, I2C_DEVICE_CMD_READ, I2C_DEVICE_ADDRESS_MAIN);
|
||||
|
||||
if ( len > 1 ){
|
||||
break;
|
||||
} else if ( len == 1 ) {
|
||||
continue;
|
||||
} else if ( len <= 0 ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// after three
|
||||
if ( len <= 1 )
|
||||
return false;
|
||||
|
||||
*destlen = (uint8_t)len & 0xFF;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GetATR(smart_card_atr_t *card_ptr) {
|
||||
|
||||
// clear
|
||||
|
@ -545,15 +606,39 @@ bool GetATR(smart_card_atr_t *card_ptr) {
|
|||
I2C_WriteCmd(I2C_DEVICE_CMD_GENERATE_ATR, I2C_DEVICE_ADDRESS_MAIN);
|
||||
|
||||
//wait for sim card to answer.
|
||||
// 1byte = 1ms , max frame 256bytes. SHould wait 256ms atleast just in case.
|
||||
if (!I2C_WaitForSim())
|
||||
return false;
|
||||
|
||||
// read answer
|
||||
uint8_t len = I2C_BufferRead(card_ptr->atr, sizeof(card_ptr->atr), I2C_DEVICE_CMD_READ, I2C_DEVICE_ADDRESS_MAIN);
|
||||
|
||||
if ( len == 0 )
|
||||
// read bytes from module
|
||||
uint8_t len = sizeof(card_ptr->atr);
|
||||
if ( !sc_rx_bytes(card_ptr->atr, &len) )
|
||||
return false;
|
||||
|
||||
uint8_t pos_td = 1;
|
||||
if ( (card_ptr->atr[1] & 0x10) == 0x10) pos_td++;
|
||||
if ( (card_ptr->atr[1] & 0x20) == 0x20) pos_td++;
|
||||
if ( (card_ptr->atr[1] & 0x40) == 0x40) pos_td++;
|
||||
|
||||
// T0 indicate presence T=0 vs T=1. T=1 has checksum TCK
|
||||
if ( (card_ptr->atr[1] & 0x80) == 0x80) {
|
||||
|
||||
pos_td++;
|
||||
|
||||
// 1 == T1 , presence of checksum TCK
|
||||
if ( (card_ptr->atr[pos_td] & 0x01) == 0x01) {
|
||||
|
||||
uint8_t chksum = 0;
|
||||
// xor property. will be zero when xored with chksum.
|
||||
for (uint8_t i = 1; i < len; ++i)
|
||||
chksum ^= card_ptr->atr[i];
|
||||
|
||||
if ( chksum ) {
|
||||
if ( MF_DBGLEVEL > 2) DbpString("Wrong ATR checksum");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( card_ptr ) {
|
||||
card_ptr->atr_len = len;
|
||||
LogTrace(card_ptr->atr, card_ptr->atr_len, 0, 0, NULL, false);
|
||||
|
@ -611,7 +696,10 @@ void SmartCardRaw( uint64_t arg0, uint64_t arg1, uint8_t *data ) {
|
|||
if ( !I2C_WaitForSim() )
|
||||
goto OUT;
|
||||
|
||||
len = I2C_BufferRead(resp, ISO7618_MAX_FRAME, I2C_DEVICE_CMD_READ, I2C_DEVICE_ADDRESS_MAIN);
|
||||
|
||||
// read bytes from module
|
||||
len = ISO7618_MAX_FRAME;
|
||||
sc_rx_bytes(resp, &len);
|
||||
LogTrace(resp, len, 0, 0, NULL, false);
|
||||
}
|
||||
OUT:
|
||||
|
@ -631,7 +719,7 @@ void SmartCardUpgrade(uint64_t arg0) {
|
|||
I2C_Reset_EnterBootloader();
|
||||
|
||||
bool isOK = true;
|
||||
uint8_t res = 0;
|
||||
int16_t res = 0;
|
||||
uint16_t length = arg0;
|
||||
uint16_t pos = 0;
|
||||
uint8_t *fwdata = BigBuf_get_addr();
|
||||
|
@ -659,7 +747,7 @@ void SmartCardUpgrade(uint64_t arg0) {
|
|||
|
||||
// read
|
||||
res = I2C_ReadFW(verfiydata, size, msb, lsb, I2C_DEVICE_ADDRESS_BOOT);
|
||||
if ( res == 0) {
|
||||
if ( res <= 0) {
|
||||
DbpString("Reading back failed");
|
||||
isOK = false;
|
||||
break;
|
||||
|
|
|
@ -30,10 +30,10 @@ bool I2C_WriteCmd(uint8_t device_cmd, uint8_t device_address);
|
|||
|
||||
bool I2C_WriteByte(uint8_t data, uint8_t device_cmd, uint8_t device_address);
|
||||
bool I2C_BufferWrite(uint8_t *data, uint8_t len, uint8_t device_cmd, uint8_t device_address);
|
||||
uint8_t I2C_BufferRead(uint8_t *data, uint8_t len, uint8_t device_cmd, uint8_t device_address);
|
||||
int16_t I2C_BufferRead(uint8_t *data, uint8_t len, uint8_t device_cmd, uint8_t device_address);
|
||||
|
||||
// for firmware
|
||||
uint8_t I2C_ReadFW(uint8_t *data, uint8_t len, uint8_t msb, uint8_t lsb, uint8_t device_address);
|
||||
int16_t I2C_ReadFW(uint8_t *data, uint8_t len, uint8_t msb, uint8_t lsb, uint8_t device_address);
|
||||
bool I2C_WriteFW(uint8_t *data, uint8_t len, uint8_t msb, uint8_t lsb, uint8_t device_address);
|
||||
|
||||
//
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
#define LFDEMOD_H__
|
||||
#include <stdint.h> // for uint_32+
|
||||
#include <stdbool.h> // for bool
|
||||
#include <string.h> // for strcmp
|
||||
#include <string.h> // for strcmp, memset, memcmp and size_t
|
||||
#include <stdlib.h> // for
|
||||
#include <stdbool.h> // for bool
|
||||
#include "parity.h" // for parity test
|
||||
|
|
|
@ -222,7 +222,7 @@ void usart_init(void) {
|
|||
pPIOA->PIO_PER |= (AT91C_PA21_RXD1 | AT91C_PA22_TXD1);
|
||||
|
||||
// Configure the pins to be outputs
|
||||
pPIOA->PIO_OER |= (AT91C_PA21_RXD1 | AT91C_PA22_TXD1);
|
||||
pPIOA->PIO_OER |= AT91C_PA22_TXD1;
|
||||
|
||||
//enable PIO in input mode
|
||||
//pPIOA->PIO_ODR = AT91C_PA21_RXD1;
|
||||
|
|
|
@ -7,16 +7,16 @@
|
|||
#
|
||||
|
||||
# proxmark3
|
||||
ACTION!="add|change", GOTO="mm_usb_device_blacklist_end"
|
||||
SUBSYSTEM!="tty", GOTO="mm_ignore"
|
||||
ACTION!="add|change", GOTO="pm3_usb_device_blacklist_end"
|
||||
SUBSYSTEM!="tty", GOTO="pm3_ignore"
|
||||
|
||||
ATTRS{idVendor}=="2d2d" ATTRS{idProduct}=="504d", ENV{ID_MM_DEVICE_IGNORE}="1" SYMLINK+="pm3-%n"
|
||||
ATTRS{idVendor}=="9ac4" ATTRS{idProduct}=="4b8f", ENV{ID_MM_DEVICE_IGNORE}="1" SYMLINK+="pm3-%n"
|
||||
ATTRS{idVendor}=="502d" ATTRS{idProduct}=="502d", ENV{ID_MM_DEVICE_IGNORE}="1" SYMLINK+="pm3-%n"
|
||||
|
||||
LABEL="mm_ignore"
|
||||
LABEL="pm3_ignore"
|
||||
ATTRS{idVendor}=="2d2d" ATTRS{idProduct}=="504d", ENV{ID_MM_DEVICE_IGNORE}="1"
|
||||
ATTRS{idVendor}=="9ac4" ATTRS{idProduct}=="4b8f", ENV{ID_MM_DEVICE_IGNORE}="1"
|
||||
ATTRS{idVendor}=="502d" ATTRS{idProduct}=="502d", ENV{ID_MM_DEVICE_IGNORE}="1"
|
||||
|
||||
LABEL="mm_usb_device_blacklist_end"
|
||||
LABEL="pm3_usb_device_blacklist_end"
|
|
@ -11,10 +11,12 @@ DriverVer=03/05/2018,1.1.1.0
|
|||
[DeviceList.NTx86]
|
||||
%DeviceName%=DriverInstall,USB\VID_9AC4&PID_4B8F
|
||||
%DeviceName_old%=DriverInstall,USB\VID_2d2d&PID_504d
|
||||
%DeviceName_easy%=DriverInstall,USB\VID_502d&PID_502d
|
||||
|
||||
[DeviceList.NTamd64]
|
||||
%DeviceName%=DriverInstall,USB\VID_9AC4&PID_4B8F
|
||||
%DeviceName_old%=DriverInstall,USB\VID_2d2d&PID_504d
|
||||
%DeviceName_easy%=DriverInstall,USB\VID_502d&PID_502d
|
||||
|
||||
[DriverInstall]
|
||||
include=mdmcpq.inf
|
||||
|
@ -32,4 +34,5 @@ HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"
|
|||
[Strings]
|
||||
ProviderName = "proxmark.org"
|
||||
DeviceName = "Proxmark3"
|
||||
DeviceName_old = "Proxmark3 (old)"
|
||||
DeviceName_old = "Proxmark3 (old)"
|
||||
DeviceName_easy = "Proxmark3 (easy?)"
|
|
@ -17,8 +17,8 @@ sudo apt-get autoclean -y
|
|||
sudo apt-get clean -y
|
||||
sudo apt-get update
|
||||
|
||||
# install iceman fork - proxmark3
|
||||
git clone https://github.com/iceman1001/proxmark3.git
|
||||
# install RDV40 - proxmark3
|
||||
git clone https://github.com/RfidResearchGroup/proxmark3.git
|
||||
(
|
||||
cd proxmark3 || exit 1
|
||||
git reset --hard
|
||||
|
|
0
rdv40.txt
Normal file
0
rdv40.txt
Normal file
Loading…
Add table
Add a link
Reference in a new issue