text
[RRG-proxmark3.git] / client / luascripts / hf_14a_aztek.lua
blobc63a9f85cf95080e5e9d65cd510309a308ef570b
1 local cmds = require('commands')
2 local getopt = require('getopt')
3 local lib14a = require('read14a')
4 local utils = require('utils')
5 local ansicolors = require('ansicolors')
7 copyright = ''
8 author = 'Iceman'
9 version = 'v1.0.2'
10 desc = [[
11 This is a script that reads AZTEK ISO14443a tags.
12 It starts from block 0 and ends at default block 20. Use 'b' to say different endblock.
13 xor: the first three block (0,1,2) is not XORED. The rest seems to be xored.
15 example = [[
16 -- default
17 script run hf_14a_aztek
19 -- stop at block 10
20 script run hf_14a_aztek -b 10
22 usage = [[
23 script run hf_14a_aztek [-h] [-b]
25 arguments = [[
26 -h This help
27 -b endblock in decimal (1-255, default 20)
30 -- Some globals
31 local DEBUG = false -- the debug flag
32 ---
33 -- A debug printout-function
34 local function dbg(args)
35 if not DEBUG then return end
36 if type(args) == 'table' then
37 local i = 1
38 while args[i] do
39 dbg(args[i])
40 i = i+1
41 end
42 else
43 print('###', args)
44 end
45 end
46 ---
47 -- This is only meant to be used when errors occur
48 local function oops(err)
49 print('ERROR:', err)
50 core.clearCommandBuffer()
51 return nil, err
52 end
53 ---
54 -- Usage help
55 local function help()
56 print(copyright)
57 print(author)
58 print(version)
59 print(desc)
60 print(ansicolors.cyan..'Usage'..ansicolors.reset)
61 print(usage)
62 print(ansicolors.cyan..'Arguments'..ansicolors.reset)
63 print(arguments)
64 print(ansicolors.cyan..'Example usage'..ansicolors.reset)
65 print(example)
66 end
68 --- Picks out and displays the data read from a tag
69 -- Specifically, takes a usb packet, converts to a Command
70 -- (as in commands.lua), takes the data-array and
71 -- reads the number of bytes specified in arg1 (arg0 in c-struct)
72 -- and displays the data
73 -- @blockno just to print which block the data belong to
74 -- @param usbpacket the data received from the device
75 function showdata(blockno, data)
76 local xorkey = '55AA55AA55AA55AA6262'
77 local s = data.." | "
78 local dex = ''
79 local rs
80 for i = 1, 20-4, 4 do
81 local item = string.sub(data, i, i+3)
82 local xor = string.sub(xorkey, i, i+3)
84 if blockno > 2 then
85 rs = bit32.bxor(tonumber(item,16) , tonumber(xor,16))
86 else
87 rs = tonumber(item, 16)
88 end
89 dex = (dex..'%04X'):format(rs)
90 end
91 s = s..dex.." | "
92 print( (" %02d | %s"):format(blockno,s))
93 end
95 -- Send a "raw" iso14443a package, ie "hf 14a raw" command
96 function sendRaw(rawdata, options)
98 local flags = lib14a.ISO14A_COMMAND.ISO14A_NO_DISCONNECT
99 + lib14a.ISO14A_COMMAND.ISO14A_RAW
100 + lib14a.ISO14A_COMMAND.ISO14A_APPEND_CRC
101 + lib14a.ISO14A_COMMAND.ISO14A_NO_RATS
103 local command = Command:newMIX{cmd = cmds.CMD_HF_ISO14443A_READER,
104 arg1 = flags, -- Send raw
105 -- arg2 contains the length, which is half the length
106 -- of the ASCII-string rawdata
107 arg2 = string.len(rawdata)/2,
108 data = rawdata}
110 return command:sendMIX(options.ignore_response)
113 -- The main entry point
114 function main(args)
116 local ignore_response = false
117 local endblock = 20
119 -- Read the parameters
120 for o, a in getopt.getopt(args, 'hb:') do
121 if o == 'h' then return help() end
122 if o == 'b' then endblock = a end
124 endblock = endblock or 20
126 -- First of all, connect
127 info, err = lib14a.read(true, true)
128 if err then
129 lib14a.disconnect()
130 return oops(err)
132 core.clearCommandBuffer()
134 local blockData = {}
136 -- Show tag info
137 print(('\nFound Card UID [%s]\n'):format(info.uid))
139 print('blk | data | xored')
140 print('----+------------------+-------------------')
141 for block = 00, endblock do
142 local cmd = string.format('10%02x00', block)
143 res, err = sendRaw(cmd , {ignore_response = ignore_response})
144 if err then
145 lib14a.disconnect()
146 return oops(err)
149 local cmd_response = Command.parse(res)
150 local len = tonumber(cmd_response.arg1) * 2
151 local data = string.sub(tostring(cmd_response.data), 0, len-4)
153 showdata(block, data)
154 table.insert(blockData, data)
156 print("----+------------------+-------------------")
157 lib14a.disconnect()
159 local filename, err = utils.WriteDumpFile(info.uid, blockData)
160 if err then return oops(err) end
162 print(string.format('\nDumped data into %s', filename))
165 -------------------------
166 -- Testing
167 -------------------------
168 function selftest()
169 DEBUG = true
170 dbg('Performing test')
171 main()
172 dbg('Tests done')
174 -- Flip the switch here to perform a sanity check.
175 -- It read a nonce in two different ways, as specified in the usage-section
176 if '--test' == args then
177 selftest()
178 else
179 -- Call the main
180 main(args)