FIX: basic fixes for lua reader14a, reader14b, reader15

ADD: utils got iso15693 crc support
This commit is contained in:
iceman1001 2018-11-30 01:41:39 +01:00
parent ccb0cd23f5
commit a5898158c5
5 changed files with 135 additions and 175 deletions

View file

@ -6,160 +6,7 @@ This library utilises other libraries under the hood, but can be used as a gener
local reader14443A = require('read14a')
local reader14443B = require('read14b')
local cmds = require('commands')
local TIMEOUT = 2000
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
-------------------------------------------------------
-- This will be moved to a separate 14443B library
-------------------------------------------------------
local reader14443B = {
read = reader14443B.read14443b()
}
-------------------------------------------------------
-- This will be moved to a separate 1593 library
-------------------------------------------------------
local function errorString15693(number)
local errors = {}
errors[0x01] = "The command is not supported"
errors[0x02] = "The command is not recognised"
errors[0x03] = "The option is not supported."
errors[0x0f] = "Unknown error."
errors[0x10] = "The specified block is not available (doesnt exist)."
errors[0x11] = "The specified block is already -locked and thus cannot be locked again"
errors[0x12] = "The specified block is locked and its content cannot be changed."
errors[0x13] = "The specified block was not successfully programmed."
errors[0x14] = "The specified block was not successfully locked."
return errors[number] or "Reserved for Future Use or Custom command error."
end
-------------------------------------------------------
-- This will be moved to a separate 1593 library
-------------------------------------------------------
local function parse15693(data)
-- From common/iso15693tools.h :
--[[
#define ISO15_CRC_CHECK ((uint16_t)(~0xF0B8 & 0xFFFF)) // use this for checking of a correct crc
--]]
-- But that is very strange. Basically what is says is:
-- define ISO15_CRC_CHECK 0F47
-- So we can just use that directly...
-- The following code is based on cmdhf15.c around line 666 (NoTB!) and onwards
if core.iso15693_crc(data, string.len(data)) ~= 0xF47 then
return nil, "CRC failed"
elseif data[1] % 2 == 1 then
-- Above is a poor-mans bit check:
-- recv[0] & ISO15_RES_ERROR //(0x01)
local err = "Tag returned error %i: %s"
err = string.format(err, data[1],errorString15693(data[1]))
return nil, err
end
-- Finally, let the parsing begin...
-- the UID is just the data in reverse... almost:
-- 0FC481FF70000104E001001B0301
-- 8877665544332211
-- UID = E004010070FF81C4
-- 1122334455667788
-- So, cut out the relevant part and reverse it
local uid = data:sub(2,9):reverse()
local uidStr = bin.unpack("H8", uid)
local _,manufacturer_code = bin.unpack("s",uid:sub(2,2))
local _,tag_size = bin.unpack(">I",data:sub(12,13))
local _,micref_modelcode = bin.unpack("s",data:sub(14,14))
return {
uid = uidStr,
manufacturer_code = manufacturer_code,
tag_size = tag_size,
micref_modelcode = micref_modelcode,
}
end
-------------------------------------------------------
-- This will be moved to a separate 1593 library
-------------------------------------------------------
local function read15693()
--[[
We start by trying this command:
proxmark3> hf 15 cmd sysinfo -2 u
0F C4 81 FF 70 00 01 04 E0 01 00 1B 03 01
UID = E004010070FF81C4
Philips; IC SL2 ICS20
DSFID supported, set to 01
AFI supported, set to 000
Tag provides info on memory layout (vendor dependent)
4 (or 3) bytes/page x 28 pages
IC reference given: 01
This command is not always present in ISO15693 tags (it is an optional standard command) but if it is present usually the tags contain all the "colored" info above.
If the above command doesn't give an answer (see example below):
proxmark3> hf 15 cmd sysinfo -2 u
timeout: no
we must send the MANDATORY (present in ALL iso15693 tags) command (the example below is sent to a tag different from the above one):
proxmark3> hf 15 cmd inquiry
UID=E007C1A257394244
Tag Info: Texas Instrument; Tag-it HF-I Standard; 8x32bit
proxmark3>
From which we obtain less information than the above one.
--]]
local command, result, info, err, data
local data = "02"
local datalen = string.len(data) / 2
local speed = 1
local recv = 1
command = Command:new{cmd = cmds.CMD_ISO_15693_COMMAND,
arg1 = datalen,arg2 = speed,arg3 =recv, data=data}
-- These are defined in common/iso15693tools.h
-- #define ISO15_REQ_SUBCARRIER_SINGLE 0x00 // Tag should respond using one subcarrier (ASK)
-- #define ISO15_REQ_DATARATE_HIGH 0x02 // Tag should respond using high data rate
-- #define ISO15_REQ_NONINVENTORY 0x00
local result,err = sendToDevice(command)
if not result then
print(err)
return nil, "15693 sysinfo: no answer"
end
local count,cmd,recvlen,arg1,arg2 = bin.unpack('LLLL',result)
data = string.sub(result,recvlen)
info, err = parse15693(data)
if err then
return nil, err
end
return info
end
local reader15693 = {
read = read15693
}
local reader15693 = require('read15')
---
-- This method library can be set waits or a 13.56 MHz tag, and when one is found, returns info about

