mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-07-16 10:03:04 -07:00
ADD: tnp3.lua can now validate the checkums in the dump
ADD: added CRC16 CCITT functionality to LUA FIX: tnp3.lua is now correctly decryping data while dumping
This commit is contained in:
parent
f595de25e9
commit
47cbb2d418
5 changed files with 114 additions and 13 deletions
|
@ -86,6 +86,15 @@ local Utils =
|
||||||
end
|
end
|
||||||
return t
|
return t
|
||||||
end,
|
end,
|
||||||
|
ConvertHexToAscii = function(s)
|
||||||
|
local t={}
|
||||||
|
if s == nil then return t end
|
||||||
|
if #s == 0 then return t end
|
||||||
|
for k in s:gmatch"(%x%x)" do
|
||||||
|
table.insert(t, string.char(tonumber(k,16)))
|
||||||
|
end
|
||||||
|
return table.concat(t)
|
||||||
|
end,
|
||||||
|
|
||||||
-- function convertStringToBytes(str)
|
-- function convertStringToBytes(str)
|
||||||
-- local bytes = {}
|
-- local bytes = {}
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "nonce2key/nonce2key.h"
|
#include "nonce2key/nonce2key.h"
|
||||||
#include "../common/iso15693tools.h"
|
#include "../common/iso15693tools.h"
|
||||||
#include <openssl/aes.h>
|
#include <openssl/aes.h>
|
||||||
|
#include "../common/crc16.h"
|
||||||
/**
|
/**
|
||||||
* The following params expected:
|
* The following params expected:
|
||||||
* UsbCommand c
|
* UsbCommand c
|
||||||
|
@ -263,6 +264,16 @@ static int l_aes(lua_State *L)
|
||||||
return 1;// return 1 to signal one return value
|
return 1;// return 1 to signal one return value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int l_crc16(lua_State *L)
|
||||||
|
{
|
||||||
|
size_t size;
|
||||||
|
const char *p_str = luaL_checklstring(L, 1, &size);
|
||||||
|
|
||||||
|
unsigned short retval = crc16_ccitt( p_str, size);
|
||||||
|
lua_pushinteger(L, (int) retval);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Sets the lua path to include "./lualibs/?.lua", in order for a script to be
|
* @brief Sets the lua path to include "./lualibs/?.lua", in order for a script to be
|
||||||
* able to do "require('foobar')" if foobar.lua is within lualibs folder.
|
* able to do "require('foobar')" if foobar.lua is within lualibs folder.
|
||||||
|
@ -301,6 +312,7 @@ int set_pm3_libraries(lua_State *L)
|
||||||
{"console", l_CmdConsole},
|
{"console", l_CmdConsole},
|
||||||
{"iso15693_crc", l_iso15693_crc},
|
{"iso15693_crc", l_iso15693_crc},
|
||||||
{"aes", l_aes},
|
{"aes", l_aes},
|
||||||
|
{"crc16", l_crc16},
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -93,6 +93,16 @@ local function waitCmd()
|
||||||
return nil, "No response from device"
|
return nil, "No response from device"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function computeCrc16(s)
|
||||||
|
local hash = core.crc16(utils.ConvertHexToAscii(s))
|
||||||
|
return hash
|
||||||
|
end
|
||||||
|
|
||||||
|
local function reverseCrcBytes(crc)
|
||||||
|
crc2 = crc:sub(3,4)..crc:sub(1,2)
|
||||||
|
return tonumber(crc2,16)
|
||||||
|
end
|
||||||
|
|
||||||
local function main(args)
|
local function main(args)
|
||||||
|
|
||||||
print( string.rep('--',20) )
|
print( string.rep('--',20) )
|
||||||
|
@ -104,7 +114,7 @@ local function main(args)
|
||||||
local useNested = false
|
local useNested = false
|
||||||
local cmdReadBlockString = 'hf mf rdbl %d A %s'
|
local cmdReadBlockString = 'hf mf rdbl %d A %s'
|
||||||
local input = "dumpkeys.bin"
|
local input = "dumpkeys.bin"
|
||||||
local outputTemplate = os.date("toydump-%Y-%m-%d_%H%M%S");
|
local outputTemplate = os.date("toydump_%Y-%m-%d_%H%M%S");
|
||||||
|
|
||||||
-- Arguments for the script
|
-- Arguments for the script
|
||||||
for o, a in getopt.getopt(args, 'hk:no:') do
|
for o, a in getopt.getopt(args, 'hk:no:') do
|
||||||
|
@ -175,6 +185,7 @@ local function main(args)
|
||||||
core.clearCommandBuffer()
|
core.clearCommandBuffer()
|
||||||
|
|
||||||
-- main loop
|
-- main loop
|
||||||
|
io.write('Decrypting blocks > ')
|
||||||
for blockNo = 0, numBlocks-1, 1 do
|
for blockNo = 0, numBlocks-1, 1 do
|
||||||
|
|
||||||
if core.ukbhit() then
|
if core.ukbhit() then
|
||||||
|
@ -195,9 +206,8 @@ local function main(args)
|
||||||
-- Block 0-7 not encrypted
|
-- Block 0-7 not encrypted
|
||||||
blocks[blockNo+1] = ('%02d :: %s'):format(blockNo,blockdata)
|
blocks[blockNo+1] = ('%02d :: %s'):format(blockNo,blockdata)
|
||||||
else
|
else
|
||||||
local base = ('%s%s%02d%s'):format(block0, block1, blockNo, hashconstant)
|
local base = ('%s%s%02x%s'):format(block0, block1, blockNo, hashconstant)
|
||||||
local baseArr = utils.ConvertHexStringToBytes(base)
|
local baseStr = utils.ConvertHexToAscii(base)
|
||||||
local baseStr = utils.ConvertBytesToAsciiString(baseArr)
|
|
||||||
local md5hash = md5.sumhexa(baseStr)
|
local md5hash = md5.sumhexa(baseStr)
|
||||||
local aestest = core.aes(md5hash, blockdata)
|
local aestest = core.aes(md5hash, blockdata)
|
||||||
|
|
||||||
|
@ -205,10 +215,12 @@ local function main(args)
|
||||||
hex = utils.ConvertBytes2HexString(hex)
|
hex = utils.ConvertBytes2HexString(hex)
|
||||||
--local _,hex = bin.unpack(("H%d"):format(16),aestest)
|
--local _,hex = bin.unpack(("H%d"):format(16),aestest)
|
||||||
|
|
||||||
|
-- blocks with zero not encrypted.
|
||||||
if string.find(blockdata, '^0+$') then
|
if string.find(blockdata, '^0+$') then
|
||||||
blocks[blockNo+1] = ('%02d :: %s'):format(blockNo,blockdata)
|
blocks[blockNo+1] = ('%02d :: %s'):format(blockNo,blockdata)
|
||||||
else
|
else
|
||||||
blocks[blockNo+1] = ('%02d :: %s'):format(blockNo,hex)
|
blocks[blockNo+1] = ('%02d :: %s'):format(blockNo,hex)
|
||||||
|
io.write( blockNo..',')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
|
@ -216,6 +228,7 @@ local function main(args)
|
||||||
blocks[blockNo+1] = ('%02d :: %s%s'):format(blockNo,key,blockdata:sub(13,32))
|
blocks[blockNo+1] = ('%02d :: %s%s'):format(blockNo,key,blockdata:sub(13,32))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
io.write('\n')
|
||||||
|
|
||||||
core.clearCommandBuffer()
|
core.clearCommandBuffer()
|
||||||
|
|
||||||
|
@ -224,7 +237,7 @@ local function main(args)
|
||||||
local emldata = ''
|
local emldata = ''
|
||||||
|
|
||||||
for _,s in pairs(blocks) do
|
for _,s in pairs(blocks) do
|
||||||
local slice = s:sub(7,#s)
|
local slice = s:sub(8,#s)
|
||||||
local str = utils.ConvertBytesToAsciiString(
|
local str = utils.ConvertBytesToAsciiString(
|
||||||
utils.ConvertHexStringToBytes(slice)
|
utils.ConvertHexStringToBytes(slice)
|
||||||
)
|
)
|
||||||
|
@ -235,10 +248,12 @@ local function main(args)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Write dump to files
|
-- Write dump to files
|
||||||
local foo = dumplib.SaveAsBinary(bindata, outputTemplate..'.bin')
|
if not DEBUG then
|
||||||
print(("Wrote a BIN dump to the file %s"):format(foo))
|
local foo = dumplib.SaveAsBinary(bindata, outputTemplate..'.bin')
|
||||||
local bar = dumplib.SaveAsText(emldata, outputTemplate..'.eml')
|
print(("Wrote a BIN dump to the file %s"):format(foo))
|
||||||
print(("Wrote a EML dump to the file %s"):format(bar))
|
local bar = dumplib.SaveAsText(emldata, outputTemplate..'.eml')
|
||||||
|
print(("Wrote a EML dump to the file %s"):format(bar))
|
||||||
|
end
|
||||||
|
|
||||||
local uid = block0:sub(1,8)
|
local uid = block0:sub(1,8)
|
||||||
local itemtype = block1:sub(1,4)
|
local itemtype = block1:sub(1,4)
|
||||||
|
@ -251,6 +266,47 @@ local function main(args)
|
||||||
print( (' CARDID : 0x%s'):format(cardid ) )
|
print( (' CARDID : 0x%s'):format(cardid ) )
|
||||||
print( string.rep('--',20) )
|
print( string.rep('--',20) )
|
||||||
|
|
||||||
end
|
print('Validating checksums')
|
||||||
|
-- Checksum Typ 0
|
||||||
|
local test1 = ('%s%s'):format(block0, block1:sub(1,28))
|
||||||
|
local crc = block1:sub(29,32)
|
||||||
|
local revcrc = reverseCrcBytes(crc)
|
||||||
|
|
||||||
|
io.write( ('BLOCK 0-1 : %04x = %04x \n'):format(revcrc,computeCrc16(test1)))
|
||||||
|
|
||||||
|
-- Checksum Typ 1 BLOCK 9
|
||||||
|
local block9 = blocks[9]:sub(8,35)
|
||||||
|
test1 = ('%s0500'):format(block9)
|
||||||
|
crc = blocks[9]:sub(36,39)
|
||||||
|
revcrc = reverseCrcBytes(crc)
|
||||||
|
io.write( ('BLOCK 8 : %04x = %04x \n'):format(revcrc,computeCrc16(test1)))
|
||||||
|
|
||||||
|
-- Checksum Typ 1 BLOCK 37
|
||||||
|
local block37 = blocks[37]:sub(8,35)
|
||||||
|
test1 = ('%s0500'):format(block37)
|
||||||
|
crc = blocks[37]:sub(36,39)
|
||||||
|
revcrc = reverseCrcBytes(crc)
|
||||||
|
io.write( ('BLOCK 36 : %04x = %04x \n'):format(revcrc,computeCrc16(test1)))
|
||||||
|
|
||||||
|
-- Checksum Typ 2
|
||||||
|
-- 10,11,13
|
||||||
|
test1 = blocks[10]:sub(8,39)..
|
||||||
|
blocks[11]:sub(8,39)..
|
||||||
|
blocks[13]:sub(8,39)
|
||||||
|
|
||||||
|
crc = blocks[9]:sub(32,35)
|
||||||
|
revcrc = reverseCrcBytes(crc)
|
||||||
|
io.write( ('BLOCK 10-11-13 :%04x = %04x \n'):format(revcrc,computeCrc16(test1)))
|
||||||
|
-- Checksum Typ 3
|
||||||
|
-- 15,17,18,19
|
||||||
|
crc = blocks[9]:sub(28,31)
|
||||||
|
revcrc = reverseCrcBytes(crc)
|
||||||
|
test1 = blocks[14]:sub(8,39)..
|
||||||
|
blocks[15]:sub(8,39)..
|
||||||
|
blocks[17]:sub(8,39)
|
||||||
|
|
||||||
|
local tohash = test1..string.rep('00',0xe0)
|
||||||
|
local hashed = computeCrc16(tohash)
|
||||||
|
io.write( ('BLOCK 14-15-17 %04x = %04x \n'):format(revcrc,hashed))
|
||||||
|
end
|
||||||
main(args)
|
main(args)
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
#include "crc16.h"
|
#include "crc16.h"
|
||||||
|
|
||||||
|
|
||||||
unsigned short update_crc16( unsigned short crc, unsigned char c )
|
unsigned short update_crc16( unsigned short crc, unsigned char c )
|
||||||
{
|
{
|
||||||
unsigned short i, v, tcrc = 0;
|
unsigned short i, v, tcrc = 0;
|
||||||
|
@ -20,3 +21,25 @@ unsigned short update_crc16( unsigned short crc, unsigned char c )
|
||||||
|
|
||||||
return ((crc >> 8) ^ tcrc)&0xffff;
|
return ((crc >> 8) ^ tcrc)&0xffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint16_t crc16(uint8_t const *message, int length, uint16_t remainder, uint16_t polynomial) {
|
||||||
|
|
||||||
|
if (length == 0)
|
||||||
|
return (~remainder);
|
||||||
|
|
||||||
|
for (int byte = 0; byte < length; ++byte) {
|
||||||
|
remainder ^= (message[byte] << 8);
|
||||||
|
for (uint8_t bit = 8; bit > 0; --bit) {
|
||||||
|
if (remainder & 0x8000) {
|
||||||
|
remainder = (remainder << 1) ^ polynomial;
|
||||||
|
} else {
|
||||||
|
remainder = (remainder << 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return remainder;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t crc16_ccitt(uint8_t const *message, int length) {
|
||||||
|
return crc16(message, length, 0xffff, 0x1021);
|
||||||
|
}
|
||||||
|
|
|
@ -5,10 +5,11 @@
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// CRC16
|
// CRC16
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
#ifndef __CRC16_H
|
#ifndef __CRC16_H
|
||||||
#define __CRC16_H
|
#define __CRC16_H
|
||||||
|
|
||||||
unsigned short update_crc16(unsigned short crc, unsigned char c);
|
unsigned short update_crc16(unsigned short crc, unsigned char c);
|
||||||
|
uint16_t crc16(uint8_t const *message, int length, uint16_t remainder, uint16_t polynomial);
|
||||||
|
uint16_t crc16_ccitt(uint8_t const *message, int length);
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue