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