mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2026-05-12 11:18:11 -07:00
Merge branch 'master' into master
This commit is contained in:
@@ -32,6 +32,7 @@ luac
|
||||
fpga_compress
|
||||
mfkey32
|
||||
mfkey64
|
||||
tools/nonce2key/nonce2key
|
||||
|
||||
fpga/*
|
||||
!fpga/tests
|
||||
|
||||
@@ -79,6 +79,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
|
||||
- Added to `hf 14a apdu` - apdu and tlv results parser (@merlokk)
|
||||
- Added 'hf emv' commands (@merlokk)
|
||||
- lots of bug fixes (many many)
|
||||
- Changed hf mfp security. Now it works in all the modes. (drHatson)
|
||||
### Fixed
|
||||
- Changed driver file proxmark3.inf to support both old and new Product/Vendor IDs (piwi)
|
||||
- Changed start sequence in Qt mode (fix: short commands hangs main Qt thread) (Merlok)
|
||||
|
||||
@@ -47,6 +47,9 @@ This fork now compiles just fine on
|
||||
- Mac OS X / Homebrew
|
||||
- Docker container
|
||||
|
||||
## KALI and ARCHLINUX users
|
||||
Kali and ArchLinux users usually must kill their modem manager in order for the proxmark3 to enumerate properly.
|
||||
|
||||
## Setup and build for UBUNTU
|
||||
GC made updates to allow this to build easily on Ubuntu 14.04.2 LTS, 15.10 or 16.04
|
||||
See https://github.com/Proxmark/proxmark3/wiki/Ubuntu%20Linux
|
||||
@@ -57,7 +60,7 @@ I have also added this script to the fork.
|
||||
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`
|
||||
`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 libjansson-dev`
|
||||
|
||||
- Clone fork
|
||||
`git clone https://github.com/RfidResearchGroup/proxmark3.git`
|
||||
@@ -82,7 +85,7 @@ https://github.com/RfidResearchGroup/proxmark3/blob/master/install.sh
|
||||
|
||||
## Setup and build for ArchLinux
|
||||
- Run
|
||||
`sudo pacman -Sy base-devel p7zip libusb readline ncurses arm-none-eabi-newlib --needed`
|
||||
`sudo pacman -Sy base-devel p7zip libusb readline ncurses libjansson-dev arm-none-eabi-newlib --needed`
|
||||
`yaourt -S termcap`
|
||||
|
||||
- Clone fork
|
||||
@@ -148,8 +151,8 @@ Afterwards just clone the iceman repo or download someone elses.
|
||||
Read instructions on @Gator96100 repo page. (https://github.com/Gator96100/ProxSpace/)
|
||||
|
||||
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/v3.1 (release v3.1 with gcc v7.3.0 )
|
||||
- https://github.com/Gator96100/ProxSpace/releases/tag/v2.2 (release v2.2 with gcc v5.3.0 arm-none-eabi-gcc v7.1.0)
|
||||
|
||||
|
||||
### 7. Build and run
|
||||
|
||||
+41
-10
@@ -66,9 +66,20 @@ clone_script:
|
||||
Write-Host "[ OK ]" -ForegroundColor Green
|
||||
|
||||
|
||||
Write-Host "Fill msys\etc\fstab file..." -NoNewLine
|
||||
Write-Host "Fill msys2\etc\fstab file..." -NoNewLine
|
||||
|
||||
New-Item c:\ProxSpace\msys\etc\fstab -type file -force -value "#Win32_Path Mount_Point`nc:\ProxSpace\devkitARM /devkitARM`nc:\ProxSpace\Qt\5.6 /qt `nc:\ProxSpace\pm3 /pm3`n"
|
||||
New-Item c:\ProxSpace\msys2\etc\fstab -type file -force -value "# For a description of the file format, see the Users Guide`n# http://cygwin.com/cygwin-ug-net/using.html#mount-table`nnone / cygdrive binary,posix=0,noacl,user 0 0 `nC:\ProxSpace\pm3 /pm3 ntfs noacl 0 0 `nC:\ProxSpace\gcc-arm-none-eabi /gcc-arm-none-eabi ntfs noacl 0 0 `n"
|
||||
|
||||
Write-Host "[ OK ]" -ForegroundColor Green
|
||||
|
||||
|
||||
Write-Host "Update msys2 packages..." -NoNewLine
|
||||
|
||||
$env:Path = "C:\ProxSpace\msys2\usr\bin;C:\ProxSpace\msys2\mingw32\bin;C:\ProxSpace\gcc-arm-none-eabi\bin;$env:Path"
|
||||
|
||||
C:\ProxSpace\msys2\msys2_shell.cmd -mingw32 -defterm -no-start /dev/null 1> msys1.txt 2>&1
|
||||
|
||||
C:\ProxSpace\msys2\msys2_shell.cmd -mingw32 -defterm -no-start /dev/null 1> msys1.txt 2>&1
|
||||
|
||||
Write-Host "[ OK ]" -ForegroundColor Green
|
||||
install:
|
||||
@@ -84,12 +95,25 @@ install:
|
||||
}
|
||||
build_script:
|
||||
- ps: >-
|
||||
$env:Path = "C:\ProxSpace\msys\bin;$env:Path"
|
||||
"C:\ProxSpace\msys2\usr\bin;C:\ProxSpace\msys2\mingw32\bin;C:\ProxSpace\gcc-arm-none-eabi\bin;$env:Path"
|
||||
|
||||
|
||||
$env:MINGW_HOME="C:\ProxSpace\msys2\mingw32"
|
||||
|
||||
$env:MSYS_HOME="C:\ProxSpace\msys2"
|
||||
|
||||
$env:MSYSTEM="MINGW32"
|
||||
|
||||
$env:MINGW_PREFIX="/mingw32"
|
||||
|
||||
$env:SHELL="/bin/bash"
|
||||
|
||||
$env:MSYSTEM_CHOST="i686-w64-mingw32"
|
||||
|
||||
|
||||
#make
|
||||
|
||||
bash -lc -i "pwd;make all"
|
||||
bash -c -i 'pwd;make clean;make all'
|
||||
|
||||
|
||||
#some checks
|
||||
@@ -232,8 +256,8 @@ test_script:
|
||||
#--- end Job
|
||||
|
||||
[bool]$res=$false
|
||||
# Wait 60 sec timeout for Job
|
||||
if(Wait-Job $Job -Timeout 60){
|
||||
# Wait 120 sec timeout for Job
|
||||
if(Wait-Job $Job -Timeout 150){
|
||||
$Results = $Job | Receive-Job
|
||||
if($Results -like "true"){
|
||||
$res=$true
|
||||
@@ -268,13 +292,20 @@ test_script:
|
||||
|
||||
#proxmark logic tests
|
||||
|
||||
ExecTest "proxmark help" "proxmark3 -h" {bash -lc 'cd ~/client;proxmark3 -h | grep -q Execute && echo Passed || echo Failed'}
|
||||
ExecTest "proxmark help" "proxmark3 -h" {bash -lc 'cd ~/client;./proxmark3 -h | grep -q Execute && echo Passed || echo Failed'}
|
||||
|
||||
ExecTest "proxmark help hardnested" "proxmark3 -h" {bash -lc 'cd ~/client;proxmark3 -h | grep -q hardnested && echo Passed || echo Failed'}
|
||||
ExecTest "proxmark help hardnested" "proxmark3 -h" {bash -lc 'cd ~/client;./proxmark3 -h | grep -q hardnested && echo Passed || echo Failed'}
|
||||
|
||||
ExecTest "hf mf offline text" "hf mf" {bash -lc "cd ~/client;proxmark3 comx -c 'hf mf'"} "at_enc"
|
||||
|
||||
ExecTest "hf mf hardnested" "hf mf hardnested" {bash -lc "cd ~/client;proxmark3 comx -c 'hf mf hardnested t 1 000000000000'"} "found:"
|
||||
ExecTest "hf mf offline text" "hf mf" {bash -lc "cd ~/client;./proxmark3 comx -c 'hf mf'"} "at_enc"
|
||||
|
||||
ExecTest "hf mf hardnested" "hf mf hardnested" {bash -lc "cd ~/client;./proxmark3 comx -c 'hf mf hardnested t 1 000000000000'"} "found:"
|
||||
|
||||
|
||||
#proxmark crypto tests
|
||||
|
||||
ExecTest "hf emv test" "hf emv test" {bash -lc "cd ~/client;./proxmark3 comx -c 'hf emv test'"} "Tests ?OK"
|
||||
|
||||
|
||||
if ($global:TestsPassed) {
|
||||
Write-Host "Tests [ OK ]" -ForegroundColor Green
|
||||
|
||||
+16
-16
@@ -44,8 +44,7 @@ uint8_t FindOffsetInFlash() {
|
||||
return 0; // wrap-around
|
||||
}
|
||||
|
||||
void EraseMemory()
|
||||
{
|
||||
void EraseMemory() {
|
||||
if (!FlashInit()){
|
||||
return;
|
||||
}
|
||||
@@ -59,10 +58,9 @@ void EraseMemory()
|
||||
SpinDelay(100);
|
||||
}
|
||||
|
||||
// This is actually copied from SniffIso14443a
|
||||
void RAMFUNC SniffAndStore(uint8_t param) {
|
||||
|
||||
/* This is actually copied from SniffIso14443a */
|
||||
|
||||
iso14443a_setup(FPGA_HF_ISO14443A_SNIFFER);
|
||||
|
||||
// Allocate memory from BigBuf for some buffers
|
||||
@@ -268,10 +266,7 @@ void RAMFUNC SniffAndStore(uint8_t param) {
|
||||
|
||||
// Erase first page of flash mem
|
||||
EraseMemory();
|
||||
|
||||
//for (int i=0; i<memoffset + 4 * auth_attempts; i++)
|
||||
// if (MF_DBGLEVEL > 1) Dbprintf("[-] total_data[%d] = 0x%02x", i, total_data[i]);
|
||||
|
||||
|
||||
// Write total data to flash mem
|
||||
uint16_t writelen = Flash_WriteData(0, total_data, memoffset + 4 * auth_attempts);
|
||||
if (MF_DBGLEVEL > 1) Dbprintf("[!] Wrote %u bytes into flash mem", writelen);
|
||||
@@ -283,18 +278,23 @@ void RAMFUNC SniffAndStore(uint8_t param) {
|
||||
}
|
||||
}
|
||||
|
||||
void RunMod()
|
||||
{
|
||||
Dbprintf("Sniffing started");
|
||||
void RunMod() {
|
||||
|
||||
SpinDelay(200);
|
||||
Dbprintf(">> Bogiton 14a Sniff UL/UL-EV1/NTAG a.k.a BogitoRun Started <<");
|
||||
Dbprintf("Starting to sniff");
|
||||
|
||||
SpinDown(50);
|
||||
SpinOff(50);
|
||||
SpinUp(50);
|
||||
SpinOff(50);
|
||||
SpinDown(50);
|
||||
SpinDelay(500);
|
||||
|
||||
// param:
|
||||
// bit 0 - trigger from first card answer
|
||||
// bit 1 - trigger from first reader 7-bit request
|
||||
SniffAndStore(0);
|
||||
|
||||
LEDsoff();
|
||||
|
||||
SniffAndStore(0);
|
||||
LEDsoff();
|
||||
SpinDelay(300);
|
||||
Dbprintf("- [ End ] -> You can take shell back ...");
|
||||
}
|
||||
|
||||
+22
-220
@@ -1,5 +1,5 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Colin Brigato, 2016,2017
|
||||
// Colin Brigato, 2016, 2017
|
||||
// Christian Herrmann, 2017
|
||||
//
|
||||
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
||||
@@ -21,10 +21,11 @@ int currfline;
|
||||
int curlline;
|
||||
|
||||
// TODO : Implement fast read of KEYS like in RFIdea
|
||||
// als ohttp://ext.delaat.net/rp/2015-2016/p04/report.pdf
|
||||
// also http://ext.delaat.net/rp/2015-2016/p04/report.pdf
|
||||
|
||||
// Colin's VIGIKPWN sniff/simulate/clone repeat routine for HF Mifare
|
||||
|
||||
/*
|
||||
void cjPrintBigArray(const char *bigar, int len, uint8_t newlines, uint8_t debug)
|
||||
{
|
||||
uint32_t chunksize = (USB_CMD_DATA_SIZE / 4);
|
||||
@@ -56,6 +57,7 @@ void cjPrintBigArray(const char *bigar, int len, uint8_t newlines, uint8_t debug
|
||||
DbprintfEx(FLAG_NOLOG, " ");
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
void cjSetCursFRight()
|
||||
{
|
||||
@@ -85,151 +87,8 @@ void cjPrintKey(uint64_t key, uint8_t *foundKey, uint16_t sectorNo, uint8_t type
|
||||
DbprintfEx(FLAG_NOLOG, "SEC: %02x | KEY : %s | TYP: %d", sectorNo, tosendkey, type);
|
||||
}
|
||||
|
||||
void SpinOff(uint32_t pause)
|
||||
void ReadLastTagFromFlash()
|
||||
{
|
||||
LED_A_OFF();
|
||||
LED_B_OFF();
|
||||
LED_C_OFF();
|
||||
LED_D_OFF();
|
||||
SpinDelay(pause);
|
||||
}
|
||||
|
||||
// 0=A, 1=B, 2=C, 3=D
|
||||
void SpinErr(uint8_t led, uint32_t speed, uint8_t times)
|
||||
{
|
||||
SpinOff(speed);
|
||||
NTIME(times)
|
||||
{
|
||||
switch (led)
|
||||
{
|
||||
case 0:
|
||||
LED_A_INV();
|
||||
break;
|
||||
case 1:
|
||||
LED_B_INV();
|
||||
break;
|
||||
case 2:
|
||||
LED_C_INV();
|
||||
break;
|
||||
case 3:
|
||||
LED_D_INV();
|
||||
break;
|
||||
}
|
||||
SpinDelay(speed);
|
||||
}
|
||||
}
|
||||
|
||||
void SpinDown(uint32_t speed)
|
||||
{
|
||||
SpinOff(speed);
|
||||
LED_D_ON();
|
||||
SpinDelay(speed);
|
||||
LED_D_OFF();
|
||||
LED_C_ON();
|
||||
SpinDelay(speed);
|
||||
LED_C_OFF();
|
||||
LED_B_ON();
|
||||
SpinDelay(speed);
|
||||
LED_B_OFF();
|
||||
LED_A_ON();
|
||||
SpinDelay(speed);
|
||||
LED_A_OFF();
|
||||
}
|
||||
|
||||
void SpinUp(uint32_t speed)
|
||||
{
|
||||
SpinOff(speed);
|
||||
LED_A_ON();
|
||||
SpinDelay(speed);
|
||||
LED_A_OFF();
|
||||
LED_B_ON();
|
||||
SpinDelay(speed);
|
||||
LED_B_OFF();
|
||||
LED_C_ON();
|
||||
SpinDelay(speed);
|
||||
LED_C_OFF();
|
||||
LED_D_ON();
|
||||
SpinDelay(speed);
|
||||
LED_D_OFF();
|
||||
}
|
||||
|
||||
void TestFlashmemSpeed(size_t buffersize, uint32_t spibaudrate) {
|
||||
|
||||
FLASHMEM_SPIBAUDRATE = spibaudrate*1000000;
|
||||
DbprintfEx(FLAG_NOLOG, "%s---+----[ %s %s[%dKB] %s] (%d)", _GREEN_, _WHITE_, _YELLOW_, buffersize / 1024, _WHITE_, FLASHMEM_SPIBAUDRATE);
|
||||
uint16_t t = 0;
|
||||
|
||||
LED_B_ON();
|
||||
uint8_t *mem = BigBuf_malloc(buffersize);
|
||||
bool isok = false;
|
||||
size_t len = 0;
|
||||
uint32_t startidx = 0;
|
||||
uint32_t numofbytes = 0x3FFFF;
|
||||
|
||||
if (!FlashInit()) {
|
||||
return;
|
||||
}
|
||||
//Flash_CheckBusy(BUSY_TIMEOUT);
|
||||
|
||||
//Flash_ReadStat1();
|
||||
|
||||
uint32_t end_time;
|
||||
uint32_t start_time = end_time = GetTickCount();
|
||||
|
||||
for (size_t i = 0; i < numofbytes; i += buffersize)
|
||||
{
|
||||
len = MIN((numofbytes - i), buffersize);
|
||||
|
||||
//isok = Flash_ReadData(startidx + i, mem, len);
|
||||
//uint32_t iend_time;
|
||||
//uint32_t istart_time = iend_time = GetTickCount();
|
||||
isok = Flash_ReadDataCont(startidx + i, mem, len);
|
||||
//iend_time = GetTickCount();
|
||||
//DbprintfEx(FLAG_RAWPRINT, "%s%dms%s>", _YELLOW_, iend_time - istart_time, _WHITE_);
|
||||
//cjSetCursLeft();
|
||||
if (!isok)
|
||||
{
|
||||
Dbprintf("[FAIL] reading flash memory failed :: | bytes between %d - %d", i, len);
|
||||
return;
|
||||
}
|
||||
//isok = cmd_send(CMD_FLASHMEM_DOWNLOADED, i, len, 0, mem, len);
|
||||
//if (!isok)
|
||||
// Dbprintf("transfer to client failed :: | bytes between %d - %d", i, len);
|
||||
t++;
|
||||
}
|
||||
end_time = GetTickCount();
|
||||
DbprintfEx(FLAG_NOLOG, "%s |--< %s %s%dms%s for FULL_FLASH_READ", _GREEN_, _WHITE_, _YELLOW_, end_time - start_time, _WHITE_);
|
||||
DbprintfEx(FLAG_NOLOG, "%s `--= %s %d runs of %s~%dms%s each", _GREEN_, _WHITE_, t, _YELLOW_, (end_time - start_time) / t, _WHITE_);
|
||||
DbprintfEx(FLAG_NOLOG, "");
|
||||
//cjSetCursLeft();
|
||||
LED_B_OFF();
|
||||
FlashStop();
|
||||
}
|
||||
|
||||
void TestFlashmemRoutine()
|
||||
{
|
||||
DbprintfEx(FLAG_NOLOG, "%s>>%s Will Now Test dumping Full flash [256Kb] (2Mbits)through Bigbuf buffers\n", _GREEN_, _WHITE_);
|
||||
MF_DBGLEVEL = MF_DBG_NONE;
|
||||
//DbprintfEx(FLAG_NOLOG, "---------\n%s[A]%s Using NORMAL Reads @Max (24Mhz=MCK/2)\n--------", _GREEN_, _WHITE_);
|
||||
TestFlashmemSpeed(32768,24);
|
||||
TestFlashmemSpeed(16384 + 4096 + 4096,24);
|
||||
TestFlashmemSpeed(16384,24);
|
||||
TestFlashmemSpeed(4096,24);
|
||||
TestFlashmemSpeed(1024,24);
|
||||
//SpinDelay(1000);
|
||||
//WDT_HIT();
|
||||
//DbprintfEx(FLAG_NOLOG, "--------\n%s[B]%s Using FAST Reads @Max (48Mhz=MCK=CPUClock/2=MAXSPI)\n--------", _GREEN_, _WHITE_);
|
||||
TestFlashmemSpeed(32768,48);
|
||||
TestFlashmemSpeed(16384 + 4096 + 4096,48);
|
||||
TestFlashmemSpeed(16384,48);
|
||||
TestFlashmemSpeed(4096,48);
|
||||
TestFlashmemSpeed(1024,48);
|
||||
//SpinDelay(1000);
|
||||
//WDT_HIT();
|
||||
return;
|
||||
}
|
||||
|
||||
void ReadLastTagFromFlash() {
|
||||
SpinOff(0);
|
||||
LED_A_ON();
|
||||
LED_B_ON();
|
||||
@@ -250,20 +109,15 @@ void ReadLastTagFromFlash() {
|
||||
}
|
||||
Flash_CheckBusy(BUSY_TIMEOUT);
|
||||
|
||||
//Flash_ReadStat1();
|
||||
|
||||
uint32_t end_time;
|
||||
uint32_t start_time = end_time = GetTickCount();
|
||||
|
||||
for (size_t i = 0; i < len; i += size)
|
||||
{
|
||||
len = MIN((len - i), size);
|
||||
|
||||
// isok = Flash_FastReadDataCont(startidx + i, mem, len);
|
||||
isok = Flash_ReadDataCont(startidx + i, mem, len);
|
||||
if (isok == len)
|
||||
{
|
||||
//print_result("Chunk: ", mem, len);
|
||||
emlSetMem(mem, 0, 64);
|
||||
}
|
||||
else
|
||||
@@ -287,7 +141,6 @@ void ReadLastTagFromFlash() {
|
||||
|
||||
void WriteTagToFlash(uint8_t index, size_t size)
|
||||
{
|
||||
|
||||
SpinOff(0);
|
||||
LED_A_ON();
|
||||
LED_B_ON();
|
||||
@@ -302,7 +155,7 @@ void WriteTagToFlash(uint8_t index, size_t size)
|
||||
|
||||
uint8_t data[(size * (16 * 64))/1024];
|
||||
uint8_t buff[PAGESIZE];
|
||||
// cnt = 0;
|
||||
|
||||
emlGetMem(data, 0, (size * 64)/1024);
|
||||
|
||||
if (!FlashInit()){
|
||||
@@ -318,9 +171,8 @@ void WriteTagToFlash(uint8_t index, size_t size)
|
||||
|
||||
while (bytes_remaining > 0)
|
||||
{
|
||||
|
||||
Flash_CheckBusy(BUSY_TIMEOUT);
|
||||
Flash_WriteEnable();
|
||||
Flash_CheckBusy(BUSY_TIMEOUT);
|
||||
Flash_WriteEnable();
|
||||
|
||||
uint32_t bytes_in_packet = MIN(FLASH_MEM_BLOCK_SIZE, bytes_remaining);
|
||||
|
||||
@@ -337,7 +189,6 @@ void WriteTagToFlash(uint8_t index, size_t size)
|
||||
DbprintfEx(FLAG_NOLOG, "FlashMem write FAILEd [offset %u]", bytes_sent);
|
||||
cjSetCursLeft();
|
||||
SpinOff(100);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -352,11 +203,8 @@ void WriteTagToFlash(uint8_t index, size_t size)
|
||||
cjSetCursLeft();
|
||||
DbprintfEx(FLAG_NOLOG, "%s[IN]%s %s%dms%s for TAG_FLASH_WRITE", _GREEN_, _WHITE_, _YELLOW_, end_time - start_time, _WHITE_);
|
||||
cjSetCursLeft();
|
||||
|
||||
FlashStop();
|
||||
|
||||
SpinOff(0);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -473,11 +321,12 @@ ACCBITS : 796788[00]+VALUE
|
||||
{
|
||||
for (uint16_t sectorNo = 0; sectorNo < sectorsCnt; sectorNo++)
|
||||
{
|
||||
// validKey[t][sectorNo] = false;
|
||||
for (uint16_t i = 0; i < 6; i++)
|
||||
{
|
||||
foundKey[t][sectorNo][i] = 0xff;
|
||||
}
|
||||
foundKey[t][sectorNo][0] = 0xFF;
|
||||
foundKey[t][sectorNo][1] = 0xFF;
|
||||
foundKey[t][sectorNo][2] = 0xFF;
|
||||
foundKey[t][sectorNo][3] = 0xFF;
|
||||
foundKey[t][sectorNo][4] = 0xFF;
|
||||
foundKey[t][sectorNo][5] = 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -491,7 +340,6 @@ ACCBITS : 796788[00]+VALUE
|
||||
// banner:
|
||||
vtsend_reset(NULL);
|
||||
DbprintfEx(FLAG_NOLOG, "\r\n%s", clearTerm);
|
||||
cjPrintBigArray(LOGO, sizeof(LOGO), 0, 0);
|
||||
DbprintfEx(FLAG_NOLOG, "%s%s%s", _CYAN_, sub_banner, _WHITE_);
|
||||
DbprintfEx(FLAG_NOLOG, "%s>>%s C.J.B's MifareFastPwn Started\r\n", _RED_, _WHITE_);
|
||||
|
||||
@@ -506,11 +354,6 @@ ACCBITS : 796788[00]+VALUE
|
||||
SpinOff(50);
|
||||
SpinDown(50);
|
||||
|
||||
#if 0
|
||||
TestFlashmemRoutine();
|
||||
return;
|
||||
#endif
|
||||
|
||||
failtag:
|
||||
|
||||
vtsend_cursor_position_save(NULL);
|
||||
@@ -607,7 +450,7 @@ failtag:
|
||||
for (int sec = 0; sec < sectorsCnt && !err && !trapped; ++sec)
|
||||
{
|
||||
key = cjat91_saMifareChkKeys(sec * 4, type, NULL, size, &keyBlock[0], &key64);
|
||||
// key = saMifareChkKeys(sec * 4, type, NULL, size, &keyBlock[0], &key64);
|
||||
|
||||
if (key == -1)
|
||||
{
|
||||
err = 1;
|
||||
@@ -932,7 +775,7 @@ failtag:
|
||||
cjSetCursLeft();
|
||||
cjSetCursLeft();
|
||||
|
||||
WriteTagToFlash(0,1024);
|
||||
WriteTagToFlash(0, 1024);
|
||||
|
||||
readysim:
|
||||
// SIM ?
|
||||
@@ -966,16 +809,6 @@ readysim:
|
||||
DbprintfEx(FLAG_NOLOG, "<- We're out of Emulation");
|
||||
// END SIM
|
||||
|
||||
/*for (;;) {
|
||||
WDT_HIT();
|
||||
|
||||
int button_action = BUTTON_HELD(500);
|
||||
if (button_action == 0) { // No button action, proceed with sim
|
||||
SpinDelay(100);
|
||||
WDT_HIT();
|
||||
|
||||
} else if (button_action == BUTTON_SINGLE_CLICK) {
|
||||
*/
|
||||
cjSetCursLeft();
|
||||
|
||||
DbprintfEx(FLAG_NOLOG, "-> Trying a clone !");
|
||||
@@ -987,15 +820,7 @@ readysim:
|
||||
DbprintfEx(FLAG_NOLOG, "-> End Cloning.");
|
||||
WDT_HIT();
|
||||
|
||||
// break;
|
||||
/*} else if (button_action == BUTTON_HOLD) {
|
||||
DbprintfEx(FLAG_RAWPRINT,"Playtime over. Begin cloning...");
|
||||
iGotoClone = 1;
|
||||
break;
|
||||
}*/
|
||||
|
||||
// Debunk...
|
||||
// SpinDelay(300);
|
||||
cjSetCursLeft();
|
||||
cjTabulize();
|
||||
vtsend_set_attribute(NULL, 0);
|
||||
@@ -1020,14 +845,13 @@ void e_MifareECardLoad(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *dat
|
||||
uint8_t numSectors = arg0;
|
||||
uint8_t keyType = arg1;
|
||||
uint64_t ui64Key = 0;
|
||||
// uint32_t cuid;
|
||||
|
||||
struct Crypto1State mpcs = {0, 0};
|
||||
struct Crypto1State *pcs;
|
||||
pcs = &mpcs;
|
||||
|
||||
byte_t dataoutbuf[16];
|
||||
byte_t dataoutbuf2[16];
|
||||
// uint8_t uid[10];
|
||||
|
||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||
|
||||
@@ -1035,7 +859,6 @@ void e_MifareECardLoad(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *dat
|
||||
set_tracing(false);
|
||||
|
||||
bool isOK = true;
|
||||
// iso14443a_fast_select_card(cjuid, 0);
|
||||
|
||||
if (!iso14443a_select_card(cjuid, NULL, &cjcuid, true, 0, true))
|
||||
{
|
||||
@@ -1113,22 +936,17 @@ void e_MifareECardLoad(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *dat
|
||||
DbpString("EMUL FILL SECTORS FINISHED\n");
|
||||
}
|
||||
|
||||
/* . . . */
|
||||
|
||||
/* the chk function is a piwi’ed(tm) check that will try all keys for
|
||||
a particular sector. also no tracing no dbg */
|
||||
|
||||
int cjat91_saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace, uint8_t keyCount, uint8_t *datain, uint64_t *key)
|
||||
{
|
||||
MF_DBGLEVEL = MF_DBG_NONE;
|
||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||
set_tracing(false);
|
||||
// uint8_t uid[10];
|
||||
// uint32_t cuid;
|
||||
|
||||
struct Crypto1State mpcs = {0, 0};
|
||||
struct Crypto1State *pcs;
|
||||
pcs = &mpcs;
|
||||
// byte_t isOK = 0;
|
||||
|
||||
for (int i = 0; i < keyCount; ++i)
|
||||
{
|
||||
@@ -1241,7 +1059,6 @@ void saMifareMakeTag(void)
|
||||
//-----------------------------------------------------------------------------
|
||||
int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain)
|
||||
{
|
||||
|
||||
// params
|
||||
uint8_t needWipe = arg0;
|
||||
// bit 0 - need get UID
|
||||
@@ -1259,9 +1076,7 @@ int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *data
|
||||
|
||||
// variables
|
||||
byte_t isOK = 0;
|
||||
// uint8_t uid[10] = {0x00};
|
||||
uint8_t d_block[18] = {0x00};
|
||||
// uint32_t cuid;
|
||||
|
||||
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
|
||||
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
|
||||
@@ -1270,7 +1085,6 @@ int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *data
|
||||
if (workFlags & 0x08)
|
||||
{
|
||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||
|
||||
// clear_trace();
|
||||
set_tracing(FALSE);
|
||||
}
|
||||
@@ -1282,19 +1096,15 @@ int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *data
|
||||
// get UID from chip
|
||||
if (workFlags & 0x01)
|
||||
{
|
||||
// if (!iso14443a_fast_select_card(cjuid, 0)) {
|
||||
|
||||
if (!iso14443a_select_card(cjuid, NULL, &cjcuid, true, 0, true))
|
||||
{
|
||||
if (MF_DBGLEVEL >= 1)
|
||||
DbprintfEx(FLAG_NOLOG, "Can't select card");
|
||||
DbprintfEx(FLAG_NOLOG, "Can't select card");
|
||||
break;
|
||||
};
|
||||
|
||||
if (mifare_classic_halt(NULL, cjcuid))
|
||||
{
|
||||
if (MF_DBGLEVEL >= 1)
|
||||
DbprintfEx(FLAG_NOLOG, "Halt error");
|
||||
DbprintfEx(FLAG_NOLOG, "Halt error");
|
||||
break;
|
||||
};
|
||||
};
|
||||
@@ -1305,7 +1115,6 @@ int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *data
|
||||
ReaderTransmitBitsPar(wupC1, 7, 0, NULL);
|
||||
if (!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a))
|
||||
{
|
||||
// if (MF_DBGLEVEL >= 1)
|
||||
DbprintfEx(FLAG_NOLOG, "wupC1 error");
|
||||
break;
|
||||
};
|
||||
@@ -1313,15 +1122,13 @@ int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *data
|
||||
ReaderTransmit(wipeC, sizeof(wipeC), NULL);
|
||||
if (!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a))
|
||||
{
|
||||
if (MF_DBGLEVEL >= 1)
|
||||
DbprintfEx(FLAG_NOLOG, "wipeC error");
|
||||
DbprintfEx(FLAG_NOLOG, "wipeC error");
|
||||
break;
|
||||
};
|
||||
|
||||
if (mifare_classic_halt(NULL, cjcuid))
|
||||
{
|
||||
if (MF_DBGLEVEL >= 1)
|
||||
DbprintfEx(FLAG_NOLOG, "Halt error");
|
||||
DbprintfEx(FLAG_NOLOG, "Halt error");
|
||||
break;
|
||||
};
|
||||
};
|
||||
@@ -1333,7 +1140,6 @@ int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *data
|
||||
ReaderTransmitBitsPar(wupC1, 7, 0, NULL);
|
||||
if (!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a))
|
||||
{
|
||||
// if (MF_DBGLEVEL >= 1)
|
||||
DbprintfEx(FLAG_NOLOG, "wupC1 error");
|
||||
break;
|
||||
};
|
||||
@@ -1341,7 +1147,6 @@ int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *data
|
||||
ReaderTransmit(wupC2, sizeof(wupC2), NULL);
|
||||
if (!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a))
|
||||
{
|
||||
// if (MF_DBGLEVEL >= 1)
|
||||
DbprintfEx(FLAG_NOLOG, "wupC2 errorv");
|
||||
break;
|
||||
};
|
||||
@@ -1349,7 +1154,6 @@ int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *data
|
||||
|
||||
if ((mifare_sendcmd_short(NULL, 0, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL) != 1) || (receivedAnswer[0] != 0x0a))
|
||||
{
|
||||
// if (MF_DBGLEVEL >= 1)
|
||||
DbprintfEx(FLAG_NOLOG, "write block send command error");
|
||||
break;
|
||||
};
|
||||
@@ -1359,7 +1163,6 @@ int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *data
|
||||
ReaderTransmit(d_block, sizeof(d_block), NULL);
|
||||
if ((ReaderReceive(receivedAnswer, receivedAnswerPar) != 1) || (receivedAnswer[0] != 0x0a))
|
||||
{
|
||||
// if (MF_DBGLEVEL >= 1)
|
||||
DbprintfEx(FLAG_NOLOG, "write block send data error");
|
||||
break;
|
||||
};
|
||||
@@ -1368,7 +1171,6 @@ int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *data
|
||||
{
|
||||
if (mifare_classic_halt(NULL, cjcuid))
|
||||
{
|
||||
// if (MF_DBGLEVEL >= 1)
|
||||
cjSetCursFRight();
|
||||
|
||||
DbprintfEx(FLAG_NOLOG, "Halt error");
|
||||
|
||||
@@ -16,18 +16,15 @@
|
||||
#ifndef __HF_COLIN_H
|
||||
#define __HF_COLIN_H
|
||||
|
||||
|
||||
#include "proxmark3.h"
|
||||
#include "mifareutil.h"
|
||||
#include "iso14443a.h"
|
||||
//#include "printf.h"
|
||||
#include "protocols.h"
|
||||
#include "util.h"
|
||||
#include "standalone.h" // standalone definitions
|
||||
#include <stdbool.h> // for bool
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
//#include <stdio.h>
|
||||
#include "vtsend.h"
|
||||
#include "apps.h"
|
||||
#include "printf.h"
|
||||
@@ -41,23 +38,21 @@
|
||||
#define _WHITE_ "\x1b[0m"
|
||||
#define _ORANGE_ _YELLOW_
|
||||
|
||||
#define NTIME(n) for (int _index = 0; _index < n; _index++)
|
||||
|
||||
int cjat91_saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace, uint8_t keyCount, uint8_t *datain, uint64_t *key);
|
||||
void e_MifareECardLoad(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
|
||||
void saMifareMakeTag(void);
|
||||
int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
|
||||
void cjPrintBigArray(const char *bigar, int len, uint8_t newlines, uint8_t debug);
|
||||
void WriteTagToFlash(uint8_t index, size_t size);
|
||||
|
||||
const char clearTerm[8] = {0x1b, 0x5b, 0x48, 0x1b, 0x5b, 0x32, 0x4a, '\0'};
|
||||
|
||||
void TestFlashmemSpeed(size_t buffersize, uint32_t spibaudrate);
|
||||
//void cjPrintBigArray(const char *bigar, int len, uint8_t newlines, uint8_t debug);
|
||||
//void TestFlashmemSpeed(size_t buffersize, uint32_t spibaudrate);
|
||||
|
||||
//#define LOGO logo_kigiv
|
||||
|
||||
#define LOGO logo_kigiv
|
||||
|
||||
const char sub_banner[] = " From Vigik : \"20 years of (un)security without a single update\"";
|
||||
const char sub_banner[] = " From Vigik : \"20 years of (un)security without a single update\"";
|
||||
/*
|
||||
const char logo_kigiv[] = {
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x1b, 0x5b, 0x33, 0x38, 0x3b, 0x35,
|
||||
0x3b, 0x39, 0x35, 0x6d, 0x30, 0x1b, 0x5b, 0x33, 0x38, 0x3b, 0x35, 0x3b, 0x31, 0x33, 0x37, 0x6d, 0x30, 0x1b, 0x5b, 0x33, 0x38, 0x3b, 0x35, 0x3b, 0x39, 0x35,
|
||||
@@ -418,6 +413,7 @@ const char logo_kigiv[] = {
|
||||
0x31, 0x1b, 0x5b, 0x33, 0x38, 0x3b, 0x35, 0x3b, 0x35, 0x39, 0x6d, 0x31, 0x1b, 0x5b, 0x33, 0x38, 0x3b, 0x35, 0x3b, 0x35, 0x39, 0x6d, 0x30, 0x1b, 0x5b, 0x33,
|
||||
0x38, 0x3b, 0x35, 0x3b, 0x35, 0x39, 0x6d, 0x31, 0x1b, 0x5b, 0x33, 0x38, 0x3b, 0x35, 0x3b, 0x35, 0x39, 0x6d, 0x31, 0x0d, 0x0a};
|
||||
unsigned int logo_kigiv_len = 9303;
|
||||
*/
|
||||
|
||||
/*const char logo_kigiv_nocolor[] = {
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x30, 0x30, 0x30, 0x30, 0x20, 0x20,
|
||||
|
||||
+2
-14
@@ -254,12 +254,7 @@ uint16_t Flash_ReadData(uint32_t address, uint8_t *out, uint16_t len) {
|
||||
// length should never be zero
|
||||
if (!len || Flash_CheckBusy(BUSY_TIMEOUT)) return 0;
|
||||
|
||||
|
||||
uint8_t cmd = READDATA;
|
||||
|
||||
if(FASTFLASH) {
|
||||
cmd = FASTREAD;
|
||||
}
|
||||
uint8_t cmd = (FASTFLASH) ? FASTREAD : READDATA;
|
||||
|
||||
FlashSendByte(cmd);
|
||||
Flash_TransferAdresse(address);
|
||||
@@ -273,8 +268,6 @@ uint16_t Flash_ReadData(uint32_t address, uint8_t *out, uint16_t len) {
|
||||
out[i] = FlashSendByte(0xFF);
|
||||
|
||||
out[i] = FlashSendLastByte(0xFF);
|
||||
|
||||
|
||||
FlashStop();
|
||||
return len;
|
||||
}
|
||||
@@ -291,11 +284,7 @@ uint16_t Flash_ReadDataCont(uint32_t address, uint8_t *out, uint16_t len) {
|
||||
// length should never be zero
|
||||
if (!len) return 0;
|
||||
|
||||
uint8_t cmd = READDATA;
|
||||
|
||||
if(FASTFLASH) {
|
||||
cmd = FASTREAD;
|
||||
}
|
||||
uint8_t cmd = (FASTFLASH) ? FASTREAD : READDATA;
|
||||
|
||||
FlashSendByte(cmd);
|
||||
Flash_TransferAdresse(address);
|
||||
@@ -309,7 +298,6 @@ uint16_t Flash_ReadDataCont(uint32_t address, uint8_t *out, uint16_t len) {
|
||||
out[i] = FlashSendByte(0xFF);
|
||||
|
||||
out[i] = FlashSendLastByte(0xFF);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
+21
-6
@@ -90,9 +90,9 @@ void setT55xxConfig(uint8_t arg0, t55xx_config *c) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t *buf = BigBuf_malloc(4096);
|
||||
uint8_t *buf = BigBuf_malloc(T55XX_CONFIG_LEN);
|
||||
Flash_CheckBusy(BUSY_TIMEOUT);
|
||||
uint16_t res = Flash_ReadDataCont(T55XX_CONFIG_OFFSET, buf, 4096);
|
||||
uint16_t res = Flash_ReadDataCont(T55XX_CONFIG_OFFSET, buf, T55XX_CONFIG_LEN);
|
||||
if ( res == 0) {
|
||||
FlashStop();
|
||||
BigBuf_free();
|
||||
@@ -104,9 +104,9 @@ void setT55xxConfig(uint8_t arg0, t55xx_config *c) {
|
||||
Flash_CheckBusy(BUSY_TIMEOUT);
|
||||
Flash_WriteEnable();
|
||||
Flash_Erase4k(3, 0xD);
|
||||
res = Flash_Write(T55XX_CONFIG_OFFSET, buf, 4096);
|
||||
res = Flash_Write(T55XX_CONFIG_OFFSET, buf, T55XX_CONFIG_LEN);
|
||||
|
||||
if ( res == 4096 && MF_DBGLEVEL > 1) {
|
||||
if ( res == T55XX_CONFIG_LEN && MF_DBGLEVEL > 1) {
|
||||
DbpString("T55XX Config save success");
|
||||
}
|
||||
|
||||
@@ -124,10 +124,25 @@ void loadT55xxConfig(void) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t *buf = BigBuf_malloc(T55XX_CONFIG_LEN);
|
||||
|
||||
Flash_CheckBusy(BUSY_TIMEOUT);
|
||||
uint16_t isok = Flash_ReadDataCont(T55XX_CONFIG_OFFSET, (uint8_t *)&t_config, T55XX_CONFIG_LEN);
|
||||
uint16_t isok = Flash_ReadDataCont(T55XX_CONFIG_OFFSET, buf, T55XX_CONFIG_LEN);
|
||||
FlashStop();
|
||||
|
||||
|
||||
// verify read mem is actual data.
|
||||
uint8_t cntA = T55XX_CONFIG_LEN, cntB = T55XX_CONFIG_LEN;
|
||||
for (int i=0; i< T55XX_CONFIG_LEN; i++) {
|
||||
if ( buf[i] == 0xFF) cntA--;
|
||||
if ( buf[i] == 0x00) cntB--;
|
||||
}
|
||||
if ( !cntA || !cntB ) {
|
||||
BigBuf_free();
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy((uint8_t *)&t_config, buf, T55XX_CONFIG_LEN);
|
||||
|
||||
if ( isok == T55XX_CONFIG_LEN) {
|
||||
if (MF_DBGLEVEL > 1) DbpString("T55XX Config load success");
|
||||
}
|
||||
|
||||
@@ -1425,6 +1425,8 @@ OUT:
|
||||
|
||||
void MifareChkKeys(uint16_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) {
|
||||
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
|
||||
struct Crypto1State mpcs = {0, 0};
|
||||
struct Crypto1State *pcs;
|
||||
pcs = &mpcs;
|
||||
|
||||
@@ -154,6 +154,70 @@ void LED(int led, int ms) {
|
||||
LED_D_OFF();
|
||||
}
|
||||
|
||||
void SpinOff(uint32_t pause) {
|
||||
LED_A_OFF();
|
||||
LED_B_OFF();
|
||||
LED_C_OFF();
|
||||
LED_D_OFF();
|
||||
SpinDelay(pause);
|
||||
}
|
||||
|
||||
// 0=A, 1=B, 2=C, 3=D
|
||||
void SpinErr(uint8_t led, uint32_t speed, uint8_t times) {
|
||||
SpinOff(speed);
|
||||
NTIME(times)
|
||||
{
|
||||
switch (led) {
|
||||
case 0:
|
||||
LED_A_INV();
|
||||
break;
|
||||
case 1:
|
||||
LED_B_INV();
|
||||
break;
|
||||
case 2:
|
||||
LED_C_INV();
|
||||
break;
|
||||
case 3:
|
||||
LED_D_INV();
|
||||
break;
|
||||
}
|
||||
SpinDelay(speed);
|
||||
}
|
||||
}
|
||||
|
||||
void SpinDown(uint32_t speed) {
|
||||
SpinOff(speed);
|
||||
LED_D_ON();
|
||||
SpinDelay(speed);
|
||||
LED_D_OFF();
|
||||
LED_C_ON();
|
||||
SpinDelay(speed);
|
||||
LED_C_OFF();
|
||||
LED_B_ON();
|
||||
SpinDelay(speed);
|
||||
LED_B_OFF();
|
||||
LED_A_ON();
|
||||
SpinDelay(speed);
|
||||
LED_A_OFF();
|
||||
}
|
||||
|
||||
void SpinUp(uint32_t speed) {
|
||||
SpinOff(speed);
|
||||
LED_A_ON();
|
||||
SpinDelay(speed);
|
||||
LED_A_OFF();
|
||||
LED_B_ON();
|
||||
SpinDelay(speed);
|
||||
LED_B_OFF();
|
||||
LED_C_ON();
|
||||
SpinDelay(speed);
|
||||
LED_C_OFF();
|
||||
LED_D_ON();
|
||||
SpinDelay(speed);
|
||||
LED_D_OFF();
|
||||
}
|
||||
|
||||
|
||||
// Determine if a button is double clicked, single clicked,
|
||||
// not clicked, or held down (for ms || 1sec)
|
||||
// In general, don't use this function unless you expect a
|
||||
|
||||
+10
-1
@@ -39,6 +39,10 @@
|
||||
# define ARRAYLEN(x) (sizeof(x)/sizeof((x)[0]))
|
||||
#endif
|
||||
|
||||
#ifndef NTIME
|
||||
# define NTIME(n) for (int _index = 0; _index < n; _index++)
|
||||
#endif
|
||||
|
||||
size_t nbytes(size_t nbits);
|
||||
|
||||
extern uint32_t reflect(uint32_t v, int b); // used in crc.c ...
|
||||
@@ -53,7 +57,12 @@ int32_t le24toh (uint8_t data[3]);
|
||||
uint8_t hex2int(char hexchar);
|
||||
|
||||
void LED(int led, int ms);
|
||||
void LEDsoff();
|
||||
void LEDsoff(void);
|
||||
void SpinOff(uint32_t pause);
|
||||
void SpinErr(uint8_t led, uint32_t speed, uint8_t times);
|
||||
void SpinDown(uint32_t speed);
|
||||
void SpinUp(uint32_t speed);
|
||||
|
||||
int BUTTON_CLICKED(int ms);
|
||||
int BUTTON_HELD(int ms);
|
||||
void FormatVersionInformation(char *dst, int len, const char *prefix, void *version_information);
|
||||
|
||||
@@ -105,11 +105,13 @@ CMDSRCS = crapto1/crapto1.c \
|
||||
tea.c \
|
||||
polarssl/des.c \
|
||||
polarssl/aes.c \
|
||||
polarssl/aes_cmac128.c \
|
||||
polarssl/bignum.c \
|
||||
polarssl/rsa.c \
|
||||
polarssl/sha1.c \
|
||||
polarssl/sha256.c \
|
||||
polarssl/base64.c \
|
||||
polarssl/libpcrypto.c \
|
||||
cliparser/argtable3.c\
|
||||
cliparser/cliparser.c\
|
||||
loclass/cipher.c \
|
||||
@@ -147,6 +149,7 @@ CMDSRCS = crapto1/crapto1.c \
|
||||
emv/test/dda_test.c\
|
||||
emv/test/cda_test.c\
|
||||
emv/cmdemv.c \
|
||||
mifare4.c \
|
||||
cmdanalyse.c \
|
||||
cmdhf.c \
|
||||
cmdhflist.c \
|
||||
@@ -158,6 +161,7 @@ CMDSRCS = crapto1/crapto1.c \
|
||||
cmdhficlass.c \
|
||||
cmdhfmf.c \
|
||||
cmdhfmfu.c \
|
||||
cmdhfmfp.c \
|
||||
cmdhfmfhard.c \
|
||||
hardnested/hardnested_bruteforce.c \
|
||||
cmdhfmfdes.c \
|
||||
|
||||
@@ -153,23 +153,14 @@ void CLIParserFree() {
|
||||
// convertors
|
||||
int CLIParamHexToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int *datalen) {
|
||||
*datalen = 0;
|
||||
if (!argstr->count)
|
||||
return 0;
|
||||
|
||||
char buf[256] = {0};
|
||||
int ibuf = 0;
|
||||
uint8_t buf[256] = {0};
|
||||
int res = CLIParamStrToBuf(argstr, buf, maxdatalen * 2, &ibuf); // *2 because here HEX
|
||||
if (res || !ibuf)
|
||||
return res;
|
||||
|
||||
for (int i = 0; i < argstr->count; i++) {
|
||||
int len = strlen(argstr->sval[i]);
|
||||
memcpy(&buf[ibuf], argstr->sval[i], len);
|
||||
ibuf += len;
|
||||
}
|
||||
buf[ibuf] = 0;
|
||||
|
||||
if (!ibuf)
|
||||
return 0;
|
||||
|
||||
switch(param_gethex_to_eol(buf, 0, data, maxdatalen, datalen)) {
|
||||
switch(param_gethex_to_eol((char *)buf, 0, data, maxdatalen, datalen)) {
|
||||
case 1:
|
||||
printf("Parameter error: Invalid HEX value.\n");
|
||||
return 1;
|
||||
@@ -184,5 +175,31 @@ int CLIParamHexToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CLIParamStrToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int *datalen) {
|
||||
*datalen = 0;
|
||||
if (!argstr->count)
|
||||
return 0;
|
||||
|
||||
uint8_t buf[256] = {0};
|
||||
int ibuf = 0;
|
||||
|
||||
for (int i = 0; i < argstr->count; i++) {
|
||||
int len = strlen(argstr->sval[i]);
|
||||
memcpy(&buf[ibuf], argstr->sval[i], len);
|
||||
ibuf += len;
|
||||
}
|
||||
buf[ibuf] = 0;
|
||||
|
||||
if (!ibuf)
|
||||
return 0;
|
||||
|
||||
if (ibuf > maxdatalen)
|
||||
return 2;
|
||||
|
||||
memcpy(data, buf, ibuf);
|
||||
*datalen = ibuf;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -17,7 +17,9 @@
|
||||
|
||||
#define arg_getsize(a) (sizeof(a) / sizeof(a[0]))
|
||||
#define arg_get_lit(n)(((struct arg_lit*)argtable[n])->count)
|
||||
#define arg_get_int_count(n)(((struct arg_int*)argtable[n])->count)
|
||||
#define arg_get_int(n)(((struct arg_int*)argtable[n])->ival[0])
|
||||
#define arg_get_int_def(n,def)(arg_get_int_count(n)?(arg_get_int(n)):(def))
|
||||
#define arg_get_str(n)((struct arg_str*)argtable[n])
|
||||
#define arg_get_str_len(n)(strlen(((struct arg_str*)argtable[n])->sval[0]))
|
||||
|
||||
@@ -25,8 +27,9 @@
|
||||
#define arg_strx0(shortopts, longopts, datatype, glossary) (arg_strn((shortopts), (longopts), (datatype), 0, 250, (glossary)))
|
||||
|
||||
#define CLIExecWithReturn(cmd, atbl, ifempty) if (CLIParserParseString(cmd, atbl, arg_getsize(atbl), ifempty)){CLIParserFree();return 0;}
|
||||
#define CLIGetStrBLessWithReturn(paramnum, data, datalen, delta) if (CLIParamHexToBuf(arg_get_str(paramnum), data, sizeof(data) - (delta), datalen)) {CLIParserFree();return 1;}
|
||||
#define CLIGetStrWithReturn(paramnum, data, datalen) if (CLIParamHexToBuf(arg_get_str(paramnum), data, sizeof(data), datalen)) {CLIParserFree();return 1;}
|
||||
#define CLIGetHexBLessWithReturn(paramnum, data, datalen, delta) if (CLIParamHexToBuf(arg_get_str(paramnum), data, sizeof(data) - (delta), datalen)) {CLIParserFree();return 1;}
|
||||
#define CLIGetHexWithReturn(paramnum, data, datalen) if (CLIParamHexToBuf(arg_get_str(paramnum), data, sizeof(data), datalen)) {CLIParserFree();return 1;}
|
||||
#define CLIGetStrWithReturn(paramnum, data, datalen) if (CLIParamStrToBuf(arg_get_str(paramnum), data, sizeof(data), datalen)) {CLIParserFree();return 1;}
|
||||
|
||||
extern int CLIParserInit(char *vprogramName, char *vprogramHint, char *vprogramHelp);
|
||||
extern int CLIParserParseString(const char* str, void* argtable[], size_t vargtableLen, bool allowEmptyExec);
|
||||
@@ -35,3 +38,4 @@ extern int CLIParserParseArg(int argc, char **argv, void* argtable[], size_t var
|
||||
extern void CLIParserFree();
|
||||
|
||||
extern int CLIParamHexToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int *datalen);
|
||||
extern int CLIParamStrToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int *datalen);
|
||||
|
||||
@@ -117,6 +117,7 @@ static command_t CommandTable[] = {
|
||||
{"legic", CmdHFLegic, 1, "{ LEGIC RFIDs... }"},
|
||||
{"iclass", CmdHFiClass, 1, "{ ICLASS RFIDs... }"},
|
||||
{"mf", CmdHFMF, 1, "{ MIFARE RFIDs... }"},
|
||||
{"mfp", CmdHFMFP, 1, "{ MIFARE Plus RFIDs... }"},
|
||||
{"mfu", CmdHFMFUltra, 1, "{ MIFARE Ultralight RFIDs... }"},
|
||||
{"mfdes", CmdHFMFDes, 1, "{ MIFARE Desfire RFIDs... }"},
|
||||
{"topaz", CmdHFTopaz, 1, "{ TOPAZ (NFC Type 1) RFIDs... }"},
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "cmdhficlass.h" // ICLASS
|
||||
#include "cmdhfmf.h" // CLASSIC
|
||||
#include "cmdhfmfu.h" // ULTRALIGHT/NTAG etc
|
||||
#include "cmdhfmfp.h" // Mifare Plus
|
||||
#include "cmdhfmfdes.h" // DESFIRE
|
||||
#include "cmdhftopaz.h" // TOPAZ
|
||||
#include "cmdhffelica.h" // ISO18092 / FeliCa
|
||||
|
||||
+19
-9
@@ -669,10 +669,12 @@ int CmdHF14ASniff(const char *Cmd) {
|
||||
}
|
||||
|
||||
int ExchangeRAW14a(uint8_t *datain, int datainlen, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen) {
|
||||
static bool responseNum = false;
|
||||
uint16_t cmdc = 0;
|
||||
*dataoutlen = 0;
|
||||
|
||||
if (activateField) {
|
||||
responseNum = false;
|
||||
UsbCommand resp;
|
||||
|
||||
// Anticollision + SELECT card
|
||||
@@ -685,7 +687,7 @@ int ExchangeRAW14a(uint8_t *datain, int datainlen, bool activateField, bool leav
|
||||
|
||||
// check result
|
||||
if (resp.arg[0] == 0) {
|
||||
PrintAndLogEx(NORMAL, "No card in field.");
|
||||
PrintAndLogEx(ERR, "No card in field.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -715,8 +717,11 @@ int ExchangeRAW14a(uint8_t *datain, int datainlen, bool activateField, bool leav
|
||||
if (leaveSignalON)
|
||||
cmdc |= ISO14A_NO_DISCONNECT;
|
||||
|
||||
UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_RAW | ISO14A_APPEND_CRC | cmdc, (datainlen & 0xFFFF), 0}};
|
||||
memcpy(c.d.asBytes, datain, datainlen);
|
||||
UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_RAW | ISO14A_APPEND_CRC | cmdc, (datainlen & 0xFFFF) + 2, 0}};
|
||||
uint8_t header[] = {0x0a | responseNum, 0x00};
|
||||
responseNum ^= 1;
|
||||
memcpy(c.d.asBytes, header, 2);
|
||||
memcpy(&c.d.asBytes[2], datain, datainlen);
|
||||
SendCommand(&c);
|
||||
|
||||
uint8_t *recv;
|
||||
@@ -726,6 +731,11 @@ int ExchangeRAW14a(uint8_t *datain, int datainlen, bool activateField, bool leav
|
||||
recv = resp.d.asBytes;
|
||||
int iLen = resp.arg[0];
|
||||
|
||||
if(!iLen) {
|
||||
PrintAndLogEx(ERR, "No card response.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
*dataoutlen = iLen - 2;
|
||||
if (*dataoutlen < 0)
|
||||
*dataoutlen = 0;
|
||||
@@ -735,13 +745,13 @@ int ExchangeRAW14a(uint8_t *datain, int datainlen, bool activateField, bool leav
|
||||
return 2;
|
||||
}
|
||||
|
||||
memcpy(dataout, recv, *dataoutlen);
|
||||
|
||||
if(!iLen) {
|
||||
PrintAndLogEx(ERR, "No card response.");
|
||||
return 1;
|
||||
if (recv[0] != header[0]) {
|
||||
PrintAndLogEx(ERR, "iso14443-4 framing error. Card send %2x must be %2x", dataout[0], header[0]);
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
||||
memcpy(dataout, &recv[2], *dataoutlen);
|
||||
|
||||
// CRC Check
|
||||
if (iLen == -1) {
|
||||
PrintAndLogEx(ERR, "ISO 14443A CRC error.");
|
||||
|
||||
@@ -2047,7 +2047,7 @@ int CmdHFiClassCheckKeys(const char *Cmd) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
PrintPreCalcMac(keyBlock, keycnt, pre);
|
||||
//PrintPreCalcMac(keyBlock, keycnt, pre);
|
||||
|
||||
// max 42 keys inside USB_COMMAND. 512/4 = 103 mac
|
||||
uint32_t chunksize = keycnt > (USB_CMD_DATA_SIZE/4) ? (USB_CMD_DATA_SIZE/4) : keycnt;
|
||||
|
||||
+47
-119
@@ -9,6 +9,7 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "cmdhfmf.h"
|
||||
#include "mifare4.h"
|
||||
|
||||
#define MIFARE_4K_MAXBLOCK 255
|
||||
#define MIFARE_2K_MAXBLOCK 128
|
||||
@@ -130,6 +131,13 @@ int usage_hf14_hardnested(void){
|
||||
PrintAndLogEx(NORMAL, " u <UID> read/write hf-mf-<UID>-nonces.bin instead of default name");
|
||||
PrintAndLogEx(NORMAL, " f <name> read/write <name> instead of default name");
|
||||
PrintAndLogEx(NORMAL, " t tests?");
|
||||
PrintAndLogEx(NORMAL, " i <X> set type of SIMD instructions. Without this flag programs autodetect it.");
|
||||
PrintAndLogEx(NORMAL, " i 5 = AVX512");
|
||||
PrintAndLogEx(NORMAL, " i 2 = AVX2");
|
||||
PrintAndLogEx(NORMAL, " i a = AVX");
|
||||
PrintAndLogEx(NORMAL, " i s = SSE2");
|
||||
PrintAndLogEx(NORMAL, " i m = MMX");
|
||||
PrintAndLogEx(NORMAL, " i n = none (use CPU regular instruction set)");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(NORMAL, "Examples:");
|
||||
PrintAndLogEx(NORMAL, " hf mf hardnested 0 A FFFFFFFFFFFF 4 A");
|
||||
@@ -1251,8 +1259,8 @@ int CmdHF14AMfNestedHard(const char *Cmd) {
|
||||
switch(tolower(param_getchar(Cmd, cmdp))) {
|
||||
case 'h': return usage_hf14_hardnested();
|
||||
case 'r':
|
||||
fptr=GenerateFilename("hf-mf-","-nonces.bin");
|
||||
if(fptr==NULL)
|
||||
fptr = GenerateFilename("hf-mf-","-nonces.bin");
|
||||
if (fptr == NULL)
|
||||
strncpy(filename,"nonces.bin", FILE_PATH_SIZE);
|
||||
else
|
||||
strncpy(filename,fptr, FILE_PATH_SIZE);
|
||||
@@ -1268,10 +1276,10 @@ int CmdHF14AMfNestedHard(const char *Cmd) {
|
||||
if (!param_gethex(Cmd, cmdp+2, trgkey, 12)) {
|
||||
know_target_key = true;
|
||||
}
|
||||
cmdp+=2;
|
||||
cmdp += 2;
|
||||
break;
|
||||
default:
|
||||
if(param_getchar(Cmd, cmdp) == 0x00)
|
||||
if (param_getchar(Cmd, cmdp) == 0x00)
|
||||
{
|
||||
PrintAndLogEx(NORMAL, "Block number is missing");
|
||||
return 1;
|
||||
@@ -1308,7 +1316,7 @@ int CmdHF14AMfNestedHard(const char *Cmd) {
|
||||
if (ctmp != 'A' && ctmp != 'a') {
|
||||
trgKeyType = 1;
|
||||
}
|
||||
cmdp+=5;
|
||||
cmdp += 5;
|
||||
}
|
||||
if (!param_gethex(Cmd, cmdp, trgkey, 12)) {
|
||||
know_target_key = true;
|
||||
@@ -1316,14 +1324,13 @@ int CmdHF14AMfNestedHard(const char *Cmd) {
|
||||
}
|
||||
|
||||
while ((ctmp = param_getchar(Cmd, cmdp))) {
|
||||
switch(tolower(ctmp))
|
||||
{
|
||||
switch(tolower(ctmp)) {
|
||||
case 's':
|
||||
slow = true;
|
||||
break;
|
||||
case 'w':
|
||||
nonce_file_write = true;
|
||||
fptr=GenerateFilename("hf-mf-","-nonces.bin");
|
||||
fptr = GenerateFilename("hf-mf-","-nonces.bin");
|
||||
if (fptr == NULL)
|
||||
return 1;
|
||||
strncpy(filename, fptr, FILE_PATH_SIZE);
|
||||
@@ -1338,6 +1345,34 @@ int CmdHF14AMfNestedHard(const char *Cmd) {
|
||||
strncpy(filename, szTemp, FILE_PATH_SIZE);
|
||||
cmdp++;
|
||||
break;
|
||||
case 'i':
|
||||
SetSIMDInstr(SIMD_AUTO);
|
||||
ctmp = tolower(param_getchar(Cmd, cmdp+1));
|
||||
switch (ctmp) {
|
||||
case '5':
|
||||
SetSIMDInstr(SIMD_AVX512);
|
||||
break;
|
||||
case '2':
|
||||
SetSIMDInstr(SIMD_AVX2);
|
||||
break;
|
||||
case 'a':
|
||||
SetSIMDInstr(SIMD_AVX);
|
||||
break;
|
||||
case 's':
|
||||
SetSIMDInstr(SIMD_SSE2);
|
||||
break;
|
||||
case 'm':
|
||||
SetSIMDInstr(SIMD_MMX);
|
||||
break;
|
||||
case 'n':
|
||||
SetSIMDInstr(SIMD_NONE);
|
||||
break;
|
||||
default:
|
||||
PrintAndLog("Unknown SIMD type. %c", ctmp);
|
||||
return 1;
|
||||
}
|
||||
cmdp += 2;
|
||||
break;
|
||||
default:
|
||||
PrintAndLogEx(WARNING, "Unknown parameter '%c'\n", ctmp);
|
||||
usage_hf14_hardnested();
|
||||
@@ -3067,50 +3102,12 @@ out:
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aes_encode(uint8_t *iv, uint8_t *key, uint8_t *input, uint8_t *output, int length){
|
||||
uint8_t iiv[16] = {0};
|
||||
if (iv)
|
||||
memcpy(iiv, iv, 16);
|
||||
|
||||
aes_context aes;
|
||||
aes_init(&aes);
|
||||
if (aes_setkey_enc(&aes, key, 128))
|
||||
return 1;
|
||||
if (aes_crypt_cbc(&aes, AES_ENCRYPT, length, iiv, input, output))
|
||||
return 2;
|
||||
aes_free(&aes);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aes_decode(uint8_t *iv, uint8_t *key, uint8_t *input, uint8_t *output, int length){
|
||||
uint8_t iiv[16] = {0};
|
||||
if (iv)
|
||||
memcpy(iiv, iv, 16);
|
||||
|
||||
aes_context aes;
|
||||
aes_init(&aes);
|
||||
if (aes_setkey_dec(&aes, key, 128))
|
||||
return 1;
|
||||
if (aes_crypt_cbc(&aes, AES_DECRYPT, length, iiv, input, output))
|
||||
return 2;
|
||||
aes_free(&aes);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CmdHF14AMfAuth4(const char *cmd) {
|
||||
uint8_t keyn[20] = {0};
|
||||
int keynlen = 0;
|
||||
uint8_t key[16] = {0};
|
||||
int keylen = 0;
|
||||
uint8_t data[257] = {0};
|
||||
int datalen = 0;
|
||||
|
||||
uint8_t Rnd1[17] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00};
|
||||
uint8_t Rnd2[17] = {0};
|
||||
|
||||
|
||||
|
||||
CLIParserInit("hf mf auth4",
|
||||
"Executes AES authentication command in ISO14443-4",
|
||||
"Usage:\n\thf mf auth4 4000 000102030405060708090a0b0c0d0e0f -> executes authentication\n"
|
||||
@@ -3124,8 +3121,8 @@ int CmdHF14AMfAuth4(const char *cmd) {
|
||||
};
|
||||
CLIExecWithReturn(cmd, argtable, true);
|
||||
|
||||
CLIGetStrWithReturn(1, keyn, &keynlen);
|
||||
CLIGetStrWithReturn(2, key, &keylen);
|
||||
CLIGetHexWithReturn(1, keyn, &keynlen);
|
||||
CLIGetHexWithReturn(2, key, &keylen);
|
||||
CLIParserFree();
|
||||
|
||||
if (keynlen != 2) {
|
||||
@@ -3138,76 +3135,7 @@ int CmdHF14AMfAuth4(const char *cmd) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint8_t cmd1[] = {0x0a, 0x00, 0x70, keyn[1], keyn[0], 0x00};
|
||||
int res = ExchangeRAW14a(cmd1, sizeof(cmd1), true, true, data, sizeof(data), &datalen);
|
||||
if (res) {
|
||||
PrintAndLog("ERROR exchande raw error: %d", res);
|
||||
return 2;
|
||||
}
|
||||
|
||||
PrintAndLog("<phase1: %s", sprint_hex(data, datalen));
|
||||
|
||||
if (datalen < 3) {
|
||||
PrintAndLogEx(ERR, "card response length: %d", datalen);
|
||||
return 3;
|
||||
}
|
||||
|
||||
if (data[0] != 0x0a || data[1] != 0x00) {
|
||||
PrintAndLogEx(ERR, "Framing error in card response. :%s", sprint_hex(data, 2));
|
||||
return 3;
|
||||
}
|
||||
|
||||
if (data[2] != 0x90) {
|
||||
PrintAndLogEx(ERR, "card response error: %02x", data[2]);
|
||||
return 3;
|
||||
}
|
||||
|
||||
if (datalen != 19) {
|
||||
PrintAndLogEx(ERR, "card response must be 16 bytes long instead of: %d", datalen);
|
||||
return 3;
|
||||
}
|
||||
|
||||
aes_decode(NULL, key, &data[3], Rnd2, 16);
|
||||
Rnd2[16] = Rnd2[0];
|
||||
PrintAndLog("Rnd2: %s", sprint_hex(Rnd2, 16));
|
||||
|
||||
uint8_t cmd2[35] = {0};
|
||||
cmd2[0] = 0x0b;
|
||||
cmd2[1] = 0x00;
|
||||
cmd2[2] = 0x72;
|
||||
|
||||
uint8_t raw[32] = {0};
|
||||
memmove(raw, Rnd1, 16);
|
||||
memmove(&raw[16], &Rnd2[1], 16);
|
||||
|
||||
aes_encode(NULL, key, raw, &cmd2[3], 32);
|
||||
PrintAndLog(">phase2: %s", sprint_hex(cmd2, 35));
|
||||
|
||||
res = ExchangeRAW14a(cmd2, sizeof(cmd2), false, false, data, sizeof(data), &datalen);
|
||||
if (res) {
|
||||
PrintAndLogEx(ERR, "exchande raw error: %d", res);
|
||||
DropField();
|
||||
return 4;
|
||||
}
|
||||
|
||||
PrintAndLog("<phase2: %s", sprint_hex(data, datalen));
|
||||
|
||||
aes_decode(NULL, key, &data[3], raw, 32);
|
||||
PrintAndLog("res: %s", sprint_hex(raw, 32));
|
||||
|
||||
PrintAndLog("Rnd1`: %s", sprint_hex(&raw[4], 16));
|
||||
if (memcmp(&raw[4], &Rnd1[1], 16)) {
|
||||
PrintAndLogEx(ERR, "\nAuthentication FAILED. rnd not equal");
|
||||
PrintAndLog("rnd1 reader: %s", sprint_hex(&Rnd1[1], 16));
|
||||
PrintAndLog("rnd1 card: %s", sprint_hex(&raw[4], 16));
|
||||
DropField();
|
||||
return 5;
|
||||
}
|
||||
|
||||
DropField();
|
||||
PrintAndLogEx(INFO, "Authentication OK");
|
||||
|
||||
return 0;
|
||||
return MifareAuth4(NULL, keyn, key, true, false, true);
|
||||
}
|
||||
|
||||
static command_t CommandTable[] = {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user