]> git.zerfleddert.de Git - proxmark3-svn/blame - client/cmdhf14b.c
Merge pull request #114 from pwpiwi/iso14443b_fix
[proxmark3-svn] / client / cmdhf14b.c
CommitLineData
a553f267 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
7fe9b0b7 11#include <stdio.h>
12#include <stdlib.h>
13#include <stdbool.h>
14#include <string.h>
15#include <stdint.h>
16#include "iso14443crc.h"
902cb3c0 17#include "proxmark3.h"
7fe9b0b7 18#include "data.h"
19#include "graph.h"
3fe4ff4f 20#include "util.h"
7fe9b0b7 21#include "ui.h"
22#include "cmdparser.h"
23#include "cmdhf14b.h"
7cf3ef20 24#include "cmdmain.h"
7fe9b0b7 25
26static int CmdHelp(const char *Cmd);
27
7fe9b0b7 28int CmdHF14BList(const char *Cmd)
29{
388c92bd 30 PrintAndLog("Deprecated command, use 'hf list 14b' instead");
7fe9b0b7 31
388c92bd 32 return 0;
7fe9b0b7 33}
7fe9b0b7 34
132a0217 35int CmdHF14BSim(const char *Cmd)
7fe9b0b7 36{
132a0217 37 UsbCommand c={CMD_SIMULATE_TAG_ISO_14443B};
7fe9b0b7 38 SendCommand(&c);
39 return 0;
40}
41
42int CmdHF14BSnoop(const char *Cmd)
43{
132a0217 44 UsbCommand c = {CMD_SNOOP_ISO_14443B};
7fe9b0b7 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 */
53int 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 */
64int 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
7cf3ef20 71int 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;
5ee70129 80 uint8_t data[100] = {0x00};
7cf3ef20 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");
5ee70129 134 return 1;
7cf3ef20 135 }
06b82e6a 136 if (datalen == 0)
137 {
138 PrintAndLog("Missing data input");
139 return 0;
140 }
7cf3ef20 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]);
51d4f6f1 160 if(resp.arg[0] == 0)
7cf3ef20 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
7bb9d33e 166 sprintf(&hexout[i * 3], "%02X ", recv[i]);
7cf3ef20 167 }
168 PrintAndLog("%s", hexout);
169 free(hexout);
51d4f6f1 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 }
7cf3ef20 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
3fe4ff4f 188int 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
b5be31f9 206 if (strlen(Cmd) < 1 || cmdp == 'h' || cmdp == 'H') {
3fe4ff4f 207 PrintAndLog("Usage: hf 14b write <1|2> <BLOCK> <DATA>");
b5be31f9 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");
3fe4ff4f 215 return 0;
216 }
217
b5be31f9 218 if ( cmdp == '2' )
3fe4ff4f 219 isSrix4k = false;
220
b5be31f9 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 }
3fe4ff4f 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)
b5be31f9 246 PrintAndLog("[%s] Write special block %02X [ %s ]", (isSrix4k)?"SRIX4K":"SRI512" , blockno, sprint_hex(data,4) );
3fe4ff4f 247 else
b5be31f9 248 PrintAndLog("[%s] Write block %02X [ %s ]", (isSrix4k)?"SRIX4K":"SRI512", blockno, sprint_hex(data,4) );
3fe4ff4f 249
fe5b3a44 250 sprintf(str, "-c 09 %02x %02x%02x%02x%02x", blockno, data[0], data[1], data[2], data[3]);
b5be31f9 251
3fe4ff4f 252 CmdHF14BCmdRaw(str);
253 return 0;
254}
255
7fe9b0b7 256static command_t CommandTable[] =
257{
258 {"help", CmdHelp, 1, "This help"},
388c92bd 259 {"list", CmdHF14BList, 0, "[Deprecated] List ISO 14443b history"},
132a0217 260 {"sim", CmdHF14BSim, 0, "Fake ISO 14443B tag"},
261 {"snoop", CmdHF14BSnoop, 0, "Eavesdrop ISO 14443B"},
7cf3ef20 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"},
3fe4ff4f 265 {"write", CmdHF14BWrite, 0, "Write data to a SRI512 | SRIX4K tag"},
7fe9b0b7 266 {NULL, NULL, 0, NULL}
267};
268
269int CmdHF14B(const char *Cmd)
270{
271 CmdsParse(CommandTable, Cmd);
272 return 0;
273}
274
275int CmdHelp(const char *Cmd)
276{
277 CmdsHelp(CommandTable);
278 return 0;
279}
Impressum, Datenschutz