mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-21 13:53:55 -07:00
Moved script libraries into lualibs/folder, and added a patch to include the folder in the LUA_PATH (a.k.a package.path). See http://proxmark.org/forum/viewtopic.php?id=1750 for more details
This commit is contained in:
parent
5f6d6c9003
commit
686f0a1794
5 changed files with 30 additions and 0 deletions
188
client/lualibs/commands.lua
Normal file
188
client/lualibs/commands.lua
Normal file
|
@ -0,0 +1,188 @@
|
|||
--[[
|
||||
These are command definitions. This file should correspond exactly to usb_cmd.h.
|
||||
--]]
|
||||
--// For the bootloader
|
||||
local _commands = {
|
||||
CMD_DEVICE_INFO = 0x0000,
|
||||
CMD_SETUP_WRITE = 0x0001,
|
||||
CMD_FINISH_WRITE = 0x0003,
|
||||
CMD_HARDWARE_RESET = 0x0004,
|
||||
CMD_START_FLASH = 0x0005,
|
||||
CMD_NACK = 0x00fe,
|
||||
CMD_ACK = 0x00ff,
|
||||
|
||||
--// For general mucking around
|
||||
CMD_DEBUG_PRINT_STRING = 0x0100,
|
||||
CMD_DEBUG_PRINT_INTEGERS = 0x0101,
|
||||
CMD_DEBUG_PRINT_BYTES = 0x0102,
|
||||
CMD_LCD_RESET = 0x0103,
|
||||
CMD_LCD = 0x0104,
|
||||
CMD_BUFF_CLEAR = 0x0105,
|
||||
CMD_READ_MEM = 0x0106,
|
||||
CMD_VERSION = 0x0107,
|
||||
|
||||
--// For low-frequency tags
|
||||
CMD_READ_TI_TYPE = 0x0202,
|
||||
CMD_WRITE_TI_TYPE = 0x0203,
|
||||
CMD_DOWNLOADED_RAW_BITS_TI_TYPE = 0x0204,
|
||||
CMD_ACQUIRE_RAW_ADC_SAMPLES_125K = 0x0205,
|
||||
CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K = 0x0206,
|
||||
CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K = 0x0207,
|
||||
CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K = 0x0208,
|
||||
CMD_DOWNLOADED_SIM_SAMPLES_125K = 0x0209,
|
||||
CMD_SIMULATE_TAG_125K = 0x020A,
|
||||
CMD_HID_DEMOD_FSK = 0x020B,
|
||||
CMD_HID_SIM_TAG = 0x020C,
|
||||
CMD_SET_LF_DIVISOR = 0x020D,
|
||||
CMD_LF_SIMULATE_BIDIR = 0x020E,
|
||||
CMD_SET_ADC_MUX = 0x020F,
|
||||
CMD_HID_CLONE_TAG = 0x0210,
|
||||
CMD_EM410X_WRITE_TAG = 0x0211,
|
||||
CMD_INDALA_CLONE_TAG = 0x0212,
|
||||
--// for 224 bits UID
|
||||
CMD_INDALA_CLONE_TAG_L = 0x0213,
|
||||
CMD_T55XX_READ_BLOCK = 0x0214,
|
||||
CMD_T55XX_WRITE_BLOCK = 0x0215,
|
||||
CMD_T55XX_READ_TRACE = 0x0216,
|
||||
CMD_PCF7931_READ = 0x0217,
|
||||
CMD_EM4X_READ_WORD = 0x0218,
|
||||
CMD_EM4X_WRITE_WORD = 0x0219,
|
||||
--/* CMD_SET_ADC_MUX: ext1 is 0 for lopkd, 1 for loraw, 2 for hipkd, 3 for hiraw */
|
||||
|
||||
--// For the 13.56 MHz tags
|
||||
CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693 = 0x0300,
|
||||
CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443 = 0x0301,
|
||||
CMD_READ_SRI512_TAG = 0x0303,
|
||||
CMD_READ_SRIX4K_TAG = 0x0304,
|
||||
CMD_READER_ISO_15693 = 0x0310,
|
||||
CMD_SIMTAG_ISO_15693 = 0x0311,
|
||||
CMD_RECORD_RAW_ADC_SAMPLES_ISO_15693 = 0x0312,
|
||||
CMD_ISO_15693_COMMAND = 0x0313,
|
||||
CMD_ISO_15693_COMMAND_DONE = 0x0314,
|
||||
CMD_ISO_15693_FIND_AFI = 0x0315,
|
||||
CMD_ISO_15693_DEBUG = 0x0316,
|
||||
|
||||
--// For Hitag2 transponders
|
||||
CMD_SNOOP_HITAG = 0x0370,
|
||||
CMD_SIMULATE_HITAG = 0x0371,
|
||||
CMD_READER_HITAG = 0x0372,
|
||||
|
||||
CMD_SIMULATE_TAG_HF_LISTEN = 0x0380,
|
||||
CMD_SIMULATE_TAG_ISO_14443 = 0x0381,
|
||||
CMD_SNOOP_ISO_14443 = 0x0382,
|
||||
CMD_SNOOP_ISO_14443a = 0x0383,
|
||||
CMD_SIMULATE_TAG_ISO_14443a = 0x0384,
|
||||
CMD_READER_ISO_14443a = 0x0385,
|
||||
CMD_SIMULATE_TAG_LEGIC_RF = 0x0387,
|
||||
CMD_READER_LEGIC_RF = 0x0388,
|
||||
CMD_WRITER_LEGIC_RF = 0x0389,
|
||||
CMD_EPA_PACE_COLLECT_NONCE = 0x038A,
|
||||
|
||||
CMD_SNOOP_ICLASS = 0x0392,
|
||||
CMD_SIMULATE_TAG_ICLASS = 0x0393,
|
||||
CMD_READER_ICLASS = 0x0394,
|
||||
|
||||
--// For measurements of the antenna tuning
|
||||
CMD_MEASURE_ANTENNA_TUNING = 0x0400,
|
||||
CMD_MEASURE_ANTENNA_TUNING_HF = 0x0401,
|
||||
CMD_MEASURED_ANTENNA_TUNING = 0x0410,
|
||||
CMD_LISTEN_READER_FIELD = 0x0420,
|
||||
|
||||
--// For direct FPGA control
|
||||
CMD_FPGA_MAJOR_MODE_OFF = 0x0500,
|
||||
|
||||
--// For mifare commands
|
||||
CMD_MIFARE_SET_DBGMODE = 0x0600,
|
||||
CMD_MIFARE_EML_MEMCLR = 0x0601,
|
||||
CMD_MIFARE_EML_MEMSET = 0x0602,
|
||||
CMD_MIFARE_EML_MEMGET = 0x0603,
|
||||
CMD_MIFARE_EML_CARDLOAD = 0x0604,
|
||||
CMD_MIFARE_EML_CSETBLOCK = 0x0605,
|
||||
CMD_MIFARE_EML_CGETBLOCK = 0x0606,
|
||||
|
||||
CMD_SIMULATE_MIFARE_CARD = 0x0610,
|
||||
|
||||
CMD_READER_MIFARE = 0x0611,
|
||||
CMD_MIFARE_NESTED = 0x0612,
|
||||
|
||||
CMD_MIFARE_READBL = 0x0620,
|
||||
CMD_MIFARE_READSC = 0x0621,
|
||||
CMD_MIFARE_WRITEBL = 0x0622,
|
||||
CMD_MIFARE_CHKKEYS = 0x0623,
|
||||
|
||||
CMD_MIFARE_SNIFFER = 0x0630,
|
||||
|
||||
CMD_UNKNOWN = 0xFFFF,
|
||||
}
|
||||
|
||||
|
||||
local _reverse_lookup,k,v = {}
|
||||
for k, v in pairs(_commands) do
|
||||
_reverse_lookup[v] = k
|
||||
end
|
||||
_commands.tostring = function(command)
|
||||
if(type(command) == 'number') then
|
||||
return ("%s (%d)"):format(_reverse_lookup[command]or "ERROR UNDEFINED!", command)
|
||||
end
|
||||
return ("Error, numeric argument expected, got : %s"):format(tostring(command))
|
||||
end
|
||||
|
||||
Command = {
|
||||
|
||||
new = function(self, o)
|
||||
|
||||
local o = o or {} -- create object if user does not provide one
|
||||
setmetatable(o, self) -- DIY inheritance a'la javascript
|
||||
self.__index = self
|
||||
|
||||
o.cmd = o.cmd or _commands.CMD_UNKNOWN
|
||||
--o.arg1 = "test"
|
||||
o.arg1 = o.arg1 or 0
|
||||
o.arg2 = o.arg2 or 0
|
||||
o.arg3 = o.arg3 or 0
|
||||
local data = o.data or "0"
|
||||
|
||||
if(type(data) == 'string') then
|
||||
-- We need to check if it is correct length, otherwise pad it
|
||||
local len = string.len(data)
|
||||
if(len < 1024) then
|
||||
--Should be 1024 hex characters to represent 512 bytes of data
|
||||
data = data .. string.rep("0",1024 - len )
|
||||
end
|
||||
if(len > 1024) then
|
||||
-- OOps, a bit too much data here
|
||||
print( ( "WARNING: data size too large, was %s chars, will be truncated "):format(len) )
|
||||
--
|
||||
data = data:sub(1,1024)
|
||||
end
|
||||
else
|
||||
print(("WARNING; data was NOT a (hex-) string, but was %s"):format(type(data)))
|
||||
end
|
||||
o.data = data
|
||||
|
||||
return o
|
||||
end,
|
||||
parse = function (packet)
|
||||
local count,cmd,arg1,arg2,arg3,data = bin.unpack('LLLLH512',packet)
|
||||
return Command:new{cmd = cmd, arg1 = arg1, arg2 = arg2, arg3 = arg3, data = data}
|
||||
end,
|
||||
}
|
||||
function Command:__tostring()
|
||||
local output = ("%s\r\nargs : (%s, %s, %s)\r\ndata:\r\n%s\r\n"):format(
|
||||
_commands.tostring(self.cmd),
|
||||
tostring(self.arg1),
|
||||
tostring(self.arg2),
|
||||
tostring(self.arg3),
|
||||
tostring(self.data))
|
||||
return output
|
||||
end
|
||||
function Command:getBytes()
|
||||
--If a hex-string has been used
|
||||
local data = self.data
|
||||
local cmd = self.cmd
|
||||
local arg1, arg2, arg3 = self.arg1, self.arg2, self.arg3
|
||||
|
||||
|
||||
return bin.pack("LLLLH",cmd, arg1, arg2, arg3,data);
|
||||
end
|
||||
return _commands
|
107
client/lualibs/getopt.lua
Normal file
107
client/lualibs/getopt.lua
Normal file
|
@ -0,0 +1,107 @@
|
|||
|
||||
--[[This file is an adaptation from the following source:
|
||||
|
||||
https://github.com/attractivechaos/klib/blob/master/lua/klib.lua
|
||||
|
||||
]]
|
||||
|
||||
--[[
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2011, Attractive Chaos <attractor@live.co.uk>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
]]--
|
||||
|
||||
|
||||
local function split(txt)
|
||||
local retval = {};
|
||||
for i in string.gmatch(txt, "%S+") do
|
||||
table.insert(retval,i)
|
||||
end
|
||||
return retval
|
||||
end
|
||||
|
||||
|
||||
-- Description: getopt() translated from the BSD getopt(); compatible with the default Unix getopt()
|
||||
--[[ Example:
|
||||
for o, a in os.getopt(arg, 'a:b') do
|
||||
print(o, a)
|
||||
end
|
||||
]]--
|
||||
|
||||
local function getopt(args, ostr)
|
||||
-- Modification to handle strings instead of tables:
|
||||
if type(args) == 'string' then
|
||||
args = split(args)
|
||||
end
|
||||
|
||||
local arg, place = nil, 0;
|
||||
return function ()
|
||||
if place == 0 then -- update scanning pointer
|
||||
place = 1
|
||||
if #args == 0
|
||||
or args[1]:sub(1, 1) ~= '-' then
|
||||
place = 0; return nil end
|
||||
if #args[1] >= 2 then
|
||||
place = place + 1
|
||||
if args[1]:sub(2, 2) == '-' then -- found "--"
|
||||
place = 0
|
||||
table.remove(args, 1);
|
||||
return nil;
|
||||
end
|
||||
end
|
||||
end
|
||||
local optopt = args[1]:sub(place, place);
|
||||
place = place + 1;
|
||||
local oli = ostr:find(optopt);
|
||||
if optopt == ':' or oli == nil then -- unknown option
|
||||
if optopt == '-' then return nil end
|
||||
if place > #args[1] then
|
||||
table.remove(args, 1);
|
||||
place = 0;
|
||||
end
|
||||
return '?';
|
||||
end
|
||||
oli = oli + 1;
|
||||
if ostr:sub(oli, oli) ~= ':' then -- do not need argument
|
||||
arg = nil;
|
||||
if place > #args[1] then
|
||||
table.remove(args, 1);
|
||||
place = 0;
|
||||
end
|
||||
else -- need an argument
|
||||
if place <= #args[1] then -- no white space
|
||||
arg = args[1]:sub(place);
|
||||
else
|
||||
table.remove(args, 1);
|
||||
if #args == 0 then -- an option requiring argument is the last one
|
||||
place = 0;
|
||||
if ostr:sub(1, 1) == ':' then return ':' end
|
||||
return '?';
|
||||
else arg = args[1] end
|
||||
end
|
||||
table.remove(args, 1);
|
||||
place = 0;
|
||||
end
|
||||
return optopt, arg;
|
||||
end
|
||||
end
|
||||
|
||||
return { getopt = getopt }
|
151
client/lualibs/mf_default_keys.lua
Normal file
151
client/lualibs/mf_default_keys.lua
Normal file
|
@ -0,0 +1,151 @@
|
|||
|
||||
|
||||
local _keys = {
|
||||
|
||||
--[[
|
||||
|
||||
These keys are from the pm3 c-codebase.
|
||||
|
||||
--]]
|
||||
'ffffffffffff', -- Default key (first key used by program if no user defined key)
|
||||
'000000000000', -- Blank key
|
||||
'a0a1a2a3a4a5', -- NFCForum MAD key
|
||||
'b0b1b2b3b4b5',
|
||||
'aabbccddeeff',
|
||||
'4d3a99c351dd',
|
||||
'1a982c7e459a',
|
||||
'd3f7d3f7d3f7',
|
||||
'714c5c886e97',
|
||||
'587ee5f9350f',
|
||||
'a0478cc39091',
|
||||
'533cb6c723f6',
|
||||
'8fd0a4f256e9',
|
||||
|
||||
|
||||
--[[
|
||||
The data below is taken form the Slurp project,
|
||||
https://github.com/4ZM/slurp/blob/master/res/xml/mifare_default_keys.xml
|
||||
released as GPLV3.
|
||||
|
||||
--]]
|
||||
|
||||
'000000000000', -- Default key
|
||||
'ffffffffffff', -- Default key
|
||||
'b0b1b2b3b4b5', -- Key from mfoc
|
||||
'4d3a99c351dd', -- Key from mfoc
|
||||
'1a982c7e459a', -- Key from mfoc
|
||||
'aabbccddeeff', -- Key from mfoc
|
||||
'714c5c886e97', -- Key from mfoc
|
||||
'587ee5f9350f', -- Key from mfoc
|
||||
'a0478cc39091', -- Key from mfoc
|
||||
'533cb6c723f6', -- Key from mfoc
|
||||
'8fd0a4f256e9', -- Key from mfoc
|
||||
-- Data from: http://pastebin.com/wcTHXLZZ
|
||||
'a64598a77478', -- RKF SL Key A
|
||||
'26940b21ff5d', -- RKF SL Key A
|
||||
'fc00018778f7', -- RKF SL Key A
|
||||
'00000ffe2488', -- RKF SL Key B
|
||||
'5c598c9c58b5', -- RKF SL Key B
|
||||
'e4d2770a89be', -- RKF SL Key B
|
||||
-- Data from: http://pastebin.com/svGjN30Q
|
||||
'434f4d4d4f41', -- RKF JOJO GROUP Key A
|
||||
'434f4d4d4f42', -- RKF JOJO GROUP Key B
|
||||
'47524f555041', -- RKF JOJO GROUP Key A
|
||||
'47524f555042', -- RKF JOJO GROUP Key B
|
||||
'505249564141', -- RKF JOJO PRIVA Key A
|
||||
'505249564142', -- RKF JOJO PRIVA Key B
|
||||
-- Data from: http://pastebin.com/d7sSetef
|
||||
'fc00018778f7', -- RKF Rejskort Danmark Key A
|
||||
'00000ffe2488', -- RKF Rejskort Danmark Key B
|
||||
'0297927c0f77', -- RKF Rejskort Danmark Key A
|
||||
'ee0042f88840', -- RKF Rejskort Danmark Key B
|
||||
'722bfcc5375f', -- RKF Rejskort Danmark Key A
|
||||
'f1d83f964314', -- RKF Rejskort Danmark Key B
|
||||
-- Data from: http://pastebin.com/pvJX0xVS
|
||||
'54726176656C', -- Transport Key A
|
||||
'776974687573', -- Transport Key B
|
||||
'4AF9D7ADEBE4', -- Directory and event log Key A
|
||||
'2BA9621E0A36', -- Directory and event log Key B
|
||||
-- Data from: http://pastebin.com/Dnnc5dFC
|
||||
-- New cards are not encrypted (MF Ultralight)
|
||||
'fc00018778f7', -- Västtrafiken Key A
|
||||
'00000ffe2488', -- Västtrafiken Key B
|
||||
'0297927c0f77', -- Västtrafiken Key A
|
||||
'ee0042f88840', -- Västtrafiken Key B
|
||||
'54726176656c', -- Västtrafiken Key A
|
||||
'776974687573', -- Västtrafiken Key B
|
||||
-- Data from: http://pastebin.com/y3PDBWR1
|
||||
'000000000001',
|
||||
'a0a1a2a3a4a5',
|
||||
'123456789abc',
|
||||
'b127c6f41436',
|
||||
'12f2ee3478c1',
|
||||
'34d1df9934c5',
|
||||
'55f5a5dd38c9',
|
||||
'f1a97341a9fc',
|
||||
'33f974b42769',
|
||||
'14d446e33363',
|
||||
'c934fe34d934',
|
||||
'1999a3554a55',
|
||||
'27dd91f1fcf1',
|
||||
'a94133013401',
|
||||
'99c636334433',
|
||||
'43ab19ef5c31',
|
||||
'a053a292a4af',
|
||||
'434f4d4d4f41',
|
||||
'434f4d4d4f42',
|
||||
'505249565441',
|
||||
'505249565442',
|
||||
-- Data from,:, http://pastebin.com/TUXj17K3
|
||||
'fc0001877bf7', -- RKF ÖstgötaTrafiken Key A
|
||||
'00000ffe2488', -- RKF ÖstgötaTrafiken Key B
|
||||
'0297927c0f77', -- RKF ÖstgötaTrafiken Key A
|
||||
'ee0042f88840', -- RKF ÖstgötaTrafiken Key B
|
||||
'54726176656c', -- RKF ÖstgötaTrafiken Key A
|
||||
'776974687573', -- RKF ÖstgötaTrafiken Key B
|
||||
|
||||
--[[
|
||||
The keys below are taken from from https://code.google.com/p/mifare-key-cracker/downloads/list
|
||||
--]]
|
||||
|
||||
'bd493a3962b6',
|
||||
'010203040506',
|
||||
'111111111111',
|
||||
'222222222222',
|
||||
'333333333333',
|
||||
'444444444444',
|
||||
'555555555555',
|
||||
'666666666666',
|
||||
'777777777777',
|
||||
'888888888888',
|
||||
'999999999999',
|
||||
'aaaaaaaaaaaa',
|
||||
'bbbbbbbbbbbb',
|
||||
'cccccccccccc',
|
||||
'dddddddddddd',
|
||||
'eeeeeeeeeeee',
|
||||
'0123456789ab',
|
||||
'123456789abc',
|
||||
}
|
||||
|
||||
---
|
||||
-- The keys above have just been pasted in, for completeness sake. They contain duplicates.
|
||||
-- We need to weed the duplicates out before we expose the list to someone who actually wants to use them
|
||||
-- @param list a list to do 'uniq' on
|
||||
|
||||
local function uniq(list)
|
||||
|
||||
local foobar = {}
|
||||
--print("list length ", #list)
|
||||
for _, value in pairs(list) do
|
||||
value = value:lower()
|
||||
if not foobar[value] then
|
||||
foobar[value] = true
|
||||
table.insert(foobar, value);
|
||||
end
|
||||
end
|
||||
--print("final list length length ", #foobar)
|
||||
return foobar
|
||||
end
|
||||
|
||||
return uniq(_keys)
|
127
client/lualibs/read14a.lua
Normal file
127
client/lualibs/read14a.lua
Normal file
|
@ -0,0 +1,127 @@
|
|||
--[[
|
||||
This is a library to read 14443a tags. It can be used something like this
|
||||
|
||||
local reader = require('read14a')
|
||||
result, err = reader.read1443a()
|
||||
if not result then
|
||||
print(err)
|
||||
return
|
||||
end
|
||||
print(result.name)
|
||||
|
||||
--]]
|
||||
-- Loads the commands-library
|
||||
local cmds = require('commands')
|
||||
local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds
|
||||
local ISO14A_COMMAND = {
|
||||
ISO14A_CONNECT = 1,
|
||||
ISO14A_NO_DISCONNECT = 2,
|
||||
ISO14A_APDU = 4,
|
||||
ISO14A_RAW = 8,
|
||||
ISO14A_REQUEST_TRIGGER = 0x10,
|
||||
ISO14A_APPEND_CRC = 0x20,
|
||||
ISO14A_SET_TIMEOUT = 0x40
|
||||
}
|
||||
|
||||
local ISO14443a_TYPES = {}
|
||||
ISO14443a_TYPES[0x00] = "NXP MIFARE Ultralight | Ultralight C"
|
||||
ISO14443a_TYPES[0x04] = "NXP MIFARE (various !DESFire !DESFire EV1)"
|
||||
ISO14443a_TYPES[0x08] = "NXP MIFARE CLASSIC 1k | Plus 2k"
|
||||
ISO14443a_TYPES[0x09] = "NXP MIFARE Mini 0.3k"
|
||||
ISO14443a_TYPES[0x10] = "NXP MIFARE Plus 2k"
|
||||
ISO14443a_TYPES[0x11] = "NXP MIFARE Plus 4k"
|
||||
ISO14443a_TYPES[0x18] = "NXP MIFARE Classic 4k | Plus 4k"
|
||||
ISO14443a_TYPES[0x20] = "NXP MIFARE DESFire 4k | DESFire EV1 2k/4k/8k | Plus 2k/4k | JCOP 31/41"
|
||||
ISO14443a_TYPES[0x24] = "NXP MIFARE DESFire | DESFire EV1"
|
||||
ISO14443a_TYPES[0x28] = "JCOP31 or JCOP41 v2.3.1"
|
||||
ISO14443a_TYPES[0x38] = "Nokia 6212 or 6131 MIFARE CLASSIC 4K"
|
||||
ISO14443a_TYPES[0x88] = "Infineon MIFARE CLASSIC 1K"
|
||||
ISO14443a_TYPES[0x98] = "Gemplus MPCOS"
|
||||
|
||||
|
||||
local function tostring_1443a(sak)
|
||||
return ISO14443a_TYPES[sak] or ("Unknown (SAK=%x)"):format(sak)
|
||||
end
|
||||
|
||||
local function parse1443a(data)
|
||||
--[[
|
||||
|
||||
Based on this struct :
|
||||
|
||||
typedef struct {
|
||||
byte_t uid[10];
|
||||
byte_t uidlen;
|
||||
byte_t atqa[2];
|
||||
byte_t sak;
|
||||
byte_t ats_len;
|
||||
byte_t ats[256];
|
||||
} __attribute__((__packed__)) iso14a_card_select_t;
|
||||
|
||||
--]]
|
||||
|
||||
local count,uid,uidlen, atqa, sak, ats_len, ats= bin.unpack('H10CH2CC',data)
|
||||
uid = uid:sub(1,2*uidlen)
|
||||
--print("uid, atqa, sak: ",uid, atqa, sak)
|
||||
--print("TYPE: ", tostring_1443a(sak))
|
||||
return { uid = uid, atqa = atqa, sak = sak, name = tostring_1443a(sak)}
|
||||
end
|
||||
|
||||
--- Sends a USBpacket to the device
|
||||
-- @param command - the usb packet to send
|
||||
-- @param ignoreresponse - if set to true, we don't read the device answer packet
|
||||
-- which is usually recipe for fail. If not sent, the host will wait 2s for a
|
||||
-- response of type CMD_ACK
|
||||
-- @return packet,nil if successfull
|
||||
-- nil, errormessage if unsuccessfull
|
||||
|
||||
local function sendToDevice(command, ignoreresponse)
|
||||
core.clearCommandBuffer()
|
||||
local err = core.SendCommand(command:getBytes())
|
||||
if err then
|
||||
print(err)
|
||||
return nil, err
|
||||
end
|
||||
if ignoreresponse then return nil,nil end
|
||||
|
||||
local response = core.WaitForResponseTimeout(cmds.CMD_ACK,TIMEOUT)
|
||||
return response,nil
|
||||
end
|
||||
|
||||
|
||||
local library = {
|
||||
-- This function does a connect.
|
||||
-- @param dont_disconnect - if true, does not disable the field
|
||||
read1443a = function(dont_disconnect)
|
||||
|
||||
local command, result, info, err, data
|
||||
|
||||
command = Command:new{cmd = cmds.CMD_READER_ISO_14443a,
|
||||
arg1 = ISO14A_COMMAND.ISO14A_CONNECT}
|
||||
if dont_disconnect then
|
||||
command.arg1 = command.arg1 + ISO14A_COMMAND.ISO14A_NO_DISCONNECT
|
||||
end
|
||||
local result,err = sendToDevice(command)
|
||||
if result then
|
||||
local count,cmd,arg0,arg1,arg2 = bin.unpack('LLLL',result)
|
||||
if arg0 == 0 then
|
||||
print("iso14443a card select failed");
|
||||
return nil, "iso14443a card select failed"
|
||||
end
|
||||
data = string.sub(result,count)
|
||||
info, err = parse1443a(data)
|
||||
else
|
||||
err ="No response from card"
|
||||
end
|
||||
|
||||
if err then
|
||||
print(err)
|
||||
return nil, err
|
||||
end
|
||||
return info
|
||||
end,
|
||||
parse1443a = parse1443a,
|
||||
sendToDevice = sendToDevice,
|
||||
ISO14A_COMMAND = ISO14A_COMMAND,
|
||||
}
|
||||
|
||||
return library
|
Loading…
Add table
Add a link
Reference in a new issue