maur keys
[RRG-proxmark3.git] / client / luascripts / hf_14a_raw.lua
blob1d087a1c40eb6cefa4c475ada5be5c30e9b2e9e4
1 local cmds = require('commands')
2 local getopt = require('getopt')
3 local lib14a = require('read14a')
4 local ansicolors = require('ansicolors')
6 copyright = ''
7 author = "Martin Holst Swende"
8 version = 'v1.0.2'
9 desc = [[
10 This is a script to allow raw 14443a commands to be sent and received.
12 example = [[
13 # 1. Connect and don't disconnect
14 script run hf_14a_raw -k
16 # 2. Send mf auth, read response (nonce)
17 script run hf_14a_raw -o -x 6000F57b -k
19 # 3. disconnect
20 script run hf_14a_raw -o
22 # All three steps in one go:
23 script run hf_14a_raw -x 6000F57b
25 usage = [[
26 script run hf_14a_raw -x 6000F57b
28 arguments = [[
29 -o do not connect - use this only if you previously used -k to stay connected
30 -r do not read response
31 -c calculate and append CRC
32 -k stay connected - dont inactivate the field
33 -x <payload> Data to send (NO SPACES!)
34 -d Debug flag
35 -t Topaz mode
36 -3 ISO14443-4 (use RATS)
39 --[[
41 This script communicates with
42 /armsrc/iso14443a.c, specifically ReaderIso14443a() at around line 1779 and onwards.
44 Check there for details about data format and how commands are interpreted on the
45 device-side.
48 -- Some globals
49 local DEBUG = false -- the debug flag
51 -------------------------------
52 -- Some utilities
53 -------------------------------
55 ---
56 -- A debug printout-function
57 local function dbg(args)
58 if not DEBUG then return end
59 if type(args) == 'table' then
60 local i = 1
61 while args[i] do
62 dbg(args[i])
63 i = i+1
64 end
65 else
66 print('###', args)
67 end
68 end
69 ---
70 -- This is only meant to be used when errors occur
71 local function oops(err)
72 print('ERROR:', err)
73 core.clearCommandBuffer()
74 return nil, err
75 end
76 ---
77 -- Usage help
78 local function help()
79 print(copyright)
80 print(author)
81 print(version)
82 print(desc)
83 print(ansicolors.cyan..'Usage'..ansicolors.reset)
84 print(usage)
85 print(ansicolors.cyan..'Arguments'..ansicolors.reset)
86 print(arguments)
87 print(ansicolors.cyan..'Example usage'..ansicolors.reset)
88 print(example)
89 end
90 ---
91 -- The main entry point
92 function main(args)
94 if args == nil or #args == 0 then return help() end
96 local ignore_response = false
97 local append_crc = false
98 local stayconnected = false
99 local payload = nil
100 local doconnect = true
101 local topaz_mode = false
102 local no_rats = false
104 -- Read the parameters
105 for o, a in getopt.getopt(args, 'orcpx:dt3') do
106 if o == 'o' then doconnect = false end
107 if o == 'r' then ignore_response = true end
108 if o == 'c' then append_crc = true end
109 if o == 'p' then stayconnected = true end
110 if o == 'x' then payload = a end
111 if o == 'd' then DEBUG = true end
112 if o == 't' then topaz_mode = true end
113 if o == '3' then no_rats = true end
116 -- First of all, connect
117 if doconnect then
118 dbg("doconnect")
120 info, err = lib14a.read(true, no_rats)
121 if err then
122 lib14a.disconnect()
123 return oops(err)
125 print(('Connected to card, uid = %s'):format(info.uid))
128 -- The actual raw payload, if any
129 if payload then
130 res, err = sendRaw(payload,{ignore_response = ignore_response, topaz_mode = topaz_mode, append_crc = append_crc})
131 if err then
132 lib14a.disconnect()
133 return oops(err)
136 if not ignoreresponse then
137 -- Display the returned data
138 showdata(res)
141 -- And, perhaps disconnect?
142 if not stayconnected then
143 lib14a.disconnect()
147 --- Picks out and displays the data read from a tag
148 -- Specifically, takes a usb packet, converts to a Command
149 -- (as in commands.lua), takes the data-array and
150 -- reads the number of bytes specified in arg1 (arg0 in c-struct)
151 -- and displays the data
152 -- @param usbpacket the data received from the device
153 function showdata(usbpacket)
154 local cmd_response = Command.parse(usbpacket)
155 local len = tonumber(cmd_response.arg1) *2
156 --print("data length:",len)
157 local data = string.sub(tostring(cmd_response.data), 0, len);
158 print("<< ",data)
161 function sendRaw(rawdata, options)
162 print('>> ', rawdata)
164 local flags = lib14a.ISO14A_COMMAND.ISO14A_NO_DISCONNECT + lib14a.ISO14A_COMMAND.ISO14A_RAW
166 if options.topaz_mode then
167 flags = flags + lib14a.ISO14A_COMMAND.ISO14A_TOPAZMODE
169 if options.append_crc then
170 flags = flags + lib14a.ISO14A_COMMAND.ISO14A_APPEND_CRC
173 local command = Command:newMIX{cmd = cmds.CMD_HF_ISO14443A_READER,
174 arg1 = flags, -- Send raw
175 -- arg2 contains the length, which is half the length
176 -- of the ASCII-string rawdata
177 arg2 = string.len(rawdata)/2,
178 data = rawdata}
179 return command:sendMIX(options.ignore_response)
183 -------------------------
184 -- Testing
185 -------------------------
186 function selftest()
187 DEBUG = true
188 dbg('Performing test')
189 main()
190 main('-k')
191 main(' -o -x 6000F57b -k')
192 main('-o')
193 main('-x 6000F57b')
194 dbg('Tests done')
196 -- Flip the switch here to perform a sanity check.
197 -- It read a nonce in two different ways, as specified in the usage-section
198 if '--test'==args then
199 selftest()
200 else
201 -- Call the main
202 main(args)