]> git.zerfleddert.de Git - proxmark3-svn/blob - client/lualibs/hf_reader.lua
First steps towards creating a generic HF reader/identifier. A coop with Asper.
[proxmark3-svn] / client / lualibs / hf_reader.lua
1 [[
2 THIS IS WORK IN PROGREESS, very much not finished.
3
4 This library utilises other libraries under the hood, but can be used as a generic reader for 13.56MHz tags.
5 ]]
6
7 local reader14443A = require('read14a')
8
9 local function sendToDevice(command, ignoreresponse)
10 core.clearCommandBuffer()
11 local err = core.SendCommand(command:getBytes())
12 if err then
13 print(err)
14 return nil, err
15 end
16 if ignoreresponse then return nil,nil end
17
18 local response = core.WaitForResponseTimeout(cmds.CMD_ACK,TIMEOUT)
19 return response,nil
20 end
21
22 -------------------------------------------------------
23 -- This will be moved to a separate 14443B library
24 -------------------------------------------------------
25
26 local function read14443B()
27 return nil, "Not implemented"
28 end
29 local reader14443B = {
30 read = read14443B
31 }
32
33
34 -------------------------------------------------------
35 -- This will be moved to a separate 1593 library
36 -------------------------------------------------------
37
38 local function errorString15693(number)
39 local errors = {
40 0x01 : "The command is not supported",
41 0x02 : "The command is not recognised",
42 0x03 : "The option is not supported.",
43 0x0f : "Unknown error.",
44 0x10 : "The specified block is not available (doesn’t exist).",
45 0x11 : "The specified block is already -locked and thus cannot be locked again",
46 0x12 : "The specified block is locked and its content cannot be changed.",
47 0x13 : "The specified block was not successfully programmed.",
48 0x14 : "The specified block was not successfully locked.",
49 }
50 return errors[number] or "Reserved for Future Use or Custom command error."
51 end
52 -------------------------------------------------------
53 -- This will be moved to a separate 1593 library
54 -------------------------------------------------------
55
56 local function parse15693(data)
57 -- From common/iso15693tools.h :
58 --[[
59 #define ISO15_CRC_CHECK ((uint16_t)(~0xF0B8 & 0xFFFF)) // use this for checking of a correct crc
60 --]]
61 -- But that is very strange. Basically what is says is:
62 -- define ISO15_CRC_CHECK 0F47
63 -- So we can just use that directly...
64 -- The following code is based on cmdhf15.c around line 666 (NoTB!) and onwards
65 if core.iso15693_crc(data, string.len(data)) ~= 0xF47 then
66 return nil, "CRC failed"
67 else if data[1] % 2 == 1 then
68 -- Above is a poor-mans bit check:
69 -- recv[0] & ISO15_RES_ERROR //(0x01)
70 local err = "Tag returned error %i: %s"
71 err = string.format(err, data[1],errorString15693(data[1]))
72 return nil, err
73 end
74 -- Finally, let the parsing begin...
75 -- the UID is just the data in reverse... almost:
76 -- 0FC481FF70000104E001001B0301
77 -- 8877665544332211
78 -- UID = E004010070FF81C4
79 -- 1122334455667788
80 -- So, cut out the relevant part and reverse it
81 local uid = data:sub(2,9):reverse()
82 local uidStr = bin.unpack("H8", uid)
83
84 local _,manufacturer_code = bin.unpack("s",uid:sub(2,2))
85 local _,tag_size = bin.unpack(">I",data:sub(12,13))
86 local _,micref_modelcode = bin.unpack("s",data:sub(14,14))
87
88 return {
89 uid = uidStr,
90 manufacturer_code = manufacturer_code,
91 tag_size = tag_size,
92 micref_modelcode = micref_modelcode,
93 }
94 end
95 -------------------------------------------------------
96 -- This will be moved to a separate 1593 library
97 -------------------------------------------------------
98
99 local function read15693()
100 [[
101
102 We start by trying this command:
103
104 proxmark3> hf 15 cmd sysinfo -2 u
105 0F C4 81 FF 70 00 01 04 E0 01 00 1B 03 01
106 UID = E004010070FF81C4
107 Philips; IC SL2 ICS20
108 DSFID supported, set to 01
109 AFI supported, set to 000
110 Tag provides info on memory layout (vendor dependent)
111 4 (or 3) bytes/page x 28 pages
112 IC reference given: 01
113
114 This command is not always present in ISO15693 tags (it is an optional standard command) but if it is present usually the tags contain all the "colored" info above.
115
116 If the above command doesn't give an answer (see example below):
117
118 proxmark3> hf 15 cmd sysinfo -2 u
119 timeout: no
120
121 we must send the MANDATORY (present in ALL iso15693 tags) command (the example below is sent to a tag different from the above one):
122
123 proxmark3> hf 15 cmd inquiry
124 UID=E007C1A257394244
125 Tag Info: Texas Instrument; Tag-it HF-I Standard; 8x32bit
126 proxmark3>
127
128 From which we obtain less information than the above one.
129 ]]
130
131 local command, result, info, err, data
132 local data = "02"
133 local datalen = string.len(data) / 2
134 local speed = 1
135 local recv = 1
136 command = Command:new{cmd = cmds.CMD_ISO_15693_COMMAND,
137 arg1 = datalen,arg2 = speed,arg3 =recv, data=data}
138 -- These are defined in common/iso15693tools.h
139
140 -- #define ISO15_REQ_SUBCARRIER_SINGLE 0x00 // Tag should respond using one subcarrier (ASK)
141 -- #define ISO15_REQ_DATARATE_HIGH 0x02 // Tag should respond using high data rate
142 -- #define ISO15_REQ_NONINVENTORY 0x00
143
144 local result,err = sendToDevice(command)
145
146 if not result then
147 print(err)
148 return nil, "15693 sysinfo: no answer"
149 end
150
151 local count,cmd,recvLen,arg1,arg2 = bin.unpack('LLLL',result)
152 data = string.sub(result,recvlen)
153 info, err = parse15693(data)
154
155 if err then
156 return nil, err
157 end
158
159 return info
160 end
161
162
163 }
164 local reader15693 = {
165 read = read15693
166 }
167
168
169 ---
170 -- This method library can be set waits or a 13.56 MHz tag, and when one is found, returns info about
171 -- what tag it is.
172 --
173 -- @return if successfull: an table containing card info
174 -- @return if unsuccessfull : nil, error
175 local function waitForTag()
176 print("Waiting for card... press any key to quit")
177 local readers = [reader14443A, reader14443B, readerISO15693]
178 local r
179 while not core.ukbhit() do
180 for _, r in ipairs(readers) do
181 res, err = r.read()
182 if res then return res end
183 -- err means that there was no response from card
184 end
185 return nil, "Aborted by user"
186 end
Impressum, Datenschutz