]> git.zerfleddert.de Git - proxmark3-svn/blob - client/cmdhficlass.c
MAJOR update, added hitag2 reader, emulation and eavesdropping, lots of new code...
[proxmark3-svn] / client / cmdhficlass.c
1 //-----------------------------------------------------------------------------
2 // Copyright (C) 2010 iZsh <izsh at fail0verflow.com>, Hagen Fritsch
3 // Copyright (C) 2011 Gerhard de Koning Gans
4 //
5 // This code is licensed to you under the terms of the GNU GPL, version 2 or,
6 // at your option, any later version. See the LICENSE.txt file for the text of
7 // the license.
8 //-----------------------------------------------------------------------------
9 // High frequency iClass commands
10 //-----------------------------------------------------------------------------
11
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include "iso14443crc.h" // Can also be used for iClass, using 0xE012 as CRC-type
16 #include "data.h"
17 #include "proxusb.h"
18 #include "ui.h"
19 #include "cmdparser.h"
20 #include "cmdhficlass.h"
21 #include "common.h"
22 #include "util.h"
23
24 static int CmdHelp(const char *Cmd);
25
26 int CmdHFiClassList(const char *Cmd)
27 {
28 uint8_t got[1920];
29 GetFromBigBuf(got,sizeof(got),0);
30
31 PrintAndLog("recorded activity:");
32 PrintAndLog(" ETU :rssi: who bytes");
33 PrintAndLog("---------+----+----+-----------");
34
35 int i = 0;
36 int prev = -1;
37
38 for (;;) {
39 if(i >= 1900) {
40 break;
41 }
42
43 bool isResponse;
44 int timestamp = *((uint32_t *)(got+i));
45 if (timestamp & 0x80000000) {
46 timestamp &= 0x7fffffff;
47 isResponse = 1;
48 } else {
49 isResponse = 0;
50 }
51
52 int metric = 0;
53 int parityBits = *((uint32_t *)(got+i+4));
54 // 4 bytes of additional information...
55 // maximum of 32 additional parity bit information
56 //
57 // TODO:
58 // at each quarter bit period we can send power level (16 levels)
59 // or each half bit period in 256 levels.
60
61
62 int len = got[i+8];
63
64 if (len > 100) {
65 break;
66 }
67 if (i + len >= 1900) {
68 break;
69 }
70
71 uint8_t *frame = (got+i+9);
72
73 // Break and stick with current result if buffer was not completely full
74 if (frame[0] == 0x44 && frame[1] == 0x44 && frame[3] == 0x44) { break; }
75
76 char line[1000] = "";
77 int j;
78 for (j = 0; j < len; j++) {
79 int oddparity = 0x01;
80 int k;
81
82 for (k=0;k<8;k++) {
83 oddparity ^= (((frame[j] & 0xFF) >> k) & 0x01);
84 }
85
86 //if((parityBits >> (len - j - 1)) & 0x01) {
87 if (isResponse && (oddparity != ((parityBits >> (len - j - 1)) & 0x01))) {
88 sprintf(line+(j*4), "%02x! ", frame[j]);
89 }
90 else {
91 sprintf(line+(j*4), "%02x ", frame[j]);
92 }
93 }
94
95 char *crc;
96 crc = "";
97 if (len > 2) {
98 uint8_t b1, b2;
99 for (j = 0; j < (len - 1); j++) {
100 // gives problems... search for the reason..
101 /*if(frame[j] == 0xAA) {
102 switch(frame[j+1]) {
103 case 0x01:
104 crc = "[1] Two drops close after each other";
105 break;
106 case 0x02:
107 crc = "[2] Potential SOC with a drop in second half of bitperiod";
108 break;
109 case 0x03:
110 crc = "[3] Segment Z after segment X is not possible";
111 break;
112 case 0x04:
113 crc = "[4] Parity bit of a fully received byte was wrong";
114 break;
115 default:
116 crc = "[?] Unknown error";
117 break;
118 }
119 break;
120 }*/
121 }
122
123 if (strlen(crc)==0) {
124 if(!isResponse && len == 4) {
125 // Rough guess that this is a command from the reader
126 // For iClass the command byte is not part of the CRC
127 ComputeCrc14443(CRC_ICLASS, &frame[1], len-3, &b1, &b2);
128 }
129 else {
130 // For other data.. CRC might not be applicable (UPDATE commands etc.)
131 ComputeCrc14443(CRC_ICLASS, frame, len-2, &b1, &b2);
132 }
133 //printf("%1x %1x",(unsigned)b1,(unsigned)b2);
134 if (b1 != frame[len-2] || b2 != frame[len-1]) {
135 crc = (isResponse & (len < 8)) ? "" : " !crc";
136 } else {
137 crc = "";
138 }
139 }
140 } else {
141 crc = ""; // SHORT
142 }
143
144 char metricString[100];
145 if (isResponse) {
146 sprintf(metricString, "%3d", metric);
147 } else {
148 strcpy(metricString, " ");
149 }
150
151 PrintAndLog(" +%7d: %s: %s %s %s",
152 (prev < 0 ? 0 : (timestamp - prev)),
153 metricString,
154 (isResponse ? "TAG" : " "), line, crc);
155
156 prev = timestamp;
157 i += (len + 9);
158 }
159 return 0;
160 }
161
162 /*void iso14a_set_timeout(uint32_t timeout) {
163 UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_SET_TIMEOUT, 0, timeout}};
164 SendCommand(&c);
165 }*/
166
167 int CmdHFiClassSnoop(const char *Cmd)
168 {
169 UsbCommand c = {CMD_SNOOP_ICLASS};
170 SendCommand(&c);
171 return 0;
172 }
173
174 int CmdHFiClassSim(const char *Cmd)
175 {
176 uint8_t simType = 0;
177 uint8_t CSN[8] = {0, 0, 0, 0, 0, 0, 0, 0};
178
179 if (strlen(Cmd)<2) {
180 PrintAndLog("Usage: hf iclass sim <sim type> <CSN (16 hex symbols)>");
181 PrintAndLog(" sample: hf iclass sim 0 031FEC8AF7FF12E0");
182 return 0;
183 }
184
185 simType = param_get8(Cmd, 0);
186 if (param_gethex(Cmd, 1, CSN, 16)) {
187 PrintAndLog("A CSN should consist of 16 HEX symbols");
188 return 1;
189 }
190 PrintAndLog("--simtype:%02x csn:%s", simType, sprint_hex(CSN, 8));
191
192 UsbCommand c = {CMD_SIMULATE_TAG_ICLASS, {simType}};
193 memcpy(c.d.asBytes, CSN, 8);
194 SendCommand(&c);
195
196 /*UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 1500);
197 if (resp != NULL) {
198 uint8_t isOK = resp->arg[0] & 0xff;
199 PrintAndLog("isOk:%02x", isOK);
200 } else {
201 PrintAndLog("Command execute timeout");
202 }*/
203
204 return 0;
205 }
206
207 int CmdHFiClassReader(const char *Cmd)
208 {
209 uint8_t readerType = 0;
210
211 if (strlen(Cmd)<1) {
212 PrintAndLog("Usage: hf iclass reader <reader type>");
213 PrintAndLog(" sample: hf iclass reader 0");
214 return 0;
215 }
216
217 readerType = param_get8(Cmd, 0);
218 PrintAndLog("--readertype:%02x", readerType);
219
220 UsbCommand c = {CMD_READER_ICLASS, {readerType}};
221 //memcpy(c.d.asBytes, CSN, 8);
222 SendCommand(&c);
223
224 /*UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 1500);
225 if (resp != NULL) {
226 uint8_t isOK = resp->arg[0] & 0xff;
227 PrintAndLog("isOk:%02x", isOK);
228 } else {
229 PrintAndLog("Command execute timeout");
230 }*/
231
232 return 0;
233 }
234
235 static command_t CommandTable[] =
236 {
237 {"help", CmdHelp, 1, "This help"},
238 {"list", CmdHFiClassList, 0, "List iClass history"},
239 {"snoop", CmdHFiClassSnoop, 0, "Eavesdrop iClass communication"},
240 {"sim", CmdHFiClassSim, 0, "Simulate iClass tag"},
241 {"reader", CmdHFiClassReader, 0, "Read an iClass tag"},
242 {NULL, NULL, 0, NULL}
243 };
244
245 int CmdHFiClass(const char *Cmd)
246 {
247 CmdsParse(CommandTable, Cmd);
248 return 0;
249 }
250
251 int CmdHelp(const char *Cmd)
252 {
253 CmdsHelp(CommandTable);
254 return 0;
255 }
Impressum, Datenschutz