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