]> git.zerfleddert.de Git - proxmark3-svn/blob - client/cmdlfhitag.c
Added mifare trailer block decoding for sector commands (#734)
[proxmark3-svn] / client / cmdlfhitag.c
1 //-----------------------------------------------------------------------------
2 // Copyright (C) 2012 Roel Verdult
3 //
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
6 // the license.
7 //-----------------------------------------------------------------------------
8 // Low frequency Hitag support
9 //-----------------------------------------------------------------------------
10
11 #include "cmdlfhitag.h"
12
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include "comms.h"
17 #include "ui.h"
18 #include "cmdparser.h"
19 #include "common.h"
20 #include "util.h"
21 #include "parity.h"
22 #include "hitag2.h"
23 #include "hitagS.h"
24 #include "cmdmain.h"
25
26 static int CmdHelp(const char *Cmd);
27
28 size_t nbytes(size_t nbits) {
29 return (nbits/8)+((nbits%8)>0);
30 }
31
32 int CmdLFHitagList(const char *Cmd)
33 {
34 uint8_t *got = malloc(USB_CMD_DATA_SIZE);
35 // Query for the actual size of the trace
36 UsbCommand response;
37 GetFromBigBuf(got, USB_CMD_DATA_SIZE, 0, &response, -1, false);
38 uint16_t traceLen = response.arg[2];
39 if (traceLen > USB_CMD_DATA_SIZE) {
40 uint8_t *p = realloc(got, traceLen);
41 if (p == NULL) {
42 PrintAndLog("Cannot allocate memory for trace");
43 free(got);
44 return 2;
45 }
46 got = p;
47 GetFromBigBuf(got, traceLen, 0, NULL, -1, false);
48 }
49
50 PrintAndLog("recorded activity (TraceLen = %d bytes):");
51 PrintAndLog(" ETU :nbits: who bytes");
52 PrintAndLog("---------+-----+----+-----------");
53
54 int j;
55 int i = 0;
56 int prev = -1;
57 int len = strlen(Cmd);
58
59 char filename[FILE_PATH_SIZE] = { 0x00 };
60 FILE* pf = NULL;
61
62 if (len > FILE_PATH_SIZE)
63 len = FILE_PATH_SIZE;
64 memcpy(filename, Cmd, len);
65
66 if (strlen(filename) > 0) {
67 if ((pf = fopen(filename,"wb")) == NULL) {
68 PrintAndLog("Error: Could not open file [%s]",filename);
69 free(got);
70 return 1;
71 }
72 }
73
74 for (;;) {
75
76 if(i > traceLen) { break; }
77
78 bool isResponse;
79 int timestamp = *((uint32_t *)(got+i));
80 if (timestamp & 0x80000000) {
81 timestamp &= 0x7fffffff;
82 isResponse = 1;
83 } else {
84 isResponse = 0;
85 }
86
87 int parityBits = *((uint32_t *)(got+i+4));
88 // 4 bytes of additional information...
89 // maximum of 32 additional parity bit information
90 //
91 // TODO:
92 // at each quarter bit period we can send power level (16 levels)
93 // or each half bit period in 256 levels.
94
95 int bits = got[i+8];
96 int len = nbytes(bits);
97
98 if (len > 100) {
99 break;
100 }
101 if (i + len > traceLen) { break;}
102
103 uint8_t *frame = (got+i+9);
104 /*
105 int fillupBits = 8 - (bits % 8);
106 byte_t framefilled[bits+fillupBits];
107 byte_t* ff = framefilled;
108
109 int response_bit[200] = {0};
110 int z = 0;
111 for (int y = 0; y < len; y++) {
112 for (j = 0; j < 8; j++) {
113 response_bit[z] = 0;
114 if ((frame[y] & ((mask << 7) >> j)) != 0)
115 response_bit[z] = 1;
116 z++;
117 }
118 }
119 z = 0;
120 for (int y = 0; y < len; y++) {
121 ff[y] = (response_bit[z] << 7) | (response_bit[z + 1] << 6)
122 | (response_bit[z + 2] << 5) | (response_bit[z + 3] << 4)
123 | (response_bit[z + 4] << 3) | (response_bit[z + 5] << 2)
124 | (response_bit[z + 6] << 1) | response_bit[z + 7];
125 z += 8;
126 }
127 */
128
129
130
131
132 // Break and stick with current result if buffer was not completely full
133 if (frame[0] == 0x44 && frame[1] == 0x44 && frame[3] == 0x44) { break; }
134
135 char line[1000] = "";
136 for (j = 0; j < len; j++) {
137 //if((parityBits >> (len - j - 1)) & 0x01) {
138 if (isResponse && (oddparity8(frame[j]) != ((parityBits >> (len - j - 1)) & 0x01))) {
139 sprintf(line+(j*4), "%02x! ", frame[j]);
140 } else {
141 sprintf(line+(j*4), "%02x ", frame[j]);
142 }
143 }
144
145 PrintAndLog(" +%7d: %3d: %s %s",
146 (prev < 0 ? 0 : (timestamp - prev)),
147 bits,
148 (isResponse ? "TAG" : " "),
149 line);
150
151 if (pf) {
152 fprintf(pf," +%7d: %3d: %s %s\n",
153 (prev < 0 ? 0 : (timestamp - prev)),
154 bits,
155 (isResponse ? "TAG" : " "),
156 line);
157 }
158
159 prev = timestamp;
160 i += (len + 9);
161 }
162
163 if (pf) {
164 fclose(pf);
165 PrintAndLog("Recorded activity succesfully written to file: %s", filename);
166 }
167
168 free(got);
169 return 0;
170 }
171
172 int CmdLFHitagSnoop(const char *Cmd) {
173 UsbCommand c = {CMD_SNOOP_HITAG};
174 SendCommand(&c);
175 return 0;
176 }
177
178 int CmdLFHitagSim(const char *Cmd) {
179
180 UsbCommand c = {CMD_SIMULATE_HITAG};
181 char filename[FILE_PATH_SIZE] = { 0x00 };
182 FILE* pf;
183 bool tag_mem_supplied;
184 int len = strlen(Cmd);
185 if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE;
186 memcpy(filename, Cmd, len);
187
188 if (strlen(filename) > 0) {
189 if ((pf = fopen(filename,"rb+")) == NULL) {
190 PrintAndLog("Error: Could not open file [%s]",filename);
191 return 1;
192 }
193 tag_mem_supplied = true;
194 if (fread(c.d.asBytes,1,48,pf) != 48) {
195 PrintAndLog("Error: File reading error");
196 fclose(pf);
197 return 1;
198 }
199 fclose(pf);
200 } else {
201 tag_mem_supplied = false;
202 }
203
204 // Does the tag comes with memory
205 c.arg[0] = (uint32_t)tag_mem_supplied;
206
207 SendCommand(&c);
208 return 0;
209 }
210
211 int CmdLFHitagReader(const char *Cmd) {
212 UsbCommand c = {CMD_READER_HITAG};//, {param_get32ex(Cmd,0,0,10),param_get32ex(Cmd,1,0,16),param_get32ex(Cmd,2,0,16),param_get32ex(Cmd,3,0,16)}};
213 hitag_data* htd = (hitag_data*)c.d.asBytes;
214 hitag_function htf = param_get32ex(Cmd,0,0,10);
215
216 switch (htf) {
217 case 01: { //RHTSF_CHALLENGE
218 c = (UsbCommand){ CMD_READ_HITAG_S };
219 num_to_bytes(param_get32ex(Cmd,1,0,16),4,htd->auth.NrAr);
220 num_to_bytes(param_get32ex(Cmd,2,0,16),4,htd->auth.NrAr+4);
221 c.arg[1] = param_get64ex(Cmd,3,0,0); //firstpage
222 c.arg[2] = param_get64ex(Cmd,4,0,0); //tag mode
223 } break;
224 case 02: { //RHTSF_KEY
225 c = (UsbCommand){ CMD_READ_HITAG_S };
226 num_to_bytes(param_get64ex(Cmd,1,0,16),6,htd->crypto.key);
227 c.arg[1] = param_get64ex(Cmd,2,0,0); //firstpage
228 c.arg[2] = param_get64ex(Cmd,3,0,0); //tag mode
229 } break;
230 case 03: { //RHTSF_CHALLENGE BLOCK
231 c = (UsbCommand){ CMD_READ_HITAG_S_BLK };
232 num_to_bytes(param_get32ex(Cmd,1,0,16),4,htd->auth.NrAr);
233 num_to_bytes(param_get32ex(Cmd,2,0,16),4,htd->auth.NrAr+4);
234 c.arg[1] = param_get64ex(Cmd,3,0,0); //firstpage
235 c.arg[2] = param_get64ex(Cmd,4,0,0); //tag mode
236 } break;
237 case 04: { //RHTSF_KEY BLOCK
238 c = (UsbCommand){ CMD_READ_HITAG_S_BLK };
239 num_to_bytes(param_get64ex(Cmd,1,0,16),6,htd->crypto.key);
240 c.arg[1] = param_get64ex(Cmd,2,0,0); //firstpage
241 c.arg[2] = param_get64ex(Cmd,3,0,0); //tag mode
242 } break;
243 case RHT2F_PASSWORD: {
244 num_to_bytes(param_get32ex(Cmd,1,0,16),4,htd->pwd.password);
245 } break;
246 case RHT2F_AUTHENTICATE: {
247 num_to_bytes(param_get32ex(Cmd,1,0,16),4,htd->auth.NrAr);
248 num_to_bytes(param_get32ex(Cmd,2,0,16),4,htd->auth.NrAr+4);
249 } break;
250 case RHT2F_CRYPTO: {
251 num_to_bytes(param_get64ex(Cmd,1,0,16),6,htd->crypto.key);
252 // num_to_bytes(param_get32ex(Cmd,2,0,16),4,htd->auth.NrAr+4);
253 } break;
254 case RHT2F_TEST_AUTH_ATTEMPTS: {
255 // No additional parameters needed
256 } break;
257 case RHT2F_UID_ONLY: {
258 // No additional parameters needed
259 } break;
260 default: {
261 PrintAndLog("\nError: unkown reader function %d",htf);
262 PrintAndLog("");
263 PrintAndLog("Usage: hitag reader <Reader Function #>");
264 PrintAndLog("Reader Functions:");
265 PrintAndLog(" HitagS (0*)");
266 PrintAndLog(" 01 <nr> <ar> (Challenge) <firstPage> <tagmode> read all pages from a Hitag S tag");
267 PrintAndLog(" 02 <key> (set to 0 if no authentication is needed) <firstPage> <tagmode> read all pages from a Hitag S tag");
268 PrintAndLog(" 03 <nr> <ar> (Challenge) <firstPage> <tagmode> read all blocks from a Hitag S tag");
269 PrintAndLog(" 04 <key> (set to 0 if no authentication is needed) <firstPage> <tagmode> read all blocks from a Hitag S tag");
270 PrintAndLog(" Valid tagmodes are 0=STANDARD, 1=ADVANCED, 2=FAST_ADVANCED (default is ADVANCED)");
271 PrintAndLog(" Hitag1 (1*)");
272 PrintAndLog(" Hitag2 (2*)");
273 PrintAndLog(" 21 <password> (password mode)");
274 PrintAndLog(" 22 <nr> <ar> (authentication)");
275 PrintAndLog(" 23 <key> (authentication) key is in format: ISK high + ISK low");
276 PrintAndLog(" 25 (test recorded authentications)");
277 PrintAndLog(" 26 just read UID");
278 return 1;
279 } break;
280 }
281
282 // Copy the hitag2 function into the first argument
283 c.arg[0] = htf;
284
285 // Send the command to the proxmark
286 clearCommandBuffer();
287 SendCommand(&c);
288
289 UsbCommand resp;
290 WaitForResponse(CMD_ACK,&resp);
291
292 // Check the return status, stored in the first argument
293 if (resp.arg[0] == false) return 1;
294
295 uint32_t id = bytes_to_num(resp.d.asBytes,4);
296
297 if (htf == RHT2F_UID_ONLY){
298 PrintAndLog("Valid Hitag2 tag found - UID: %08x",id);
299 } else {
300 char filename[256];
301 FILE* pf = NULL;
302
303 sprintf(filename,"%08x_%04x.ht2",id,(rand() & 0xffff));
304 if ((pf = fopen(filename,"wb")) == NULL) {
305 PrintAndLog("Error: Could not open file [%s]",filename);
306 return 1;
307 }
308
309 // Write the 48 tag memory bytes to file and finalize
310 fwrite(resp.d.asBytes,1,48,pf);
311 fclose(pf);
312
313 PrintAndLog("Succesfully saved tag memory to [%s]",filename);
314 }
315
316
317 return 0;
318 }
319
320
321 int CmdLFHitagSimS(const char *Cmd) {
322 UsbCommand c = { CMD_SIMULATE_HITAG_S };
323 char filename[FILE_PATH_SIZE] = { 0x00 };
324 FILE* pf;
325 bool tag_mem_supplied;
326 int len = strlen(Cmd);
327 if (len > FILE_PATH_SIZE)
328 len = FILE_PATH_SIZE;
329 memcpy(filename, Cmd, len);
330
331 if (strlen(filename) > 0) {
332 if ((pf = fopen(filename, "rb+")) == NULL) {
333 PrintAndLog("Error: Could not open file [%s]", filename);
334 return 1;
335 }
336 tag_mem_supplied = true;
337 if (fread(c.d.asBytes, 1, 4*64, pf) != 4*64) {
338 PrintAndLog("Error: File reading error");
339 fclose(pf);
340 return 1;
341 }
342 fclose(pf);
343 } else {
344 tag_mem_supplied = false;
345 }
346
347 // Does the tag comes with memory
348 c.arg[0] = (uint32_t) tag_mem_supplied;
349
350 SendCommand(&c);
351 return 0;
352 }
353
354 int CmdLFHitagCheckChallenges(const char *Cmd) {
355 UsbCommand c = { CMD_TEST_HITAGS_TRACES };
356 char filename[FILE_PATH_SIZE] = { 0x00 };
357 FILE* pf;
358 bool file_given;
359 int len = strlen(Cmd);
360 if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE;
361 memcpy(filename, Cmd, len);
362
363 if (strlen(filename) > 0) {
364 if ((pf = fopen(filename,"rb+")) == NULL) {
365 PrintAndLog("Error: Could not open file [%s]",filename);
366 return 1;
367 }
368 file_given = true;
369 if (fread(c.d.asBytes,1,8*60,pf) != 8*60) {
370 PrintAndLog("Error: File reading error");
371 fclose(pf);
372 return 1;
373 }
374 fclose(pf);
375 } else {
376 file_given = false;
377 }
378
379 //file with all the challenges to try
380 c.arg[0] = (uint32_t)file_given;
381 c.arg[1] = param_get64ex(Cmd,2,0,0); //get mode
382
383 SendCommand(&c);
384 return 0;
385 }
386
387
388 int CmdLFHitagWP(const char *Cmd) {
389 UsbCommand c = { CMD_WR_HITAG_S };
390 hitag_data* htd = (hitag_data*)c.d.asBytes;
391 hitag_function htf = param_get32ex(Cmd,0,0,10);
392 switch (htf) {
393 case 03: { //WHTSF_CHALLENGE
394 num_to_bytes(param_get64ex(Cmd,1,0,16),8,htd->auth.NrAr);
395 c.arg[2]= param_get32ex(Cmd, 2, 0, 10);
396 num_to_bytes(param_get32ex(Cmd,3,0,16),4,htd->auth.data);
397 } break;
398 case 04:
399 case 24:
400 { //WHTSF_KEY
401 num_to_bytes(param_get64ex(Cmd,1,0,16),6,htd->crypto.key);
402 c.arg[2]= param_get32ex(Cmd, 2, 0, 10);
403 num_to_bytes(param_get32ex(Cmd,3,0,16),4,htd->crypto.data);
404
405 } break;
406 default: {
407 PrintAndLog("Error: unkown writer function %d",htf);
408 PrintAndLog("Hitag writer functions");
409 PrintAndLog(" HitagS (0*)");
410 PrintAndLog(" 03 <nr,ar> (Challenge) <page> <byte0...byte3> write page on a Hitag S tag");
411 PrintAndLog(" 04 <key> (set to 0 if no authentication is needed) <page> <byte0...byte3> write page on a Hitag S tag");
412 PrintAndLog(" Hitag1 (1*)");
413 PrintAndLog(" Hitag2 (2*)");
414 PrintAndLog(" 24 <key> (set to 0 if no authentication is needed) <page> <byte0...byte3> write page on a Hitag S tag");
415 return 1;
416 } break;
417 }
418 // Copy the hitag function into the first argument
419 c.arg[0] = htf;
420
421 // Send the command to the proxmark
422 SendCommand(&c);
423
424 UsbCommand resp;
425 WaitForResponse(CMD_ACK,&resp);
426
427 // Check the return status, stored in the first argument
428 if (resp.arg[0] == false) return 1;
429 return 0;
430 }
431
432
433 static command_t CommandTable[] =
434 {
435 {"help", CmdHelp, 1, "This help"},
436 {"list", CmdLFHitagList, 1, "<outfile> List Hitag trace history"},
437 {"reader", CmdLFHitagReader, 1, "Act like a Hitag Reader"},
438 {"sim", CmdLFHitagSim, 1, "<infile> Simulate Hitag transponder"},
439 {"snoop", CmdLFHitagSnoop, 1, "Eavesdrop Hitag communication"},
440 {"writer", CmdLFHitagWP, 1, "Act like a Hitag Writer" },
441 {"simS", CmdLFHitagSimS, 1, "<hitagS.hts> Simulate HitagS transponder" },
442 {"checkChallenges", CmdLFHitagCheckChallenges, 1, "<challenges.cc> <tagmode> test all challenges" }, {
443 NULL,NULL, 0, NULL }
444 };
445
446 int CmdLFHitag(const char *Cmd)
447 {
448 CmdsParse(CommandTable, Cmd);
449 return 0;
450 }
451
452 int CmdHelp(const char *Cmd)
453 {
454 CmdsHelp(CommandTable);
455 return 0;
456 }
Impressum, Datenschutz