add new ht2 tools, thanks to anonymous donator

This commit is contained in:
Philippe Teuwen
2020-04-04 14:03:21 +02:00
parent 5277a95364
commit 8ab297ae6a
24 changed files with 5762 additions and 1 deletions
+49 -1
View File
@@ -1,7 +1,10 @@
HiTag2 Cracking Suite
---------------------
Author: Kevin Sheldrake <kev@headhacking.com>
Authors:
* Attacks 1, 2, 3, 4 : Kevin Sheldrake <kev@headhacking.com>
* Attacks 5, 5gpu : anonymous, based on https://github.com/factoritbv/hitag2hell by FactorIT B.V.
Introduction
------------
@@ -89,6 +92,21 @@ 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.
Attack 5
--------
Attack 5 is heavily based on the HiTag2 Hell CPU implementation from https://github.com/factoritbv/hitag2hell by FactorIT B.V.,
with the following changes:
* Main takes a UID and 2 {nR},{aR} pairs as arguments and searches for states producing the first aR sample, reconstructs the corresponding key candidates and tests them against the second nR,aR pair;
* Reuses the Hitag helping functions of the other attacks.
Attack 5gpu
-----------
Attack 5gpu is identical to attack 5, simply the code has been ported to OpenCL
to run on GPUs and is therefore much faster than attack 5.
Usage details: Attack 1
-----------------------
@@ -172,6 +190,36 @@ Stop once you got enough pairs.
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.
Usage details: Attack 5
-----------------------
Attack 5 requires two encrypted nonce and challenge
response value pairs (nR, aR) for the tag's UID.
```
pm3 --> lf hitag sniff
```
Stop once you got two pairs.
```
$ ./ht2crack5 <UID> <nR1> <aR1> <nR2> <aR2>
```
Usage details: Attack 5gpu
--------------------------
Attack 5gpu requires two encrypted nonce and challenge
response value pairs (nR, aR) for the tag's UID.
```
pm3 --> lf hitag sniff
```
Stop once you got two pairs.
```
$ ./ht2crack5gpu <UID> <nR1> <aR1> <nR2> <aR2>
```
Usage details: Next steps
-------------------------
File diff suppressed because it is too large Load Diff
+18
View File
@@ -0,0 +1,18 @@
CFLAGS?=-Wall
LIBS=-lpthread
all: ht2crack5.c utilpart.o ht2crack2utils.o hitagcrypto.o
$(CC) $(CFLAGS) -O3 ht2crack5.c -o ht2crack5 utilpart.o ht2crack2utils.o hitagcrypto.o $(LIBS)
utilpart.o: util.h utilpart.c
$(CC) $(CFLAGS) -c utilpart.c
hitagcrypto.o: hitagcrypto.h hitagcrypto.c
$(CC) $(CFLAGS) -c hitagcrypto.c
ht2crack2utils.o: ht2crack2utils.h ht2crack2utils.c
$(CC) $(CFLAGS) -c ht2crack2utils.c
clean:
rm -f *.o ht2crack5
fresh: clean all
+23
View File
@@ -0,0 +1,23 @@
ht2crack5
Build
-----
```
make clean
make
```
Run
---
You'll need just two nR aR pairs. These are the
encrypted nonces and challenge response values. They should be in hex.
```
./ht2crack5 <UID> <nR1> <aR1> <nR2> <aR2>
```
UID is the UID of the tag that you used to gather the nR aR values.
+373
View File
@@ -0,0 +1,373 @@
/***************************************************************************
* A copy of the GNU GPL is appended to this file. *
* *
* This licence is based on the nmap licence, and we express our gratitude *
* for the work that went into producing it. There is no other connection *
* between RFIDler and nmap either expressed or implied. *
* *
********************** IMPORTANT RFIDler LICENSE TERMS ********************
* *
* *
* All references to RFIDler herein imply all it's derivatives, namely: *
* *
* o RFIDler-LF Standard *
* o RFIDler-LF Lite *
* o RFIDler-LF Nekkid *
* *
* *
* RFIDler is (C) 2013-2015 Aperture Labs Ltd. *
* *
* This program is free software; you may redistribute and/or modify it *
* under the terms of the GNU General Public License as published by the *
* Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE *
* CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your *
* right to use, modify, and redistribute this software under certain *
* conditions. If you wish to embed RFIDler technology into proprietary *
* software or hardware, we sell alternative licenses *
* (contact sales@aperturelabs.com). *
* *
* Note that the GPL places important restrictions on "derivative works", *
* yet it does not provide a detailed definition of that term. To avoid *
* misunderstandings, we interpret that term as broadly as copyright law *
* allows. For example, we consider an application to constitute a *
* derivative work for the purpose of this license if it does any of the *
* following with any software or content covered by this license *
* ("Covered Software"): *
* *
* o Integrates source code from Covered Software. *
* *
* o Is designed specifically to execute Covered Software and parse the *
* results (as opposed to typical shell or execution-menu apps, which will *
* execute anything you tell them to). *
* *
* o Includes Covered Software in a proprietary executable installer. The *
* installers produced by InstallShield are an example of this. Including *
* RFIDler with other software in compressed or archival form does not *
* trigger this provision, provided appropriate open source decompression *
* or de-archiving software is widely available for no charge. For the *
* purposes of this license, an installer is considered to include Covered *
* Software even if it actually retrieves a copy of Covered Software from *
* another source during runtime (such as by downloading it from the *
* Internet). *
* *
* o Links (statically or dynamically) to a library which does any of the *
* above. *
* *
* o Executes a helper program, module, or script to do any of the above. *
* *
* This list is not exclusive, but is meant to clarify our interpretation *
* of derived works with some common examples. Other people may interpret *
* the plain GPL differently, so we consider this a special exception to *
* the GPL that we apply to Covered Software. Works which meet any of *
* these conditions must conform to all of the terms of this license, *
* particularly including the GPL Section 3 requirements of providing *
* source code and allowing free redistribution of the work as a whole. *
* *
* As another special exception to the GPL terms, Aperture Labs Ltd. grants*
* permission to link the code of this program with any version of the *
* OpenSSL library which is distributed under a license identical to that *
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
* linked combinations including the two. *
* *
* Any redistribution of Covered Software, including any derived works, *
* must obey and carry forward all of the terms of this license, including *
* obeying all GPL rules and restrictions. For example, source code of *
* the whole work must be provided and free redistribution must be *
* allowed. All GPL references to "this License", are to be treated as *
* including the terms and conditions of this license text as well. *
* *
* Because this license imposes special exceptions to the GPL, Covered *
* Work may not be combined (even as part of a larger work) with plain GPL *
* software. The terms, conditions, and exceptions of this license must *
* be included as well. This license is incompatible with some other open *
* source licenses as well. In some cases we can relicense portions of *
* RFIDler or grant special permissions to use it in other open source *
* software. Please contact sales@aperturelabs.com with any such requests.*
* Similarly, we don't incorporate incompatible open source software into *
* Covered Software without special permission from the copyright holders. *
* *
* If you have any questions about the licensing restrictions on using *
* RFIDler in other works, are happy to help. As mentioned above, we also *
* offer alternative license to integrate RFIDler into proprietary *
* applications and appliances. These contracts have been sold to dozens *
* of software vendors, and generally include a perpetual license as well *
* as providing for priority support and updates. They also fund the *
* continued development of RFIDler. Please email sales@aperturelabs.com *
* for further information. *
* If you have received a written license agreement or contract for *
* Covered Software stating terms other than these, you may choose to use *
* and redistribute Covered Software under those terms instead of these. *
* *
* Source is provided to this software because we believe users have a *
* right to know exactly what a program is going to do before they run it. *
* This also allows you to audit the software for security holes (none *
* have been found so far). *
* *
* Source code also allows you to port RFIDler to new platforms, fix bugs, *
* and add new features. You are highly encouraged to send your changes *
* to the RFIDler mailing list for possible incorporation into the *
* main distribution. By sending these changes to Aperture Labs Ltd. or *
* one of the Aperture Labs Ltd. development mailing lists, or checking *
* them into the RFIDler source code repository, it is understood (unless *
* you specify otherwise) that you are offering the RFIDler Project *
* (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, *
* modify, and relicense the code. RFIDler will always be available Open *
* Source, but this is important because the inability to relicense code *
* has caused devastating problems for other Free Software projects (such *
* as KDE and NASM). We also occasionally relicense the code to third *
* parties as discussed above. If you wish to specify special license *
* conditions of your contributions, just say so when you send them. *
* *
* This program is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler *
* license file for more details (it's in a COPYING file included with *
* RFIDler, and also available from *
* https://github.com/ApertureLabsLtd/RFIDler/COPYING *
* *
***************************************************************************/
// Author: unknown.
// Modifications for RFIDler: Tony Naggs <tony.naggs@gmail.com>, Adam Laurie <adam@aperturelabs.com>
// uncomment this to build file as a standalone crypto test program
// #define UNIT_TEST
// also uncomment to include verbose debug prints
// #define TEST_DEBUG
//#include <GenericTypeDefs.h>
#include "HardwareProfile.h"
#include "rfidler.h"
#include "hitagcrypto.h"
#include "util.h"
#ifdef UNIT_TEST
#include <stdio.h>
#endif
#if defined(UNIT_TEST) && defined(TEST_DEBUG)
// Note that printf format %I64x prints 64 bit ints in MS Visual C/C++.
// This may need changing for other compilers/platforms.
#define DEBUG_PRINTF(...) printf(__VA_ARGS__)
#else
#define DEBUG_PRINTF(...)
#endif
/* Brief info about NXP Hitag 1, Hitag 2, Hitag S and Hitag u (mu)
Hitag 125kHz RFID was created by a company called Mikron (Mikron Gesellschaft
fur Integrierte Mikroelektronik Mbh), of Austria, for micropayment applications.
At about the same time, late 1980s to early 1990s, Mikron developed the
similarly featured Mifare micropayment card for 13.56MHz RFID.
(Mikron's European Patent EP 0473569 A2 was filed 23 August 1991, with a
priority date of 23 Aug 1990.)
Mikron was subsequently acquired by Philips Semiconductors in 1995.
Philips Semiconductors divsion subsequently became NXP.
+ Modulation read/write device -> transponder: 100 % ASK and binary pulse
length coding
+ Modulation transponder -> read/write device: Strong ASK modulation,
selectable Manchester or Biphase coding
+ Hitag S, Hitag u; anti-collision procedure
+ Fast anti-collision protocol
+ Hitag u; optional Cyclic Redundancy Check (CRC)
+ Reader Talks First mode
+ Hitag 2 & later; Transponder Talks First (TTF) mode
+ Temporary switch from Transponder Talks First into Reader Talks First
(RTF) Mode
+ Data rate read/write device to transponder: 5.2 kbit/s
+ Data rates transponder to read/write device: 2 kbit/s, 4 kbit/s, 8 kbit/s
+ 32-bit password feature
+ Hitag 2, S = 32-bit Unique Identifier
+ Hitag u = 48-bit Unique Identifier
+ Selectable password modes for reader / tag mutual authentication
(Hitag 1 has 2 pairs of keys, later versions have 1 pair)
+ Hitag 2 & Hitag S; Selectable encrypted mode, 48 bit key
Known tag types:
HITAG 1 2048 bits total memory
HITAG 2 256 Bit total memory Read/Write
8 pages of 32 bits, inc UID (32),
secret key (64), password (24), config (8)
HITAG S 32 32 bits Unique Identifier Read Only
HITAG S 256 256 bits total memory Read/Write
HITAG S 2048 2048 bits total memory Read/Write
HITAG u RO64 64 bits total memory Read Only
HITAG u 128 bits total memory Read/Write
HITAG u Advanced 512 bits total memory Read/Write
HITAG u Advanced+ 1760 bits total memory Read/Write
Default 48-bit key for Hitag 2, S encryption:
"MIKRON" = O N M I K R
Key = 4F 4E 4D 49 4B 52
*/
// We want the crypto functions to be as fast as possible, so optimize!
// The best compiler optimization in Microchip's free XC32 edition is -O1
#pragma GCC optimize("O1")
// private, nonlinear function to generate 1 crypto bit
static uint32_t hitag2_crypt(uint64_t x);
// macros to pick out 4 bits in various patterns of 1s & 2s & make a new number
#define pickbits2_2(S, A, B) ( ((S >> A) & 3) | ((S >> (B - 2)) & 0xC) )
#define pickbits1x4(S, A, B, C, D) ( ((S >> A) & 1) | ((S >> (B - 1)) & 2) | \
((S >> (C - 2)) & 4) | ((S >> (D - 3)) & 8) )
#define pickbits1_1_2(S, A, B, C) ( ((S >> A) & 1) | ((S >> (B - 1)) & 2) | \
((S >> (C - 2)) & 0xC) )
#define pickbits2_1_1(S, A, B, C) ( ((S >> A) & 3) | ((S >> (B - 2)) & 4) | \
((S >> (C - 3)) & 8) )
#define pickbits1_2_1(S, A, B, C) ( ((S >> A) & 1) | ((S >> (B - 1)) & 6) | \
((S >> (C - 3)) & 8) )
static uint32_t hitag2_crypt(uint64_t x) {
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(x, 1, 4)) & 1;
bitindex |= ((ht2_function4b << 1) >> pickbits1_1_2(x, 7, 11, 13)) & 0x02;
bitindex |= ((ht2_function4b << 2) >> pickbits1x4(x, 16, 20, 22, 25)) & 0x04;
bitindex |= ((ht2_function4b << 3) >> pickbits2_1_1(x, 27, 30, 32)) & 0x08;
bitindex |= ((ht2_function4a << 4) >> pickbits1_2_1(x, 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
+167
View File
@@ -0,0 +1,167 @@
/***************************************************************************
* A copy of the GNU GPL is appended to this file. *
* *
* This licence is based on the nmap licence, and we express our gratitude *
* for the work that went into producing it. There is no other connection *
* between RFIDler and nmap either expressed or implied. *
* *
********************** IMPORTANT RFIDler LICENSE TERMS ********************
* *
* *
* All references to RFIDler herein imply all it's derivatives, namely: *
* *
* o RFIDler-LF Standard *
* o RFIDler-LF Lite *
* o RFIDler-LF Nekkid *
* *
* *
* RFIDler is (C) 2013-2014 Aperture Labs Ltd. *
* *
* This program is free software; you may redistribute and/or modify it *
* under the terms of the GNU General Public License as published by the *
* Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE *
* CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your *
* right to use, modify, and redistribute this software under certain *
* conditions. If you wish to embed RFIDler technology into proprietary *
* software or hardware, we sell alternative licenses *
* (contact sales@aperturelabs.com). *
* *
* Note that the GPL places important restrictions on "derivative works", *
* yet it does not provide a detailed definition of that term. To avoid *
* misunderstandings, we interpret that term as broadly as copyright law *
* allows. For example, we consider an application to constitute a *
* derivative work for the purpose of this license if it does any of the *
* following with any software or content covered by this license *
* ("Covered Software"): *
* *
* o Integrates source code from Covered Software. *
* *
* o Is designed specifically to execute Covered Software and parse the *
* results (as opposed to typical shell or execution-menu apps, which will *
* execute anything you tell them to). *
* *
* o Includes Covered Software in a proprietary executable installer. The *
* installers produced by InstallShield are an example of this. Including *
* RFIDler with other software in compressed or archival form does not *
* trigger this provision, provided appropriate open source decompression *
* or de-archiving software is widely available for no charge. For the *
* purposes of this license, an installer is considered to include Covered *
* Software even if it actually retrieves a copy of Covered Software from *
* another source during runtime (such as by downloading it from the *
* Internet). *
* *
* o Links (statically or dynamically) to a library which does any of the *
* above. *
* *
* o Executes a helper program, module, or script to do any of the above. *
* *
* This list is not exclusive, but is meant to clarify our interpretation *
* of derived works with some common examples. Other people may interpret *
* the plain GPL differently, so we consider this a special exception to *
* the GPL that we apply to Covered Software. Works which meet any of *
* these conditions must conform to all of the terms of this license, *
* particularly including the GPL Section 3 requirements of providing *
* source code and allowing free redistribution of the work as a whole. *
* *
* As another special exception to the GPL terms, Aperture Labs Ltd. grants*
* permission to link the code of this program with any version of the *
* OpenSSL library which is distributed under a license identical to that *
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
* linked combinations including the two. *
* *
* Any redistribution of Covered Software, including any derived works, *
* must obey and carry forward all of the terms of this license, including *
* obeying all GPL rules and restrictions. For example, source code of *
* the whole work must be provided and free redistribution must be *
* allowed. All GPL references to "this License", are to be treated as *
* including the terms and conditions of this license text as well. *
* *
* Because this license imposes special exceptions to the GPL, Covered *
* Work may not be combined (even as part of a larger work) with plain GPL *
* software. The terms, conditions, and exceptions of this license must *
* be included as well. This license is incompatible with some other open *
* source licenses as well. In some cases we can relicense portions of *
* RFIDler or grant special permissions to use it in other open source *
* software. Please contact sales@aperturelabs.com with any such requests.*
* Similarly, we don't incorporate incompatible open source software into *
* Covered Software without special permission from the copyright holders. *
* *
* If you have any questions about the licensing restrictions on using *
* RFIDler in other works, are happy to help. As mentioned above, we also *
* offer alternative license to integrate RFIDler into proprietary *
* applications and appliances. These contracts have been sold to dozens *
* of software vendors, and generally include a perpetual license as well *
* as providing for priority support and updates. They also fund the *
* continued development of RFIDler. Please email sales@aperturelabs.com *
* for further information. *
* If you have received a written license agreement or contract for *
* Covered Software stating terms other than these, you may choose to use *
* and redistribute Covered Software under those terms instead of these. *
* *
* Source is provided to this software because we believe users have a *
* right to know exactly what a program is going to do before they run it. *
* This also allows you to audit the software for security holes (none *
* have been found so far). *
* *
* Source code also allows you to port RFIDler to new platforms, fix bugs, *
* and add new features. You are highly encouraged to send your changes *
* to the RFIDler mailing list for possible incorporation into the *
* main distribution. By sending these changes to Aperture Labs Ltd. or *
* one of the Aperture Labs Ltd. development mailing lists, or checking *
* them into the RFIDler source code repository, it is understood (unless *
* you specify otherwise) that you are offering the RFIDler Project *
* (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, *
* modify, and relicense the code. RFIDler will always be available Open *
* Source, but this is important because the inability to relicense code *
* has caused devastating problems for other Free Software projects (such *
* as KDE and NASM). We also occasionally relicense the code to third *
* parties as discussed above. If you wish to specify special license *
* conditions of your contributions, just say so when you send them. *
* *
* This program is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler *
* license file for more details (it's in a COPYING file included with *
* RFIDler, and also available from *
* https://github.com/ApertureLabsLtd/RFIDler/COPYING *
* *
***************************************************************************/
// Author: unknown.
// Modifications for RFIDler: Tony Naggs <tony.naggs@gmail.com>, Adam Laurie <adam@aperturelabs.com>
#ifndef HITAGCRYPTO_H
#define HITAGCRYPTO_H
#include <stdint.h>
/*
Our model of Hitag 2 crypto uses 2 parallel shift registers:
a. 48 bit Feedback Shift Register, required for inputs to the nonlinear function.
b. 48 bit Linear Feedback Shift Register (LFSR).
A transform of initial register (a) value, which is then run in parallel.
Enables much faster calculation of the feedback values.
API:
void hitag2_init(Hitag_State* pstate, uint64_t sharedkey, uint32_t serialnum,
uint32_t initvector);
Initialise state from 48 bit shared (secret) reader/tag key,
32 bit tag serial number and 32 bit initialisation vector from reader.
uint32_t hitag2_nstep(Hitag_State* pstate, uint32_t steps);
update shift register state and generate N cipher bits (N should be <= 32)
*/
typedef struct {
uint64_t shiftreg; // naive shift register, required for nonlinear fn input
uint64_t lfsr; // fast lfsr, used to make software faster
} Hitag_State;
void hitag2_init(Hitag_State *pstate, uint64_t sharedkey, uint32_t serialnum, uint32_t initvector);
uint32_t hitag2_nstep(Hitag_State *pstate, uint32_t steps);
#endif /* HITAGCRYPTO_H */
+172
View File
@@ -0,0 +1,172 @@
#include "ht2crack2utils.h"
// writes a value into a buffer as a series of bytes
void writebuf(unsigned char *buf, uint64_t val, unsigned int len) {
int i;
char c;
for (i = len - 1; i >= 0; i--) {
c = val & 0xff;
buf[i] = c;
val = val >> 8;
}
}
/* simple hexdump for testing purposes */
void shexdump(unsigned char *data, int data_len) {
int i;
if (!data || (data_len <= 0)) {
printf("shexdump: invalid parameters\n");
return;
}
printf("Hexdump from %p:\n", data);
for (i = 0; i < data_len; i++) {
if ((i % HEX_PER_ROW) == 0) {
printf("\n0x%04x: ", i);
}
printf("%02x ", data[i]);
}
printf("\n\n");
}
void printbin(unsigned char *c) {
int i, j;
unsigned char x;
if (!c) {
printf("printbin: invalid params\n");
return;
}
for (i = 0; i < 6; i++) {
x = c[i];
for (j = 0; j < 8; j++) {
printf("%d", (x & 0x80) >> 7);
x = x << 1;
}
}
printf("\n");
}
void printbin2(uint64_t val, unsigned int size) {
int i;
uint64_t mask = 1;
mask = mask << (size - 1);
for (i = 0; i < size; i++) {
if (val & mask) {
printf("1");
} else {
printf("0");
}
val = val << 1;
}
}
void printstate(Hitag_State *hstate) {
printf("shiftreg =\t");
printbin2(hstate->shiftreg, 48);
printf("\n");
}
// convert hex char to binary
unsigned char hex2bin(unsigned char c) {
if ((c >= '0') && (c <= '9')) {
return (c - '0');
} else if ((c >= 'a') && (c <= 'f')) {
return (c - 'a' + 10);
} else if ((c >= 'A') && (c <= 'F')) {
return (c - 'A' + 10);
} else {
return 0;
}
}
// return a single bit from a value
int bitn(uint64_t x, int bit) {
uint64_t bitmask = 1;
bitmask = bitmask << bit;
if (x & bitmask) {
return 1;
} else {
return 0;
}
}
// the sub-function R that rollback depends upon
int fnR(uint64_t x) {
// renumbered bits because my state is 0-47, not 1-48
return (bitn(x, 1) ^ bitn(x, 2) ^ bitn(x, 5) ^ bitn(x, 6) ^ bitn(x, 7) ^
bitn(x, 15) ^ bitn(x, 21) ^ bitn(x, 22) ^ bitn(x, 25) ^ bitn(x, 29) ^ bitn(x, 40) ^
bitn(x, 41) ^ bitn(x, 42) ^ bitn(x, 45) ^ bitn(x, 46) ^ bitn(x, 47));
}
// the rollback function that lets us go backwards in time
void rollback(Hitag_State *hstate, unsigned int steps) {
int i;
for (i = 0; i < steps; i++) {
hstate->shiftreg = ((hstate->shiftreg << 1) & 0xffffffffffff) | fnR(hstate->shiftreg);
}
}
// the three filter sub-functions that feed fnf
int fa(unsigned int i) {
return bitn(0x2C79, i);
}
int fb(unsigned int i) {
return bitn(0x6671, i);
}
int fc(unsigned int i) {
return bitn(0x7907287B, i);
}
// the filter function that generates a bit of output from the prng state
int fnf(uint64_t s) {
unsigned int x1, x2, x3, x4, x5, x6;
x1 = (bitn(s, 2) << 0) | (bitn(s, 3) << 1) | (bitn(s, 5) << 2) | (bitn(s, 6) << 3);
x2 = (bitn(s, 8) << 0) | (bitn(s, 12) << 1) | (bitn(s, 14) << 2) | (bitn(s, 15) << 3);
x3 = (bitn(s, 17) << 0) | (bitn(s, 21) << 1) | (bitn(s, 23) << 2) | (bitn(s, 26) << 3);
x4 = (bitn(s, 28) << 0) | (bitn(s, 29) << 1) | (bitn(s, 31) << 2) | (bitn(s, 33) << 3);
x5 = (bitn(s, 34) << 0) | (bitn(s, 43) << 1) | (bitn(s, 44) << 2) | (bitn(s, 46) << 3);
x6 = (fa(x1) << 0) | (fb(x2) << 1) | (fb(x3) << 2) | (fb(x4) << 3) | (fa(x5) << 4);
return fc(x6);
}
// builds the lfsr for the prng (quick calcs for hitag2_nstep())
void buildlfsr(Hitag_State *hstate) {
uint64_t state = hstate->shiftreg;
uint64_t temp;
temp = state ^ (state >> 1);
hstate->lfsr = state ^ (state >> 6) ^ (state >> 16)
^ (state >> 26) ^ (state >> 30) ^ (state >> 41)
^ (temp >> 2) ^ (temp >> 7) ^ (temp >> 22)
^ (temp >> 42) ^ (temp >> 46);
}
+35
View File
@@ -0,0 +1,35 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>
#include "HardwareProfile.h"
#include "rfidler.h"
#include "util.h"
#include "hitagcrypto.h"
#define HEX_PER_ROW 16
void writebuf(unsigned char *buf, uint64_t val, unsigned int len);
void shexdump(unsigned char *data, int data_len);
void printbin(unsigned char *c);
void printbin2(uint64_t val, unsigned int size);
void printstate(Hitag_State *hstate);
unsigned char hex2bin(unsigned char c);
int bitn(uint64_t x, int bit);
int fnR(uint64_t x);
void rollback(Hitag_State *hstate, unsigned int steps);
int fa(unsigned int i);
int fb(unsigned int i);
int fc(unsigned int i);
int fnf(uint64_t s);
void buildlfsr(Hitag_State *hstate);
File diff suppressed because it is too large Load Diff
+412
View File
@@ -0,0 +1,412 @@
/***************************************************************************
* A copy of the GNU GPL is appended to this file. *
* *
* This licence is based on the nmap licence, and we express our gratitude *
* for the work that went into producing it. There is no other connection *
* between RFIDler and nmap either expressed or implied. *
* *
********************** IMPORTANT RFIDler LICENSE TERMS ********************
* *
* *
* All references to RFIDler herein imply all it's derivatives, namely: *
* *
* o RFIDler-LF Standard *
* o RFIDler-LF Lite *
* o RFIDler-LF Nekkid *
* *
* *
* RFIDler is (C) 2013-2015 Aperture Labs Ltd. *
* *
* This program is free software; you may redistribute and/or modify it *
* under the terms of the GNU General Public License as published by the *
* Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE *
* CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your *
* right to use, modify, and redistribute this software under certain *
* conditions. If you wish to embed RFIDler technology into proprietary *
* software or hardware, we sell alternative licenses *
* (contact sales@aperturelabs.com). *
* *
* Note that the GPL places important restrictions on "derivative works", *
* yet it does not provide a detailed definition of that term. To avoid *
* misunderstandings, we interpret that term as broadly as copyright law *
* allows. For example, we consider an application to constitute a *
* derivative work for the purpose of this license if it does any of the *
* following with any software or content covered by this license *
* ("Covered Software"): *
* *
* o Integrates source code from Covered Software. *
* *
* o Is designed specifically to execute Covered Software and parse the *
* results (as opposed to typical shell or execution-menu apps, which will *
* execute anything you tell them to). *
* *
* o Includes Covered Software in a proprietary executable installer. The *
* installers produced by InstallShield are an example of this. Including *
* RFIDler with other software in compressed or archival form does not *
* trigger this provision, provided appropriate open source decompression *
* or de-archiving software is widely available for no charge. For the *
* purposes of this license, an installer is considered to include Covered *
* Software even if it actually retrieves a copy of Covered Software from *
* another source during runtime (such as by downloading it from the *
* Internet). *
* *
* o Links (statically or dynamically) to a library which does any of the *
* above. *
* *
* o Executes a helper program, module, or script to do any of the above. *
* *
* This list is not exclusive, but is meant to clarify our interpretation *
* of derived works with some common examples. Other people may interpret *
* the plain GPL differently, so we consider this a special exception to *
* the GPL that we apply to Covered Software. Works which meet any of *
* these conditions must conform to all of the terms of this license, *
* particularly including the GPL Section 3 requirements of providing *
* source code and allowing free redistribution of the work as a whole. *
* *
* As another special exception to the GPL terms, Aperture Labs Ltd. grants*
* permission to link the code of this program with any version of the *
* OpenSSL library which is distributed under a license identical to that *
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
* linked combinations including the two. *
* *
* Any redistribution of Covered Software, including any derived works, *
* must obey and carry forward all of the terms of this license, including *
* obeying all GPL rules and restrictions. For example, source code of *
* the whole work must be provided and free redistribution must be *
* allowed. All GPL references to "this License", are to be treated as *
* including the terms and conditions of this license text as well. *
* *
* Because this license imposes special exceptions to the GPL, Covered *
* Work may not be combined (even as part of a larger work) with plain GPL *
* software. The terms, conditions, and exceptions of this license must *
* be included as well. This license is incompatible with some other open *
* source licenses as well. In some cases we can relicense portions of *
* RFIDler or grant special permissions to use it in other open source *
* software. Please contact sales@aperturelabs.com with any such requests.*
* Similarly, we don't incorporate incompatible open source software into *
* Covered Software without special permission from the copyright holders. *
* *
* If you have any questions about the licensing restrictions on using *
* RFIDler in other works, are happy to help. As mentioned above, we also *
* offer alternative license to integrate RFIDler into proprietary *
* applications and appliances. These contracts have been sold to dozens *
* of software vendors, and generally include a perpetual license as well *
* as providing for priority support and updates. They also fund the *
* continued development of RFIDler. Please email sales@aperturelabs.com *
* for further information. *
* If you have received a written license agreement or contract for *
* Covered Software stating terms other than these, you may choose to use *
* and redistribute Covered Software under those terms instead of these. *
* *
* Source is provided to this software because we believe users have a *
* right to know exactly what a program is going to do before they run it. *
* This also allows you to audit the software for security holes (none *
* have been found so far). *
* *
* Source code also allows you to port RFIDler to new platforms, fix bugs, *
* and add new features. You are highly encouraged to send your changes *
* to the RFIDler mailing list for possible incorporation into the *
* main distribution. By sending these changes to Aperture Labs Ltd. or *
* one of the Aperture Labs Ltd. development mailing lists, or checking *
* them into the RFIDler source code repository, it is understood (unless *
* you specify otherwise) that you are offering the RFIDler Project *
* (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, *
* modify, and relicense the code. RFIDler will always be available Open *
* Source, but this is important because the inability to relicense code *
* has caused devastating problems for other Free Software projects (such *
* as KDE and NASM). We also occasionally relicense the code to third *
* parties as discussed above. If you wish to specify special license *
* conditions of your contributions, just say so when you send them. *
* *
* This program is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler *
* license file for more details (it's in a COPYING file included with *
* RFIDler, and also available from *
* https://github.com/ApertureLabsLtd/RFIDler/COPYING *
* *
***************************************************************************/
// Author: Adam Laurie <adam@aperturelabs.com>
#include <stdio.h>
#include <string.h>
// BCD hardware revision for usb descriptor (usb_descriptors.c)
#define RFIDLER_HW_VERSION 0x020
// max sizes in BITS
#define MAXBLOCKSIZE 512
#define MAXTAGSIZE 4096
#define MAXUID 512
#define TMP_LARGE_BUFF_LEN 2048
#define TMP_SMALL_BUFF_LEN 256
#define ANALOGUE_BUFF_LEN 8192
#define COMMS_BUFFER_SIZE 128
#define DETECT_BUFFER_SIZE 512
#define SAMPLEMASK ~(BIT_1 | BIT_0) // mask to remove two bottom bits from analogue sample - we will then use those for reader & bit period
// globals
extern BOOL WiegandOutput; // Output wiegand data whenenver UID is read
extern BYTE *EMU_Reset_Data; // Pointer to full array of bits as bytes, stored as 0x00/0x01, '*' terminated
extern BYTE *EMU_Data; // Pointer to current location in EMU_Reset_Data
extern BYTE EMU_ThisBit; // The next data bit to transmit
extern BYTE EMU_SubCarrier_T0; // Number of Frame Clocks for sub-carrier '0'
extern BYTE EMU_SubCarrier_T1; // Number of Frame Clocks for sub-carrier '1'
extern unsigned int EMU_Repeat; // Number of times to transmit full data set
extern BOOL EMU_Background; // Emulate in the background until told to stop
extern unsigned int EMU_DataBitRate; // Number of Frame Clocks per bit
extern BYTE TmpBits[TMP_LARGE_BUFF_LEN]; // Shared scratchpad
extern BYTE ReaderPeriod; // Flag for sample display
extern unsigned char Comms_In_Buffer[COMMS_BUFFER_SIZE]; // USB/Serial buffer
extern BYTE Interface; // user interface - CLI or API
extern BYTE CommsChannel; // user comms channel - USB or UART
extern BOOL FakeRead; // flag for analogue sampler to signal it wants access to buffers during read
extern BOOL PWD_Mode; // is this tag password protected?
extern BYTE Password[9]; // 32 bits as HEX string set with LOGIN
extern unsigned int Led_Count; // LED status counter, also used for entropy
extern unsigned long Reader_Bit_Count; // Reader ISR bit counter
extern char Previous; // Reader ISR previous bit type
// RWD (read/write device) coil state
extern BYTE RWD_State; // current state of RWD coil
extern unsigned int RWD_Fc; // field clock in uS
extern unsigned int RWD_Gap_Period; // length of command gaps in OC5 ticks
extern unsigned int RWD_Zero_Period; // length of '0' in OC5 ticks
extern unsigned int RWD_One_Period; // length of '1' in OC5 ticks
extern unsigned int RWD_Sleep_Period; // length of initial sleep to reset tag in OC5 ticks
extern unsigned int RWD_Wake_Period; // length required for tag to restart in OC5 ticks
extern unsigned int RWD_Wait_Switch_TX_RX; // length to wait when switching from TX to RX in OC5 ticks
extern unsigned int RWD_Wait_Switch_RX_TX; // length to wait when switching from RX to TX in OC5 ticks
extern unsigned int RWD_Post_Wait; // low level ISR wait period in OC5 ticks
extern unsigned int RWD_OC5_config; // Output Compare Module settings
extern unsigned int RWD_OC5_r; // Output Compare Module primary compare value
extern unsigned int RWD_OC5_rs; // Output Compare Module secondary compare value
extern BYTE RWD_Command_Buff[TMP_SMALL_BUFF_LEN]; // Command buffer, array of bits as bytes, stored as 0x00/0x01, '*' terminated
extern BYTE *RWD_Command_ThisBit; // Current command bit
extern BOOL Reader_ISR_State; // current state of reader ISR
// NVM variables
// timings etc. that want to survive a reboot should go here
typedef struct {
BYTE Name[7]; // will be set to "RFIDler" so we can test for new device
BYTE AutoRun[128]; // optional command to run at startup
unsigned char TagType;
unsigned int PSK_Quality;
unsigned int Timeout;
unsigned int Wiegand_Pulse;
unsigned int Wiegand_Gap;
BOOL Wiegand_IdleState;
unsigned int FrameClock;
unsigned char Modulation;
unsigned int DataRate;
unsigned int DataRateSub0;
unsigned int DataRateSub1;
unsigned int DataBits;
unsigned int DataBlocks;
unsigned int BlockSize;
unsigned char SyncBits;
BYTE Sync[4];
BOOL BiPhase;
BOOL Invert;
BOOL Manchester;
BOOL HalfDuplex;
unsigned int Repeat;
unsigned int PotLow;
unsigned int PotHigh;
unsigned int RWD_Gap_Period;
unsigned int RWD_Zero_Period;
unsigned int RWD_One_Period;
unsigned int RWD_Sleep_Period;
unsigned int RWD_Wake_Period;
unsigned int RWD_Wait_Switch_TX_RX;
unsigned int RWD_Wait_Switch_RX_TX;
} StoredConfig;
// somewhere to store TAG data. this will be interpreted according to the TAG
// type.
typedef struct {
BYTE TagType; // raw tag type
BYTE EmulatedTagType; // tag type this tag is configured to emulate
BYTE UID[MAXUID + 1]; // Null-terminated HEX string
BYTE Data[MAXTAGSIZE]; // raw data
unsigned char DataBlocks; // number of blocks in Data field
unsigned int BlockSize; // blocksize in bits
} VirtualTag;
extern StoredConfig RFIDlerConfig;
extern VirtualTag RFIDlerVTag;
extern BYTE TmpBuff[NVM_PAGE_SIZE];
extern BYTE DataBuff[ANALOGUE_BUFF_LEN];
extern unsigned int DataBuffCount;
extern const BYTE *ModulationSchemes[];
extern const BYTE *OnOff[];
extern const BYTE *HighLow[];
extern const BYTE *TagTypes[];
// globals for ISRs
extern BYTE EmulationMode;
extern unsigned long HW_Bits;
extern BYTE HW_Skip_Bits;
extern unsigned int PSK_Min_Pulse;
extern BOOL PSK_Read_Error;
extern BOOL Manchester_Error;
extern BOOL SnifferMode;
extern unsigned int Clock_Tick_Counter;
extern BOOL Clock_Tick_Counter_Reset;
// smart card lib
#define MAX_ATR_LEN (BYTE)33
extern BYTE scCardATR[MAX_ATR_LEN];
extern BYTE scATRLength;
// RTC
extern rtccTime RTC_time; // time structure
extern rtccDate RTC_date; // date structure
// digital pots
#define POTLOW_DEFAULT 100
#define POTHIGH_DEFAULT 150
#define DC_OFFSET 60 // analogue circuit DC offset (as close as we can get without using 2 LSB)
#define VOLTS_TO_POT 0.019607843F
// RWD/clock states
#define RWD_STATE_INACTIVE 0 // RWD not in use
#define RWD_STATE_GO_TO_SLEEP 1 // RWD coil shutdown request
#define RWD_STATE_SLEEPING 2 // RWD coil shutdown for sleep period
#define RWD_STATE_WAKING 3 // RWD active for pre-determined period after reset
#define RWD_STATE_START_SEND 4 // RWD starting send of data
#define RWD_STATE_SENDING_GAP 5 // RWD sending a gap
#define RWD_STATE_SENDING_BIT 6 // RWD sending a data bit
#define RWD_STATE_POST_WAIT 7 // RWD finished sending data, now in forced wait period
#define RWD_STATE_ACTIVE 8 // RWD finished, now just clocking a carrier
// reader ISR states
#define READER_STOPPED 0 // reader not in use
#define READER_IDLING 1 // reader ISR running to preserve timing, but not reading
#define READER_RUNNING 2 // reader reading bits
// user interface types
#define INTERFACE_API 0
#define INTERFACE_CLI 1
// comms channel
#define COMMS_NONE 0
#define COMMS_USB 1
#define COMMS_UART 2
#define MAX_HISTORY 2 // disable most of history for now - memory issue
// tag write retries
#define TAG_WRITE_RETRY 5
// modulation modes - uppdate ModulationSchemes[] in tags.c if you change this
#define MOD_MODE_NONE 0
#define MOD_MODE_ASK_OOK 1
#define MOD_MODE_FSK1 2
#define MOD_MODE_FSK2 3
#define MOD_MODE_PSK1 4
#define MOD_MODE_PSK2 5
#define MOD_MODE_PSK3 6
// TAG types - update TagTypes[] in tags.c if you add to this list
#define TAG_TYPE_NONE 0
#define TAG_TYPE_ASK_RAW 1
#define TAG_TYPE_FSK1_RAW 2
#define TAG_TYPE_FSK2_RAW 3
#define TAG_TYPE_PSK1_RAW 4
#define TAG_TYPE_PSK2_RAW 5
#define TAG_TYPE_PSK3_RAW 6
#define TAG_TYPE_HITAG1 7
#define TAG_TYPE_HITAG2 8
#define TAG_TYPE_EM4X02 9
#define TAG_TYPE_Q5 10
#define TAG_TYPE_HID_26 11
#define TAG_TYPE_INDALA_64 12
#define TAG_TYPE_INDALA_224 13
#define TAG_TYPE_UNIQUE 14
#define TAG_TYPE_FDXB 15
#define TAG_TYPE_T55X7 16 // same as Q5 but different timings and no modulation-defeat
#define TAG_TYPE_AWID_26 17
#define TAG_TYPE_EM4X05 18
#define TAG_TYPE_TAMAGOTCHI 19
#define TAG_TYPE_HDX 20 // same underlying data as FDX-B, but different modulation & telegram
// various
#define BINARY 0
#define HEX 1
#define NO_ADDRESS -1
#define ACK TRUE
#define NO_ACK FALSE
#define BLOCK TRUE
#define NO_BLOCK FALSE
#define DATA TRUE
#define NO_DATA FALSE
#define DEBUG_PIN_ON HIGH
#define DEBUG_PIN_OFF LOW
#define FAST FALSE
#define SLOW TRUE
#define NO_TRIGGER 0
#define LOCK TRUE
#define NO_LOCK FALSE
#define NFC_MODE TRUE
#define NO_NFC_MODE FALSE
#define ONESHOT_READ TRUE
#define NO_ONESHOT_READ FALSE
#define RESET TRUE
#define NO_RESET FALSE
#define SHUTDOWN_CLOCK TRUE
#define NO_SHUTDOWN_CLOCK FALSE
#define SYNC TRUE
#define NO_SYNC FALSE
#define VERIFY TRUE
#define NO_VERIFY FALSE
#define VOLATILE FALSE
#define NON_VOLATILE TRUE
#define NEWLINE TRUE
#define NO_NEWLINE FALSE
#define WAIT TRUE
#define NO_WAIT FALSE
#define WIPER_HIGH 0
#define WIPER_LOW 1
// conversion for time to ticks
#define US_TO_TICKS 1000000L
#define US_OVER_10_TO_TICKS 10000000L
#define US_OVER_100_TO_TICKS 100000000L
// we can't get down to this level on pic, but we want to standardise on timings, so for now we fudge it
#define CONVERT_TO_TICKS(x) ((x / 10) * (GetSystemClock() / US_OVER_10_TO_TICKS))
#define CONVERT_TICKS_TO_US(x) (x / (GetSystemClock() / US_TO_TICKS))
#define TIMER5_PRESCALER 16
#define MAX_TIMER5_TICKS (65535 * TIMER5_PRESCALER)
// other conversions
// bits to hex digits
#define HEXDIGITS(x) (x / 4)
#define HEXTOBITS(x) (x * 4)
+147
View File
@@ -0,0 +1,147 @@
/***************************************************************************
* A copy of the GNU GPL is appended to this file. *
* *
* This licence is based on the nmap licence, and we express our gratitude *
* for the work that went into producing it. There is no other connection *
* between RFIDler and nmap either expressed or implied. *
* *
********************** IMPORTANT RFIDler LICENSE TERMS ********************
* *
* *
* All references to RFIDler herein imply all it's derivatives, namely: *
* *
* o RFIDler-LF Standard *
* o RFIDler-LF Lite *
* o RFIDler-LF Nekkid *
* *
* *
* RFIDler is (C) 2013-2015 Aperture Labs Ltd. *
* *
* This program is free software; you may redistribute and/or modify it *
* under the terms of the GNU General Public License as published by the *
* Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE *
* CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your *
* right to use, modify, and redistribute this software under certain *
* conditions. If you wish to embed RFIDler technology into proprietary *
* software or hardware, we sell alternative licenses *
* (contact sales@aperturelabs.com). *
* *
* Note that the GPL places important restrictions on "derivative works", *
* yet it does not provide a detailed definition of that term. To avoid *
* misunderstandings, we interpret that term as broadly as copyright law *
* allows. For example, we consider an application to constitute a *
* derivative work for the purpose of this license if it does any of the *
* following with any software or content covered by this license *
* ("Covered Software"): *
* *
* o Integrates source code from Covered Software. *
* *
* o Is designed specifically to execute Covered Software and parse the *
* results (as opposed to typical shell or execution-menu apps, which will *
* execute anything you tell them to). *
* *
* o Includes Covered Software in a proprietary executable installer. The *
* installers produced by InstallShield are an example of this. Including *
* RFIDler with other software in compressed or archival form does not *
* trigger this provision, provided appropriate open source decompression *
* or de-archiving software is widely available for no charge. For the *
* purposes of this license, an installer is considered to include Covered *
* Software even if it actually retrieves a copy of Covered Software from *
* another source during runtime (such as by downloading it from the *
* Internet). *
* *
* o Links (statically or dynamically) to a library which does any of the *
* above. *
* *
* o Executes a helper program, module, or script to do any of the above. *
* *
* This list is not exclusive, but is meant to clarify our interpretation *
* of derived works with some common examples. Other people may interpret *
* the plain GPL differently, so we consider this a special exception to *
* the GPL that we apply to Covered Software. Works which meet any of *
* these conditions must conform to all of the terms of this license, *
* particularly including the GPL Section 3 requirements of providing *
* source code and allowing free redistribution of the work as a whole. *
* *
* As another special exception to the GPL terms, Aperture Labs Ltd. grants*
* permission to link the code of this program with any version of the *
* OpenSSL library which is distributed under a license identical to that *
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
* linked combinations including the two. *
* *
* Any redistribution of Covered Software, including any derived works, *
* must obey and carry forward all of the terms of this license, including *
* obeying all GPL rules and restrictions. For example, source code of *
* the whole work must be provided and free redistribution must be *
* allowed. All GPL references to "this License", are to be treated as *
* including the terms and conditions of this license text as well. *
* *
* Because this license imposes special exceptions to the GPL, Covered *
* Work may not be combined (even as part of a larger work) with plain GPL *
* software. The terms, conditions, and exceptions of this license must *
* be included as well. This license is incompatible with some other open *
* source licenses as well. In some cases we can relicense portions of *
* RFIDler or grant special permissions to use it in other open source *
* software. Please contact sales@aperturelabs.com with any such requests.*
* Similarly, we don't incorporate incompatible open source software into *
* Covered Software without special permission from the copyright holders. *
* *
* If you have any questions about the licensing restrictions on using *
* RFIDler in other works, are happy to help. As mentioned above, we also *
* offer alternative license to integrate RFIDler into proprietary *
* applications and appliances. These contracts have been sold to dozens *
* of software vendors, and generally include a perpetual license as well *
* as providing for priority support and updates. They also fund the *
* continued development of RFIDler. Please email sales@aperturelabs.com *
* for further information. *
* If you have received a written license agreement or contract for *
* Covered Software stating terms other than these, you may choose to use *
* and redistribute Covered Software under those terms instead of these. *
* *
* Source is provided to this software because we believe users have a *
* right to know exactly what a program is going to do before they run it. *
* This also allows you to audit the software for security holes (none *
* have been found so far). *
* *
* Source code also allows you to port RFIDler to new platforms, fix bugs, *
* and add new features. You are highly encouraged to send your changes *
* to the RFIDler mailing list for possible incorporation into the *
* main distribution. By sending these changes to Aperture Labs Ltd. or *
* one of the Aperture Labs Ltd. development mailing lists, or checking *
* them into the RFIDler source code repository, it is understood (unless *
* you specify otherwise) that you are offering the RFIDler Project *
* (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, *
* modify, and relicense the code. RFIDler will always be available Open *
* Source, but this is important because the inability to relicense code *
* has caused devastating problems for other Free Software projects (such *
* as KDE and NASM). We also occasionally relicense the code to third *
* parties as discussed above. If you wish to specify special license *
* conditions of your contributions, just say so when you send them. *
* *
* This program is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler *
* license file for more details (it's in a COPYING file included with *
* RFIDler, and also available from *
* https://github.com/ApertureLabsLtd/RFIDler/COPYING *
* *
***************************************************************************/
// Author: Adam Laurie <adam@aperturelabs.com>
/*
* Hitag Crypto support macros
* These macros reverse the bit order in a byte, or *within* each byte of a
* 16 , 32 or 64 bit unsigned integer. (Not across the whole 16 etc bits.)
*/
#define rev8(X) ((((X) >> 7) &1) + (((X) >> 5) &2) + (((X) >> 3) &4) \
+ (((X) >> 1) &8) + (((X) << 1) &16) + (((X) << 3) &32) \
+ (((X) << 5) &64) + (((X) << 7) &128) )
#define rev16(X) (rev8 (X) + (rev8 (X >> 8) << 8))
#define rev32(X) (rev16(X) + (rev16(X >> 16) << 16))
#define rev64(X) (rev32(X) + (rev32(X >> 32) << 32))
unsigned long hexreversetoulong(BYTE *hex);
unsigned long long hexreversetoulonglong(BYTE *hex);
+180
View File
@@ -0,0 +1,180 @@
/***************************************************************************
* A copy of the GNU GPL is appended to this file. *
* *
* This licence is based on the nmap licence, and we express our gratitude *
* for the work that went into producing it. There is no other connection *
* between RFIDler and nmap either expressed or implied. *
* *
********************** IMPORTANT RFIDler LICENSE TERMS ********************
* *
* *
* All references to RFIDler herein imply all it's derivatives, namely: *
* *
* o RFIDler-LF Standard *
* o RFIDler-LF Lite *
* o RFIDler-LF Nekkid *
* *
* *
* RFIDler is (C) 2013-2014 Aperture Labs Ltd. *
* *
* This program is free software; you may redistribute and/or modify it *
* under the terms of the GNU General Public License as published by the *
* Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE *
* CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your *
* right to use, modify, and redistribute this software under certain *
* conditions. If you wish to embed RFIDler technology into proprietary *
* software or hardware, we sell alternative licenses *
* (contact sales@aperturelabs.com). *
* *
* Note that the GPL places important restrictions on "derivative works", *
* yet it does not provide a detailed definition of that term. To avoid *
* misunderstandings, we interpret that term as broadly as copyright law *
* allows. For example, we consider an application to constitute a *
* derivative work for the purpose of this license if it does any of the *
* following with any software or content covered by this license *
* ("Covered Software"): *
* *
* o Integrates source code from Covered Software. *
* *
* o Is designed specifically to execute Covered Software and parse the *
* results (as opposed to typical shell or execution-menu apps, which will *
* execute anything you tell them to). *
* *
* o Includes Covered Software in a proprietary executable installer. The *
* installers produced by InstallShield are an example of this. Including *
* RFIDler with other software in compressed or archival form does not *
* trigger this provision, provided appropriate open source decompression *
* or de-archiving software is widely available for no charge. For the *
* purposes of this license, an installer is considered to include Covered *
* Software even if it actually retrieves a copy of Covered Software from *
* another source during runtime (such as by downloading it from the *
* Internet). *
* *
* o Links (statically or dynamically) to a library which does any of the *
* above. *
* *
* o Executes a helper program, module, or script to do any of the above. *
* *
* This list is not exclusive, but is meant to clarify our interpretation *
* of derived works with some common examples. Other people may interpret *
* the plain GPL differently, so we consider this a special exception to *
* the GPL that we apply to Covered Software. Works which meet any of *
* these conditions must conform to all of the terms of this license, *
* particularly including the GPL Section 3 requirements of providing *
* source code and allowing free redistribution of the work as a whole. *
* *
* As another special exception to the GPL terms, Aperture Labs Ltd. grants*
* permission to link the code of this program with any version of the *
* OpenSSL library which is distributed under a license identical to that *
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
* linked combinations including the two. *
* *
* Any redistribution of Covered Software, including any derived works, *
* must obey and carry forward all of the terms of this license, including *
* obeying all GPL rules and restrictions. For example, source code of *
* the whole work must be provided and free redistribution must be *
* allowed. All GPL references to "this License", are to be treated as *
* including the terms and conditions of this license text as well. *
* *
* Because this license imposes special exceptions to the GPL, Covered *
* Work may not be combined (even as part of a larger work) with plain GPL *
* software. The terms, conditions, and exceptions of this license must *
* be included as well. This license is incompatible with some other open *
* source licenses as well. In some cases we can relicense portions of *
* RFIDler or grant special permissions to use it in other open source *
* software. Please contact sales@aperturelabs.com with any such requests.*
* Similarly, we don't incorporate incompatible open source software into *
* Covered Software without special permission from the copyright holders. *
* *
* If you have any questions about the licensing restrictions on using *
* RFIDler in other works, are happy to help. As mentioned above, we also *
* offer alternative license to integrate RFIDler into proprietary *
* applications and appliances. These contracts have been sold to dozens *
* of software vendors, and generally include a perpetual license as well *
* as providing for priority support and updates. They also fund the *
* continued development of RFIDler. Please email sales@aperturelabs.com *
* for further information. *
* If you have received a written license agreement or contract for *
* Covered Software stating terms other than these, you may choose to use *
* and redistribute Covered Software under those terms instead of these. *
* *
* Source is provided to this software because we believe users have a *
* right to know exactly what a program is going to do before they run it. *
* This also allows you to audit the software for security holes (none *
* have been found so far). *
* *
* Source code also allows you to port RFIDler to new platforms, fix bugs, *
* and add new features. You are highly encouraged to send your changes *
* to the RFIDler mailing list for possible incorporation into the *
* main distribution. By sending these changes to Aperture Labs Ltd. or *
* one of the Aperture Labs Ltd. development mailing lists, or checking *
* them into the RFIDler source code repository, it is understood (unless *
* you specify otherwise) that you are offering the RFIDler Project *
* (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, *
* modify, and relicense the code. RFIDler will always be available Open *
* Source, but this is important because the inability to relicense code *
* has caused devastating problems for other Free Software projects (such *
* as KDE and NASM). We also occasionally relicense the code to third *
* parties as discussed above. If you wish to specify special license *
* conditions of your contributions, just say so when you send them. *
* *
* This program is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler *
* license file for more details (it's in a COPYING file included with *
* RFIDler, and also available from *
* https://github.com/ApertureLabsLtd/RFIDler/COPYING *
* *
***************************************************************************/
// Author: Adam Laurie <adam@aperturelabs.com>
#include <string.h>
#include <stdio.h>
#include "HardwareProfile.h"
#include "util.h"
#include "rfidler.h"
//#include "comms.h"
// rtc
rtccTime RTC_time; // time structure
rtccDate RTC_date; // date structure
// convert byte-reversed 8 digit hex to unsigned long
unsigned long hexreversetoulong(BYTE *hex) {
unsigned long ret = 0L;
unsigned int x;
BYTE i;
if (strlen(hex) != 8)
return 0L;
for (i = 0 ; i < 4 ; ++i) {
if (sscanf(hex, "%2X", &x) != 1)
return 0L;
ret += ((unsigned long) x) << i * 8;
hex += 2;
}
return ret;
}
// convert byte-reversed 12 digit hex to unsigned long
unsigned long long hexreversetoulonglong(BYTE *hex) {
unsigned long long ret = 0LL;
BYTE tmp[9];
// this may seem an odd way to do it, but weird compiler issues were
// breaking direct conversion!
tmp[8] = '\0';
memset(tmp + 4, '0', 4);
memcpy(tmp, hex + 8, 4);
ret = hexreversetoulong(tmp);
ret <<= 32;
memcpy(tmp, hex, 8);
ret += hexreversetoulong(tmp);
return ret;
}
File diff suppressed because it is too large Load Diff
+24
View File
@@ -0,0 +1,24 @@
CFLAGS?=-Wall
#INCLUDE=-I/usr/local/cuda-7.5/include
INCLUDE=-I/opt/nvidia/cuda/include
#Linux
#LIBS=-L/usr/local/cuda-7.5/lib64 -lOpenCL
LIBS=-L/opt/nvidia/cuda/lib64 -lOpenCL
#Mac
#LIBS=-framework OpenCL
all: ht2crack5.c utilpart.o ht2crack2utils.o hitagcrypto.o
$(CC) $(CFLAGS) ht2crack5.c -o ht2crack5gpu utilpart.o ht2crack2utils.o hitagcrypto.o $(LIBS) -lpthread
utilpart.o: util.h utilpart.c
$(CC) $(CFLAGS) $(INCLUDE) -c utilpart.c
hitagcrypto.o: hitagcrypto.h hitagcrypto.c
$(CC) $(CFLAGS) $(INCLUDE) -c hitagcrypto.c
ht2crack2utils.o: ht2crack2utils.h ht2crack2utils.c
$(CC) $(CFLAGS) $(INCLUDE) -c ht2crack2utils.c
clean:
rm -f *.o ht2crack5gpu
fresh: clean all
+27
View File
@@ -0,0 +1,27 @@
ht2crack5gpu
Build
-----
It requires an OpenCL framework.
If required, edit Makefile and adjust INCLUDE and LIBS directives to your setup.
```
make clean
make
```
Run
---
You'll need just two nR aR pairs. These are the
encrypted nonces and challenge response values. They should be in hex.
```
./ht2crack5gpu <UID> <nR1> <aR1> <nR2> <aR2>
```
UID is the UID of the tag that you used to gather the nR aR values.
+373
View File
@@ -0,0 +1,373 @@
/***************************************************************************
* A copy of the GNU GPL is appended to this file. *
* *
* This licence is based on the nmap licence, and we express our gratitude *
* for the work that went into producing it. There is no other connection *
* between RFIDler and nmap either expressed or implied. *
* *
********************** IMPORTANT RFIDler LICENSE TERMS ********************
* *
* *
* All references to RFIDler herein imply all it's derivatives, namely: *
* *
* o RFIDler-LF Standard *
* o RFIDler-LF Lite *
* o RFIDler-LF Nekkid *
* *
* *
* RFIDler is (C) 2013-2015 Aperture Labs Ltd. *
* *
* This program is free software; you may redistribute and/or modify it *
* under the terms of the GNU General Public License as published by the *
* Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE *
* CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your *
* right to use, modify, and redistribute this software under certain *
* conditions. If you wish to embed RFIDler technology into proprietary *
* software or hardware, we sell alternative licenses *
* (contact sales@aperturelabs.com). *
* *
* Note that the GPL places important restrictions on "derivative works", *
* yet it does not provide a detailed definition of that term. To avoid *
* misunderstandings, we interpret that term as broadly as copyright law *
* allows. For example, we consider an application to constitute a *
* derivative work for the purpose of this license if it does any of the *
* following with any software or content covered by this license *
* ("Covered Software"): *
* *
* o Integrates source code from Covered Software. *
* *
* o Is designed specifically to execute Covered Software and parse the *
* results (as opposed to typical shell or execution-menu apps, which will *
* execute anything you tell them to). *
* *
* o Includes Covered Software in a proprietary executable installer. The *
* installers produced by InstallShield are an example of this. Including *
* RFIDler with other software in compressed or archival form does not *
* trigger this provision, provided appropriate open source decompression *
* or de-archiving software is widely available for no charge. For the *
* purposes of this license, an installer is considered to include Covered *
* Software even if it actually retrieves a copy of Covered Software from *
* another source during runtime (such as by downloading it from the *
* Internet). *
* *
* o Links (statically or dynamically) to a library which does any of the *
* above. *
* *
* o Executes a helper program, module, or script to do any of the above. *
* *
* This list is not exclusive, but is meant to clarify our interpretation *
* of derived works with some common examples. Other people may interpret *
* the plain GPL differently, so we consider this a special exception to *
* the GPL that we apply to Covered Software. Works which meet any of *
* these conditions must conform to all of the terms of this license, *
* particularly including the GPL Section 3 requirements of providing *
* source code and allowing free redistribution of the work as a whole. *
* *
* As another special exception to the GPL terms, Aperture Labs Ltd. grants*
* permission to link the code of this program with any version of the *
* OpenSSL library which is distributed under a license identical to that *
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
* linked combinations including the two. *
* *
* Any redistribution of Covered Software, including any derived works, *
* must obey and carry forward all of the terms of this license, including *
* obeying all GPL rules and restrictions. For example, source code of *
* the whole work must be provided and free redistribution must be *
* allowed. All GPL references to "this License", are to be treated as *
* including the terms and conditions of this license text as well. *
* *
* Because this license imposes special exceptions to the GPL, Covered *
* Work may not be combined (even as part of a larger work) with plain GPL *
* software. The terms, conditions, and exceptions of this license must *
* be included as well. This license is incompatible with some other open *
* source licenses as well. In some cases we can relicense portions of *
* RFIDler or grant special permissions to use it in other open source *
* software. Please contact sales@aperturelabs.com with any such requests.*
* Similarly, we don't incorporate incompatible open source software into *
* Covered Software without special permission from the copyright holders. *
* *
* If you have any questions about the licensing restrictions on using *
* RFIDler in other works, are happy to help. As mentioned above, we also *
* offer alternative license to integrate RFIDler into proprietary *
* applications and appliances. These contracts have been sold to dozens *
* of software vendors, and generally include a perpetual license as well *
* as providing for priority support and updates. They also fund the *
* continued development of RFIDler. Please email sales@aperturelabs.com *
* for further information. *
* If you have received a written license agreement or contract for *
* Covered Software stating terms other than these, you may choose to use *
* and redistribute Covered Software under those terms instead of these. *
* *
* Source is provided to this software because we believe users have a *
* right to know exactly what a program is going to do before they run it. *
* This also allows you to audit the software for security holes (none *
* have been found so far). *
* *
* Source code also allows you to port RFIDler to new platforms, fix bugs, *
* and add new features. You are highly encouraged to send your changes *
* to the RFIDler mailing list for possible incorporation into the *
* main distribution. By sending these changes to Aperture Labs Ltd. or *
* one of the Aperture Labs Ltd. development mailing lists, or checking *
* them into the RFIDler source code repository, it is understood (unless *
* you specify otherwise) that you are offering the RFIDler Project *
* (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, *
* modify, and relicense the code. RFIDler will always be available Open *
* Source, but this is important because the inability to relicense code *
* has caused devastating problems for other Free Software projects (such *
* as KDE and NASM). We also occasionally relicense the code to third *
* parties as discussed above. If you wish to specify special license *
* conditions of your contributions, just say so when you send them. *
* *
* This program is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler *
* license file for more details (it's in a COPYING file included with *
* RFIDler, and also available from *
* https://github.com/ApertureLabsLtd/RFIDler/COPYING *
* *
***************************************************************************/
// Author: unknown.
// Modifications for RFIDler: Tony Naggs <tony.naggs@gmail.com>, Adam Laurie <adam@aperturelabs.com>
// uncomment this to build file as a standalone crypto test program
// #define UNIT_TEST
// also uncomment to include verbose debug prints
// #define TEST_DEBUG
//#include <GenericTypeDefs.h>
#include "HardwareProfile.h"
#include "rfidler.h"
#include "hitagcrypto.h"
#include "util.h"
#ifdef UNIT_TEST
#include <stdio.h>
#endif
#if defined(UNIT_TEST) && defined(TEST_DEBUG)
// Note that printf format %I64x prints 64 bit ints in MS Visual C/C++.
// This may need changing for other compilers/platforms.
#define DEBUG_PRINTF(...) printf(__VA_ARGS__)
#else
#define DEBUG_PRINTF(...)
#endif
/* Brief info about NXP Hitag 1, Hitag 2, Hitag S and Hitag u (mu)
Hitag 125kHz RFID was created by a company called Mikron (Mikron Gesellschaft
fur Integrierte Mikroelektronik Mbh), of Austria, for micropayment applications.
At about the same time, late 1980s to early 1990s, Mikron developed the
similarly featured Mifare micropayment card for 13.56MHz RFID.
(Mikron's European Patent EP 0473569 A2 was filed 23 August 1991, with a
priority date of 23 Aug 1990.)
Mikron was subsequently acquired by Philips Semiconductors in 1995.
Philips Semiconductors divsion subsequently became NXP.
+ Modulation read/write device -> transponder: 100 % ASK and binary pulse
length coding
+ Modulation transponder -> read/write device: Strong ASK modulation,
selectable Manchester or Biphase coding
+ Hitag S, Hitag u; anti-collision procedure
+ Fast anti-collision protocol
+ Hitag u; optional Cyclic Redundancy Check (CRC)
+ Reader Talks First mode
+ Hitag 2 & later; Transponder Talks First (TTF) mode
+ Temporary switch from Transponder Talks First into Reader Talks First
(RTF) Mode
+ Data rate read/write device to transponder: 5.2 kbit/s
+ Data rates transponder to read/write device: 2 kbit/s, 4 kbit/s, 8 kbit/s
+ 32-bit password feature
+ Hitag 2, S = 32-bit Unique Identifier
+ Hitag u = 48-bit Unique Identifier
+ Selectable password modes for reader / tag mutual authentication
(Hitag 1 has 2 pairs of keys, later versions have 1 pair)
+ Hitag 2 & Hitag S; Selectable encrypted mode, 48 bit key
Known tag types:
HITAG 1 2048 bits total memory
HITAG 2 256 Bit total memory Read/Write
8 pages of 32 bits, inc UID (32),
secret key (64), password (24), config (8)
HITAG S 32 32 bits Unique Identifier Read Only
HITAG S 256 256 bits total memory Read/Write
HITAG S 2048 2048 bits total memory Read/Write
HITAG u RO64 64 bits total memory Read Only
HITAG u 128 bits total memory Read/Write
HITAG u Advanced 512 bits total memory Read/Write
HITAG u Advanced+ 1760 bits total memory Read/Write
Default 48-bit key for Hitag 2, S encryption:
"MIKRON" = O N M I K R
Key = 4F 4E 4D 49 4B 52
*/
// We want the crypto functions to be as fast as possible, so optimize!
// The best compiler optimization in Microchip's free XC32 edition is -O1
#pragma GCC optimize("O1")
// private, nonlinear function to generate 1 crypto bit
static uint32_t hitag2_crypt(uint64_t x);
// macros to pick out 4 bits in various patterns of 1s & 2s & make a new number
#define pickbits2_2(S, A, B) ( ((S >> A) & 3) | ((S >> (B - 2)) & 0xC) )
#define pickbits1x4(S, A, B, C, D) ( ((S >> A) & 1) | ((S >> (B - 1)) & 2) | \
((S >> (C - 2)) & 4) | ((S >> (D - 3)) & 8) )
#define pickbits1_1_2(S, A, B, C) ( ((S >> A) & 1) | ((S >> (B - 1)) & 2) | \
((S >> (C - 2)) & 0xC) )
#define pickbits2_1_1(S, A, B, C) ( ((S >> A) & 3) | ((S >> (B - 2)) & 4) | \
((S >> (C - 3)) & 8) )
#define pickbits1_2_1(S, A, B, C) ( ((S >> A) & 1) | ((S >> (B - 1)) & 6) | \
((S >> (C - 3)) & 8) )
static uint32_t hitag2_crypt(uint64_t x) {
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(x, 1, 4)) & 1;
bitindex |= ((ht2_function4b << 1) >> pickbits1_1_2(x, 7, 11, 13)) & 0x02;
bitindex |= ((ht2_function4b << 2) >> pickbits1x4(x, 16, 20, 22, 25)) & 0x04;
bitindex |= ((ht2_function4b << 3) >> pickbits2_1_1(x, 27, 30, 32)) & 0x08;
bitindex |= ((ht2_function4a << 4) >> pickbits1_2_1(x, 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
+167
View File
@@ -0,0 +1,167 @@
/***************************************************************************
* A copy of the GNU GPL is appended to this file. *
* *
* This licence is based on the nmap licence, and we express our gratitude *
* for the work that went into producing it. There is no other connection *
* between RFIDler and nmap either expressed or implied. *
* *
********************** IMPORTANT RFIDler LICENSE TERMS ********************
* *
* *
* All references to RFIDler herein imply all it's derivatives, namely: *
* *
* o RFIDler-LF Standard *
* o RFIDler-LF Lite *
* o RFIDler-LF Nekkid *
* *
* *
* RFIDler is (C) 2013-2014 Aperture Labs Ltd. *
* *
* This program is free software; you may redistribute and/or modify it *
* under the terms of the GNU General Public License as published by the *
* Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE *
* CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your *
* right to use, modify, and redistribute this software under certain *
* conditions. If you wish to embed RFIDler technology into proprietary *
* software or hardware, we sell alternative licenses *
* (contact sales@aperturelabs.com). *
* *
* Note that the GPL places important restrictions on "derivative works", *
* yet it does not provide a detailed definition of that term. To avoid *
* misunderstandings, we interpret that term as broadly as copyright law *
* allows. For example, we consider an application to constitute a *
* derivative work for the purpose of this license if it does any of the *
* following with any software or content covered by this license *
* ("Covered Software"): *
* *
* o Integrates source code from Covered Software. *
* *
* o Is designed specifically to execute Covered Software and parse the *
* results (as opposed to typical shell or execution-menu apps, which will *
* execute anything you tell them to). *
* *
* o Includes Covered Software in a proprietary executable installer. The *
* installers produced by InstallShield are an example of this. Including *
* RFIDler with other software in compressed or archival form does not *
* trigger this provision, provided appropriate open source decompression *
* or de-archiving software is widely available for no charge. For the *
* purposes of this license, an installer is considered to include Covered *
* Software even if it actually retrieves a copy of Covered Software from *
* another source during runtime (such as by downloading it from the *
* Internet). *
* *
* o Links (statically or dynamically) to a library which does any of the *
* above. *
* *
* o Executes a helper program, module, or script to do any of the above. *
* *
* This list is not exclusive, but is meant to clarify our interpretation *
* of derived works with some common examples. Other people may interpret *
* the plain GPL differently, so we consider this a special exception to *
* the GPL that we apply to Covered Software. Works which meet any of *
* these conditions must conform to all of the terms of this license, *
* particularly including the GPL Section 3 requirements of providing *
* source code and allowing free redistribution of the work as a whole. *
* *
* As another special exception to the GPL terms, Aperture Labs Ltd. grants*
* permission to link the code of this program with any version of the *
* OpenSSL library which is distributed under a license identical to that *
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
* linked combinations including the two. *
* *
* Any redistribution of Covered Software, including any derived works, *
* must obey and carry forward all of the terms of this license, including *
* obeying all GPL rules and restrictions. For example, source code of *
* the whole work must be provided and free redistribution must be *
* allowed. All GPL references to "this License", are to be treated as *
* including the terms and conditions of this license text as well. *
* *
* Because this license imposes special exceptions to the GPL, Covered *
* Work may not be combined (even as part of a larger work) with plain GPL *
* software. The terms, conditions, and exceptions of this license must *
* be included as well. This license is incompatible with some other open *
* source licenses as well. In some cases we can relicense portions of *
* RFIDler or grant special permissions to use it in other open source *
* software. Please contact sales@aperturelabs.com with any such requests.*
* Similarly, we don't incorporate incompatible open source software into *
* Covered Software without special permission from the copyright holders. *
* *
* If you have any questions about the licensing restrictions on using *
* RFIDler in other works, are happy to help. As mentioned above, we also *
* offer alternative license to integrate RFIDler into proprietary *
* applications and appliances. These contracts have been sold to dozens *
* of software vendors, and generally include a perpetual license as well *
* as providing for priority support and updates. They also fund the *
* continued development of RFIDler. Please email sales@aperturelabs.com *
* for further information. *
* If you have received a written license agreement or contract for *
* Covered Software stating terms other than these, you may choose to use *
* and redistribute Covered Software under those terms instead of these. *
* *
* Source is provided to this software because we believe users have a *
* right to know exactly what a program is going to do before they run it. *
* This also allows you to audit the software for security holes (none *
* have been found so far). *
* *
* Source code also allows you to port RFIDler to new platforms, fix bugs, *
* and add new features. You are highly encouraged to send your changes *
* to the RFIDler mailing list for possible incorporation into the *
* main distribution. By sending these changes to Aperture Labs Ltd. or *
* one of the Aperture Labs Ltd. development mailing lists, or checking *
* them into the RFIDler source code repository, it is understood (unless *
* you specify otherwise) that you are offering the RFIDler Project *
* (Aperture Labs Ltd.) the unlimited, non-exclusive right to reuse, *
* modify, and relicense the code. RFIDler will always be available Open *
* Source, but this is important because the inability to relicense code *
* has caused devastating problems for other Free Software projects (such *
* as KDE and NASM). We also occasionally relicense the code to third *
* parties as discussed above. If you wish to specify special license *
* conditions of your contributions, just say so when you send them. *
* *
* This program is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the RFIDler *
* license file for more details (it's in a COPYING file included with *
* RFIDler, and also available from *
* https://github.com/ApertureLabsLtd/RFIDler/COPYING *
* *
***************************************************************************/
// Author: unknown.
// Modifications for RFIDler: Tony Naggs <tony.naggs@gmail.com>, Adam Laurie <adam@aperturelabs.com>
#ifndef HITAGCRYPTO_H
#define HITAGCRYPTO_H
#include <stdint.h>
/*
Our model of Hitag 2 crypto uses 2 parallel shift registers:
a. 48 bit Feedback Shift Register, required for inputs to the nonlinear function.
b. 48 bit Linear Feedback Shift Register (LFSR).
A transform of initial register (a) value, which is then run in parallel.
Enables much faster calculation of the feedback values.
API:
void hitag2_init(Hitag_State* pstate, uint64_t sharedkey, uint32_t serialnum,
uint32_t initvector);
Initialise state from 48 bit shared (secret) reader/tag key,
32 bit tag serial number and 32 bit initialisation vector from reader.
uint32_t hitag2_nstep(Hitag_State* pstate, uint32_t steps);
update shift register state and generate N cipher bits (N should be <= 32)
*/
typedef struct {
uint64_t shiftreg; // naive shift register, required for nonlinear fn input
uint64_t lfsr; // fast lfsr, used to make software faster
} Hitag_State;
void hitag2_init(Hitag_State *pstate, uint64_t sharedkey, uint32_t serialnum, uint32_t initvector);
uint32_t hitag2_nstep(Hitag_State *pstate, uint32_t steps);
#endif /* HITAGCRYPTO_H */
@@ -0,0 +1,172 @@
#include "ht2crack2utils.h"
// writes a value into a buffer as a series of bytes
void writebuf(unsigned char *buf, uint64_t val, unsigned int len) {
int i;
char c;
for (i = len - 1; i >= 0; i--) {
c = val & 0xff;
buf[i] = c;
val = val >> 8;
}
}
/* simple hexdump for testing purposes */
void shexdump(unsigned char *data, int data_len) {
int i;
if (!data || (data_len <= 0)) {
printf("shexdump: invalid parameters\n");
return;
}
printf("Hexdump from %p:\n", data);
for (i = 0; i < data_len; i++) {
if ((i % HEX_PER_ROW) == 0) {
printf("\n0x%04x: ", i);
}
printf("%02x ", data[i]);
}
printf("\n\n");
}
void printbin(unsigned char *c) {
int i, j;
unsigned char x;
if (!c) {
printf("printbin: invalid params\n");
return;
}
for (i = 0; i < 6; i++) {
x = c[i];
for (j = 0; j < 8; j++) {
printf("%d", (x & 0x80) >> 7);
x = x << 1;
}
}
printf("\n");
}
void printbin2(uint64_t val, unsigned int size) {
int i;
uint64_t mask = 1;
mask = mask << (size - 1);
for (i = 0; i < size; i++) {
if (val & mask) {
printf("1");
} else {
printf("0");
}
val = val << 1;
}
}
void printstate(Hitag_State *hstate) {
printf("shiftreg =\t");
printbin2(hstate->shiftreg, 48);
printf("\n");
}
// convert hex char to binary
unsigned char hex2bin(unsigned char c) {
if ((c >= '0') && (c <= '9')) {
return (c - '0');
} else if ((c >= 'a') && (c <= 'f')) {
return (c - 'a' + 10);
} else if ((c >= 'A') && (c <= 'F')) {
return (c - 'A' + 10);
} else {
return 0;
}
}
// return a single bit from a value
int bitn(uint64_t x, int bit) {
uint64_t bitmask = 1;
bitmask = bitmask << bit;
if (x & bitmask) {
return 1;
} else {
return 0;
}
}
// the sub-function R that rollback depends upon
int fnR(uint64_t x) {
// renumbered bits because my state is 0-47, not 1-48
return (bitn(x, 1) ^ bitn(x, 2) ^ bitn(x, 5) ^ bitn(x, 6) ^ bitn(x, 7) ^
bitn(x, 15) ^ bitn(x, 21) ^ bitn(x, 22) ^ bitn(x, 25) ^ bitn(x, 29) ^ bitn(x, 40) ^
bitn(x, 41) ^ bitn(x, 42) ^ bitn(x, 45) ^ bitn(x, 46) ^ bitn(x, 47));
}
// the rollback function that lets us go backwards in time
void rollback(Hitag_State *hstate, unsigned int steps) {
int i;
for (i = 0; i < steps; i++) {
hstate->shiftreg = ((hstate->shiftreg << 1) & 0xffffffffffff) | fnR(hstate->shiftreg);
}
}
// the three filter sub-functions that feed fnf
int fa(unsigned int i) {
return bitn(0x2C79, i);
}
int fb(unsigned int i) {
return bitn(0x6671, i);
}
int fc(unsigned int i) {
return bitn(0x7907287B, i);
}
// the filter function that generates a bit of output from the prng state
int fnf(uint64_t s) {
unsigned int x1, x2, x3, x4, x5, x6;
x1 = (bitn(s, 2) << 0) | (bitn(s, 3) << 1) | (bitn(s, 5) << 2) | (bitn(s, 6) << 3);
x2 = (bitn(s, 8) << 0) | (bitn(s, 12) << 1) | (bitn(s, 14) << 2) | (bitn(s, 15) << 3);
x3 = (bitn(s, 17) << 0) | (bitn(s, 21) << 1) | (bitn(s, 23) << 2) | (bitn(s, 26) << 3);
x4 = (bitn(s, 28) << 0) | (bitn(s, 29) << 1) | (bitn(s, 31) << 2) | (bitn(s, 33) << 3);
x5 = (bitn(s, 34) << 0) | (bitn(s, 43) << 1) | (bitn(s, 44) << 2) | (bitn(s, 46) << 3);
x6 = (fa(x1) << 0) | (fb(x2) << 1) | (fb(x3) << 2) | (fb(x4) << 3) | (fa(x5) << 4);
return fc(x6);
}
// builds the lfsr for the prng (quick calcs for hitag2_nstep())
void buildlfsr(Hitag_State *hstate) {
uint64_t state = hstate->shiftreg;
uint64_t temp;
temp = state ^ (state >> 1);
hstate->lfsr = state ^ (state >> 6) ^ (state >> 16)
^ (state >> 26) ^ (state >> 30) ^ (state >> 41)
^ (temp >> 2) ^ (temp >> 7) ^ (temp >> 22)
^ (temp >> 42) ^ (temp >> 46);
}
@@ -0,0 +1,35 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>
#include "HardwareProfile.h"
#include "rfidler.h"
#include "util.h"
#include "hitagcrypto.h"
#define HEX_PER_ROW 16
void writebuf(unsigned char *buf, uint64_t val, unsigned int len);
void shexdump(unsigned char *data, int data_len);
void printbin(unsigned char *c);
void printbin2(uint64_t val, unsigned int size);
void printstate(Hitag_State *hstate);
unsigned char hex2bin(unsigned char c);
int bitn(uint64_t x, int bit);
int fnR(uint64_t x);
void rollback(Hitag_State *hstate, unsigned int steps);
int fa(unsigned int i);
int fb(unsigned int i);
int fc(unsigned int i);
int fnf(uint64_t s);
void buildlfsr(Hitag_State *hstate);
+421
View File
@@ -0,0 +1,421 @@
/* ht2crack5.c
*
* This code is heavily based on the HiTag2 Hell CPU implementation
* from https://github.com/factoritbv/hitag2hell by FactorIT B.V.,
* with the following changes:
* * Main takes a UID and 2 {nR},{aR} pairs as arguments
* and searches for states producing the first aR sample,
* reconstructs the corresponding key candidates
* and tests them against the second nR,aR pair;
* * Reduce max_bitslices and some type sizes to fit OpenCL
* * Reuses the Hitag helping functions of the other attacks.
*/
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <inttypes.h>
#include <pthread.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifdef __APPLE__
#include <OpenCL/opencl.h>
#else
#define CL_TARGET_OPENCL_VERSION 220
#define CL_USE_DEPRECATED_OPENCL_1_2_APIS
#include <CL/cl.h>
#endif
#include "ht2crack2utils.h"
const uint8_t bits[9] = {20, 14, 4, 3, 1, 1, 1, 1, 1};
#define lfsr_inv(state) (((state)<<1) | (__builtin_parityll((state) & ((0xce0044c101cd>>1)|(1ull<<(47))))))
#define i4(x,a,b,c,d) ((uint32_t)((((x)>>(a))&1)<<3)|(((x)>>(b))&1)<<2|(((x)>>(c))&1)<<1|(((x)>>(d))&1))
#define f(state) ((0xdd3929b >> ( (((0x3c65 >> i4(state, 2, 3, 5, 6) ) & 1) <<4) \
| ((( 0xee5 >> i4(state, 8,12,14,15) ) & 1) <<3) \
| ((( 0xee5 >> i4(state,17,21,23,26) ) & 1) <<2) \
| ((( 0xee5 >> i4(state,28,29,31,33) ) & 1) <<1) \
| (((0x3c65 >> i4(state,34,43,44,46) ) & 1) ))) & 1)
#define MAX_BITSLICES 32
#define VECTOR_SIZE (MAX_BITSLICES/8)
#define KERNELFILENAME "ht2crack5kernel.cl"
typedef unsigned int __attribute__((aligned(VECTOR_SIZE))) __attribute__((vector_size(VECTOR_SIZE))) bitslice_value_t;
typedef union {
bitslice_value_t value;
uint8_t bytes[MAX_BITSLICES / 8];
} bitslice_t;
// we never actually set or use the lowest 2 bits the initial state, so we can save 2 bitslices everywhere
__thread bitslice_t state[-2 + 32 + 48];
bitslice_t keystream[32];
bitslice_t bs_zeroes, bs_ones;
#define f_a_bs(a,b,c,d) (~(((a|b)&c)^(a|d)^b)) // 6 ops
#define f_b_bs(a,b,c,d) (~(((d|c)&(a^b))^(d|a|b))) // 7 ops
#define f_c_bs(a,b,c,d,e) (~((((((c^e)|d)&a)^b)&(c^b))^(((d^e)|a)&((d^b)|c)))) // 13 ops
#define lfsr_bs(i) (state[-2+i+ 0].value ^ state[-2+i+ 2].value ^ state[-2+i+ 3].value ^ state[-2+i+ 6].value ^ \
state[-2+i+ 7].value ^ state[-2+i+ 8].value ^ state[-2+i+16].value ^ state[-2+i+22].value ^ \
state[-2+i+23].value ^ state[-2+i+26].value ^ state[-2+i+30].value ^ state[-2+i+41].value ^ \
state[-2+i+42].value ^ state[-2+i+43].value ^ state[-2+i+46].value ^ state[-2+i+47].value);
#define get_bit(n, word) ((word >> (n)) & 1)
const uint64_t expand(uint64_t mask, uint64_t value) {
uint64_t fill = 0;
for (uint64_t bit_index = 0; bit_index < 48; bit_index++) {
if (mask & 1) {
fill |= (value & 1) << bit_index;
value >>= 1;
}
mask >>= 1;
}
return fill;
}
void bitslice(const uint64_t value, bitslice_t *restrict bitsliced_value, const size_t bit_len, bool reverse) {
size_t bit_idx;
for (bit_idx = 0; bit_idx < bit_len; bit_idx++) {
bool bit;
if (reverse) {
bit = get_bit(bit_len - 1 - bit_idx, value);
} else {
bit = get_bit(bit_idx, value);
}
if (bit) {
bitsliced_value[bit_idx].value = bs_ones.value;
} else {
bitsliced_value[bit_idx].value = bs_zeroes.value;
}
}
}
uint32_t uid, nR1, aR1, nR2, aR2;
// Reduce type size of candidates array to fit OpenCL
uint16_t candidates[(1 << 20) * 3];
bitslice_t initial_bitslices[48];
size_t filter_pos[20] = {4, 7, 9, 13, 16, 18, 22, 24, 27, 30, 32, 35, 45, 47 };
size_t thread_count = 8;
size_t layer_0_found;
static void try_state(uint64_t s);
struct context {
char *kernelSource; // source for kernel
cl_platform_id platform_id; // compute platform id
cl_device_id device_id; // compute device id
cl_context context; // compute context
cl_command_queue commands; // compute command queue
cl_program program; // compute program
cl_kernel kernel; // compute kernel
// cl_mem cand_base; // device memory used for the candidate base
cl_mem keystream; // device memory used for the keystream array
cl_mem candidates; // device memory used for the candidates array
cl_mem matches; // device memory used for the matches array
cl_mem matches_found; // device memory used for the matches_found array
};
void runKernel(struct context *ctx, uint32_t cand_base, uint64_t *matches, uint32_t *matches_found) {
int err;
size_t global[2];
// Write our data set into the input array in device memory
err = clEnqueueWriteBuffer(ctx->commands, ctx->matches_found, CL_TRUE, 0, sizeof(uint32_t), matches_found, 0, NULL, NULL);
// Set the arguments to our compute kernel
err = clSetKernelArg(ctx->kernel, 0, sizeof(uint32_t), &cand_base);
err |= clSetKernelArg(ctx->kernel, 4, sizeof(cl_mem), &ctx->matches_found);
if (err != CL_SUCCESS) {
printf("Error: Failed to set kernel arguments in runKernel! %d\n", err);
exit(1);
}
// Execute the kernel over the entire range of our 2d input data set using 8K * 1K threads
global[0] = 8192;
global[1] = 1024;
err = clEnqueueNDRangeKernel(ctx->commands, ctx->kernel, 2, NULL, global, NULL, 0, NULL, NULL);
if (err) {
printf("Error: Failed to execute kernel!\n");
exit(1);
}
// Wait for the command commands to get serviced before reading back results
err = clFinish(ctx->commands);
if (err) {
printf("Error: Failed to execute kernel! clFinish = %d\n", err);
exit(1);
}
// Read back the results from the device to verify the output
err = clEnqueueReadBuffer(ctx->commands, ctx->matches, CL_TRUE, 0, sizeof(uint64_t) * 8192, matches, 0, NULL, NULL);
if (err != CL_SUCCESS) {
printf("Error: Failed to read matches array! %d\n", err);
exit(1);
}
err = clEnqueueReadBuffer(ctx->commands, ctx->matches_found, CL_TRUE, 0, sizeof(uint32_t), matches_found, 0, NULL, NULL);
if (err != CL_SUCCESS) {
printf("Error: Failed to read matches_found! %d\n", err);
exit(1);
}
}
int main(int argc, char *argv[]) {
memset(candidates, 0, sizeof(candidates));
struct context ctx;
uint64_t matches[8192];
uint32_t matches_found[1];
// set constants
memset(bs_ones.bytes, 0xff, VECTOR_SIZE);
memset(bs_zeroes.bytes, 0x00, VECTOR_SIZE);
uint32_t target = 0;
if (argc < 6) {
printf("%s UID {nR1} {aR1} {nR2} {aR2}\n", argv[0]);
exit(1);
}
if (!strncmp(argv[1], "0x", 2) || !strncmp(argv[1], "0X", 2)) {
uid = rev32(hexreversetoulong(argv[1] + 2));
} else {
uid = rev32(hexreversetoulong(argv[1]));
}
if (!strncmp(argv[2], "0x", 2) || !strncmp(argv[2], "0X", 2)) {
nR1 = rev32(hexreversetoulong(argv[2] + 2));
} else {
nR1 = rev32(hexreversetoulong(argv[2]));
}
aR1 = strtol(argv[3], NULL, 16);
if (!strncmp(argv[4], "0x", 2) || !strncmp(argv[4], "0X", 2)) {
nR2 = rev32(hexreversetoulong(argv[4] + 2));
} else {
nR2 = rev32(hexreversetoulong(argv[4]));
}
aR2 = strtol(argv[5], NULL, 16);
target = ~aR1;
// bitslice inverse target bits
bitslice(~target, keystream, 32, true);
// bitslice all possible 256 values in the lowest 8 bits
memset(initial_bitslices[0].bytes, 0xaa, VECTOR_SIZE);
memset(initial_bitslices[1].bytes, 0xcc, VECTOR_SIZE);
memset(initial_bitslices[2].bytes, 0xf0, VECTOR_SIZE);
size_t interval = 1;
for (size_t bit = 3; bit < 8; bit++) {
for (size_t byte = 0; byte < VECTOR_SIZE;) {
for (size_t length = 0; length < interval; length++) {
initial_bitslices[bit].bytes[byte++] = 0x00;
}
for (size_t length = 0; length < interval; length++) {
initial_bitslices[bit].bytes[byte++] = 0xff;
}
}
interval <<= 1;
}
// compute layer 0 output
for (size_t i0 = 0; i0 < 1 << 20; i0++) {
uint64_t state0 = expand(0x5806b4a2d16c, i0);
if (f(state0) == target >> 31) {
// cf kernel, state is now split in 3 shorts >> 2
candidates[(layer_0_found * 3) + 0] = (uint16_t)((state0 >> (32 + 2)) & 0xffff);
candidates[(layer_0_found * 3) + 1] = (uint16_t)((state0 >> (16 + 2)) & 0xffff);
candidates[(layer_0_found * 3) + 2] = (uint16_t)((state0 >> (0 + 2)) & 0xffff);
layer_0_found++;
}
}
// load OpenCL kernel source
////////////////////////////
struct stat filestat;
int fd;
fd = open(KERNELFILENAME, O_RDONLY);
if (fd <= 0) {
printf("Cannot open %s\n", KERNELFILENAME);
exit(1);
}
if (fstat(fd, &filestat)) {
printf("Cannot stat %s\n", KERNELFILENAME);
exit(1);
}
ctx.kernelSource = (char *)malloc(filestat.st_size);
if (!ctx.kernelSource) {
printf("Cannot malloc kernelSource\n");
exit(1);
}
if (read(fd, ctx.kernelSource, filestat.st_size) < filestat.st_size) {
printf("Cannot read %s\n", KERNELFILENAME);
exit(1);
}
close(fd);
// discover and set up compute device
/////////////////////////////////////
int err;
// Connect to a compute device
err = clGetPlatformIDs(1, &(ctx.platform_id), NULL);
if (err != CL_SUCCESS) {
printf("Error: Failed to get platform id: %d\n", err);
exit(1);
}
int gpu = 1;
err = clGetDeviceIDs(ctx.platform_id, gpu ? CL_DEVICE_TYPE_GPU : CL_DEVICE_TYPE_CPU, 1, &(ctx.device_id), NULL);
if (err != CL_SUCCESS) {
printf("Error: Failed to create a device group!: %d\n", err);
exit(1);
}
// Create a compute context
ctx.context = clCreateContext(0, 1, &(ctx.device_id), NULL, NULL, &err);
if (!ctx.context) {
printf("Error: Failed to create a compute context!\n");
exit(1);
}
// Create a command commands
ctx.commands = clCreateCommandQueue(ctx.context, ctx.device_id, 0, &err);
if (!ctx.commands) {
printf("Error: Failed to create a command commands!\n");
exit(1);
}
// Create the compute program from the source buffer
ctx.program = clCreateProgramWithSource(ctx.context, 1, (const char **) & (ctx.kernelSource), NULL, &err);
if (!ctx.program) {
printf("Error: Failed to create compute program!\n");
exit(1);
}
// Build the program executable
err = clBuildProgram(ctx.program, 0, NULL, "-Werror", NULL, NULL);
if (err != CL_SUCCESS) {
size_t len;
char buffer[1024 * 1024];
printf("Error: Failed to build program executable!\n");
err = clGetProgramBuildInfo(ctx.program, ctx.device_id, CL_PROGRAM_BUILD_LOG, sizeof(buffer), buffer, &len);
if (err != CL_SUCCESS) {
printf("clGetProgramBuildInfo failed: %d\n", err);
exit(1);
} else {
printf("%s\n", buffer);
exit(1);
}
}
// Create the compute kernel in the program we wish to run
ctx.kernel = clCreateKernel(ctx.program, "find_state", &err);
if (!ctx.kernel || err != CL_SUCCESS) {
printf("Error: Failed to create compute kernel!\n");
exit(1);
}
ctx.candidates = clCreateBuffer(ctx.context, CL_MEM_READ_ONLY, sizeof(uint16_t) * ((1 << 20) * 3), NULL, NULL);
ctx.keystream = clCreateBuffer(ctx.context, CL_MEM_READ_ONLY, VECTOR_SIZE * 32, NULL, NULL);
ctx.matches = clCreateBuffer(ctx.context, CL_MEM_WRITE_ONLY, sizeof(uint64_t) * 8192, NULL, NULL);
ctx.matches_found = clCreateBuffer(ctx.context, CL_MEM_READ_WRITE, sizeof(uint32_t), NULL, NULL);
if (!ctx.candidates || !ctx.keystream || !ctx.matches || !ctx.matches_found) {
printf("Error: Failed to allocate device memory!\n");
exit(1);
}
// set up constant vars
///////////////////////
// Write our data set into the input array in device memory
err = clEnqueueWriteBuffer(ctx.commands, ctx.keystream, CL_TRUE, 0, VECTOR_SIZE * 32, keystream, 0, NULL, NULL);
if (err != CL_SUCCESS) {
printf("Error: Failed to write to keystream array!\n");
exit(1);
}
err = clEnqueueWriteBuffer(ctx.commands, ctx.candidates, CL_TRUE, 0, sizeof(uint16_t) * ((1 << 20) * 3), candidates, 0, NULL, NULL);
if (err != CL_SUCCESS) {
printf("Error: Failed to write to candidates array!\n");
exit(1);
}
// Set the arguments to our compute kernel
err = clSetKernelArg(ctx.kernel, 1, sizeof(cl_mem), &ctx.candidates);
err |= clSetKernelArg(ctx.kernel, 2, sizeof(cl_mem), &ctx.keystream);
err |= clSetKernelArg(ctx.kernel, 3, sizeof(cl_mem), &ctx.matches);
if (err != CL_SUCCESS) {
printf("Error: Failed to set kernel arguments! %d\n", err);
exit(1);
}
// run kernel
/////////////
for (uint32_t step = 0; step < 64; step++) {
printf("slice %3u/64: ", step + 1);
fflush(stdout);
matches_found[0] = 0;
runKernel(&ctx, step << 13, matches, matches_found);
printf("%5u candidates\n", matches_found[0]);
for (uint32_t match = 0; match < matches_found[0]; match++) {
try_state(matches[match]);
}
}
printf("Key not found\n");
exit(1);
}
static void try_state(uint64_t s) {
Hitag_State hstate;
uint64_t keyrev, key, nR1xk;
uint32_t b = 0;
hstate.shiftreg = s;
rollback(&hstate, 2);
// recover key
keyrev = hstate.shiftreg & 0xffff;
nR1xk = (hstate.shiftreg >> 16) & 0xffffffff;
for (int i = 0; i < 32; i++) {
hstate.shiftreg = ((hstate.shiftreg) << 1) | ((uid >> (31 - i)) & 0x1);
b = (b << 1) | fnf(hstate.shiftreg);
}
keyrev |= (nR1xk ^ nR1 ^ b) << 16;
// test key
hitag2_init(&hstate, keyrev, uid, nR2);
if ((aR2 ^ hitag2_nstep(&hstate, 32)) == 0xffffffff) {
key = rev64(keyrev);
printf("Key: ");
for (int i = 0; i < 6; i++) {
printf("%02X", (uint8_t)(key & 0xff));
key = key >> 8;
}
printf("\n");
exit(0);
}
}

Some files were not shown because too many files have changed in this diff Show More