From 452aab1e5958de169a5407b4cbd07f11642d0028 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 20 Mar 2016 20:22:35 +0100 Subject: [PATCH] ADD; first try at reading calypso tags --- .gitignore | 4 +- client/scripts/calypso.lua | 240 +++++++++++++++++++++++++++++++++++++ 2 files changed, 242 insertions(+), 2 deletions(-) create mode 100644 client/scripts/calypso.lua diff --git a/.gitignore b/.gitignore index 7a71c19a..56a3b756 100644 --- a/.gitignore +++ b/.gitignore @@ -36,5 +36,5 @@ fpga/* !fpga/go.bat !fpga/sim.tcl -client/* - +#client/* +client/traces/* diff --git a/client/scripts/calypso.lua b/client/scripts/calypso.lua new file mode 100644 index 00000000..5f834edd --- /dev/null +++ b/client/scripts/calypso.lua @@ -0,0 +1,240 @@ +local cmds = require('commands') +local getopt = require('getopt') +local lib14b = require('read14b') +local utils = require('utils') + +example = "script runs 14b raw commands to query a CAPLYPSO tag" +author = "Iceman, 2016" +desc = +[[ +This is a script to communicate with a CALYSPO / 14443b tag using the '14b raw' commands + +Arguments: + -b 123 +Examples : + script run f -b 11223344 + script run f + +Examples : + +# 1. Connect and don't disconnect +script run f +# 2. Send mf auth, read response +script run f +# 3. disconnect +script run f + +]] + +--[[ +This script communicates with /armsrc/iso14443b.c, +Check there for details about data format and how commands are interpreted on the +device-side. +]] + +--- +-- +local function calypso_switch_on_field() + local flags = lib14b.ISO14B_COMMAND.ISO14B_CONNECT + local c = Command:new{cmd = cmds.CMD_ISO_14443B_COMMAND, arg1 = flags} + return lib14b.sendToDevice(c, true) +end +--- +-- Disconnect (poweroff) the antenna forcing a disconnect of a 14b tag. +local function calypso_switch_off_field() + local flags = lib14b.ISO14B_COMMAND.ISO14B_DISCONNECT + local c = Command:new{cmd = cmds.CMD_ISO_14443B_COMMAND, arg1 = flags} + return lib14b.sendToDevice(c, true) +end + +local function calypso_parse(result) + local r = Command.parse(result) + local len = r.arg2 * 2 + r.data = string.sub(r.data, 0, len); + if r.arg1 == 0 then + return r, nil + end + return nil,nil +end +--- +-- A debug printout-function +local function dbg(args) + if DEBUG then + print("###", args) + end +end +--- +-- This is only meant to be used when errors occur +local function oops(err) + print("ERROR: ",err) + calypso_switch_off_field() + return nil,err +end +--- +-- Usage help +local function help() + print(desc) + print("Example usage") + print(example) +end +-- +-- helper function, give current count of items in lua-table. +local function tablelen(T) + local count = 0 + for _ in pairs(T) do count = count + 1 end + return count +end +--- +-- helper function, gives a sorted table from table t, +-- order can be a seperate sorting-order function. +local function spairs(t, order) + -- collect the keys + local keys = {} + for k in pairs(t) do keys[#keys+1] = k end + + -- if order function given, sort by it by passing the table and keys a, b, + -- otherwise just sort the keys + if order then + table.sort(keys, function(a,b) return order(t, a, b) end) + else + table.sort(keys) + end + + -- return the iterator function + local i = 0 + return function() + i = i + 1 + if keys[i] then + return keys[i], t[keys[i]] + end + end +end +--- +-- Sends a usbpackage , "hf 14b raw" +-- if it reads the response, it converts it to a lua object "Command" first and the Data is cut to correct length. +local function calypso_send_cmd_raw(data, ignoreresponse ) + + local command, flags, result, err + flags = lib14b.ISO14B_COMMAND.ISO14B_RAW + + lib14b.ISO14B_COMMAND.ISO14B_APPEND_CRC + + data = data or "00" + + command = Command:new{cmd = cmds.CMD_ISO_14443B_COMMAND, + arg1 = flags, + arg2 = #data/2, -- LEN of data, half the length of the ASCII-string hex string + arg3 = 0, + data = data} -- data bytes (commands etc) + result, err = lib14b.sendToDevice(command, false) + + if ignoreresponse then return response, err end + + if result then + local r = calypso_parse(result) + return r, nil + end + return respone, err +end +--- +-- calypso_card_num : Reads card number from ATR and +-- writes it in the tree in decimal format. +local function calypso_card_num(card) + if not card then return end + local card_num = tonumber( card.uid:sub(1,8),16 ) + print('Card UID', card.uid) + print('Card Number', card_num) +end +--- +-- analyse CALYPSO apdu status bytes. +local function calypso_apdu_status(apdu) + -- last two is CRC + -- next two is APDU status bytes. + local sw = apdu:sub( #apdu-7, #apdu-4) + print ('SW', sw ) + -- if 0x9000 OK + if sw == '9000' then return 1 end + return 0 +end + +local _calypso_cmds = { + ["1.Select ICC file"] = "02 94 a4 08 00 04 3f 00 00 02", + ["2.ICC"] = "02 94 b2 01 04 1d", + ["3.Select EnvHol file"]= '02 94 a4 08 00 04 20 00 20 01', + ["4.EnvHol1"] = '02 94 b2 01 04 1d', + ["5.Select EvLog file"] = '02 94 a4 08 00 04 20 00 20 10', + ["6.EvLog1"] = '06 00b2 0104 1d', + ["7.EvLog2"] = '06 00b2 0204 1d', + ["8.EvLog3"] = '06 00b2 0304 1d', + -- ["Select ConList file"]= '42 01 04 0a 00a4 0800 04 2000 2050', + -- ["ConList"] = '42 01 06 06 00b2 0104 1d', + -- ["Select Contra file"]= '42 01 08 0a 00a4 0800 04 2000 2020', + -- ["Contra1"] = '42 01 0a 06 00b2 0104 1d', + -- ["Contra2"] = '42 01 0c 06 00b2 0204 1d', + -- ["Contra3"] = '42 01 0e 06 00b2 0304 1d', + -- ["Contra4"] = '42 01 00 06 00b2 0404 1d', + -- ["Select Counter file"]= '42 01 02 0a 00a4 0800 04 2000 2069', + -- ["Counter"] = '42 01 04 06 00b2 0104 1d', + -- ["Select SpecEv file"]= '42 01 06 0a 00a4 08 0004 2000 2040', + -- ["SpecEv1"] = '42 01 08 06 00b2 0104 1d', +} + +--- +-- The main entry point +function main(args) + + local data, apdu, flags, uid, cid, result, err, card + -- Read the parameters + for o, a in getopt.getopt(args, 'h') do + if o == "h" then return help() end + end + + calypso_switch_on_field() + + -- Select 14b tag. + card, err = lib14b.waitFor14443b() + if not card then return oops(err) end + + calypso_card_num(card) + cid = card.cid + + --[[ + NAME VALUE APDU_POS + PCB 0x0A 0 + CID 0x00 1 + CLA 0x94 2 + SELECT FILE 0xA4 3 + READ FILE 0xB2 3 + P1 4 + P2 5 + LEN_ + 0 1 2 3 4 5 6 7 + apdu = '0a 00 94 a4 08 00 04 3f 00 00 02' --select ICC file + DF_NAME = "1TIC.ICA" + --]] + --for i = 1,10 do + --result, err = calypso_send_cmd_raw('0294a40800043f000002',false) --select ICC file + for i, apdu in spairs(_calypso_cmds) do + apdu = apdu:gsub("%s+","") + result, err = calypso_send_cmd_raw(apdu , false) + if result then + calypso_apdu_status(result.data) + print( result.data ) + end + end + calypso_switch_off_field() +end +--- +-- a simple selftest function, tries to convert +function selftest() + DEBUG = true + dbg("Performing test") + dbg("Tests done") +end +-- Flip the switch here to perform a sanity check. +-- It read a nonce in two different ways, as specified in the usage-section +if "--test"==args then + selftest() +else + -- Call the main + main(args) +end \ No newline at end of file -- 2.39.2