From d4c01572c70226ed7d53e44e7c6291de1dcae5c3 Mon Sep 17 00:00:00 2001 From: Dom Date: Tue, 27 Feb 2018 17:39:56 +0000 Subject: [PATCH 01/29] successfully receiving raw packet responses being sent from the Proxmark to the Lua code. --- client/lualibs/read14a.lua | 9 +++- client/scripting.c | 33 +++++++++++++++ client/scripts/myscript.lua | 84 +++++++++++++++++++++++++++++++++++++ 3 files changed, 124 insertions(+), 2 deletions(-) create mode 100644 client/scripts/myscript.lua diff --git a/client/lualibs/read14a.lua b/client/lualibs/read14a.lua index 60fc0e68..cdddfac3 100644 --- a/client/lualibs/read14a.lua +++ b/client/lualibs/read14a.lua @@ -80,6 +80,7 @@ end local function sendToDevice(command, ignoreresponse) core.clearCommandBuffer() + print("Sent a UsbCommand via read14a.lua.") local err = core.SendCommand(command:getBytes()) if err then print(err) @@ -88,13 +89,14 @@ local function sendToDevice(command, ignoreresponse) if ignoreresponse then return nil,nil end local response = core.WaitForResponseTimeout(cmds.CMD_ACK,TIMEOUT) + print("Received a UsbCommand packet in read14a.lua.") return response,nil end --- This function does a connect and retrieves som einfo +-- This function does a connect and retrieves some info -- @param dont_disconnect - if true, does not disable the field -- @param no_rats - if true, skips ISO14443-4 select (RATS) --- @return if successfull: an table containing card info +-- @return if successfull: a table containing card info -- @return if unsuccessfull : nil, error local function read14443a(dont_disconnect, no_rats) local command, result, info, err, data @@ -109,6 +111,7 @@ local function read14443a(dont_disconnect, no_rats) end local result,err = sendToDevice(command) if result then + print("Currently trying to decode the UsbCommand packet just received (an ACK of the connection).") local count,cmd,arg0,arg1,arg2 = bin.unpack('LLLL',result) if arg0 == 0 then return nil, "iso14443a card select failed" @@ -143,6 +146,8 @@ end local library = { read14443a = read14443a, read = read14443a, + read14443a = read14443a, + read = read14443a, waitFor14443a = waitFor14443a, parse14443a = parse14443a, sendToDevice = sendToDevice, diff --git a/client/scripting.c b/client/scripting.c index 0c761cb2..c118307b 100644 --- a/client/scripting.c +++ b/client/scripting.c @@ -102,6 +102,38 @@ static int l_WaitForResponseTimeout(lua_State *L){ if(WaitForResponseTimeout(cmd, &response, ms_timeout)) { + //BEGIN ADDED CODE + uint8_t *recv; + char *hexout; + recv = response.d.asBytes; + uint8_t iLen = response.arg[0]; + if (0){ + iLen = response.arg[1]; + if (iLen){ + PrintAndLog("Card selected. UID[%i]:", iLen); + } else { + PrintAndLog("Can't select card."); + } + } else { + PrintAndLog("received %i bytes:", iLen); + } + if(!iLen) + return 1; + hexout = (char *)malloc(iLen * 3 + 1); + if (hexout != NULL) { + for (int i = 0; i < iLen; i++) { // data in hex + sprintf(&hexout[i * 3], "%02X ", recv[i]); + } + PrintAndLog("%s", hexout); + free(hexout); + } else { + PrintAndLog("malloc failed your client has low memory?"); + return 2; + } + printf("Command response just sent back to Lua script with the bytes which were just printed. Should get sent to read14a.lua.\n"); + //END ADDED CODE + + //Push it as a string lua_pushlstring(L,(const char *)&response,sizeof(UsbCommand)); @@ -109,6 +141,7 @@ static int l_WaitForResponseTimeout(lua_State *L){ }else{ //Push a Nil instead lua_pushnil(L); + printf("Nil pushed back to Lua script - no response received.\n"); return 1;// one return value } } diff --git a/client/scripts/myscript.lua b/client/scripts/myscript.lua new file mode 100644 index 00000000..b5314e9e --- /dev/null +++ b/client/scripts/myscript.lua @@ -0,0 +1,84 @@ +local cmds = require('commands') +local lib14a = require('read14a') + + +--- +-- This is only meant to be used when errors occur +function oops(err) + print("ERROR: ",err) +end + +function sendRaw(rawdata, crc) + print(">> ", rawdata) + + -- if crc + -- then local flags = lib14a.ISO14A_COMMAND.ISO14A_NO_DISCONNECT + lib14a.ISO14A_COMMAND.ISO14A_RAW + -- else local flags = lib14a.ISO14A_COMMAND.ISO14A_NO_DISCONNECT + lib14a.ISO14A_COMMAND.ISO14A_RAW + lib14a.ISO14A_APPEND_CRC + -- end + + local flags = lib14a.ISO14A_COMMAND.ISO14A_NO_DISCONNECT + lib14a.ISO14A_COMMAND.ISO14A_RAW + lib14a.ISO14A_COMMAND.ISO14A_APPEND_CRC + + -- local flags = lib14a.ISO14A_COMMAND.ISO14A_NO_DISCONNECT + lib14a.ISO14A_COMMAND.ISO14A_RAW + + local command = Command:new{cmd = cmds.CMD_READER_ISO_14443a, + arg1 = flags, -- Send raw + arg2 = string.len(rawdata) / 2, -- arg2 contains the length, which is half the length of the ASCII-string rawdata + data = rawdata} + local ignore_response = false + return lib14a.sendToDevice(command, ignore_response) +end + +--- +-- The main entry point +function main(args) + + + + -- Manually send the card the init commands + -- firstcommand = Command:new{cmd = cmds.CMD_READER_ISO_14443a, + -- arg1 = lib14a.ISO14A_COMMAND.ISO14A_CONNECT + lib14a.ISO14A_COMMAND.ISO14A_NO_DISCONNECT, + -- arg2 = 0, + -- data = ""} + -- local restwo,errtwo = lib14a.sendToDevice(firstcommand) + -- print(firstcommand.arg1) + + -- Call the program via the command line + -- result = core.console("hf 14a raw -p -b 7 -a 26") --I can do this from the command line, but I can't capture the output easily + -- print(result) + + -- Send the card the init commands using the read14a library, reusing the connect functionality from a common library + info,err = lib14a.read14443a(true, no_rats) + if err + then oops(err) + else print(("Connected to card with a UID of %s"):format(info.uid)) + end + + --Attempt to send raw data + getvers = "0360" -- 0x0360 should begin the "get version" commands + --print(string.byte(getvers, 1, 99999)) + --crc = core.crc16(getvers) -- under the hood, calls ComputeCrc14443, which is the same function which is called by "hf 14a raw" + --print(string.byte(crc, 1, 99999)) + + local result,err = sendRaw(getvers, true) + if result then + print("Currently trying to decode raw UsbCommand packet received.") + print(result) + + local count,cmd,arg1,arg2,arg3,data = bin.unpack('LLLLH512',result) + print(data) + --data = string.sub(result,count) + --local cmd_response = Command.parse(res) + else + err ="No response from card" + end + -- local cmd_response = Command.parse(res) + -- local len = tonumber(cmd_response.arg1) *2 + -- print("data length:",len) + -- local data = string.sub(tostring(cmd_response.data), 0, len); + -- print("<< ",data) + +end + + + +main(args) -- Call the main function From 7b2e196dcb6466940aa0851943b2ef9dd62c54e9 Mon Sep 17 00:00:00 2001 From: Dom Date: Tue, 27 Feb 2018 20:13:57 +0000 Subject: [PATCH 02/29] Got rid of unnecessary code which was being used for debugging. --- client/lualibs/read14a.lua | 1 - client/scripting.c | 59 ++++++++++++++++++------------------- client/scripts/myscript.lua | 44 ++++----------------------- 3 files changed, 35 insertions(+), 69 deletions(-) diff --git a/client/lualibs/read14a.lua b/client/lualibs/read14a.lua index cdddfac3..59a43aeb 100644 --- a/client/lualibs/read14a.lua +++ b/client/lualibs/read14a.lua @@ -111,7 +111,6 @@ local function read14443a(dont_disconnect, no_rats) end local result,err = sendToDevice(command) if result then - print("Currently trying to decode the UsbCommand packet just received (an ACK of the connection).") local count,cmd,arg0,arg1,arg2 = bin.unpack('LLLL',result) if arg0 == 0 then return nil, "iso14443a card select failed" diff --git a/client/scripting.c b/client/scripting.c index c118307b..57e6cd71 100644 --- a/client/scripting.c +++ b/client/scripting.c @@ -102,36 +102,35 @@ static int l_WaitForResponseTimeout(lua_State *L){ if(WaitForResponseTimeout(cmd, &response, ms_timeout)) { - //BEGIN ADDED CODE - uint8_t *recv; - char *hexout; - recv = response.d.asBytes; - uint8_t iLen = response.arg[0]; - if (0){ - iLen = response.arg[1]; - if (iLen){ - PrintAndLog("Card selected. UID[%i]:", iLen); - } else { - PrintAndLog("Can't select card."); - } - } else { - PrintAndLog("received %i bytes:", iLen); - } - if(!iLen) - return 1; - hexout = (char *)malloc(iLen * 3 + 1); - if (hexout != NULL) { - for (int i = 0; i < iLen; i++) { // data in hex - sprintf(&hexout[i * 3], "%02X ", recv[i]); - } - PrintAndLog("%s", hexout); - free(hexout); - } else { - PrintAndLog("malloc failed your client has low memory?"); - return 2; - } - printf("Command response just sent back to Lua script with the bytes which were just printed. Should get sent to read14a.lua.\n"); - //END ADDED CODE + /* Uncomment code below to print the bytes which were received from the C code before they get passed to Lua. */ + // uint8_t *recv; + // char *hexout; + // recv = response.d.asBytes; + // uint8_t iLen = response.arg[0]; + // if (0){ + // iLen = response.arg[1]; + // if (iLen){ + // PrintAndLog("Card selected. UID[%i]:", iLen); + // } else { + // PrintAndLog("Can't select card."); + // } + // } else { + // PrintAndLog("received %i bytes:", iLen); + // } + // if(!iLen) + // return 1; + // hexout = (char *)malloc(iLen * 3 + 1); + // if (hexout != NULL) { + // for (int i = 0; i < iLen; i++) { // data in hex + // sprintf(&hexout[i * 3], "%02X ", recv[i]); + // } + // PrintAndLog("%s", hexout); + // free(hexout); + // } else { + // PrintAndLog("malloc failed your client has low memory?"); + // return 2; + // } + // printf("Command response just sent back to Lua script with the bytes which were just printed.\n"); //Push it as a string diff --git a/client/scripts/myscript.lua b/client/scripts/myscript.lua index b5314e9e..548ce597 100644 --- a/client/scripts/myscript.lua +++ b/client/scripts/myscript.lua @@ -10,16 +10,10 @@ end function sendRaw(rawdata, crc) print(">> ", rawdata) - - -- if crc - -- then local flags = lib14a.ISO14A_COMMAND.ISO14A_NO_DISCONNECT + lib14a.ISO14A_COMMAND.ISO14A_RAW - -- else local flags = lib14a.ISO14A_COMMAND.ISO14A_NO_DISCONNECT + lib14a.ISO14A_COMMAND.ISO14A_RAW + lib14a.ISO14A_APPEND_CRC - -- end + --get rid of the ISO14A_APPEND_CRC flag if we don't want a CRC to be appended to the raw bytes. local flags = lib14a.ISO14A_COMMAND.ISO14A_NO_DISCONNECT + lib14a.ISO14A_COMMAND.ISO14A_RAW + lib14a.ISO14A_COMMAND.ISO14A_APPEND_CRC - -- local flags = lib14a.ISO14A_COMMAND.ISO14A_NO_DISCONNECT + lib14a.ISO14A_COMMAND.ISO14A_RAW - local command = Command:new{cmd = cmds.CMD_READER_ISO_14443a, arg1 = flags, -- Send raw arg2 = string.len(rawdata) / 2, -- arg2 contains the length, which is half the length of the ASCII-string rawdata @@ -32,53 +26,27 @@ end -- The main entry point function main(args) - - - -- Manually send the card the init commands - -- firstcommand = Command:new{cmd = cmds.CMD_READER_ISO_14443a, - -- arg1 = lib14a.ISO14A_COMMAND.ISO14A_CONNECT + lib14a.ISO14A_COMMAND.ISO14A_NO_DISCONNECT, - -- arg2 = 0, - -- data = ""} - -- local restwo,errtwo = lib14a.sendToDevice(firstcommand) - -- print(firstcommand.arg1) - - -- Call the program via the command line - -- result = core.console("hf 14a raw -p -b 7 -a 26") --I can do this from the command line, but I can't capture the output easily - -- print(result) - - -- Send the card the init commands using the read14a library, reusing the connect functionality from a common library + -- Initialize the card using the read14a library info,err = lib14a.read14443a(true, no_rats) if err then oops(err) else print(("Connected to card with a UID of %s"):format(info.uid)) end - --Attempt to send raw data - getvers = "0360" -- 0x0360 should begin the "get version" commands - --print(string.byte(getvers, 1, 99999)) - --crc = core.crc16(getvers) -- under the hood, calls ComputeCrc14443, which is the same function which is called by "hf 14a raw" - --print(string.byte(crc, 1, 99999)) + -- Now that the card is initialized, attempt to send raw data and read the response. + getvers = "0360" -- 0x0360 begins the "get version" commands local result,err = sendRaw(getvers, true) if result then print("Currently trying to decode raw UsbCommand packet received.") - print(result) - local count,cmd,arg1,arg2,arg3,data = bin.unpack('LLLLH512',result) print(data) - --data = string.sub(result,count) - --local cmd_response = Command.parse(res) else - err ="No response from card" + err = "No response from sending the card raw data." + oops(err) end - -- local cmd_response = Command.parse(res) - -- local len = tonumber(cmd_response.arg1) *2 - -- print("data length:",len) - -- local data = string.sub(tostring(cmd_response.data), 0, len); - -- print("<< ",data) end - main(args) -- Call the main function From 8987480b61f30b7a47d82cda6275ae9c16b626f7 Mon Sep 17 00:00:00 2001 From: Dom Date: Tue, 27 Feb 2018 22:47:34 +0000 Subject: [PATCH 03/29] cleaned up code to cleanly send commands to the Proxmark. --- client/lualibs/read14a.lua | 2 -- client/scripts/myscript.lua | 47 ++++++++++++++++++++++++------------- 2 files changed, 31 insertions(+), 18 deletions(-) diff --git a/client/lualibs/read14a.lua b/client/lualibs/read14a.lua index 59a43aeb..ebcbc358 100644 --- a/client/lualibs/read14a.lua +++ b/client/lualibs/read14a.lua @@ -80,7 +80,6 @@ end local function sendToDevice(command, ignoreresponse) core.clearCommandBuffer() - print("Sent a UsbCommand via read14a.lua.") local err = core.SendCommand(command:getBytes()) if err then print(err) @@ -89,7 +88,6 @@ local function sendToDevice(command, ignoreresponse) if ignoreresponse then return nil,nil end local response = core.WaitForResponseTimeout(cmds.CMD_ACK,TIMEOUT) - print("Received a UsbCommand packet in read14a.lua.") return response,nil end diff --git a/client/scripts/myscript.lua b/client/scripts/myscript.lua index 548ce597..6949191d 100644 --- a/client/scripts/myscript.lua +++ b/client/scripts/myscript.lua @@ -8,21 +8,36 @@ function oops(err) print("ERROR: ",err) end -function sendRaw(rawdata, crc) - print(">> ", rawdata) +--- +-- Used to send raw data to the firmware to subsequently forward the data to the card. +function sendRaw(rawdata, crc, power) + print((">> %s"):format(rawdata)) - --get rid of the ISO14A_APPEND_CRC flag if we don't want a CRC to be appended to the raw bytes. - local flags = lib14a.ISO14A_COMMAND.ISO14A_NO_DISCONNECT + lib14a.ISO14A_COMMAND.ISO14A_RAW + lib14a.ISO14A_COMMAND.ISO14A_APPEND_CRC + local flags = lib14a.ISO14A_COMMAND.ISO14A_RAW + if crc then + flags = flags + lib14a.ISO14A_COMMAND.ISO14A_APPEND_CRC + end + if power then + flags = flags + lib14a.ISO14A_COMMAND.ISO14A_NO_DISCONNECT + end local command = Command:new{cmd = cmds.CMD_READER_ISO_14443a, arg1 = flags, -- Send raw arg2 = string.len(rawdata) / 2, -- arg2 contains the length, which is half the length of the ASCII-string rawdata data = rawdata} local ignore_response = false - return lib14a.sendToDevice(command, ignore_response) + local result, err = lib14a.sendToDevice(command, ignore_response) + if result then + --unpack the first 4 parts of the result as longs, and the last as an extremely long string to later be cut down based on arg1, the number of bytes returned + local count,cmd,arg1,arg2,arg3,data = bin.unpack('LLLLH512',result) + print(("<< %s"):format(string.sub(data, 1, arg1 * 2))) -- need to multiply by 2 because the hex digits are actually two bytes when they are strings + else + err = "Error sending the card raw data." + oops(err) + end end ---- +--- -- The main entry point function main(args) @@ -34,17 +49,17 @@ function main(args) end -- Now that the card is initialized, attempt to send raw data and read the response. - getvers = "0360" -- 0x0360 begins the "get version" commands + GETVERS_INIT = "0360" -- Begins the GetVersion command + GETVERS_CONT = "03AF" -- Continues the GetVersion command + POWEROFF = "OFF" + + sendRaw(GETVERS_INIT, true, true) + sendRaw(GETVERS_CONT, true, true) + sendRaw(GETVERS_CONT, true, true) + + sendRaw(POWEROFF, false, false) --power off the Proxmark + - local result,err = sendRaw(getvers, true) - if result then - print("Currently trying to decode raw UsbCommand packet received.") - local count,cmd,arg1,arg2,arg3,data = bin.unpack('LLLLH512',result) - print(data) - else - err = "No response from sending the card raw data." - oops(err) - end end From 53ef1227c4245846fec6fced0ec4f69ba4ab88cc Mon Sep 17 00:00:00 2001 From: Dom Date: Wed, 28 Feb 2018 11:20:36 +0000 Subject: [PATCH 04/29] added WritePerso() method to personalize the keys and data on the card before moving security levels. --- client/scripts/myscript.lua | 103 +++++++++++++++++++++++++++++++++--- 1 file changed, 96 insertions(+), 7 deletions(-) diff --git a/client/scripts/myscript.lua b/client/scripts/myscript.lua index 6949191d..cfbe0b32 100644 --- a/client/scripts/myscript.lua +++ b/client/scripts/myscript.lua @@ -1,6 +1,13 @@ local cmds = require('commands') local lib14a = require('read14a') +GETVERS_INIT = "0360" -- Begins the GetVersion command +GETVERS_CONT = "03AF" -- Continues the GetVersion command +POWEROFF = "OFF" +WRITEPERSO = "03A8" +AUTH_FIRST = "0370" +AUTH_CONT = "0372" +AUTH_NONFIRST = "0376" --- -- This is only meant to be used when errors occur @@ -30,13 +37,96 @@ function sendRaw(rawdata, crc, power) if result then --unpack the first 4 parts of the result as longs, and the last as an extremely long string to later be cut down based on arg1, the number of bytes returned local count,cmd,arg1,arg2,arg3,data = bin.unpack('LLLLH512',result) - print(("<< %s"):format(string.sub(data, 1, arg1 * 2))) -- need to multiply by 2 because the hex digits are actually two bytes when they are strings + returned_bytes = string.sub(data, 1, arg1 * 2) + print(("<< %s"):format(returned_bytes)) -- need to multiply by 2 because the hex digits are actually two bytes when they are strings + return returned_bytes else err = "Error sending the card raw data." oops(err) end end +function writePerso() + -- Used to write any data, including the keys (Key A and Key B), for all the sectors. + -- writePerso() command parameters: + -- 1 byte - 0xA8 - Command Code + -- 2 bytes - Address of the first block or key to be written to (40 blocks are numbered from 0x0000 to 0x00FF) + -- X bytes - The data bytes to be written, starting from the first block. Amount of data sent can be from 16 to 240 bytes in 16 byte increments. This allows + -- up to 15 blocks to be written at once. + -- response from PICC: + -- 0x90 - OK + -- 0x09 - targeted block is invalid for writes, i.e. block 0, which contains manufacturer data + -- 0x0B - command invalid + -- 0x0C - unexpected command length + + SIXTEEN_BYTES_ZEROS = "00000000000000000000000000000000" + + -- First, set all the data in the card (4kB of data) to zeros. The keys, stored in the sector trailer block, are also set to zeros. + -- The only block which cannot be explicitly set is block 0x0000, the manufacturer block. + print("Setting values of normal blocks") + for i=1,255,1 do --skip block 0 + --convert the number to hex with leading zeros, then use it as the block number in writeBlock() + blocknum = string.format("%04x", i) + writeBlock(blocknum, SIXTEEN_BYTES_ZEROS) + end + print("Finished setting values of normal blocks") + + print("Setting AES Sector keys") + -- Next, write to the AES sector keys + for i=0,39 do --for each sector number + local keyA_block = "40" .. string.format("%02x", i * 2) + local keyB_block = "40" .. string.format("%02x", (i * 2) + 1) + --Can also calculate the keys fancily to make them unique, if desired + keyA = SIXTEEN_BYTES_ZEROS + keyB = SIXTEEN_BYTES_ZEROS + writeBlock(keyA_block, keyA) + writeBlock(keyB_block, keyB) + end + print("Finished setting AES Sector keys") + + print("Setting misc keys which haven't been set yet.") + --CardMasterKey + blocknum = "9000" + writeBlock(blocknum, SIXTEEN_BYTES_ZEROS) + --CardConfigurationKey + blocknum = "9001" + writeBlock(blocknum, SIXTEEN_BYTES_ZEROS) + --L3SwitchKey + blocknum = "9003" + writeBlock(blocknum, SIXTEEN_BYTES_ZEROS) + --SL1CardAuthKey + blocknum = "9004" + writeBlock(blocknum, SIXTEEN_BYTES_ZEROS) + --L3SectorSwitchKey + blocknum = "9006" + writeBlock(blocknum, SIXTEEN_BYTES_ZEROS) + --L1L3MixSectorSwitchKey + blocknum = "9007" + writeBlock(blocknum, SIXTEEN_BYTES_ZEROS) + print("Finished setting misc keys.") + + print("WritePerso finished! Card is ready to move into new security level.") +end + +function writeBlock(blocknum, data) + -- Method writes 16 bytes of the string sent (data) to the specified block number + -- The block numbers sent to the card need to be in little endian format (i.e. block 0x0001 is sent as 0x1000) + blocknum_little_endian = string.sub(blocknum, 3, 4) .. string.sub(blocknum, 1, 2) + commandString = WRITEPERSO .. blocknum_little_endian .. data --Write 16 bytes (32 hex chars). + local response = sendRaw(commandString, true, true) --0x90 is returned upon success + if string.sub(response, 3, 4) ~= "90" then + oops(("error occurred while trying to write to block %s"):format(blocknum)) + end +end + +function authenticateAES() + -- Used to try to authenticate with the AES keys we programmed into the card, to ensure the authentication works correctly while still in SL0. + commandString = AUTH_FIRST + commandString = commandString .. "" + + +end + --- -- The main entry point function main(args) @@ -49,13 +139,12 @@ function main(args) end -- Now that the card is initialized, attempt to send raw data and read the response. - GETVERS_INIT = "0360" -- Begins the GetVersion command - GETVERS_CONT = "03AF" -- Continues the GetVersion command - POWEROFF = "OFF" - sendRaw(GETVERS_INIT, true, true) - sendRaw(GETVERS_CONT, true, true) - sendRaw(GETVERS_CONT, true, true) + --sendRaw(GETVERS_INIT, true, true) + --sendRaw(GETVERS_CONT, true, true) + --sendRaw(GETVERS_CONT, true, true) + + writePerso() sendRaw(POWEROFF, false, false) --power off the Proxmark From a65c1e82ad818b9ee7d151c4df07233979b93e29 Mon Sep 17 00:00:00 2001 From: Dom Date: Wed, 28 Feb 2018 11:30:45 +0000 Subject: [PATCH 05/29] Card has been moved to SL1. Next step is to add code for distance-bounding protocol. --- client/scripts/myscript.lua | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/client/scripts/myscript.lua b/client/scripts/myscript.lua index cfbe0b32..b42e9a62 100644 --- a/client/scripts/myscript.lua +++ b/client/scripts/myscript.lua @@ -5,6 +5,7 @@ GETVERS_INIT = "0360" -- Begins the GetVersion command GETVERS_CONT = "03AF" -- Continues the GetVersion command POWEROFF = "OFF" WRITEPERSO = "03A8" +COMMITPERSO = "03AA" AUTH_FIRST = "0370" AUTH_CONT = "0372" AUTH_NONFIRST = "0376" @@ -113,18 +114,30 @@ function writeBlock(blocknum, data) -- The block numbers sent to the card need to be in little endian format (i.e. block 0x0001 is sent as 0x1000) blocknum_little_endian = string.sub(blocknum, 3, 4) .. string.sub(blocknum, 1, 2) commandString = WRITEPERSO .. blocknum_little_endian .. data --Write 16 bytes (32 hex chars). - local response = sendRaw(commandString, true, true) --0x90 is returned upon success + response = sendRaw(commandString, true, true) --0x90 is returned upon success if string.sub(response, 3, 4) ~= "90" then oops(("error occurred while trying to write to block %s"):format(blocknum)) end end function authenticateAES() - -- Used to try to authenticate with the AES keys we programmed into the card, to ensure the authentication works correctly while still in SL0. + -- Used to try to authenticate with the AES keys we programmed into the card, to ensure the authentication works correctly. commandString = AUTH_FIRST commandString = commandString .. "" +end +function getVersion() + sendRaw(GETVERS_INIT, true, true) + sendRaw(GETVERS_CONT, true, true) + sendRaw(GETVERS_CONT, true, true) +end +function commitPerso() + commandString = COMMITPERSO .. "01" --switch to SL1 + response = sendRaw(commandString, true, true) --0x90 is returned upon success + if string.sub(response, 3, 4) ~= "90" then + oops("error occurred while trying to switch security level") + end end --- @@ -138,15 +151,14 @@ function main(args) else print(("Connected to card with a UID of %s"):format(info.uid)) end - -- Now that the card is initialized, attempt to send raw data and read the response. + -- Now, the card is initialized and we can do more interesting things. - --sendRaw(GETVERS_INIT, true, true) - --sendRaw(GETVERS_CONT, true, true) - --sendRaw(GETVERS_CONT, true, true) + --writePerso() + commitPerso() - writePerso() - sendRaw(POWEROFF, false, false) --power off the Proxmark + -- Power off the Proxmark + sendRaw(POWEROFF, false, false) From be3e1489376a5ff5a51c7a6d61ac0e8dd5d7058d Mon Sep 17 00:00:00 2001 From: Dom Date: Wed, 28 Feb 2018 12:44:30 +0000 Subject: [PATCH 06/29] Added ISO 14443-4 support (via PPS (Protocol and Parameter Selection)). Now card can be talked to in SL1. --- client/scripts/myscript.lua | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/client/scripts/myscript.lua b/client/scripts/myscript.lua index b42e9a62..019bce4a 100644 --- a/client/scripts/myscript.lua +++ b/client/scripts/myscript.lua @@ -9,6 +9,9 @@ COMMITPERSO = "03AA" AUTH_FIRST = "0370" AUTH_CONT = "0372" AUTH_NONFIRST = "0376" +PREPAREPC = "03F0" +PROXIMITYCHECK = "03F2" +VERIFYPC = "03FD" --- -- This is only meant to be used when errors occur @@ -140,22 +143,39 @@ function commitPerso() end end +function proximityCheck() + commandString = PREPAREPC + response = sendRaw(commandString, true, true) --0x90 is returned upon success + + commandString = PROXIMITYCHECK + + commandString = VERIFYPC + +end + --- -- The main entry point function main(args) -- Initialize the card using the read14a library - info,err = lib14a.read14443a(true, no_rats) - if err - then oops(err) - else print(("Connected to card with a UID of %s"):format(info.uid)) + info,err = lib14a.read14443a(true, false) + if err then + oops(err) + else + print(("Connected to card with a UID of %s"):format(info.uid)) end -- Now, the card is initialized and we can do more interesting things. --writePerso() - commitPerso() + --commitPerso() + --getVersion() + --proximityCheck() + sendRaw("e050", true, true) + sendRaw("D01100", true, true) + sendRaw("0360", true, true) + -- Power off the Proxmark sendRaw(POWEROFF, false, false) From 46473030c140aba95e3eb11663156587e56415c1 Mon Sep 17 00:00:00 2001 From: Dom Date: Wed, 28 Feb 2018 13:41:32 +0000 Subject: [PATCH 07/29] small changes --- client/scripts/myscript.lua | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/client/scripts/myscript.lua b/client/scripts/myscript.lua index 019bce4a..93207423 100644 --- a/client/scripts/myscript.lua +++ b/client/scripts/myscript.lua @@ -145,7 +145,7 @@ end function proximityCheck() commandString = PREPAREPC - response = sendRaw(commandString, true, true) --0x90 is returned upon success + response = sendRaw(commandString, true, true) commandString = PROXIMITYCHECK @@ -159,22 +159,23 @@ function main(args) -- Initialize the card using the read14a library info,err = lib14a.read14443a(true, false) + --Perform PPS (Protocol and Parameter Selection) check to finish the ISO 14443-4 protocol. + sendRaw("e050", true, true) + sendRaw("D01100", true, true) if err then oops(err) else - print(("Connected to card with a UID of %s"):format(info.uid)) + print(("Connected to card with a UID of %s."):format(info.uid)) end + -- Now, the card is initialized and we can do more interesting things. --writePerso() --commitPerso() --getVersion() - --proximityCheck() - sendRaw("e050", true, true) - sendRaw("D01100", true, true) + proximityCheck() - sendRaw("0360", true, true) -- Power off the Proxmark From a508482ae7615630066f8257e472d8be52736261 Mon Sep 17 00:00:00 2001 From: Dom Date: Tue, 13 Mar 2018 18:49:09 +0000 Subject: [PATCH 08/29] Beginning tests with VerifyPC and authenticating to change keys. --- client/scripts/myscript.lua | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/client/scripts/myscript.lua b/client/scripts/myscript.lua index 93207423..f9328de5 100644 --- a/client/scripts/myscript.lua +++ b/client/scripts/myscript.lua @@ -1,6 +1,8 @@ local cmds = require('commands') local lib14a = require('read14a') +SIXTEEN_BYTES_ZEROS = "00000000000000000000000000000000" + GETVERS_INIT = "0360" -- Begins the GetVersion command GETVERS_CONT = "03AF" -- Continues the GetVersion command POWEROFF = "OFF" @@ -12,6 +14,7 @@ AUTH_NONFIRST = "0376" PREPAREPC = "03F0" PROXIMITYCHECK = "03F2" VERIFYPC = "03FD" +READPLAINNOMACUNMACED = "0336" --- -- This is only meant to be used when errors occur @@ -63,7 +66,6 @@ function writePerso() -- 0x0B - command invalid -- 0x0C - unexpected command length - SIXTEEN_BYTES_ZEROS = "00000000000000000000000000000000" -- First, set all the data in the card (4kB of data) to zeros. The keys, stored in the sector trailer block, are also set to zeros. -- The only block which cannot be explicitly set is block 0x0000, the manufacturer block. @@ -147,7 +149,8 @@ function proximityCheck() commandString = PREPAREPC response = sendRaw(commandString, true, true) - commandString = PROXIMITYCHECK + commandString = PROXIMITYCHECK .. "08" .. "0001020304050607" + response = sendRaw(commandString, true, true) commandString = VERIFYPC @@ -174,9 +177,15 @@ function main(args) --writePerso() --commitPerso() --getVersion() - proximityCheck() + --proximityCheck() - + -- attempt to read VCProximityKey at block A001 + -- commandString = READPLAINNOMACUNMACED .. "01A0" .. "01" + -- response = sendRaw(commandString, true, true) + + -- authenticate with CardConfigurationKey + commandString = AUTH_FIRST .. "0190" .. "00" + response = sendRaw(commandString, true, true) -- Power off the Proxmark sendRaw(POWEROFF, false, false) From 7fe4589d2191ea282f247b151f43ff749beb7610 Mon Sep 17 00:00:00 2001 From: Dom Date: Tue, 20 Mar 2018 08:51:14 +0000 Subject: [PATCH 09/29] Added keys for writePerso(). --- client/scripts/myscript.lua | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/client/scripts/myscript.lua b/client/scripts/myscript.lua index f9328de5..35393486 100644 --- a/client/scripts/myscript.lua +++ b/client/scripts/myscript.lua @@ -109,6 +109,22 @@ function writePerso() --L1L3MixSectorSwitchKey blocknum = "9007" writeBlock(blocknum, SIXTEEN_BYTES_ZEROS) + --VC Keys + --VCProximityKey + blocknum = "A001" + writeBlock(blocknum, SIXTEEN_BYTES_ZEROS) + --VCSelectENCKey + blocknum = "A080" + writeBlock(blocknum, SIXTEEN_BYTES_ZEROS) + --VCSelectMACKey + blocknum = "A081" + writeBlock(blocknum, SIXTEEN_BYTES_ZEROS) + --TransactionMACKey1 + blocknum = "C000" + writeBlock(blocknum, SIXTEEN_BYTES_ZEROS) + --TransactionMACConfKey1 + blocknum = "C001" + writeBlock(blocknum, SIXTEEN_BYTES_ZEROS) print("Finished setting misc keys.") print("WritePerso finished! Card is ready to move into new security level.") @@ -138,7 +154,8 @@ function getVersion() end function commitPerso() - commandString = COMMITPERSO .. "01" --switch to SL1 + -- commandString = COMMITPERSO .. "01" --switch to SL1 + commandString = COMMITPERSO .. "03" --switch to SL3 response = sendRaw(commandString, true, true) --0x90 is returned upon success if string.sub(response, 3, 4) ~= "90" then oops("error occurred while trying to switch security level") @@ -177,15 +194,15 @@ function main(args) --writePerso() --commitPerso() --getVersion() - --proximityCheck() + proximityCheck() -- attempt to read VCProximityKey at block A001 -- commandString = READPLAINNOMACUNMACED .. "01A0" .. "01" -- response = sendRaw(commandString, true, true) -- authenticate with CardConfigurationKey - commandString = AUTH_FIRST .. "0190" .. "00" - response = sendRaw(commandString, true, true) + -- commandString = AUTH_FIRST .. "0190" .. "00" + -- response = sendRaw(commandString, true, true) -- Power off the Proxmark sendRaw(POWEROFF, false, false) From f882a16aedbcbcf664f3afad2895384301bfe1da Mon Sep 17 00:00:00 2001 From: Dom Date: Tue, 20 Mar 2018 16:46:55 +0000 Subject: [PATCH 10/29] Added MAC calculations with dummy filler as input. --- client/scripts/myscript.lua | 56 ++++++++++++++++++++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/client/scripts/myscript.lua b/client/scripts/myscript.lua index 35393486..b2455b20 100644 --- a/client/scripts/myscript.lua +++ b/client/scripts/myscript.lua @@ -162,14 +162,68 @@ function commitPerso() end end +function calculateMAC(MAC_input) + -- Pad the input if it is not a multiple of 16 bytes (32 nibbles). + if(string.len(MAC_input) % 32 != 0) then + MAC_input = MAC_input .. "80" + end + while(string.len(MAC_input) % 32 != 0) do + MAC_input = MAC_input .. "0" + end + print("Padded MAC Input = " .. MAC_input .. ", length = " .. string.len(MAC_input)) + + --The MAC would actually be calculated here, and the output stored in raw_output + raw_output = "00010203040506070001020304050607" -- Dummy filler for now of 16-byte output. To be filled with actual MAC for testing purposes. + + -- The final 8-byte MAC output is a concatenation of every 2nd byte starting from the second MSB. + final_output = "" + j = 3 + for i = 1,8 do + final_output = final_output .. string.sub(RndR, j, j + 1) .. string.sub(RndC, j, j + 1) + j = j + 4 + end + return final_output +end + function proximityCheck() commandString = PREPAREPC response = sendRaw(commandString, true, true) + OPT = string.sub(response, 5, 6) + if(tonumber(OPT) == 1) then + pps_present = true + else + pps_present = false + end + pubRespTime = string.sub(response, 7, 10) + if(pps_present == true) then + pps = string.sub(response, 11, 12) + else + pps = nil + end + print("OPT = " .. OPT .. " pubRespTime = " .. pubRespTime .. " pps = " .. pps) - commandString = PROXIMITYCHECK .. "08" .. "0001020304050607" + RndC = "0001020304050607" --Random Challenge + commandString = PROXIMITYCHECK .. "08" .. RndC response = sendRaw(commandString, true, true) + RndR = string.sub(response, 3, 18) + print("RndC = " .. RndC .. " RndR = " .. RndR) commandString = VERIFYPC + MAC_input = "FD" .. OPT .. pubRespTime + if(pps_present == true) then + MAC_input = MAC_input .. pps + end + concat = "" + j = 1 + for i = 1,8 do + concat = concat .. string.sub(RndR, j, j + 1) .. string.sub(RndC, j, j + 1) + j = j + 2 + end + MAC_input = MAC_input .. concat + print("concat = " .. concat .. " MAC_input = " .. MAC_input) + + MAC_tag = calculateMAC(MAC_input) + print(MAC_tag) end From 5bbb50319284efcc5c674dff50cb6ead6cf8b6b9 Mon Sep 17 00:00:00 2001 From: Dom Date: Tue, 20 Mar 2018 19:37:21 +0000 Subject: [PATCH 11/29] Added more MAC check functionality. TODO: implement CMAC-AES. --- client/scripts/myscript.lua | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/client/scripts/myscript.lua b/client/scripts/myscript.lua index b2455b20..1949f4a7 100644 --- a/client/scripts/myscript.lua +++ b/client/scripts/myscript.lua @@ -25,7 +25,7 @@ end --- -- Used to send raw data to the firmware to subsequently forward the data to the card. function sendRaw(rawdata, crc, power) - print((">> %s"):format(rawdata)) + print((": %s"):format(rawdata)) local flags = lib14a.ISO14A_COMMAND.ISO14A_RAW if crc then @@ -45,7 +45,7 @@ function sendRaw(rawdata, crc, power) --unpack the first 4 parts of the result as longs, and the last as an extremely long string to later be cut down based on arg1, the number of bytes returned local count,cmd,arg1,arg2,arg3,data = bin.unpack('LLLLH512',result) returned_bytes = string.sub(data, 1, arg1 * 2) - print(("<< %s"):format(returned_bytes)) -- need to multiply by 2 because the hex digits are actually two bytes when they are strings + print((": %s"):format(returned_bytes)) -- need to multiply by 2 because the hex digits are actually two bytes when they are strings return returned_bytes else err = "Error sending the card raw data." @@ -164,13 +164,13 @@ end function calculateMAC(MAC_input) -- Pad the input if it is not a multiple of 16 bytes (32 nibbles). - if(string.len(MAC_input) % 32 != 0) then + if(string.len(MAC_input) % 32 ~= 0) then MAC_input = MAC_input .. "80" end - while(string.len(MAC_input) % 32 != 0) do + while(string.len(MAC_input) % 32 ~= 0) do MAC_input = MAC_input .. "0" end - print("Padded MAC Input = " .. MAC_input .. ", length = " .. string.len(MAC_input)) + print("Padded MAC Input = " .. MAC_input .. ", length (bytes) = " .. string.len(MAC_input) / 2) --The MAC would actually be calculated here, and the output stored in raw_output raw_output = "00010203040506070001020304050607" -- Dummy filler for now of 16-byte output. To be filled with actual MAC for testing purposes. @@ -208,22 +208,30 @@ function proximityCheck() RndR = string.sub(response, 3, 18) print("RndC = " .. RndC .. " RndR = " .. RndR) - commandString = VERIFYPC + MAC_input = "FD" .. OPT .. pubRespTime if(pps_present == true) then MAC_input = MAC_input .. pps end - concat = "" + rnum_concat = "" j = 1 for i = 1,8 do - concat = concat .. string.sub(RndR, j, j + 1) .. string.sub(RndC, j, j + 1) + rnum_concat = rnum_concat .. string.sub(RndR, j, j + 1) .. string.sub(RndC, j, j + 1) j = j + 2 end - MAC_input = MAC_input .. concat - print("concat = " .. concat .. " MAC_input = " .. MAC_input) - + MAC_input = MAC_input .. rnum_concat + print("Concatenation of random numbers = " .. rnum_concat) + print("Final PCD concatenation before input into MAC function = " .. MAC_input) MAC_tag = calculateMAC(MAC_input) - print(MAC_tag) + print("8-byte PCD MAC_tag (placeholder - currently incorrect) = " .. MAC_tag) + commandString = VERIFYPC .. MAC_tag + response = sendRaw(commandString, true, true) + PICC_MAC = string.sub(response, 5, 20) + print("8-byte MAC returned by PICC = " .. PICC_MAC) + MAC_input = "90" .. string.sub(MAC_input, 3) + print("Final PICC concatenation before input into MAC function = " .. MAC_input) + MAC_tag = calculateMAC(MAC_input) + print("8-byte PICC MAC_tag (placeholder - currently incorrect) = " .. MAC_tag) end @@ -250,6 +258,10 @@ function main(args) --getVersion() proximityCheck() + --commandString = VERIFYPC .. "186EFDE8DDC7D30B" + -- MAC = f5180d6e 40fdeae8 e9dd6ac7 bcd3350b + -- response = sendRaw(commandString, true, true) + -- attempt to read VCProximityKey at block A001 -- commandString = READPLAINNOMACUNMACED .. "01A0" .. "01" -- response = sendRaw(commandString, true, true) From 7a5acc71acb36ebde44fd42363756734eb07e047 Mon Sep 17 00:00:00 2001 From: Dom Date: Fri, 30 Mar 2018 09:28:39 +0100 Subject: [PATCH 12/29] Added timing analysis based on how long it takes to receive all bytes. --- armsrc/iso14443a.c | 5 +++++ client/Makefile | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index a8273e5e..cd1529c4 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -2015,6 +2015,7 @@ void ReaderIso14443a(UsbCommand *c) byte_t buf[USB_CMD_DATA_SIZE] = {0}; uint8_t par[MAX_PARITY_SIZE]; bool cantSELECT = false; + uint32_t start_ts = 0, end_ts = 0; set_tracing(true); @@ -2091,7 +2092,11 @@ void ReaderIso14443a(UsbCommand *c) ReaderTransmit(cmd,len, NULL); // 8 bits, odd parity } } + start_ts = GetCountSspClk(); //started just after we send all our bytes to the PICC arg0 = ReaderReceive(buf, par); + end_ts = GetCountSspClk(); //ended just after we have received all the response bytes from the PICC. + uint32_t cycles_taken = end_ts - start_ts; + Dbprintf("Cycles taken to receive response from sending those bytes = %d", cycles_taken); LED_B_ON(); cmd_send(CMD_ACK,arg0,0,0,buf,sizeof(buf)); diff --git a/client/Makefile b/client/Makefile index 883f3b6f..fcaae89b 100644 --- a/client/Makefile +++ b/client/Makefile @@ -20,7 +20,7 @@ OBJDIR = obj LDLIBS = -L/opt/local/lib -L/usr/local/lib -lreadline -lpthread -lm LUALIB = ../liblua/liblua.a LDFLAGS = $(ENV_LDFLAGS) -CFLAGS = $(ENV_CFLAGS) -std=c99 -D_ISOC99_SOURCE -I. -I../include -I../common -I../common/polarssl -I../zlib -I../uart -I/opt/local/include -I../liblua -Wall -g -O3 +CFLAGS = $(ENV_CFLAGS) -std=c99 -D_ISOC99_SOURCE -I. -I../include -I../common -I../common/polarssl -I../zlib -I../uart -I/opt/local/include -I../liblua -Wall -g -O3 -Wa,-q,-mavx512f CXXFLAGS = -I../include -Wall -O3 LUAPLATFORM = generic From d4a97eb4c71876830be9e858cf7f47a2035ccbf6 Mon Sep 17 00:00:00 2001 From: Dom Date: Fri, 30 Mar 2018 14:29:15 +0100 Subject: [PATCH 13/29] Timing analysis now starts when first bit is received. --- armsrc/iso14443a.c | 67 +++++++++++++++++++++++++++---------- client/scripts/myscript.lua | 2 +- 2 files changed, 50 insertions(+), 19 deletions(-) diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index cd1529c4..945a5b9a 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -88,6 +88,9 @@ uint8_t trigger = 0; // the block number for the ISO14443-4 PCB static uint8_t iso14_pcb_blocknum = 0; +int manchester_recv_started = 0; +int recorded = 0; + // // ISO14443 timing: // @@ -292,12 +295,12 @@ static void UartInit(uint8_t *data, uint8_t *parity) // use parameter non_real_time to provide a timestamp. Set to 0 if the decoder should measure real time static RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time) { - + //Dbprintf("Miller decoding now!"); Uart.fourBits = (Uart.fourBits << 8) | bit; - if (Uart.state == STATE_UNSYNCD) { // not yet synced + if (Uart.state == STATE_UNSYNCD) { // not yet synced - Uart.syncBit = 9999; // not set + Uart.syncBit = 9999; // not set // The start bit is one ore more Sequence Y followed by a Sequence Z (... 11111111 00x11111). We need to distinguish from // Sequence X followed by Sequence Y followed by Sequence Z (111100x1 11111111 00x11111) // we therefore look for a ...xx11111111111100x11111xxxxxx... pattern @@ -463,6 +466,7 @@ static void DemodInit(uint8_t *data, uint8_t *parity) } // use parameter non_real_time to provide a timestamp. Set to 0 if the decoder should measure real time +// Input *bit* to the Manchester decoding is four bytes (32 bits) which are read from the RHR. static RAMFUNC int ManchesterDecoding(uint8_t bit, uint16_t offset, uint32_t non_real_time) { @@ -470,7 +474,7 @@ static RAMFUNC int ManchesterDecoding(uint8_t bit, uint16_t offset, uint32_t non if (Demod.state == DEMOD_UNSYNCD) { - if (Demod.highCnt < 2) { // wait for a stable unmodulated signal + if (Demod.highCnt < 2) { // wait for a stable unmodulated signal if (Demod.twoBits == 0x0000) { Demod.highCnt++; } else { @@ -494,14 +498,18 @@ static RAMFUNC int ManchesterDecoding(uint8_t bit, uint16_t offset, uint32_t non } } - } else { - - if (IsManchesterModulationNibble1(Demod.twoBits >> Demod.syncBit)) { // modulation in first half - if (IsManchesterModulationNibble2(Demod.twoBits >> Demod.syncBit)) { // ... and in second half = collision + } else { //Demod.state == DEMOD_MANCHESTER_DATA + //Determine the modulation details for each nibble (4 bits) separately + if (IsManchesterModulationNibble1(Demod.twoBits >> Demod.syncBit)) { // if modulation in first half + if (IsManchesterModulationNibble2(Demod.twoBits >> Demod.syncBit)) { // ... and in second half, that specifies collision + //Save the collision position and treat as Sequence D if (!Demod.collisionPos) { Demod.collisionPos = (Demod.len << 3) + Demod.bitCount; } - } // modulation in first half only - Sequence D = 1 + } + if(!recorded) + manchester_recv_started = 1; //specify that the data transfer has begun + // modulation in first half only - Sequence D = 1. Demod.bitCount++; Demod.shiftReg = (Demod.shiftReg >> 1) | 0x100; // in both cases, add a 1 to the shiftreg if(Demod.bitCount == 9) { // if we decoded a full byte (including parity) @@ -516,7 +524,7 @@ static RAMFUNC int ManchesterDecoding(uint8_t bit, uint16_t offset, uint32_t non } } Demod.endTime = Demod.startTime + 8*(9*Demod.len + Demod.bitCount + 1) - 4; - } else { // no modulation in first half + } else { // if no modulation in first half if (IsManchesterModulationNibble2(Demod.twoBits >> Demod.syncBit)) { // and modulation in second half = Sequence E = 0 Demod.bitCount++; Demod.shiftReg = (Demod.shiftReg >> 1); // add a 0 to the shiftreg @@ -532,7 +540,7 @@ static RAMFUNC int ManchesterDecoding(uint8_t bit, uint16_t offset, uint32_t non } } Demod.endTime = Demod.startTime + 8*(9*Demod.len + Demod.bitCount + 1); - } else { // no modulation in both halves - End of communication + } else { // no modulation in both halves - End of communication if(Demod.bitCount > 0) { // there are some remaining data bits Demod.shiftReg >>= (9 - Demod.bitCount); // right align the decoded bits Demod.output[Demod.len++] = Demod.shiftReg & 0xff; // and add them to the output @@ -1289,6 +1297,8 @@ static void TransmitFor14443a(const uint8_t *cmd, uint16_t len, uint32_t *timing // clear TXRDY AT91C_BASE_SSC->SSC_THR = SEC_Y; + Dbprintf("Sending bytes to the PICC."); + uint16_t c = 0; for(;;) { if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { @@ -1579,6 +1589,10 @@ int EmSendPrecompiledCmd(tag_response_info_t *response_info) { static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint8_t *receivedResponsePar, uint16_t offset) { uint32_t c; + uint32_t start_ts = GetCountSspClk(); + uint32_t end_ts = 0; + manchester_recv_started = 0; + recorded = 0; // Set FPGA mode to "reader listen mode", no modulation (listen // only, since we are receiving, not transmitting). @@ -1586,22 +1600,39 @@ static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint8_t *receive LED_D_ON(); FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_LISTEN); - // Now get the answer from the card + /* Now, get the answer from the card. + 32-bit registers used on the AT91: + SSC_RHR = Receive Holding Register + SSC_SR = Status Register (contains RXRDY, which is one bit. 0 is RHR is empty, or 1 if RHR has 32 bits of data in it) + */ + DemodInit(receivedResponse, receivedResponsePar); - // clear RXRDY: + + // clear RXRDY by reading the contents of RHR. uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; c = 0; for(;;) { - WDT_HIT(); + WDT_HIT(); //Watchdog Timer - if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { - b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + if(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { + b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; //read in 4 bytes of data from the RHR + if(manchester_recv_started){ + end_ts = GetCountSspClk(); + manchester_recv_started = 0; + recorded = 1; + } + + //Perform the manchester decoding on the 4 bytes just received. if(ManchesterDecoding(b, offset, 0)) { NextTransferTime = MAX(NextTransferTime, Demod.endTime - (DELAY_AIR2ARM_AS_READER + DELAY_ARM2AIR_AS_READER)/16 + FRAME_DELAY_TIME_PICC_TO_PCD); + uint32_t cycle_count = end_ts - start_ts; + Dbprintf("Finished decoding (Manchester). Value of c=%d. Cycle count (for one bit) = %d", c, cycle_count); return true; } else if (c++ > iso14a_timeout && Demod.state == DEMOD_UNSYNCD) { + //we reach here only if we time out (i.e. receiving the data from the PICC takes too long) + Dbprintf("Timed out while waiting for PICC response (c = %d)!", c); return false; } } @@ -2095,8 +2126,8 @@ void ReaderIso14443a(UsbCommand *c) start_ts = GetCountSspClk(); //started just after we send all our bytes to the PICC arg0 = ReaderReceive(buf, par); end_ts = GetCountSspClk(); //ended just after we have received all the response bytes from the PICC. - uint32_t cycles_taken = end_ts - start_ts; - Dbprintf("Cycles taken to receive response from sending those bytes = %d", cycles_taken); + uint32_t cycle_count = end_ts - start_ts; + Dbprintf("Cycle count (all bytes) = %d", cycle_count); LED_B_ON(); cmd_send(CMD_ACK,arg0,0,0,buf,sizeof(buf)); diff --git a/client/scripts/myscript.lua b/client/scripts/myscript.lua index 1949f4a7..88a15f96 100644 --- a/client/scripts/myscript.lua +++ b/client/scripts/myscript.lua @@ -255,7 +255,7 @@ function main(args) --writePerso() --commitPerso() - --getVersion() + getVersion() proximityCheck() --commandString = VERIFYPC .. "186EFDE8DDC7D30B" From 2020b129cac5e9ec9bf75138ff96533c22019102 Mon Sep 17 00:00:00 2001 From: Dom Date: Fri, 30 Mar 2018 17:36:22 +0100 Subject: [PATCH 14/29] Changed name of Lua script. --- client/scripts/{myscript.lua => mifarePlus.lua} | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) rename client/scripts/{myscript.lua => mifarePlus.lua} (99%) diff --git a/client/scripts/myscript.lua b/client/scripts/mifarePlus.lua similarity index 99% rename from client/scripts/myscript.lua rename to client/scripts/mifarePlus.lua index 88a15f96..ca48f0d9 100644 --- a/client/scripts/myscript.lua +++ b/client/scripts/mifarePlus.lua @@ -238,8 +238,7 @@ end --- -- The main entry point function main(args) - - -- Initialize the card using the read14a library + -- Initialize the card using the already-present read14a library info,err = lib14a.read14443a(true, false) --Perform PPS (Protocol and Parameter Selection) check to finish the ISO 14443-4 protocol. sendRaw("e050", true, true) From 2cbf09c3d149cebd7e5f5b603f01a67bbe46f567 Mon Sep 17 00:00:00 2001 From: Dom Date: Mon, 2 Apr 2018 10:46:05 +0100 Subject: [PATCH 15/29] Temporarily commented out distance bounding code. About to add in CMAC calculations to C Code. --- client/scripts/mifarePlus.lua | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/client/scripts/mifarePlus.lua b/client/scripts/mifarePlus.lua index ca48f0d9..9fd0cc2c 100644 --- a/client/scripts/mifarePlus.lua +++ b/client/scripts/mifarePlus.lua @@ -186,6 +186,7 @@ function calculateMAC(MAC_input) end function proximityCheck() + --PreparePC-- commandString = PREPAREPC response = sendRaw(commandString, true, true) OPT = string.sub(response, 5, 6) @@ -202,23 +203,25 @@ function proximityCheck() end print("OPT = " .. OPT .. " pubRespTime = " .. pubRespTime .. " pps = " .. pps) + --PC-- RndC = "0001020304050607" --Random Challenge commandString = PROXIMITYCHECK .. "08" .. RndC response = sendRaw(commandString, true, true) RndR = string.sub(response, 3, 18) print("RndC = " .. RndC .. " RndR = " .. RndR) - + --VerifyPC-- MAC_input = "FD" .. OPT .. pubRespTime if(pps_present == true) then MAC_input = MAC_input .. pps end rnum_concat = "" - j = 1 - for i = 1,8 do - rnum_concat = rnum_concat .. string.sub(RndR, j, j + 1) .. string.sub(RndC, j, j + 1) - j = j + 2 - end + rnum_concat = RndR .. RndC --temporary (only works for when a single random challenge (8 bytes) is sent) + -- j = 1 + -- for i = 1,8 do + -- rnum_concat = rnum_concat .. string.sub(RndR, j, j + 1) .. string.sub(RndC, j, j + 1) + -- j = j + 2 + -- end MAC_input = MAC_input .. rnum_concat print("Concatenation of random numbers = " .. rnum_concat) print("Final PCD concatenation before input into MAC function = " .. MAC_input) @@ -226,6 +229,7 @@ function proximityCheck() print("8-byte PCD MAC_tag (placeholder - currently incorrect) = " .. MAC_tag) commandString = VERIFYPC .. MAC_tag response = sendRaw(commandString, true, true) + print(response) PICC_MAC = string.sub(response, 5, 20) print("8-byte MAC returned by PICC = " .. PICC_MAC) MAC_input = "90" .. string.sub(MAC_input, 3) @@ -254,7 +258,7 @@ function main(args) --writePerso() --commitPerso() - getVersion() + --getVersion() proximityCheck() --commandString = VERIFYPC .. "186EFDE8DDC7D30B" From 675705ffcd1d2e24d0cb70f05a33b8c6789eb8e6 Mon Sep 17 00:00:00 2001 From: Dom Date: Thu, 5 Apr 2018 09:22:54 +0100 Subject: [PATCH 16/29] minor changes. Changed minor errors to warnings in compiler. --- .DS_Store | Bin 0 -> 8196 bytes armsrc/iso14443a.c | 28 ++++++++++++++-------------- common/Makefile.common | 2 +- 3 files changed, 15 insertions(+), 15 deletions(-) create mode 100644 .DS_Store diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..458ef6af6e390543679e12a17e64dc4bcb0b6424 GIT binary patch literal 8196 zcmeHMPiz%M7@uETV0NK&%HQr&=#yGSDB6~mqJX@<7O@JUp@p^-Df`~8u(I8)Z}+u8 zsTRFxg7Jh3>P3yl;K@WzCdP{q{~fdnYB+fCpcjuuqlw?_>;qcpRSoPUGvCZN-?ua0 zZ+^RznPrS2TeO-Ot6_|B%2JB?RNNrRewnXJWwEA$B*>oyBRSX4QR_l(Ec?FdP09p;1c6%;0r`DMQ|J_3CfkEaz%W^fO02&I=0Kia#Bg<&JZ6y5RZ)bgo0>vdVV@GXUHg- zlnDX}0@ouTU!QVjF`wmgW7nSFT_*?|8!w`)ykgGWd7SIIUa3FUbJ!p23C*w=WX-~$ zY;~LA;aptr^?mnB-OTNE?6D!Sq{H_@)A8&=6uznkObSzP!F^OV`2SW5>r&Ogwc)MTGdPz^Z0M zc=l>|ZZO)Rt|!V~&W)(>E|tR5^!Y~DBl?bhC+~Yb&T)H4R0R}W7d5*J_9#Wtm-pS` zuon!8>b&XZi>?{k?XD}0gZ|Jy8p_(fz%PUyk>QXK#lYTelbthacak-^E|O2$H4-|$ z7wokQ0m-^dqnfmKZo$$OtL|Fc*!sZM&Z)|URib*4uJ0pUywG{vu?u^~94kCLU4HfIoIy>%wfA4uBJ^bTV7LXq>S53T{B&{sN?;`obzPS36D*Qg;kY$t#OAY zKH&Q;n&D30k|SABk5OyXb3Q2b9R-_8E1J~Zs|~$3pjd^;wMf&jPS<;n(1MD9rXVNY z)T|qOTr+38!qRx8+R&yOeWNO5@o22vv{^U$^ZxKKg&0($fz)zNM!V6$#i#s$9D9cu zgu6y;PY%DlX4$q{!x)hIcFVFY&UsyCwZbogK@)N(G1w~B!Zx#RHbC4SW2e|@_7Z!8 zonz?igM`;Gm<{$zi#zcCk85Lkr8NaG%?!CJH-gKgN3htY-I z=)(Z^VGtIcfQw;x7{k*ziD&REPT@3O!5N&zn|KRv;~kvGN4S8`@HxJ~xA*}+s(F@` z$huRtOC>H-Eq)h?tnpo1*?}98HTBSTJ^P=M_4@^ip^KL+U0Jt!U31&!_A4tnW8JQ$ zP{bTXjfgTON<@n{orA<>BXyg;Vm2=CA;#H9xulJlH)RkvYSXEdki_9p^Uiu|mJzqP zd@l@rO^Pf{F3O{3>OQ@R6FtQo)!U+P(1^gILiOISZ{oyLF<13IsAn|!iU}4yI$NL8 z1-LeoeY0}!UG_fvn0?8 z2XngEL zNxXNJbE7>4&-J}Sq$x3Ux^dFFxezE<;nc|U|F+rh|8K6KlV}nI5(K6pfQrtZ&Mc{B z`|QiJcAD}*$}&m2NhKo}DyCfoQ2WXcL#n6ARQhCMIjJORDE;df0m=R!;jW5g|Gx%| HTdMjGk^|Rp literal 0 HcmV?d00001 diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 945a5b9a..c70a282b 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -1297,7 +1297,7 @@ static void TransmitFor14443a(const uint8_t *cmd, uint16_t len, uint32_t *timing // clear TXRDY AT91C_BASE_SSC->SSC_THR = SEC_Y; - Dbprintf("Sending bytes to the PICC."); + //Dbprintf("Sending bytes to the PICC."); uint16_t c = 0; for(;;) { @@ -1589,7 +1589,7 @@ int EmSendPrecompiledCmd(tag_response_info_t *response_info) { static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint8_t *receivedResponsePar, uint16_t offset) { uint32_t c; - uint32_t start_ts = GetCountSspClk(); + //uint32_t start_ts = GetCountSspClk(); uint32_t end_ts = 0; manchester_recv_started = 0; recorded = 0; @@ -1618,21 +1618,21 @@ static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint8_t *receive if(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; //read in 4 bytes of data from the RHR - if(manchester_recv_started){ - end_ts = GetCountSspClk(); - manchester_recv_started = 0; - recorded = 1; - } + // if(manchester_recv_started){ + // end_ts = GetCountSspClk(); + // manchester_recv_started = 0; + // recorded = 1; + // } //Perform the manchester decoding on the 4 bytes just received. if(ManchesterDecoding(b, offset, 0)) { NextTransferTime = MAX(NextTransferTime, Demod.endTime - (DELAY_AIR2ARM_AS_READER + DELAY_ARM2AIR_AS_READER)/16 + FRAME_DELAY_TIME_PICC_TO_PCD); - uint32_t cycle_count = end_ts - start_ts; - Dbprintf("Finished decoding (Manchester). Value of c=%d. Cycle count (for one bit) = %d", c, cycle_count); + //uint32_t cycle_count = end_ts - start_ts; + //Dbprintf("Finished decoding (Manchester). Value of c=%d. Cycle count (for one bit) = %d", c, cycle_count); return true; } else if (c++ > iso14a_timeout && Demod.state == DEMOD_UNSYNCD) { //we reach here only if we time out (i.e. receiving the data from the PICC takes too long) - Dbprintf("Timed out while waiting for PICC response (c = %d)!", c); + //Dbprintf("Timed out while waiting for PICC response (c = %d)!", c); return false; } } @@ -2123,11 +2123,11 @@ void ReaderIso14443a(UsbCommand *c) ReaderTransmit(cmd,len, NULL); // 8 bits, odd parity } } - start_ts = GetCountSspClk(); //started just after we send all our bytes to the PICC + //start_ts = GetCountSspClk(); //started just after we send all our bytes to the PICC arg0 = ReaderReceive(buf, par); - end_ts = GetCountSspClk(); //ended just after we have received all the response bytes from the PICC. - uint32_t cycle_count = end_ts - start_ts; - Dbprintf("Cycle count (all bytes) = %d", cycle_count); + //end_ts = GetCountSspClk(); //ended just after we have received all the response bytes from the PICC. + //uint32_t cycle_count = end_ts - start_ts; + //Dbprintf("Cycle count (all bytes) = %d", cycle_count); LED_B_ON(); cmd_send(CMD_ACK,arg0,0,0,buf,sizeof(buf)); diff --git a/common/Makefile.common b/common/Makefile.common index 29b72a4c..0b77fb19 100644 --- a/common/Makefile.common +++ b/common/Makefile.common @@ -67,7 +67,7 @@ VPATH = . ../common ../common/crapto1 ../common/polarssl ../fpga ../zlib INCLUDES = ../include/proxmark3.h ../include/at91sam7s512.h ../include/config_gpio.h ../include/usb_cmd.h $(APP_INCLUDES) -CFLAGS = -c $(INCLUDE) -Wall -Werror -pedantic -std=c99 -Os $(APP_CFLAGS) +CFLAGS = -c $(INCLUDE) -Wall -pedantic -std=c99 -Os $(APP_CFLAGS) LDFLAGS = -nostartfiles -nodefaultlibs -Wl,-gc-sections -n LIBS = -lgcc From 57f9bd734ea98646524a5f16b7d31ef42e3b7a7e Mon Sep 17 00:00:00 2001 From: Dom Date: Thu, 5 Apr 2018 10:08:35 +0100 Subject: [PATCH 17/29] Got rid of .DS_Store and other untracked binary files --- .DS_Store | Bin 8196 -> 0 bytes .gitignore | 1 + client/loclass/iclass_dump.bin | Bin 3024 -> 0 bytes 3 files changed, 1 insertion(+) delete mode 100644 .DS_Store delete mode 100644 client/loclass/iclass_dump.bin diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index 458ef6af6e390543679e12a17e64dc4bcb0b6424..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8196 zcmeHMPiz%M7@uETV0NK&%HQr&=#yGSDB6~mqJX@<7O@JUp@p^-Df`~8u(I8)Z}+u8 zsTRFxg7Jh3>P3yl;K@WzCdP{q{~fdnYB+fCpcjuuqlw?_>;qcpRSoPUGvCZN-?ua0 zZ+^RznPrS2TeO-Ot6_|B%2JB?RNNrRewnXJWwEA$B*>oyBRSX4QR_l(Ec?FdP09p;1c6%;0r`DMQ|J_3CfkEaz%W^fO02&I=0Kia#Bg<&JZ6y5RZ)bgo0>vdVV@GXUHg- zlnDX}0@ouTU!QVjF`wmgW7nSFT_*?|8!w`)ykgGWd7SIIUa3FUbJ!p23C*w=WX-~$ zY;~LA;aptr^?mnB-OTNE?6D!Sq{H_@)A8&=6uznkObSzP!F^OV`2SW5>r&Ogwc)MTGdPz^Z0M zc=l>|ZZO)Rt|!V~&W)(>E|tR5^!Y~DBl?bhC+~Yb&T)H4R0R}W7d5*J_9#Wtm-pS` zuon!8>b&XZi>?{k?XD}0gZ|Jy8p_(fz%PUyk>QXK#lYTelbthacak-^E|O2$H4-|$ z7wokQ0m-^dqnfmKZo$$OtL|Fc*!sZM&Z)|URib*4uJ0pUywG{vu?u^~94kCLU4HfIoIy>%wfA4uBJ^bTV7LXq>S53T{B&{sN?;`obzPS36D*Qg;kY$t#OAY zKH&Q;n&D30k|SABk5OyXb3Q2b9R-_8E1J~Zs|~$3pjd^;wMf&jPS<;n(1MD9rXVNY z)T|qOTr+38!qRx8+R&yOeWNO5@o22vv{^U$^ZxKKg&0($fz)zNM!V6$#i#s$9D9cu zgu6y;PY%DlX4$q{!x)hIcFVFY&UsyCwZbogK@)N(G1w~B!Zx#RHbC4SW2e|@_7Z!8 zonz?igM`;Gm<{$zi#zcCk85Lkr8NaG%?!CJH-gKgN3htY-I z=)(Z^VGtIcfQw;x7{k*ziD&REPT@3O!5N&zn|KRv;~kvGN4S8`@HxJ~xA*}+s(F@` z$huRtOC>H-Eq)h?tnpo1*?}98HTBSTJ^P=M_4@^ip^KL+U0Jt!U31&!_A4tnW8JQ$ zP{bTXjfgTON<@n{orA<>BXyg;Vm2=CA;#H9xulJlH)RkvYSXEdki_9p^Uiu|mJzqP zd@l@rO^Pf{F3O{3>OQ@R6FtQo)!U+P(1^gILiOISZ{oyLF<13IsAn|!iU}4yI$NL8 z1-LeoeY0}!UG_fvn0?8 z2XngEL zNxXNJbE7>4&-J}Sq$x3Ux^dFFxezE<;nc|U|F+rh|8K6KlV}nI5(K6pfQrtZ&Mc{B z`|QiJcAD}*$}&m2NhKo}DyCfoQ2WXcL#n6ARQhCMIjJORDE;df0m=R!;jW5g|Gx%| HTdMjGk^|Rp diff --git a/.gitignore b/.gitignore index a7cc8803..cf298b38 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ # .gitignore # don't push these files to the repository +*.DS_Store .history *.log *.eml diff --git a/client/loclass/iclass_dump.bin b/client/loclass/iclass_dump.bin deleted file mode 100644 index bfecd1bae95d3d2681ad38183b22f1408cfc285f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3024 zcmY+@YdqBX9tZH>|381j7-nR$ZdtUf+m8D!LJ7If(8wq!EMqjQnOTNaOU9;i9BI8e z*=$Q{B&=IuC5!AOlyx?h3|VT(tnS2nd3=>HeB zho9Kh%UB{&Y44%?`3HKUC;1#gQ*#5lLt8LKW32TuL8q@k@3_-R$?9K>;QnN0|V6VPL_C%Phi{pS%oWDoR2N^{xo9{w>XgzW=8tN5kbyoW!X6vFa`-VxV1 z7Moz%O@xJcL66pW$Tj1X$_O_%DRk1_k|vYIn@h;X?hiD zuhgFi!Q!qcd1z7VZ=16DHgfD`CGYEZFv*YLN^u%(9rm|>vB`aW#(|@vNqYxfLj6?> zZGAgSrfa^19wDRWHl#Y%BTU5zdVx6P{_v5(tGFtrz>x$=6l7A6o)K{qNKKOS!; zH^EbclhBVaznk;^Q!NzpAr#P`pvJlXvPWZZk!T#c4>fy5?{(9picmBL{lkpc?KWOo zI9V)w1fBD1hk=V>QXiIbSZV)t{pY{k8JpQih{Yo?FO;;5E`4nK2y0`NgFV46e|6}MMMfJ4gpOqAqN7t6o>f zs?cu#L(r=hZg$Jlc|FM2FBW=$+6Fby;{814@2lk3gVl?Q9i7Se-rY()@2pulBgMLp zh@9-JuxHqP=c57r=sCpY*g)TI`NDnM4$~%Lr$;(;pZTIj3Nc=d%xu4hKJ9bWyLj+9?dX?TK#o3C9b>!rh4}GmY?|Jl^YaXI# zsz7(oc618QXsX62G#vUemRLY9$alx7nizCb%+&hq;`1`(?0pn^qM!BkU!G752tIEa zdi24;XCGTKN|BGJ1Ul_LyJmg)9+%|lErRa-+gF1#O|_Y5i_S~v6+^i{Uy_|)K%&FX zp*I*&wVeyt8b~O32K~F{dcmH*Gbre@BeT$JB2O$U=n^-y%a;dzl_gHiJKQ^sG9?4h z;|z1w2KmollSOIwpkF&^pDzqN?urbJ2cbvA=o!cGg6?1$X?LNMS9leX-0?n?n(;gI z(N!<4=viSk3JeZ~KI4&|yWnL!j#z=g(7DlDAMXpMokU?lLD1J8NM3Rz0!tJe8UUSP zwow|MCnu1}_8#b7jIa?bua-it=ll|2$WVEUg=$Yd^CZ*I^CCR@X(IUUNt#RQqhOr`Tf^Xv()?bn4R+(=nw6CORJZ={(&5wi=Z!* z(p_@x%Tkep%h%AyY7PFVYHZy^YU&!$1>a<2i?X^dlAGfx=nY$wlb9#>^&m|O1v)Vm zB?=gtb4BVJWaySby0^E)6QL+Rfq>rZB^am=rRX75k|Fd+np|<4ewRQRAH0J8@|>*V z)dBTsBu;q>J>yQHZBP2YP9Zy+O6Zh|xHL}7Trb+YCkA>OA*jEqvrUfNoC={2EU0IF zr9G{Oj17mNZ Date: Thu, 5 Apr 2018 10:17:03 +0100 Subject: [PATCH 18/29] Got rid of duplicated code lines. --- client/lualibs/read14a.lua | 2 -- 1 file changed, 2 deletions(-) diff --git a/client/lualibs/read14a.lua b/client/lualibs/read14a.lua index ebcbc358..c1d10956 100644 --- a/client/lualibs/read14a.lua +++ b/client/lualibs/read14a.lua @@ -143,8 +143,6 @@ end local library = { read14443a = read14443a, read = read14443a, - read14443a = read14443a, - read = read14443a, waitFor14443a = waitFor14443a, parse14443a = parse14443a, sendToDevice = sendToDevice, From 6fa4f9f87baaa84318707c3712bd2ce73f28f223 Mon Sep 17 00:00:00 2001 From: Dom Date: Thu, 5 Apr 2018 14:45:57 +0100 Subject: [PATCH 19/29] Added back in the loclass dump file and updated .gitignore to include it. --- .gitignore | 1 + client/loclass/iclass_dump.bin | Bin 0 -> 3024 bytes 2 files changed, 1 insertion(+) create mode 100644 client/loclass/iclass_dump.bin diff --git a/.gitignore b/.gitignore index cf298b38..9c3a607c 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,7 @@ *.s19 *.map *.bin +!client/loclass/iclass_dump.bin !client/hardnested/*.bin *.dll *.moc.cpp diff --git a/client/loclass/iclass_dump.bin b/client/loclass/iclass_dump.bin new file mode 100644 index 0000000000000000000000000000000000000000..bfecd1bae95d3d2681ad38183b22f1408cfc285f GIT binary patch literal 3024 zcmY+@YdqBX9tZH>|381j7-nR$ZdtUf+m8D!LJ7If(8wq!EMqjQnOTNaOU9;i9BI8e z*=$Q{B&=IuC5!AOlyx?h3|VT(tnS2nd3=>HeB zho9Kh%UB{&Y44%?`3HKUC;1#gQ*#5lLt8LKW32TuL8q@k@3_-R$?9K>;QnN0|V6VPL_C%Phi{pS%oWDoR2N^{xo9{w>XgzW=8tN5kbyoW!X6vFa`-VxV1 z7Moz%O@xJcL66pW$Tj1X$_O_%DRk1_k|vYIn@h;X?hiD zuhgFi!Q!qcd1z7VZ=16DHgfD`CGYEZFv*YLN^u%(9rm|>vB`aW#(|@vNqYxfLj6?> zZGAgSrfa^19wDRWHl#Y%BTU5zdVx6P{_v5(tGFtrz>x$=6l7A6o)K{qNKKOS!; zH^EbclhBVaznk;^Q!NzpAr#P`pvJlXvPWZZk!T#c4>fy5?{(9picmBL{lkpc?KWOo zI9V)w1fBD1hk=V>QXiIbSZV)t{pY{k8JpQih{Yo?FO;;5E`4nK2y0`NgFV46e|6}MMMfJ4gpOqAqN7t6o>f zs?cu#L(r=hZg$Jlc|FM2FBW=$+6Fby;{814@2lk3gVl?Q9i7Se-rY()@2pulBgMLp zh@9-JuxHqP=c57r=sCpY*g)TI`NDnM4$~%Lr$;(;pZTIj3Nc=d%xu4hKJ9bWyLj+9?dX?TK#o3C9b>!rh4}GmY?|Jl^YaXI# zsz7(oc618QXsX62G#vUemRLY9$alx7nizCb%+&hq;`1`(?0pn^qM!BkU!G752tIEa zdi24;XCGTKN|BGJ1Ul_LyJmg)9+%|lErRa-+gF1#O|_Y5i_S~v6+^i{Uy_|)K%&FX zp*I*&wVeyt8b~O32K~F{dcmH*Gbre@BeT$JB2O$U=n^-y%a;dzl_gHiJKQ^sG9?4h z;|z1w2KmollSOIwpkF&^pDzqN?urbJ2cbvA=o!cGg6?1$X?LNMS9leX-0?n?n(;gI z(N!<4=viSk3JeZ~KI4&|yWnL!j#z=g(7DlDAMXpMokU?lLD1J8NM3Rz0!tJe8UUSP zwow|MCnu1}_8#b7jIa?bua-it=ll|2$WVEUg=$Yd^CZ*I^CCR@X(IUUNt#RQqhOr`Tf^Xv()?bn4R+(=nw6CORJZ={(&5wi=Z!* z(p_@x%Tkep%h%AyY7PFVYHZy^YU&!$1>a<2i?X^dlAGfx=nY$wlb9#>^&m|O1v)Vm zB?=gtb4BVJWaySby0^E)6QL+Rfq>rZB^am=rRX75k|Fd+np|<4ewRQRAH0J8@|>*V z)dBTsBu;q>J>yQHZBP2YP9Zy+O6Zh|xHL}7Trb+YCkA>OA*jEqvrUfNoC={2EU0IF zr9G{Oj17mNZ Date: Thu, 5 Apr 2018 14:50:34 +0100 Subject: [PATCH 20/29] Got rid of client Makefile changes. --- client/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/Makefile b/client/Makefile index fcaae89b..883f3b6f 100644 --- a/client/Makefile +++ b/client/Makefile @@ -20,7 +20,7 @@ OBJDIR = obj LDLIBS = -L/opt/local/lib -L/usr/local/lib -lreadline -lpthread -lm LUALIB = ../liblua/liblua.a LDFLAGS = $(ENV_LDFLAGS) -CFLAGS = $(ENV_CFLAGS) -std=c99 -D_ISOC99_SOURCE -I. -I../include -I../common -I../common/polarssl -I../zlib -I../uart -I/opt/local/include -I../liblua -Wall -g -O3 -Wa,-q,-mavx512f +CFLAGS = $(ENV_CFLAGS) -std=c99 -D_ISOC99_SOURCE -I. -I../include -I../common -I../common/polarssl -I../zlib -I../uart -I/opt/local/include -I../liblua -Wall -g -O3 CXXFLAGS = -I../include -Wall -O3 LUAPLATFORM = generic From 08f436d26a5558377eb709bddd912d9975ff0d31 Mon Sep 17 00:00:00 2001 From: Dom Date: Thu, 5 Apr 2018 14:54:38 +0100 Subject: [PATCH 21/29] Got rid of common Makefile changes. --- common/Makefile.common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/Makefile.common b/common/Makefile.common index 0b77fb19..29b72a4c 100644 --- a/common/Makefile.common +++ b/common/Makefile.common @@ -67,7 +67,7 @@ VPATH = . ../common ../common/crapto1 ../common/polarssl ../fpga ../zlib INCLUDES = ../include/proxmark3.h ../include/at91sam7s512.h ../include/config_gpio.h ../include/usb_cmd.h $(APP_INCLUDES) -CFLAGS = -c $(INCLUDE) -Wall -pedantic -std=c99 -Os $(APP_CFLAGS) +CFLAGS = -c $(INCLUDE) -Wall -Werror -pedantic -std=c99 -Os $(APP_CFLAGS) LDFLAGS = -nostartfiles -nodefaultlibs -Wl,-gc-sections -n LIBS = -lgcc From 70df25e7cbcc93fa9907fffde8a8f0cccb2e1a7b Mon Sep 17 00:00:00 2001 From: Dom Date: Thu, 5 Apr 2018 15:00:08 +0100 Subject: [PATCH 22/29] Got rid of client/scripting.c debug code. --- client/scripting.c | 32 -------------------------------- 1 file changed, 32 deletions(-) diff --git a/client/scripting.c b/client/scripting.c index 57e6cd71..0c761cb2 100644 --- a/client/scripting.c +++ b/client/scripting.c @@ -102,37 +102,6 @@ static int l_WaitForResponseTimeout(lua_State *L){ if(WaitForResponseTimeout(cmd, &response, ms_timeout)) { - /* Uncomment code below to print the bytes which were received from the C code before they get passed to Lua. */ - // uint8_t *recv; - // char *hexout; - // recv = response.d.asBytes; - // uint8_t iLen = response.arg[0]; - // if (0){ - // iLen = response.arg[1]; - // if (iLen){ - // PrintAndLog("Card selected. UID[%i]:", iLen); - // } else { - // PrintAndLog("Can't select card."); - // } - // } else { - // PrintAndLog("received %i bytes:", iLen); - // } - // if(!iLen) - // return 1; - // hexout = (char *)malloc(iLen * 3 + 1); - // if (hexout != NULL) { - // for (int i = 0; i < iLen; i++) { // data in hex - // sprintf(&hexout[i * 3], "%02X ", recv[i]); - // } - // PrintAndLog("%s", hexout); - // free(hexout); - // } else { - // PrintAndLog("malloc failed your client has low memory?"); - // return 2; - // } - // printf("Command response just sent back to Lua script with the bytes which were just printed.\n"); - - //Push it as a string lua_pushlstring(L,(const char *)&response,sizeof(UsbCommand)); @@ -140,7 +109,6 @@ static int l_WaitForResponseTimeout(lua_State *L){ }else{ //Push a Nil instead lua_pushnil(L); - printf("Nil pushed back to Lua script - no response received.\n"); return 1;// one return value } } From 8255d0c8371eca12429522c92b9affa61b15b201 Mon Sep 17 00:00:00 2001 From: Dom Date: Thu, 5 Apr 2018 15:14:50 +0100 Subject: [PATCH 23/29] Got rid of distance-bounding code in armsrc/iso14443a.c, updated RHR to be 1 byte. --- armsrc/iso14443a.c | 27 ++++----------------------- 1 file changed, 4 insertions(+), 23 deletions(-) diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index c70a282b..c5616a7a 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -88,9 +88,6 @@ uint8_t trigger = 0; // the block number for the ISO14443-4 PCB static uint8_t iso14_pcb_blocknum = 0; -int manchester_recv_started = 0; -int recorded = 0; - // // ISO14443 timing: // @@ -1589,10 +1586,6 @@ int EmSendPrecompiledCmd(tag_response_info_t *response_info) { static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint8_t *receivedResponsePar, uint16_t offset) { uint32_t c; - //uint32_t start_ts = GetCountSspClk(); - uint32_t end_ts = 0; - manchester_recv_started = 0; - recorded = 0; // Set FPGA mode to "reader listen mode", no modulation (listen // only, since we are receiving, not transmitting). @@ -1601,9 +1594,9 @@ static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint8_t *receive FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_LISTEN); /* Now, get the answer from the card. - 32-bit registers used on the AT91: - SSC_RHR = Receive Holding Register - SSC_SR = Status Register (contains RXRDY, which is one bit. 0 is RHR is empty, or 1 if RHR has 32 bits of data in it) + Registers used on the AT91: + SSC_RHR = Receive Holding Register (8 bits) + SSC_SR = Status Register (contains RXRDY, which is one bit. 0 is RHR is empty, or 1 if RHR has 8 bits of data in it) */ DemodInit(receivedResponse, receivedResponsePar); @@ -1617,22 +1610,15 @@ static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint8_t *receive WDT_HIT(); //Watchdog Timer if(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; //read in 4 bytes of data from the RHR - // if(manchester_recv_started){ - // end_ts = GetCountSspClk(); - // manchester_recv_started = 0; - // recorded = 1; - // } + b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; //read in 1 byte of data from the RHR //Perform the manchester decoding on the 4 bytes just received. if(ManchesterDecoding(b, offset, 0)) { NextTransferTime = MAX(NextTransferTime, Demod.endTime - (DELAY_AIR2ARM_AS_READER + DELAY_ARM2AIR_AS_READER)/16 + FRAME_DELAY_TIME_PICC_TO_PCD); - //uint32_t cycle_count = end_ts - start_ts; //Dbprintf("Finished decoding (Manchester). Value of c=%d. Cycle count (for one bit) = %d", c, cycle_count); return true; } else if (c++ > iso14a_timeout && Demod.state == DEMOD_UNSYNCD) { //we reach here only if we time out (i.e. receiving the data from the PICC takes too long) - //Dbprintf("Timed out while waiting for PICC response (c = %d)!", c); return false; } } @@ -2046,7 +2032,6 @@ void ReaderIso14443a(UsbCommand *c) byte_t buf[USB_CMD_DATA_SIZE] = {0}; uint8_t par[MAX_PARITY_SIZE]; bool cantSELECT = false; - uint32_t start_ts = 0, end_ts = 0; set_tracing(true); @@ -2123,11 +2108,7 @@ void ReaderIso14443a(UsbCommand *c) ReaderTransmit(cmd,len, NULL); // 8 bits, odd parity } } - //start_ts = GetCountSspClk(); //started just after we send all our bytes to the PICC arg0 = ReaderReceive(buf, par); - //end_ts = GetCountSspClk(); //ended just after we have received all the response bytes from the PICC. - //uint32_t cycle_count = end_ts - start_ts; - //Dbprintf("Cycle count (all bytes) = %d", cycle_count); LED_B_ON(); cmd_send(CMD_ACK,arg0,0,0,buf,sizeof(buf)); From c18e098cd341f5fb0edc32ad43514587f730b880 Mon Sep 17 00:00:00 2001 From: Dom Date: Thu, 5 Apr 2018 19:13:06 +0100 Subject: [PATCH 24/29] Got rid of unused variables (build works) and changed comment. --- armsrc/iso14443a.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index c5616a7a..4d39041f 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -463,7 +463,7 @@ static void DemodInit(uint8_t *data, uint8_t *parity) } // use parameter non_real_time to provide a timestamp. Set to 0 if the decoder should measure real time -// Input *bit* to the Manchester decoding is four bytes (32 bits) which are read from the RHR. +// Input *bit* to the Manchester decoding is one byte (8 bits) which are read from the RHR. static RAMFUNC int ManchesterDecoding(uint8_t bit, uint16_t offset, uint32_t non_real_time) { @@ -504,8 +504,6 @@ static RAMFUNC int ManchesterDecoding(uint8_t bit, uint16_t offset, uint32_t non Demod.collisionPos = (Demod.len << 3) + Demod.bitCount; } } - if(!recorded) - manchester_recv_started = 1; //specify that the data transfer has begun // modulation in first half only - Sequence D = 1. Demod.bitCount++; Demod.shiftReg = (Demod.shiftReg >> 1) | 0x100; // in both cases, add a 1 to the shiftreg From 1b1d843ab3222e067c488c6e38e03b91e3549c7d Mon Sep 17 00:00:00 2001 From: Dom Date: Thu, 5 Apr 2018 19:48:26 +0100 Subject: [PATCH 25/29] Changed another 4 bytes comment to 1 byte. --- armsrc/iso14443a.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 4d39041f..0b556269 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -1610,7 +1610,7 @@ static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint8_t *receive if(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; //read in 1 byte of data from the RHR - //Perform the manchester decoding on the 4 bytes just received. + //Perform the manchester decoding on the 1 byte just received. if(ManchesterDecoding(b, offset, 0)) { NextTransferTime = MAX(NextTransferTime, Demod.endTime - (DELAY_AIR2ARM_AS_READER + DELAY_ARM2AIR_AS_READER)/16 + FRAME_DELAY_TIME_PICC_TO_PCD); //Dbprintf("Finished decoding (Manchester). Value of c=%d. Cycle count (for one bit) = %d", c, cycle_count); From d1b56172c6a32998ace66a249585888d9527616b Mon Sep 17 00:00:00 2001 From: Dom Date: Fri, 6 Apr 2018 08:55:14 +0100 Subject: [PATCH 26/29] Added ability to send Proximity Check in multiple chunks. --- client/scripts/mifarePlus.lua | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/client/scripts/mifarePlus.lua b/client/scripts/mifarePlus.lua index 9fd0cc2c..5d8c4e7d 100644 --- a/client/scripts/mifarePlus.lua +++ b/client/scripts/mifarePlus.lua @@ -205,9 +205,20 @@ function proximityCheck() --PC-- RndC = "0001020304050607" --Random Challenge - commandString = PROXIMITYCHECK .. "08" .. RndC - response = sendRaw(commandString, true, true) - RndR = string.sub(response, 3, 18) + num_rounds = 8 --Needs to be 1, 2, 4, or 8 + part_len = 8 / num_rounds + j = 1 + RndR = "" + for i = 1,num_rounds do + pRndC = "" + for q = 1,(part_len*2) do + pRndC = pRndC .. string.sub(RndC,j,j) + j = j + 1 + end + commandString = PROXIMITYCHECK .. "0" .. tostring(part_len) .. pRndC + pRndR = string.sub(sendRaw(commandString, true, true), 3, 3+part_len) + RndR = RndR .. pRndR + end print("RndC = " .. RndC .. " RndR = " .. RndR) --VerifyPC-- From bda0d7e04bd6ee33225e427e8a6eaf33a87aee61 Mon Sep 17 00:00:00 2001 From: Dom Date: Fri, 6 Apr 2018 09:00:43 +0100 Subject: [PATCH 27/29] Created parameter in CommitPerso() function. --- client/scripts/mifarePlus.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/client/scripts/mifarePlus.lua b/client/scripts/mifarePlus.lua index 5d8c4e7d..257fdc94 100644 --- a/client/scripts/mifarePlus.lua +++ b/client/scripts/mifarePlus.lua @@ -153,9 +153,9 @@ function getVersion() sendRaw(GETVERS_CONT, true, true) end -function commitPerso() - -- commandString = COMMITPERSO .. "01" --switch to SL1 - commandString = COMMITPERSO .. "03" --switch to SL3 +function commitPerso(SL) + --pass SL as "01" to move to SL1 or "03" to move to SL3. + commandString = COMMITPERSO .. SL response = sendRaw(commandString, true, true) --0x90 is returned upon success if string.sub(response, 3, 4) ~= "90" then oops("error occurred while trying to switch security level") @@ -268,7 +268,7 @@ function main(args) -- Now, the card is initialized and we can do more interesting things. --writePerso() - --commitPerso() + --commitPerso("03") --move to SL3 --getVersion() proximityCheck() From 7e5923d0be3e9e995c82b4df01d7fd2d4fd47903 Mon Sep 17 00:00:00 2001 From: Dom Date: Fri, 6 Apr 2018 09:15:39 +0100 Subject: [PATCH 28/29] Added ability to write to 2kB and 4kB of blocks in SL0. --- client/scripts/mifarePlus.lua | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/client/scripts/mifarePlus.lua b/client/scripts/mifarePlus.lua index 257fdc94..c0fa5283 100644 --- a/client/scripts/mifarePlus.lua +++ b/client/scripts/mifarePlus.lua @@ -67,10 +67,19 @@ function writePerso() -- 0x0C - unexpected command length - -- First, set all the data in the card (4kB of data) to zeros. The keys, stored in the sector trailer block, are also set to zeros. + -- First, set all the data in the card to zeros. The keys, stored in the sector trailer block, are also set to zeros. -- The only block which cannot be explicitly set is block 0x0000, the manufacturer block. print("Setting values of normal blocks") - for i=1,255,1 do --skip block 0 + cardsize = 4 --need to set to 4 for 4k or 2 for 2k + if(cardsize == 4) then + numblocks = 255 + elseif(cardsize == 2) then + numblocks = 127 + else + oops("Invalid card size") + end + + for i=1,numblocks,1 do --skip block 0 --convert the number to hex with leading zeros, then use it as the block number in writeBlock() blocknum = string.format("%04x", i) writeBlock(blocknum, SIXTEEN_BYTES_ZEROS) From 5093fb9e07070590e4f2b399c58a1fc8702e584d Mon Sep 17 00:00:00 2001 From: Dom Date: Fri, 6 Apr 2018 09:34:47 +0100 Subject: [PATCH 29/29] Added error checking for RATS and PPS check. --- client/scripts/mifarePlus.lua | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/client/scripts/mifarePlus.lua b/client/scripts/mifarePlus.lua index c0fa5283..85815093 100644 --- a/client/scripts/mifarePlus.lua +++ b/client/scripts/mifarePlus.lua @@ -265,8 +265,14 @@ function main(args) -- Initialize the card using the already-present read14a library info,err = lib14a.read14443a(true, false) --Perform PPS (Protocol and Parameter Selection) check to finish the ISO 14443-4 protocol. - sendRaw("e050", true, true) - sendRaw("D01100", true, true) + response = sendRaw("e050", true, true) + if(response == nil) then + err = "No response from RATS" + end + response = sendRaw("D01100", true, true) + if(response == nil) then + err = "No response from PPS check" + end if err then oops(err) else