]> git.zerfleddert.de Git - proxmark3-svn/blob - client/lualibs/read14a.lua
Potential fix for 0-length usb packets seen on OSX
[proxmark3-svn] / client / lualibs / read14a.lua
1 --[[
2 This is a library to read 14443a tags. It can be used something like this
3
4 local reader = require('read14a')
5 result, err = reader.read1443a()
6 if not result then
7 print(err)
8 return
9 end
10 print(result.name)
11
12 --]]
13 -- Loads the commands-library
14 local cmds = require('commands')
15 local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds
16 local ISO14A_COMMAND = {
17 ISO14A_CONNECT = 1,
18 ISO14A_NO_DISCONNECT = 2,
19 ISO14A_APDU = 4,
20 ISO14A_RAW = 8,
21 ISO14A_REQUEST_TRIGGER = 0x10,
22 ISO14A_APPEND_CRC = 0x20,
23 ISO14A_SET_TIMEOUT = 0x40,
24 ISO14A_NO_SELECT = 0x80,
25 ISO14A_TOPAZMODE = 0x100
26 }
27
28 local ISO14443a_TYPES = {}
29 ISO14443a_TYPES[0x00] = "NXP MIFARE Ultralight | Ultralight C"
30 ISO14443a_TYPES[0x01] = "NXP MIFARE TNP3xxx Activision Game Appliance"
31 ISO14443a_TYPES[0x04] = "NXP MIFARE (various !DESFire !DESFire EV1)"
32 ISO14443a_TYPES[0x08] = "NXP MIFARE CLASSIC 1k | Plus 2k"
33 ISO14443a_TYPES[0x09] = "NXP MIFARE Mini 0.3k"
34 ISO14443a_TYPES[0x10] = "NXP MIFARE Plus 2k"
35 ISO14443a_TYPES[0x11] = "NXP MIFARE Plus 4k"
36 ISO14443a_TYPES[0x18] = "NXP MIFARE Classic 4k | Plus 4k"
37 ISO14443a_TYPES[0x20] = "NXP MIFARE DESFire 4k | DESFire EV1 2k/4k/8k | Plus 2k/4k | JCOP 31/41"
38 ISO14443a_TYPES[0x24] = "NXP MIFARE DESFire | DESFire EV1"
39 ISO14443a_TYPES[0x28] = "JCOP31 or JCOP41 v2.3.1"
40 ISO14443a_TYPES[0x38] = "Nokia 6212 or 6131 MIFARE CLASSIC 4K"
41 ISO14443a_TYPES[0x88] = "Infineon MIFARE CLASSIC 1K"
42 ISO14443a_TYPES[0x98] = "Gemplus MPCOS"
43
44
45 local function tostring_1443a(sak)
46 return ISO14443a_TYPES[sak] or ("Unknown (SAK=%x)"):format(sak)
47 end
48
49 local function parse1443a(data)
50 --[[
51
52 Based on this struct :
53
54 typedef struct {
55 byte_t uid[10];
56 byte_t uidlen;
57 byte_t atqa[2];
58 byte_t sak;
59 byte_t ats_len;
60 byte_t ats[256];
61 } __attribute__((__packed__)) iso14a_card_select_t;
62
63 --]]
64
65 local count,uid,uidlen, atqa, sak, ats_len, ats= bin.unpack('H10CH2CC',data)
66 uid = uid:sub(1,2*uidlen)
67 --print("uid, atqa, sak: ",uid, atqa, sak)
68 --print("TYPE: ", tostring_1443a(sak))
69 return { uid = uid, atqa = atqa, sak = sak, name = tostring_1443a(sak)}
70 end
71
72 --- Sends a USBpacket to the device
73 -- @param command - the usb packet to send
74 -- @param ignoreresponse - if set to true, we don't read the device answer packet
75 -- which is usually recipe for fail. If not sent, the host will wait 2s for a
76 -- response of type CMD_ACK
77 -- @return packet,nil if successfull
78 -- nil, errormessage if unsuccessfull
79
80 local function sendToDevice(command, ignoreresponse)
81 core.clearCommandBuffer()
82 local err = core.SendCommand(command:getBytes())
83 if err then
84 print(err)
85 return nil, err
86 end
87 if ignoreresponse then return nil,nil end
88
89 local response = core.WaitForResponseTimeout(cmds.CMD_ACK,TIMEOUT)
90 return response,nil
91 end
92
93 -- This function does a connect and retrieves som einfo
94 -- @param dont_disconnect - if true, does not disable the field
95 -- @return if successfull: an table containing card info
96 -- @return if unsuccessfull : nil, error
97 local function read14443a(dont_disconnect)
98 local command, result, info, err, data
99
100 command = Command:new{cmd = cmds.CMD_READER_ISO_14443a,
101 arg1 = ISO14A_COMMAND.ISO14A_CONNECT}
102 if dont_disconnect then
103 command.arg1 = command.arg1 + ISO14A_COMMAND.ISO14A_NO_DISCONNECT
104 end
105 local result,err = sendToDevice(command)
106 if result then
107 local count,cmd,arg0,arg1,arg2 = bin.unpack('LLLL',result)
108 if arg0 == 0 then
109 return nil, "iso14443a card select failed"
110 end
111 data = string.sub(result,count)
112 info, err = parse1443a(data)
113 else
114 err ="No response from card"
115 end
116
117 if err then
118 print(err)
119 return nil, err
120 end
121 return info
122 end
123
124 ---
125 -- Waits for a mifare card to be placed within the vicinity of the reader.
126 -- @return if successfull: an table containing card info
127 -- @return if unsuccessfull : nil, error
128 local function waitFor14443a()
129 print("Waiting for card... press any key to quit")
130 while not core.ukbhit() do
131 res, err = read14443a()
132 if res then return res end
133 -- err means that there was no response from card
134 end
135 return nil, "Aborted by user"
136 end
137 local library = {
138
139 read1443a = read14443a,
140 read = read14443a,
141 waitFor14443a = waitFor14443a,
142 parse1443a = parse1443a,
143 sendToDevice = sendToDevice,
144 ISO14A_COMMAND = ISO14A_COMMAND,
145 }
146
147 return library
Impressum, Datenschutz