1 local bin
= require('bin')
2 local getopt
= require('getopt')
3 local lib14a
= require('read14a')
4 local utils
= require('utils')
5 local ansicolors
= require('ansicolors')
11 This script calculates mifare Ultralight-EV1 pwd based on uid diversification for an Italian ticketsystem
15 -- if called without, it reads tag uid
16 script run hf_mfu_uidkeycalc-italy
19 script run hf_mfu_uidkeycalc-italy -u 11223344556677
22 script run hf_mfu_uidkeycalc-italy -h -u <uid> "
30 local bxor
= bit32
.bxor
32 -- A debug printout-function
33 local function dbg(args
)
34 if not DEBUG
then return end
35 if type(args
) == 'table' then
46 -- This is only meant to be used when errors occur
47 local function oops(err
)
49 core
.clearCommandBuffer()
59 print(ansicolors
.cyan
..'Usage'..ansicolors
.reset
)
61 print(ansicolors
.cyan
..'Arguments'..ansicolors
.reset
)
63 print(ansicolors
.cyan
..'Example usage'..ansicolors
.reset
)
68 local function exitMsg(msg
)
69 print( string.rep('--',20) )
70 print( string.rep('--',20) )
76 --[[ position, 4byte xor
112 local function findEntryByUid( uid
)
114 -- xor UID4,UID5,UID6,UID7
116 local pos
= (bxor(uid
[4], uid
[5], uid
[6], uid
[7])) % 32
118 -- convert to hexstring
119 pos
= string.format('%02X', pos
)
121 for k
, v
in pairs(_xortable
) do
122 if ( v
[1] == pos
) then
123 return utils
.ConvertHexToBytes(v
[2])
130 local function pwdgen(uid
)
132 -- PWD0 = T0 xor B xor C xor D
133 -- PWD1 = T1 xor A xor C xor E
134 -- PWD2 = T2 xor A xor B xor F
136 local uidbytes
= utils
.ConvertHexToBytes(uid
)
137 local entry
= findEntryByUid(uidbytes
)
138 if entry
== nil then return nil, "Can't find a xor entry" end
140 local pwd0
= bxor( entry
[1], uidbytes
[2], uidbytes
[3], uidbytes
[4])
141 local pwd1
= bxor( entry
[2], uidbytes
[1], uidbytes
[3], uidbytes
[5])
142 local pwd2
= bxor( entry
[3], uidbytes
[1], uidbytes
[2], uidbytes
[6])
143 local pwd3
= bxor( entry
[4], uidbytes
[7])
144 return string.format('%02X%02X%02X%02X', pwd0
, pwd1
, pwd2
, pwd3
)
149 local function main(args
)
151 print( string.rep('--',20) )
152 print( string.rep('--',20) )
155 local uid
= '04111211121110'
158 -- Arguments for the script
159 for o
, a
in getopt
.getopt(args
, 'hu:') do
160 if o
== 'h' then return help() end
161 if o
== 'u' then uid
= a
; useUID
= true end
166 if uid
== nil then return oops('empty uid string') end
167 if #uid
== 0 then return oops('empty uid string') end
168 if #uid
~= 14 then return oops('uid wrong length. Should be 7 hex bytes') end
171 local tag, err
= lib14a
.read(false, true)
172 if not tag then return oops(err
) end
173 core
.clearCommandBuffer()
178 local pwd
, err
= pwdgen(uid
)
179 if not pwd
then return ooops(err
) end
181 print(string.format('PWD | %s', pwd
))