]> git.zerfleddert.de Git - proxmark3-svn/blob - client/cmdhf14b.c
fixing iso 14443b (issue #103):
[proxmark3-svn] / client / cmdhf14b.c
1 //-----------------------------------------------------------------------------
2 // Copyright (C) 2010 iZsh <izsh at fail0verflow.com>
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 // High frequency ISO14443B commands
9 //-----------------------------------------------------------------------------
10
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <stdbool.h>
14 #include <string.h>
15 #include <stdint.h>
16 #include "iso14443crc.h"
17 #include "proxmark3.h"
18 #include "data.h"
19 #include "graph.h"
20 #include "util.h"
21 #include "ui.h"
22 #include "cmdparser.h"
23 #include "cmdhf14b.h"
24 #include "cmdmain.h"
25
26 static int CmdHelp(const char *Cmd);
27
28 int CmdHF14BList(const char *Cmd)
29 {
30 PrintAndLog("Deprecated command, use 'hf list 14b' instead");
31
32 return 0;
33 }
34
35 int CmdHF14BSim(const char *Cmd)
36 {
37 UsbCommand c={CMD_SIMULATE_TAG_ISO_14443B};
38 SendCommand(&c);
39 return 0;
40 }
41
42 int CmdHF14BSnoop(const char *Cmd)
43 {
44 UsbCommand c = {CMD_SNOOP_ISO_14443B};
45 SendCommand(&c);
46 return 0;
47 }
48
49 /* New command to read the contents of a SRI512 tag
50 * SRI512 tags are ISO14443-B modulated memory tags,
51 * this command just dumps the contents of the memory
52 */
53 int CmdSri512Read(const char *Cmd)
54 {
55 UsbCommand c = {CMD_READ_SRI512_TAG, {strtol(Cmd, NULL, 0), 0, 0}};
56 SendCommand(&c);
57 return 0;
58 }
59
60 /* New command to read the contents of a SRIX4K tag
61 * SRIX4K tags are ISO14443-B modulated memory tags,
62 * this command just dumps the contents of the memory/
63 */
64 int CmdSrix4kRead(const char *Cmd)
65 {
66 UsbCommand c = {CMD_READ_SRIX4K_TAG, {strtol(Cmd, NULL, 0), 0, 0}};
67 SendCommand(&c);
68 return 0;
69 }
70
71 int CmdHF14BCmdRaw (const char *cmd) {
72 UsbCommand resp;
73 uint8_t *recv;
74 UsbCommand c = {CMD_ISO_14443B_COMMAND, {0, 0, 0}}; // len,recv?
75 uint8_t reply=1;
76 uint8_t crc=0;
77 uint8_t power=0;
78 char buf[5]="";
79 int i=0;
80 uint8_t data[100] = {0x00};
81 unsigned int datalen=0, temp;
82 char *hexout;
83
84 if (strlen(cmd)<3) {
85 PrintAndLog("Usage: hf 14b raw [-r] [-c] [-p] <0A 0B 0C ... hex>");
86 PrintAndLog(" -r do not read response");
87 PrintAndLog(" -c calculate and append CRC");
88 PrintAndLog(" -p leave the field on after receive");
89 return 0;
90 }
91
92 // strip
93 while (*cmd==' ' || *cmd=='\t') cmd++;
94
95 while (cmd[i]!='\0') {
96 if (cmd[i]==' ' || cmd[i]=='\t') { i++; continue; }
97 if (cmd[i]=='-') {
98 switch (cmd[i+1]) {
99 case 'r':
100 case 'R':
101 reply=0;
102 break;
103 case 'c':
104 case 'C':
105 crc=1;
106 break;
107 case 'p':
108 case 'P':
109 power=1;
110 break;
111 default:
112 PrintAndLog("Invalid option");
113 return 0;
114 }
115 i+=2;
116 continue;
117 }
118 if ((cmd[i]>='0' && cmd[i]<='9') ||
119 (cmd[i]>='a' && cmd[i]<='f') ||
120 (cmd[i]>='A' && cmd[i]<='F') ) {
121 buf[strlen(buf)+1]=0;
122 buf[strlen(buf)]=cmd[i];
123 i++;
124
125 if (strlen(buf)>=2) {
126 sscanf(buf,"%x",&temp);
127 data[datalen]=(uint8_t)(temp & 0xff);
128 datalen++;
129 *buf=0;
130 }
131 continue;
132 }
133 PrintAndLog("Invalid char on input");
134 return 1;
135 }
136 if (datalen == 0)
137 {
138 PrintAndLog("Missing data input");
139 return 0;
140 }
141 if(crc)
142 {
143 uint8_t first, second;
144 ComputeCrc14443(CRC_14443_B, data, datalen, &first, &second);
145 data[datalen++] = first;
146 data[datalen++] = second;
147 }
148
149 c.arg[0] = datalen;
150 c.arg[1] = reply;
151 c.arg[2] = power;
152 memcpy(c.d.asBytes,data,datalen);
153
154 SendCommand(&c);
155
156 if (reply) {
157 if (WaitForResponseTimeout(CMD_ACK,&resp,1000)) {
158 recv = resp.d.asBytes;
159 PrintAndLog("received %i octets",resp.arg[0]);
160 if(resp.arg[0] == 0)
161 return 0;
162 hexout = (char *)malloc(resp.arg[0] * 3 + 1);
163 if (hexout != NULL) {
164 uint8_t first, second;
165 for (int i = 0; i < resp.arg[0]; i++) { // data in hex
166 sprintf(&hexout[i * 3], "%02X ", recv[i]);
167 }
168 PrintAndLog("%s", hexout);
169 free(hexout);
170 if (resp.arg[0] > 2) {
171 ComputeCrc14443(CRC_14443_B, recv, resp.arg[0]-2, &first, &second);
172 if(recv[resp.arg[0]-2]==first && recv[resp.arg[0]-1]==second) {
173 PrintAndLog("CRC OK");
174 } else {
175 PrintAndLog("CRC failed");
176 }
177 }
178 } else {
179 PrintAndLog("malloc failed your client has low memory?");
180 }
181 } else {
182 PrintAndLog("timeout while waiting for reply.");
183 }
184 } // if reply
185 return 0;
186 }
187
188 int CmdHF14BWrite( const char *Cmd){
189
190 /*
191 * For SRIX4K blocks 00 - 7F
192 * hf 14b raw -c -p 09 $srix4kwblock $srix4kwdata
193 *
194 * For SR512 blocks 00 - 0F
195 * hf 14b raw -c -p 09 $sr512wblock $sr512wdata
196 *
197 * Special block FF = otp_lock_reg block.
198 * Data len 4 bytes-
199 */
200 char cmdp = param_getchar(Cmd, 0);
201 uint8_t blockno = -1;
202 uint8_t data[4] = {0x00};
203 bool isSrix4k = true;
204 char str[20];
205
206 if (strlen(Cmd) < 1 || cmdp == 'h' || cmdp == 'H') {
207 PrintAndLog("Usage: hf 14b write <1|2> <BLOCK> <DATA>");
208 PrintAndLog(" [1 = SRIX4K]");
209 PrintAndLog(" [2 = SRI512]");
210 PrintAndLog(" [BLOCK number depends on tag, special block == FF]");
211 PrintAndLog(" sample: hf 14b write 1 7F 11223344");
212 PrintAndLog(" : hf 14b write 1 FF 11223344");
213 PrintAndLog(" : hf 14b write 2 15 11223344");
214 PrintAndLog(" : hf 14b write 2 FF 11223344");
215 return 0;
216 }
217
218 if ( cmdp == '2' )
219 isSrix4k = false;
220
221 //blockno = param_get8(Cmd, 1);
222
223 if ( param_gethex(Cmd,1, &blockno, 2) ) {
224 PrintAndLog("Block number must include 2 HEX symbols");
225 return 0;
226 }
227
228 if ( isSrix4k ){
229 if ( blockno > 0x7f && blockno != 0xff ){
230 PrintAndLog("Block number out of range");
231 return 0;
232 }
233 } else {
234 if ( blockno > 0x0f && blockno != 0xff ){
235 PrintAndLog("Block number out of range");
236 return 0;
237 }
238 }
239
240 if (param_gethex(Cmd, 2, data, 8)) {
241 PrintAndLog("Data must include 8 HEX symbols");
242 return 0;
243 }
244
245 if ( blockno == 0xff)
246 PrintAndLog("[%s] Write special block %02X [ %s ]", (isSrix4k)?"SRIX4K":"SRI512" , blockno, sprint_hex(data,4) );
247 else
248 PrintAndLog("[%s] Write block %02X [ %s ]", (isSrix4k)?"SRIX4K":"SRI512", blockno, sprint_hex(data,4) );
249
250 sprintf(str, "-c 09 %02x %02x%02x%02x%02x", blockno, data[0], data[1], data[2], data[3]);
251
252 CmdHF14BCmdRaw(str);
253 return 0;
254 }
255
256 static command_t CommandTable[] =
257 {
258 {"help", CmdHelp, 1, "This help"},
259 {"list", CmdHF14BList, 0, "[Deprecated] List ISO 14443b history"},
260 {"sim", CmdHF14BSim, 0, "Fake ISO 14443B tag"},
261 {"snoop", CmdHF14BSnoop, 0, "Eavesdrop ISO 14443B"},
262 {"sri512read", CmdSri512Read, 0, "Read contents of a SRI512 tag"},
263 {"srix4kread", CmdSrix4kRead, 0, "Read contents of a SRIX4K tag"},
264 {"raw", CmdHF14BCmdRaw, 0, "Send raw hex data to tag"},
265 {"write", CmdHF14BWrite, 0, "Write data to a SRI512 | SRIX4K tag"},
266 {NULL, NULL, 0, NULL}
267 };
268
269 int CmdHF14B(const char *Cmd)
270 {
271 CmdsParse(CommandTable, Cmd);
272 return 0;
273 }
274
275 int CmdHelp(const char *Cmd)
276 {
277 CmdsHelp(CommandTable);
278 return 0;
279 }
Impressum, Datenschutz