View file

@ -141,7 +141,6 @@ local function waitFor14443a()
end
local library = {
read = read14443a,
read = read14443a,
waitFor14443a = waitFor14443a,
parse14443a = parse14443a,
sendToDevice = sendToDevice,

View file

@ -41,7 +41,7 @@ local function parse1443b(data)
--]]
local count, uid, uidlen, atqb, chipid, cid = bin.unpack('H10CH7CC',data)
uid = uid:sub(1,2*uidlen)
uid = uid:sub(1, 2*uidlen)
return { uid = uid, uidlen = uidlen, atqb = atqb, chipid = chipid, cid = cid }
end
@ -96,7 +96,7 @@ local function read14443b(disconnect)
end
command = Command:new{cmd = cmds.CMD_ISO_14443B_COMMAND, arg1 = flags}
local result,err = sendToDevice(command, false)
local result, err = sendToDevice(command, false)
if result then
local count,cmd,arg0,arg1,arg2 = bin.unpack('LLLL',result)
if arg0 == 0 then
@ -147,9 +147,9 @@ local function waitFor14443b()
end
local library = {
parse1443b = parse1443b,
read1443b = read14443b,
read = read14443b,
waitFor14443b = waitFor14443b,
parse1443b = parse1443b,
sendToDevice = sendToDevice,
showData = showData,
ISO14B_COMMAND = ISO14B_COMMAND,

View file

@ -12,6 +12,7 @@
--]]
-- Loads the commands-library
local cmds = require('commands')
local utils = require('utils')
local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds
@ -34,15 +35,118 @@ local function sendToDevice(command, ignoreresponse)
return response,nil
end
local function errorString15693(number)
local errors = {}
errors[0x01] = "The command is not supported"
errors[0x02] = "The command is not recognised"
errors[0x03] = "The option is not supported."
errors[0x0f] = "Unknown error."
errors[0x10] = "The specified block is not available (doesnt exist)."
errors[0x11] = "The specified block is already -locked and thus cannot be locked again"
errors[0x12] = "The specified block is locked and its content cannot be changed."
errors[0x13] = "The specified block was not successfully programmed."
errors[0x14] = "The specified block was not successfully locked."
return errors[number] or "Reserved for Future Use or Custom command error."
end
local function parse15693(data)
-- From common/iso15693tools.h :
--[[
#define ISO15_CRC_CHECK ((uint16_t)(~0xF0B8 & 0xFFFF)) // use this for checking of a correct crc
--]]
-- But that is very strange. Basically what is says is:
-- define ISO15_CRC_CHECK 0F47
-- So we can just use that directly...
-- The following code is based on cmdhf15.c around line 666 (NoTB!) and onwards
if core.iso15693_crc(data, string.len(data)) ~= 0xF47 then
return nil, "CRC failed"
elseif data[1] % 2 == 1 then
-- Above is a poor-mans bit check:
-- recv[0] & ISO15_RES_ERROR //(0x01)
local err = "Tag returned error %i: %s"
err = string.format(err, data[1], errorString15693(data[1]))
return nil, err
end
-- Finally, let the parsing begin...
-- the UID is just the data in reverse... almost:
-- 0FC481FF70000104E001001B0301
-- 8877665544332211
-- UID = E004010070FF81C4
-- 1122334455667788
-- So, cut out the relevant part and reverse it
-- byte wise reverse.. not string reverse..
local uid = data:sub(2,9):reverse()
local uidStr = bin.unpack("H8", uid)
local _, manufacturer_code = bin.unpack("s", uid:sub(2,2))
local _, tag_size = bin.unpack(">I", data:sub(12,13))
local _, micref_modelcode = bin.unpack("s", data:sub(14,14))
return {
uid = uidStr,
manufacturer_code = manufacturer_code,
tag_size = tag_size,
micref_modelcode = micref_modelcode,
}
end
-- This function does a connect and retrieves som einfo
-- @param dont_disconnect - if true, does not disable the field
-- @return if successfull: an table containing card info
-- @return if unsuccessfull : nil, error
local function read15693(slow, dont_readresponse)
--[[
We start by trying this command:
proxmark3> hf 15 cmd sysinfo -2 u
0F C4 81 FF 70 00 01 04 E0 01 00 1B 03 01
UID = E004010070FF81C4
Philips; IC SL2 ICS20
DSFID supported, set to 01
AFI supported, set to 000
Tag provides info on memory layout (vendor dependent)
4 (or 3) bytes/page x 28 pages
IC reference given: 01
This command is not always present in ISO15693 tags (it is an optional standard command) but if it is present usually the tags contain all the "colored" info above.
If the above command doesn't give an answer (see example below):
proxmark3> hf 15 cmd sysinfo -2 u
timeout: no
we must send the MANDATORY (present in ALL iso15693 tags) command (the example below is sent to a tag different from the above one):
proxmark3> hf 15 cmd inquiry
UID=E007C1A257394244
Tag Info: Texas Instrument; Tag-it HF-I Standard; 8x32bit
proxmark3>
From which we obtain less information than the above one.
--]]
local command, result, info, err, data
command = Command:new{cmd = cmds.CMD_ISO_15693_COMMAND, arg1 = 0, arg2 = 1, arg3 = 1 }
data = "260100"
--add crc
local payload = utils.Crc15(data)
command = Command:new{cmd = cmds.CMD_ISO_15693_COMMAND,
arg1 = string.len(payload) / 2,
arg2 = 1,
arg3 = 1,
data = payload}
-- These are defined in common/iso15693tools.h
-- #define ISO15_REQ_SUBCARRIER_SINGLE 0x00 // Tag should respond using one subcarrier (ASK)
-- #define ISO15_REQ_DATARATE_HIGH 0x02 // Tag should respond using high data rate
-- #define ISO15_REQ_NONINVENTORY 0x00
if slow then
command.arg2 = 0
end
@ -51,23 +155,21 @@ local function read15693(slow, dont_readresponse)
end
local result, err = sendToDevice(command, dont_readresponse)
if result then
local count,cmd,arg0,arg1,arg2 = bin.unpack('LLLL',result)
if arg0 == 0 then
return nil, "iso15693 no bytes returned"
end
data = string.sub(result, count)
info, err = bin.unpack('H', data)
print("LEN", arg0, data )
else
err = "No response from card"
if not result then
print(err)
return nil, "15693 sysinfo: no answer"
end
if err then
print(err)
local count, cmd, recvlen, arg1, arg2 = bin.unpack('LLLL',result)
data = string.sub(result, recvlen)
info, err = parse15693(data)
if err then
print(err)
return nil, err
end
return info
return info
end
---
@ -86,7 +188,7 @@ end
local library = {
read = read15693,
waitFor15693 = waitFor15693,
-- parse15693 = parse15693,
parse15693 = parse15693,
sendToDevice = sendToDevice,
}

View file

@ -109,7 +109,19 @@ local Utils =
end
return nil
end,
----ISO15693 CRC
Crc15 = function(s)
if s == nil then return nil end
if #s == 0 then return nil end
if type(s) == 'string' then
local utils = require('utils')
return utils.ConvertAsciiToHex(
core.iso15693_crc(s)
)
end
return nil
end,
------------ CRC-8 Legic checksums
-- Takes a hex string and calculates a crc8
Crc8Legic = function(s)