]>
git.zerfleddert.de Git - proxmark3-svn/blob - client/cmdlfhid.c
1 //-----------------------------------------------------------------------------
2 // Copyright (C) 2010 iZsh <izsh at fail0verflow.com>
4 // This code is licensed to you under the terms of the GNU GPL, version 2 or,
5 // at your option, any later version. See the LICENSE.txt file for the text of
7 //-----------------------------------------------------------------------------
8 // Low frequency HID commands (known)
11 // RF interface, programming a T55x7 clone, 26-bit HID H10301 encoding:
12 // http://www.proxmark.org/files/Documents/125%20kHz%20-%20HID/HID_format_example.pdf
14 // "Understanding Card Data Formats"
15 // https://www.hidglobal.com/sites/default/files/hid-understanding_card_data_formats-wp-en.pdf
17 // "What Format Do You Need?"
18 // https://www.hidglobal.com/sites/default/files/resource_files/hid-prox-br-en.pdf
19 //-----------------------------------------------------------------------------
28 #include "cmdparser.h"
29 #include "cmddata.h" //for g_debugMode, demodbuff cmds
30 #include "lfdemod.h" // for HIDdemodFSK
31 #include "parity.h" // for parity
32 #include "util.h" // for param_get8,32,64
34 static int CmdHelp(const char *Cmd
);
37 * Packs an HID ID from component parts.
39 * This only works with 26, 34, 35, 37, and 48 bit card IDs.
41 * Returns false on invalid inputs.
43 bool pack_hid(/* out */ uint32_t *hi2
, /* out */ uint32_t *hi
, /* out */ uint32_t *lo
, /* in */ const hid_info
*info
) {
44 uint32_t higher
= 0, high
= 0, low
= 0;
46 switch (info
->fmtLen
) {
47 case 26: // HID H10301
48 low
|= (info
->cardnum
& 0xffff) << 1;
49 low
|= (info
->fc
& 0xff) << 17;
51 if (info
->parityValid
) {
53 low
|= oddparity32((low
>> 1) & 0xfff) & 1;
54 low
|= (evenparity32((low
>> 13) & 0xfff) & 1) << 25;
59 low
|= (info
->cardnum
& 0xffff) << 1;
60 low
|= (info
->fc
& 0x7fff) << 17;
61 high
|= (info
->fc
& 0x8000) >> 15;
63 if (info
->parityValid
) {
65 high
|= (evenparity32((high
& 0x00000001) ^ (low
& 0xFFFE0000)) & 1) << 1;
66 low
|= (oddparity32(low
& 0x0001FFFE) & 1);
70 case 35: // (Corporate 1000 35-bit)
71 low
|= (info
->cardnum
& 0xfffff) << 1;
72 low
|= (info
->fc
& 0x7ff) << 21;
73 high
|= (info
->fc
& 0x800) >> 11;
75 if (info
->parityValid
) {
77 high
|= (evenparity32((high
& 0x00000001) ^ (low
& 0xB6DB6DB6)) & 1) << 1;
78 low
|= (oddparity32( (high
& 0x00000003) ^ (low
& 0x6DB6DB6C)) & 1);
79 high
|= (oddparity32( (high
& 0x00000003) ^ (low
& 0xFFFFFFFF)) & 1) << 2;
84 low
|= (info
->cardnum
& 0x7ffff) << 1;
85 low
|= (info
->fc
& 0xfff) << 20;
86 high
|= (info
->fc
& 0xf000) >> 12;
88 if (info
->parityValid
) {
90 high
|= (evenparity32((high
& 0x0000000F) ^ (low
& 0xFFFC0000)) & 1) << 4;
91 low
|= (oddparity32(low
& 0x0007FFFE) & 1);
95 case 48: // Corporate 1000 48-bit
96 low
|= (info
->cardnum
& 0x7FFFFF) << 1;
97 low
|= (info
->fc
& 0xff) << 24;
98 high
|= (info
->fc
& 0x3FFF00) >> 8;
100 if (info
->parityValid
) {
102 high
|= (evenparity32((high
& 0x00001B6D) ^ (low
& 0xB6DB6DB6)) & 1) << 14;
103 low
|= (oddparity32( (high
& 0x000036DB) ^ (low
& 0x6DB6DB6C)) & 1);
104 high
|= (oddparity32( (high
& 0x00007FFF) ^ (low
& 0xFFFFFFFF)) & 1) << 15;
109 // Invalid / unsupported length
113 // Set the format length bits
114 if (info
->fmtLen
< 37) {
115 // Bit 37 is always set
118 // Set the bit corresponding to the length.
119 if (info
->fmtLen
< 32)
120 low
|= 1 << info
->fmtLen
;
122 high
|= 1 << (info
->fmtLen
- 32);
124 } else if (info
->fmtLen
> 37){
125 if (info
->fmtLen
< 64)
126 high
|= 1 << (info
->fmtLen
- 32);
128 higher
|= 1 << (info
->fmtLen
- 64);
130 // Return result only if successful.
138 * Unpacks an HID ID into its component parts.
140 * This only works with 26, 34, 35, 37, and 48 bit card IDs.
142 * Returns false on invalid inputs.
144 bool unpack_hid(hid_info
*out
, uint32_t hi2
, uint32_t hi
, uint32_t lo
) {
145 memset(out
, 0, sizeof(hid_info
));
148 uint32_t hFmt
; // for calculating card length
149 if ((hi2
& 0x000FFFFF) > 0) { // > 64 bits
150 hFmt
= hi2
& 0x000FFFFF;
152 } else if ((hi
& 0xFFFFFFC0) > 0) { // < 63-38 bits
153 hFmt
= hi
& 0xFFFFFFC0;
155 } else if ((hi
& 0x00000020) == 0) { // 37 bits
158 } else if ((hi
& 0x0000001F) > 0){ // 36-32 bits
159 hFmt
= hi
& 0x0000001F;
170 out
->fmtLen
= fmtLen
;
171 switch (out
->fmtLen
) {
172 case 26: // HID H10301
173 out
->cardnum
= (lo
>> 1) & 0xFFFF;
174 out
->fc
= (lo
>> 17) & 0xFF;
177 PrintAndLog("oddparity : input=%x, calculated=%d, provided=%d",
178 (lo
>> 1) & 0xFFF, oddparity32((lo
>> 1) & 0xFFF), lo
& 1);
179 PrintAndLog("evenparity: input=%x, calculated=%d, provided=%d",
180 (lo
>> 13) & 0xFFF, evenparity32((lo
>> 13) & 0xFFF) & 1, (lo
>> 25) & 1);
184 (oddparity32((lo
>> 1) & 0xFFF) == (lo
& 1)) &&
185 ((evenparity32((lo
>> 13) & 0xFFF) & 1) == ((lo
>> 25) & 1));
188 case 34: // HID H10306
189 out
->cardnum
= (lo
>> 1) & 0xFFFF;
190 out
->fc
= ((hi
& 1) << 15) | (lo
>> 17);
192 ((evenparity32((hi
& 0x00000001) ^ (lo
& 0xFFFE0000)) & 1) == ((hi
>> 1) & 1)) &&
193 ((oddparity32(lo
& 0x0001FFFE) & 1) == ((lo
& 1)));
196 case 35: // HID Corporate 1000-35
197 out
->cardnum
= (lo
>> 1) & 0xFFFFF;
198 out
->fc
= ((hi
& 1) << 11) | (lo
>> 21);
200 (evenparity32((hi
& 0x00000001) ^ (lo
& 0xB6DB6DB6)) == ((hi
>> 1) & 1)) &&
201 (oddparity32( (hi
& 0x00000003) ^ (lo
& 0x6DB6DB6C)) == ((lo
>> 0) & 1)) &&
202 (oddparity32( (hi
& 0x00000003) ^ (lo
& 0xFFFFFFFF)) == ((hi
>> 2) & 1));
204 PrintAndLog("Parity check: calculated {%d, %d, %d}, provided {%d, %d, %d}",
205 evenparity32((hi
& 0x00000001) ^ (lo
& 0xB6DB6DB6)),
206 oddparity32( (hi
& 0x00000003) ^ (lo
& 0x6DB6DB6C)),
207 oddparity32( (hi
& 0x00000003) ^ (lo
& 0xFFFFFFFF)),
215 case 37: // HID H10304
217 out
->cardnum
= (lo
>> 1) & 0x7FFFF;
218 out
->fc
= ((hi
& 0xF) << 12) | (lo
>> 20);
220 (evenparity32((hi
& 0x0000000F) ^ (lo
& 0xFFFC0000)) == ((hi
>> 4) & 1)) &&
221 (oddparity32( lo
& 0x0007FFFE) == (lo
& 1));
224 case 48: // HID Corporate 1000-48
225 out
->cardnum
= (lo
>> 1) & 0x7FFFFF; //Start 24, 23 length
226 out
->fc
= ((hi
& 0x3FFF) << 8 ) | (lo
>> 24); //Start 2, 22 length
228 (evenparity32((hi
& 0x00001B6D) ^ (lo
& 0xB6DB6DB6)) == ((hi
>> 14) & 1)) &&
229 (oddparity32( (hi
& 0x000036DB) ^ (lo
& 0x6DB6DB6C)) == ((lo
>> 0) & 1)) &&
230 (oddparity32( (hi
& 0x00007FFF) ^ (lo
& 0xFFFFFFFF)) == ((hi
>> 15) & 1));
232 PrintAndLog("Parity check: calculated {%d, %d, %d}, provided {%d, %d, %d}",
233 evenparity32((hi
& 0x00001B6D) ^ (lo
& 0xB6DB6DB6)),
234 oddparity32( (hi
& 0x000036DB) ^ (lo
& 0x6DB6DB6C)),
235 oddparity32( (hi
& 0x00007FFF) ^ (lo
& 0xFFFFFFFF)),
250 * Converts a hex string to component "hi2", "hi" and "lo" 32-bit integers, one nibble
253 * Returns the number of nibbles (4 bits) entered.
255 int hexstring_to_int96(/* out */ uint32_t* hi2
,/* out */ uint32_t* hi
, /* out */ uint32_t* lo
, const char* str
) {
256 // TODO: Replace this with param_gethex when it supports arbitrary length
260 while (sscanf(&str
[i
++], "%1x", &n
) == 1) {
261 *hi2
= (*hi2
<< 4) | (*hi
>> 28);
262 *hi
= (*hi
<< 4) | (*lo
>> 28);
263 *lo
= (*lo
<< 4) | (n
& 0xf);
269 //by marshmellow (based on existing demod + holiman's refactor)
270 //HID Prox demod - FSK RF/50 with preamble of 00011101 (then manchester encoded)
271 //print full HID Prox ID and some bit format details if found
272 int CmdFSKdemodHID(const char *Cmd
)
274 //raw fsk demod no manchester decoding no start bit finding just get binary from wave
275 uint32_t hi2
=0, hi
=0, lo
=0;
277 uint8_t BitStream
[MAX_GRAPH_TRACE_LEN
]={0};
278 size_t BitLen
= getFromGraphBuf(BitStream
);
279 if (BitLen
==0) return 0;
280 //get binary from fsk wave
282 int idx
= HIDdemodFSK(BitStream
,&BitLen
,&hi2
,&hi
,&lo
, &waveIdx
);
286 PrintAndLog("DEBUG: Just Noise Detected");
287 } else if (idx
== -2) {
288 PrintAndLog("DEBUG: Error demoding fsk");
289 } else if (idx
== -3) {
290 PrintAndLog("DEBUG: Preamble not found");
291 } else if (idx
== -4) {
292 PrintAndLog("DEBUG: Error in Manchester data, SIZE: %d", BitLen
);
294 PrintAndLog("DEBUG: Error demoding fsk %d", idx
);
299 if (hi2
==0 && hi
==0 && lo
==0) {
300 if (g_debugMode
) PrintAndLog("DEBUG: Error - no values found");
305 bool ret
= unpack_hid(&card_info
, (uint32_t)hi2
, (uint32_t)hi
, (uint32_t)lo
);
308 PrintAndLog("HID Prox TAG ID: %x%08x%08x (%d) - Format Len: %u bits - FC: %u - Card: %u",
309 (unsigned int) hi2
, (unsigned int) hi
, (unsigned int) lo
, (unsigned int) (lo
>>1) & 0xFFFF,
310 card_info
.fmtLen
, card_info
.fc
, card_info
.cardnum
);
312 PrintAndLog("HID Prox TAG ID: %x%08x (%d) - Format Len: %u bits - FC: %u - Card: %u",
313 (unsigned int) hi
, (unsigned int) lo
, (unsigned int) (lo
>>1) & 0xFFFF,
314 card_info
.fmtLen
, card_info
.fc
, card_info
.cardnum
);
316 if (card_info
.fmtLen
== 26 || card_info
.fmtLen
== 35 || card_info
.fmtLen
== 48) {
317 PrintAndLog("Parity: %s", card_info
.parityValid
? "valid" : "invalid");
320 PrintAndLog("Invalid or unsupported tag length.");
322 setDemodBuf(BitStream
,BitLen
,idx
);
323 setClockGrid(50, waveIdx
+ (idx
*50));
325 PrintAndLog("DEBUG: idx: %d, Len: %d, Printing Demod Buffer:", idx
, BitLen
);
331 int CmdHIDReadFSK(const char *Cmd
)
334 if(Cmd
[0]=='1') findone
=1;
335 UsbCommand c
={CMD_HID_DEMOD_FSK
};
341 int CmdHIDSim(const char *Cmd
)
343 uint32_t hi2
= 0, hi
= 0, lo
= 0;
344 hexstring_to_int96(&hi2
, &hi
, &lo
, Cmd
);
345 if (hi
>= 0x40 || hi2
!= 0) {
346 PrintAndLog("This looks like a long tag ID. Use 'lf simfsk' for long tags. Aborting!");
350 PrintAndLog("Emulating tag with ID %x%08x", hi
, lo
);
351 PrintAndLog("Press pm3-button to abort simulation");
353 UsbCommand c
= {CMD_HID_SIM_TAG
, {hi
, lo
, 0}};
358 int CmdHIDClone(const char *Cmd
)
360 unsigned int hi2
= 0, hi
= 0, lo
= 0;
362 hexstring_to_int96(&hi2
, &hi
, &lo
, Cmd
);
364 if (hi
>= 0x40 || hi2
!= 0) {
365 PrintAndLog("Cloning tag with long ID %x%08x%08x", hi2
, hi
, lo
);
368 PrintAndLog("Cloning tag with ID %x%08x", hi
, lo
);
372 c
.cmd
= CMD_HID_CLONE_TAG
;
382 int CmdHIDPack(const char *Cmd
) {
383 uint32_t hi2
= 0, hi
= 0, lo
= 0;
386 PrintAndLog("Usage: lf hid pack <length> <facility code (decimal)> <card number (decimal)>");
387 PrintAndLog(" sample: lf hid pack 26 123 4567");
390 uint8_t fmtLen
= param_get8(Cmd
, 0);
393 card_info
.fmtLen
= fmtLen
;
394 card_info
.fc
= param_get32ex(Cmd
, 1, 0, 10);
395 card_info
.cardnum
= param_get64ex(Cmd
, 2, 0, 10);
396 card_info
.parityValid
= true;
398 bool ret
= pack_hid(&hi2
, &hi
, &lo
, &card_info
);
401 PrintAndLog("HID Prox TAG ID: %x%08x%08x (%d) - Format Len: %u bits - FC: %u - Card: %u",
402 (unsigned int) hi2
, (unsigned int) hi
, (unsigned int) lo
, (unsigned int) (lo
>>1) & 0xFFFF,
403 card_info
.fmtLen
, card_info
.fc
, card_info
.cardnum
);
405 PrintAndLog("HID Prox TAG ID: %x%08x (%d) - Format Len: %u bits - FC: %u - Card: %u",
406 (unsigned int) hi
, (unsigned int) lo
, (unsigned int) (lo
>>1) & 0xFFFF,
407 card_info
.fmtLen
, card_info
.fc
, card_info
.cardnum
);
410 PrintAndLog("Invalid or unsupported tag length.");
416 int CmdHIDUnpack(const char *Cmd
)
418 uint32_t hi2
= 0, hi
= 0, lo
= 0;
420 PrintAndLog("Usage: lf hid unpack <ID>");
421 PrintAndLog(" sample: lf hid unpack 2006f623ae");
425 hexstring_to_int96(&hi2
, &hi
, &lo
, Cmd
);
428 bool ret
= unpack_hid(&card_info
, hi2
, hi
, lo
);
431 PrintAndLog("HID Prox TAG ID: %x%08x%08x (%d) - Format Len: %u bits - FC: %u - Card: %u",
432 (unsigned int) hi2
, (unsigned int) hi
, (unsigned int) lo
, (unsigned int) (lo
>>1) & 0xFFFF,
433 card_info
.fmtLen
, card_info
.fc
, card_info
.cardnum
);
435 PrintAndLog("HID Prox TAG ID: %x%08x (%d) - Format Len: %u bits - FC: %u - Card: %u",
436 (unsigned int) hi
, (unsigned int) lo
, (unsigned int) (lo
>>1) & 0xFFFF,
437 card_info
.fmtLen
, card_info
.fc
, card_info
.cardnum
);
439 PrintAndLog("Parity: %s", card_info
.parityValid
? "valid" : "invalid");
442 PrintAndLog("Invalid or unsupported tag length.");
448 static command_t CommandTable
[] =
450 {"help", CmdHelp
, 1, "This help"},
451 {"demod", CmdFSKdemodHID
, 1, "Demodulate HID Prox from GraphBuffer"},
452 {"read", CmdHIDReadFSK
, 0, "['1'] Realtime HID FSK Read from antenna (option '1' for one tag only)"},
453 {"sim", CmdHIDSim
, 0, "<ID> -- HID tag simulator"},
454 {"clone", CmdHIDClone
, 0, "<ID> -- Clone HID to T55x7 (tag must be in antenna)"},
455 {"pack", CmdHIDPack
, 1, "<len> <fc> <num> -- packs an HID ID from its length, facility code and card number"},
456 {"unpack", CmdHIDUnpack
, 1, "<ID> -- unpacks an HID ID to its length, facility code and card number"},
457 {NULL
, NULL
, 0, NULL
}
460 int CmdLFHID(const char *Cmd
)
462 CmdsParse(CommandTable
, Cmd
);
466 int CmdHelp(const char *Cmd
)
468 CmdsHelp(CommandTable
);