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