recover_pk.py: replace secp192r1 by prime192v1
[RRG-proxmark3.git] / client / luascripts / hf_mfu_pwdgen_italy.lua
blob25b111866f3016cdbb227264ed724a8076e45060
1 local bin = require('bin')
2 local getopt = require('getopt')
3 local lib14a = require('read14a')
4 local utils = require('utils')
5 local cl = require('ansicolors')
7 copyright = ''
8 author = "Iceman"
9 version = 'v1.0.2'
10 desc = [[
11 This script calculates mifare Ultralight-EV1 pwd based on uid diversification for an Italian ticketsystem
12 Algo not found by me.
14 ]].. "You can also look at the native pm3 command `" .. cl.yellow .. "hf mfu pwdgen -h" .. cl.reset .. "`\n"
16 example =[[
17 -- if called without, it reads tag uid
18 script run hf_mfu_pwdgen_italy
21 script run hf_mfu_pwdgen_italy -u 11223344556677
23 usage = [[
24 script run hf_mfu_uidkeycalc_italy -h -u <uid> "
26 arguments = [[
27 -h : this help
28 -u <UID> : UID
31 local DEBUG = true
32 local bxor = bit32.bxor
33 ---
34 -- A debug printout-function
35 local function dbg(args)
36 if not DEBUG then return end
37 if type(args) == 'table' then
38 local i = 1
39 while args[i] do
40 dbg(args[i])
41 i = i+1
42 end
43 else
44 print('###', args)
45 end
46 end
47 ---
48 -- This is only meant to be used when errors occur
49 local function oops(err)
50 print('ERROR: ', err)
51 core.clearCommandBuffer()
52 return nil, err
53 end
54 ---
55 -- Usage help
56 local function help()
57 print(copyright)
58 print(author)
59 print(version)
60 print(desc)
61 print(cl.cyan..'Usage'..cl.reset)
62 print(usage)
63 print(cl.cyan..'Arguments'..cl.reset)
64 print(arguments)
65 print(cl.cyan..'Example usage'..cl.reset)
66 print(example)
67 end
69 -- Exit message
70 local function exitMsg(msg)
71 print( string.rep('--',20) )
72 print( string.rep('--',20) )
73 print(msg)
74 print()
75 end
77 local _xortable = {
78 --[[ position, 4byte xor
79 --]]
80 {"00","4f2711c1"},
81 {"01","07D7BB83"},
82 {"02","9636EF07"},
83 {"03","B5F4460E"},
84 {"04","F271141C"},
85 {"05","7D7BB038"},
86 {"06","636EF871"},
87 {"07","5F4468E3"},
88 {"08","271149C7"},
89 {"09","D7BB0B8F"},
90 {"0A","36EF8F1E"},
91 {"0B","F446863D"},
92 {"0C","7114947A"},
93 {"0D","7BB0B0F5"},
94 {"0E","6EF8F9EB"},
95 {"0F","44686BD7"},
96 {"10","11494fAF"},
97 {"11","BB0B075F"},
98 {"12","EF8F96BE"},
99 {"13","4686B57C"},
100 {"14","1494F2F9"},
101 {"15","B0B07DF3"},
102 {"16","F8F963E6"},
103 {"17","686B5FCC"},
104 {"18","494F2799"},
105 {"19","0B07D733"},
106 {"1A","8F963667"},
107 {"1B","86B5F4CE"},
108 {"1C","94F2719C"},
109 {"1D","B07D7B38"},
110 {"1E","F9636E70"},
111 {"1F","6B5F44E0"},
114 local function findEntryByUid( uid )
116 -- xor UID4,UID5,UID6,UID7
117 -- mod 0x20 (dec 32)
118 local pos = (bxor(uid[4], uid[5], uid[6], uid[7])) % 32
120 -- convert to hexstring
121 pos = string.format('%02X', pos)
123 for k, v in pairs(_xortable) do
124 if ( v[1] == pos ) then
125 return utils.ConvertHexToBytes(v[2])
128 return nil
131 -- create pwd
132 local function pwdgen(uid)
133 -- PWD CALC
134 -- PWD0 = T0 xor B xor C xor D
135 -- PWD1 = T1 xor A xor C xor E
136 -- PWD2 = T2 xor A xor B xor F
137 -- PWD3 = T3 xor G
138 local uidbytes = utils.ConvertHexToBytes(uid)
139 local entry = findEntryByUid(uidbytes)
140 if entry == nil then return nil, "Can't find a xor entry" end
142 local pwd0 = bxor( entry[1], uidbytes[2], uidbytes[3], uidbytes[4])
143 local pwd1 = bxor( entry[2], uidbytes[1], uidbytes[3], uidbytes[5])
144 local pwd2 = bxor( entry[3], uidbytes[1], uidbytes[2], uidbytes[6])
145 local pwd3 = bxor( entry[4], uidbytes[7])
146 return string.format('%02X%02X%02X%02X', pwd0, pwd1, pwd2, pwd3)
150 -- main
151 local function main(args)
153 print( string.rep('--',20) )
154 print( string.rep('--',20) )
155 print()
157 local uid = '04111211121110'
158 local useUID = false
160 -- Arguments for the script
161 for o, a in getopt.getopt(args, 'hu:') do
162 if o == 'h' then return help() end
163 if o == 'u' then uid = a; useUID = true end
166 if useUID then
167 -- uid string checks
168 if uid == nil then return oops('empty uid string') end
169 if #uid == 0 then return oops('empty uid string') end
170 if #uid ~= 14 then return oops('uid wrong length. Should be 7 hex bytes') end
171 else
172 -- GET TAG UID
173 local tag, err = lib14a.read(false, true)
174 if not tag then return oops(err) end
175 core.clearCommandBuffer()
176 uid = tag.uid
179 print('UID | '..uid)
180 local pwd, err = pwdgen(uid)
181 if not pwd then return ooops(err) end
183 print(string.format('PWD | %s', pwd))
186 main(args)