relax ecdsa_publickey_ng_t, should help MacOS compilation
[RRG-proxmark3.git] / client / luascripts / hf_mf_ultimatecard.lua
blobe3529e366d1d1a3a9cd52459283c8c744e97e1b5
1 local cmds = require('commands')
2 local getopt = require('getopt')
3 local lib14a = require('read14a')
4 local utils = require('utils')
5 local ansicolors = require('ansicolors')
7 -- global
8 local DEBUG = false -- the debug flag
9 local bxor = bit32.bxor
10 local _ntagpassword = nil
11 local _key = '00000000' -- default UMC key
12 local err_lock = 'use -k or change cfg0 block'
13 local _print = 0
14 copyright = ''
15 author = 'Nathan Glaser'
16 version = 'v1.0.5'
17 date = 'Created - Jan 2022'
18 desc = 'This script enables easy programming of an Ultimate Mifare Magic card'
19 example = [[
20 -- read magic tag configuration
21 ]]..ansicolors.yellow..[[script run hf_mf_ultimatecard -c ]]..ansicolors.reset..[[
23 -- set uid
24 ]]..ansicolors.yellow..[[script run hf_mf_ultimatecard -u 04E10CDA993C80 ]]..ansicolors.reset..[[
26 -- set NTAG pwd / pack
27 ]]..ansicolors.yellow..[[script run hf_mf_ultimatecard -p 11223344 -a 8080 ]]..ansicolors.reset..[[
29 -- set version to NTAG213
30 ]]..ansicolors.yellow..[[script run hf_mf_ultimatecard -v 0004040201000f03 ]]..ansicolors.reset..[[
32 -- set ATQA/SAK to [00 44] [08]
33 ]]..ansicolors.yellow..[[script run hf_mf_ultimatecard -q 004408 ]]..ansicolors.reset..[[
35 -- wipe tag with a NTAG213 or Mifare 1k S50 4 byte
36 ]]..ansicolors.yellow..[[script run hf_mf_ultimatecard -w 1]]..ansicolors.reset..[[
38 -- use a non default UMC key. Only use this if the default key for the MAGIC CARD was changed.
39 ]]..ansicolors.yellow..[[script run hf_mf_ultimatecard -k ffffffff -w 1]]..ansicolors.reset..[[
41 -- Wipe tag, turn into NTAG215, set sig, version, NTAG pwd/pak, and OTP.
42 ]]..ansicolors.yellow..[[script run hf_mf_ultimatecard -w 1 -t 18 -u 04E10CDA993C80 -s 8B76052EE42F5567BEB53238B3E3F9950707C0DCC956B5C5EFCFDB709B2D82B3 -p FFFFFFFF -a 8080 -o 11111111]]..ansicolors.reset..[[
45 usage = [[
46 script run hf_mf_ultimatecard -h -k <passwd> -c -w <type> -u <uid> -t <type> -p <passwd> -a <pack> -s <signature> -o <otp> -v <version> -q <atqa/sak> -g <gtu> -z <ats> -m <ul-mode> -n <ul-protocol>
48 arguments = [[
49 -h this help
50 -c read magic configuration
51 -u UID (8-20 hexsymbols), set UID on tag
52 -t tag type to impersonate
53 1 = Mifare Mini S20 4-byte | 15 = NTAG 210
54 2 = Mifare Mini S20 7-byte | 16 = NTAG 212
55 3 = Mifare Mini S20 10-byte | 17 = NTAG 213
56 4 = Mifare 1k S50 4-byte | 18 = NTAG 215
57 5 = Mifare 1k S50 7-byte | 19 = NTAG 216
58 6 = Mifare 1k S50 10-byte | 20 = NTAG I2C 1K
59 7 = Mifare 4k S70 4-byte | 21 = NTAG I2C 2K
60 8 = Mifare 4k S70 7-byte | 22 = NTAG I2C 1K PLUS
61 9 = Mifare 4k S70 10-byte | 23 = NTAG I2C 2K PLUS
62 *** 10 = UL - NOT WORKING FULLY | 24 = NTAG 213F
63 *** 11 = UL-C - NOT WORKING FULLY | 25 = NTAG 216F
64 12 = UL EV1 48b |
65 13 = UL EV1 128b |
66 *** 14 = UL Plus - NOT WORKING YET |
68 -p NTAG password (8 hexsymbols), set NTAG password on tag.
69 -a NTAG pack ( 4 hexsymbols), set NTAG pack on tag.
70 -s Signature data (64 hexsymbols), set signature data on tag.
71 -o OTP data (8 hexsymbols), set `One-Time Programmable` data on tag.
72 -v Version data (16 hexsymbols), set version data on tag.
73 -q ATQA/SAK (<2b ATQA><1b SAK> hexsymbols), set ATQA/SAK on tag.
74 -g GTU Mode (1 hexsymbol), set GTU shadow mode.
75 -z ATS (<1b length><0-16 ATS> hexsymbols), Configure ATS. Length set to 00 will disable ATS.
76 -w Wipe tag. 0 for Mifare or 1 for UL. Fills tag with zeros and put default values for type selected.
77 -m Ultralight mode (00 UL EV1, 01 NTAG, 02 UL-C, 03 UL) Set type of UL.
78 -n Ultralight protocol (00 MFC, 01 UL), switches between UL and MFC mode]]
79 -- Need to split because reached maximum string length processed by lua
80 arguments2 = [[
81 -b Set maximum read/write blocks (2 hexsymbols)
82 NOTE: Ultralight EV1 and NTAG Version info and Signature are stored respectively in blocks 250-251 and 242-249
83 -k Ultimate Magic Card Key (IF DIFFERENT THAN DEFAULT 00000000)
85 ---
86 -- A debug printout-function
87 local function dbg(args)
88 if not DEBUG then return end
89 if type(args) == 'table' then
90 local i = 1
91 while result[i] do
92 dbg(result[i])
93 i = i+1
94 end
95 else
96 print('###', args)
97 end
98 end
99 -- This is only meant to be used when errors occur
100 local function oops(err)
101 print("ERROR: ",err)
102 core.clearCommandBuffer()
103 return nil, err
106 -- Usage help
107 local function help()
108 print(copyright)
109 print(author)
110 print(version)
111 print(date)
112 print(desc)
113 print(ansicolors.cyan..'Usage'..ansicolors.reset)
114 print(usage)
115 print(ansicolors.cyan..'Arguments'..ansicolors.reset)
116 print(arguments)
117 print(arguments2)
118 print(ansicolors.cyan..'Example usage'..ansicolors.reset)
119 print(example)
122 -- set the global password variable
123 local function set_ntagpassword(pwd)
124 if pwd == nil then _ntagpassword = nil; return true, 'Ok' end
125 if #pwd ~= 8 then return nil, 'password wrong length. Must be 4 hex bytes' end
126 if #pwd == 0 then _ntagpassword = nil end
127 _ntagpassword = pwd
128 return true, 'Ok'
130 -- set the global UMC key variable
131 local function set_key(key)
132 print('Key:'..key)
133 if key == nil then _key = '00000000'; return true, 'Ok' end
134 if #key ~= 8 then return nil, 'UMC key is wrong the length. Must be 4 hex bytes' end
135 if #key == 0 then _key = nil end
136 _key = key
137 return true, 'Ok'
139 --- Picks out and displays the data read from a tag
140 -- Specifically, takes a usb packet, converts to a Command
141 -- (as in commands.lua), takes the data-array and
142 -- reads the number of bytes specified in arg1 (arg0 in c-struct)
143 -- @param usbpacket the data received from the device
144 local function getResponseData(usbpacket)
145 local resp = Command.parse(usbpacket)
146 local len = tonumber(resp.arg1) * 2
147 return string.sub(tostring(resp.data), 0, len);
150 local function sendRaw(rawdata, options)
151 local flags = lib14a.ISO14A_COMMAND.ISO14A_NO_DISCONNECT
152 + lib14a.ISO14A_COMMAND.ISO14A_RAW
153 + lib14a.ISO14A_COMMAND.ISO14A_APPEND_CRC
154 local c = Command:newMIX{cmd = cmds.CMD_HF_ISO14443A_READER,
155 arg1 = flags,
156 arg2 = string.len(rawdata)/2,
157 data = rawdata}
158 return c:sendMIX(options.ignore_response)
161 local function send(payload)
162 local usb, err = sendRaw(payload,{ignore_response = false})
163 if err then return oops(err) end
164 return getResponseData(usb)
167 local function connect()
168 core.clearCommandBuffer()
169 -- First of all, connect
170 info, err = lib14a.read(true, true)
171 if err then
172 lib14a.disconnect()
173 return oops(err)
175 core.clearCommandBuffer()
176 --authenticate if needed using global variable
177 if _ntagpassword then
178 send('1B'.._ntagpassword)
180 return true
183 -- Read magic configuration
184 local function read_config()
185 local info = connect()
186 if not info then return false, "Can't select card" end
187 -- read Ultimate Magic Card CONFIG
188 if magicconfig == nil then
189 magicconfig = send("CF".._key.."C6")
190 else print('No Config')
192 -- extract data from CONFIG - based on CONFIG in https://github.com/RfidResearchGroup/proxmark3/blob/master/doc/magic_cards_notes.md#gen-4-gtu
193 ulprotocol, uidlength, readpass, gtumode, ats, atqa1, atqa2, sak, ulmode = magicconfig:sub(1,2), magicconfig:sub(3,4), magicconfig:sub(5,12), magicconfig:sub(13,14), magicconfig:sub(15,48), magicconfig:sub(51,52), magicconfig:sub(49,50), magicconfig:sub(53,54), magicconfig:sub(55,56)
194 maxRWblk = magicconfig:sub(57, 58)
195 atqaf = atqa1..' '..atqa2
196 cardtype, cardprotocol, gtustr, atsstr = 'unknown', 'unknown', 'unknown', 'unknown'
197 if magicconfig == nil then lib14a.disconnect(); return nil, "can't read configuration, "..err_lock end
198 if #magicconfig ~= 64 and #magicconfig ~= 68 then lib14a.disconnect(); return nil, "partial read of configuration, "..err_lock end
199 if gtumode == '00' then gtustr = 'Pre-write/Shadow Mode'
200 elseif gtumode == '01' or gtumode == '04' then gtustr = 'Restore Mode'
201 elseif gtumode == '02' then gtustr = 'Disabled'
202 elseif gtumode == '03' then gtustr = 'Disabled, high speed R/W mode for Ultralight'
204 if ats:sub(1,2) == '00' then atsstr = 'Disabled'
205 else atsstr = (string.sub(ats, 3))
207 if ulprotocol == '00' then
208 cardprotocol = 'MIFARE Classic Protocol'
209 ultype = 'Disabled'
210 if uidlength == '00' then
211 uid = send("CF".._key.."CE00"):sub(1,8)
212 if atqaf == '00 04' and sak == '09' then cardtype = 'MIFARE Mini S20 4-byte UID'
213 elseif atqaf == '00 04' and sak == '08' then cardtype = 'MIFARE 1k S50 4-byte UID'
214 elseif atqaf == '00 02' and sak == '18' then cardtype = 'MIFARE 4k S70 4-byte UID'
216 elseif uidlength == '01' then
217 uid = send("CF".._key.."CE00"):sub(1,14)
218 if atqaf == '00 44' and sak == '09' then cardtype = 'MIFARE Mini S20 7-byte UID'
219 elseif atqaf == '00 44' and sak == '08' then cardtype = 'MIFARE 1k S50 7-byte UID'
220 elseif atqaf == '00 42' and sak == '18' then cardtype = 'MIFARE 4k S70 7-byte UID'
222 elseif uidlength == '02' then
223 uid = send("CF".._key.."CE00"):sub(1,20)
224 if atqaf == '00 84' and sak == '09' then cardtype = 'MIFARE Mini S20 10-byte UID'
225 elseif atqaf == '00 84' and sak == '08' then cardtype = 'MIFARE 1k S50 10-byte UID'
226 elseif atqaf == '00 82' and sak == '18' then cardtype = 'MIFARE 4k S70 10-byte UID'
229 elseif ulprotocol == '01' then
230 -- Read Ultralight config only if UL protocol is enabled
231 cardprotocol = 'MIFARE Ultralight/NTAG'
232 block0 = send("3000")
233 uid0 = block0:sub(1,6)
234 uid = uid0..block0:sub(9,16)
235 if ulmode == '00' then ultype = 'Ultralight EV1'
236 elseif ulmode == '01' then ultype = 'NTAG21x'
237 elseif ulmode == '02' then ultype = 'Ultralight-C'
238 elseif ulmode == '03' then ultype = 'Ultralight'
240 -- read VERSION
241 cversion = send('30FA'):sub(1,16)
242 -- pwdblock must be set since the 30F1 and 30F2 special commands don't work on the ntag21x part of the UMC
243 if ulmode == '03' then versionstr = 'Ultralight'
244 elseif ulmode == '02' then versionstr = 'Ultralight-C'
245 elseif cversion == '0004030101000B03' then versionstr = 'UL EV1 48b'
246 elseif cversion == '0004030101000E03' then versionstr = 'UL EV1 128b'
247 elseif cversion == '0004040101000B03' then versionstr = 'NTAG 210'
248 elseif cversion == '0004040101000E03' then versionstr = 'NTAG 212'
249 elseif cversion == '0004040201000F03' then versionstr = 'NTAG 213'
250 elseif cversion == '0004040201001103' then versionstr = 'NTAG 215'
251 elseif cversion == '0004040201001303' then versionstr = 'NTAG 216'
252 elseif cversion == '0004040502011303' then versionstr = 'NTAG I2C 1K'
253 elseif cversion == '0004040502011503' then versionstr = 'NTAG I2C 2K'
254 elseif cversion == '0004040502021303' then versionstr = 'NTAG I2C 1K PLUS'
255 elseif cversion == '0004040502021503' then versionstr = 'NTAG I2C 2K PLUS'
256 elseif cversion == '0004040401000F03' then versionstr = 'NTAG 213F'
257 elseif cversion == '0004040401001303' then versionstr = 'NTAG 216F'
259 -- read PWD
260 cpwd = send("30F0"):sub(1,8)
261 pwd = send("30E5"):sub(1,8)
262 -- 04 response indicates that blocks has been locked down.
263 if pwd == '04' then lib14a.disconnect(); return nil, "can't read configuration, "..err_lock end
264 -- read PACK
265 cpack = send("30F1"):sub(1,4)
266 pack = send("30E6"):sub(1,4)
267 -- read SIGNATURE
268 signature1 = send('30F2'):sub(1,32)
269 signature2 = send('30F6'):sub(1,32)
270 lib14a.disconnect()
272 if _print < 1 then
273 print(string.rep('=', 88))
274 print('\t\t\tUltimate Magic Card Configuration')
275 print(string.rep('=', 88))
276 print(' - Raw Config ', string.sub(magicconfig, 1, -9))
277 print(' - Card Protocol ', cardprotocol)
278 print(' - Ultralight Mode ', ultype)
279 print(' - ULM Backdoor Key ', readpass)
280 print(' - GTU Mode ', gtustr)
281 if ulprotocol == '01' then
282 print(' - Card Type ', versionstr)
283 else
284 print(' - Card Type ', cardtype)
286 print(' - UID ', uid)
287 print(' - ATQA ', atqaf)
288 print(' - SAK ', sak)
289 if ulprotocol == '01' then
290 print('')
291 print(string.rep('=', 88))
292 print('\t\t\tMagic UL/NTAG 21* Configuration')
293 print(string.rep('=', 88))
294 print(' - ATS ', atsstr)
295 print(' - Password ', '[0xE5] '..pwd, '[0xF0] '..cpwd)
296 print(' - Pack ', '[0xE6] '..pack, '[0xF1] '..cpack)
297 print(' - Version ', cversion)
298 print(' - Signature ', signature1..signature2)
300 print(' - Max R/W Block ', maxRWblk)
302 lib14a.disconnect()
303 return true, 'Ok'
306 -- calculate block0
307 local function calculate_block0(useruid)
308 local uidbytes = utils.ConvertHexToBytes(useruid)
309 local i = 1
310 local bcc = bxor(uidbytes[i], uidbytes[i+1]);
311 local length = #useruid / 2;
313 -- bcc
314 for i = 3, length, 1 do bcc = bxor(bcc, uidbytes[i]) end
316 -- block0
317 local block0 = ""
318 for i = 1, length, 1 do block0 = block0..string.format('%02X', uidbytes[i]) end
320 return block0..string.format('%02X', bcc)
323 -- Writes a UID for MFC and MFUL/NTAG cards
324 local function write_uid(useruid)
325 -- read CONFIG
326 if not magicconfig then
327 _print = 1
328 read_config()
330 local info = connect()
331 if not info then return false, "Can't select card" end
332 -- Writes a MFC UID with GEN4 magic commands.
333 if ulprotocol == '00' then
334 -- uid string checks
335 if useruid == nil then return nil, 'empty uid string' end
336 if #useruid == 0 then return nil, 'empty uid string' end
337 if (#useruid ~= 8) and (#useruid ~= 14) and (#useruid ~= 20) then return nil, 'UID wrong length. Should be 4, 7 or 10 hex bytes' end
338 print('Writing new UID ', useruid)
339 local block0 = calculate_block0(useruid)
340 print('Calculated block0 ', block0)
341 local resp = send('CF'.._key..'CD00'..block0)
342 -- Writes a MFUL UID with bcc1, bcc2 using NTAG21xx commands.
343 elseif ulprotocol == '01' then
344 -- uid string checks
345 if useruid == nil then return nil, 'empty uid string' end
346 if #useruid == 0 then return nil, 'empty uid string' end
347 if #useruid ~= 14 then return nil, 'uid wrong length. Should be 7 hex bytes' end
348 print('Writing new UID ', useruid)
349 local uidbytes = utils.ConvertHexToBytes(useruid)
350 local bcc1 = bxor(bxor(bxor(uidbytes[1], uidbytes[2]), uidbytes[3]), 0x88)
351 local bcc2 = bxor(bxor(bxor(uidbytes[4], uidbytes[5]), uidbytes[6]), uidbytes[7])
352 local block0 = string.format('%02X%02X%02X%02X', uidbytes[1], uidbytes[2], uidbytes[3], bcc1)
353 local block1 = string.format('%02X%02X%02X%02X', uidbytes[4], uidbytes[5], uidbytes[6], uidbytes[7])
354 local block2 = string.format('%02X%02X%02X%02X', bcc2, 0x48, 0x00, 0x00)
355 local resp
356 resp = send('A200'..block0)
357 resp = send('A201'..block1)
358 resp = send('A202'..block2)
359 else
360 print('Incorrect ul')
362 lib14a.disconnect()
363 if resp ~= nil then
364 return nil, oops('Failed to write UID')
365 else
366 return true, 'Ok'
370 -- Write ATQA/SAK
371 local function write_atqasak(atqasak)
372 -- read CONFIG
373 if not magicconfig then
374 _print = 1
375 read_config()
377 if atqasak == nil then return nil, 'Empty ATQA/SAK string' end
378 if #atqasak == 0 then return nil, 'Empty ATQA/SAK string' end
379 if #atqasak ~= 6 then return nil, 'ATQA/SAK wrong length. Should be 6 hex bytes. I.E. 004408 ATQA(0044) SAK(08)' end
380 local atqauser1 = atqasak:sub(1,2)
381 local atqauser2 = atqasak:sub(3,4)
382 local atqauserf = atqauser2..atqauser1
383 local sakuser = atqasak:sub(5,6)
384 if sakuser == '04' then
385 print('Never set SAK bit 3 (e.g. SAK=04), it indicates an extra cascade level is required')
386 return nil
387 elseif (sakuser == '20' or sakuser == '28') and atslen == '00' then
388 print('When SAK equals 20 or 28, ATS must be turned on')
389 return nil
390 elseif atqauser2 == '40' then
391 print('ATQA of [00 40] will cause the card to not answer.')
392 return nil
393 else
394 local info = connect()
395 if not info then return false, "Can't select card" end
396 print('New ATQA: '..atqauser1..' '..atqauser2..' New SAK: '..sakuser)
397 local resp = send("CF".._key.."35"..atqauserf..sakuser)
398 lib14a.disconnect()
399 if resp == nil then
400 return nil, oops('Failed to write ATQA/SAK')
401 else
402 return true, 'Ok'
407 -- Write NTAG PWD
408 local function write_ntagpwd(ntagpwd)
409 -- read CONFIG
410 if not magicconfig then
411 _print = 1
412 read_config()
414 if ulprotocol == '00' then return nil, 'Magic Card is not using the Ultralight Protocol' end
415 -- PWD string checks
416 if ntagpwd == nil then return nil, 'empty NTAG PWD string' end
417 if #ntagpwd == 0 then return nil, 'empty NTAG PWD string' end
418 if #ntagpwd ~= 8 then return nil, 'NTAG PWD wrong length. Should be 4 hex bytes' end
419 local info = connect()
420 if not info then return false, "Can't select card" end
421 print('Writing new NTAG PWD ', ntagpwd)
422 local resp = send('A2E5'..ntagpwd) -- must add both for password to be read by the reader command B1
423 local resp = send('A2F0'..ntagpwd)
424 lib14a.disconnect()
425 if resp == nil then
426 return nil, 'Failed to write password'
427 else
428 return true, 'Ok'
432 -- Write PACK
433 local function write_pack(userpack)
434 -- read CONFIG
435 if not magicconfig then
436 _print = 1
437 read_config()
439 if ulprotocol == 0 then return nil, 'Magic Card is not using the Ultralight Protocol' end
440 -- PACK string checks
441 if userpack == nil then return nil, 'empty PACK string' end
442 if #userpack == 0 then return nil, 'empty PACK string' end
443 if #userpack ~= 4 then return nil, 'PACK wrong length. Should be 4 hex bytes' end
444 local info = connect()
445 if not info then return false, "Can't select card" end
446 print('Writing new PACK', userpack)
447 send('A2E6'..userpack..'0000')
448 send('A2F1'..userpack..'0000')
449 lib14a.disconnect()
450 return true, 'Ok'
453 -- Write OTP block
454 local function write_otp(block3)
455 -- OTP string checks
456 if block3 == nil then return nil, 'empty OTP string' end
457 if #block3 == 0 then return nil, 'empty OTP string' end
458 if #block3 ~= 8 then return nil, 'OTP wrong length. Should be 4 hex bytes' end
459 -- read CONFIG
460 if not magicconfig then
461 _print = 1
462 read_config()
464 if ulprotocol == '00' then return nil, 'Magic Card is not using the Ultralight Protocol' end
465 local info = connect()
466 if not info then return false, "Can't select card" end
467 print('Writing new OTP ', block3)
468 local resp = send('A203'..block3)
469 lib14a.disconnect()
470 if resp ~= '0A' then return false, oops('Failed to write OTP')
471 else
472 return true, 'Ok'
476 -- Write VERSION data,
477 -- make sure you have correct version data
478 local function write_version(data)
479 -- Version string checks
480 if data == nil then return nil, 'empty version string' end
481 if #data == 0 then return nil, 'empty version string' end
482 if #data ~= 16 then return nil, 'version wrong length. Should be 8 hex bytes' end
483 -- read CONFIG
484 if not magicconfig then
485 _print = 1
486 read_config()
488 if ulprotocol == '00' then return nil, 'Magic Card is not using the Ultralight Protocol' end
489 print('Writing new version', data)
490 local b1 = data:sub(1,8)
491 local b2 = data:sub(9,16)
492 local info = connect()
493 if not info then return false, "Can't select card" end
494 local resp
495 -- set maximum read/write blocks to 251; version is stored in blocks 250-251
496 send("CF".._key.."6B".."FB")
497 resp = send('A2FA'..b1)
498 resp = send('A2FB'..b2)
499 lib14a.disconnect()
500 if resp ~= '0A' then return nil, oops('Failed to write version')
501 else
502 return true, 'Ok'
507 -- Write SIGNATURE data
508 local function write_signature(data)
509 -- Signature string checks
510 if data == nil then return nil, 'empty data string' end
511 if #data == 0 then return nil, 'empty data string' end
512 if #data ~= 64 then return nil, 'data wrong length. Should be 32 hex bytes' end
513 -- read CONFIG
514 if not magicconfig then
515 _print = 1
516 read_config()
518 local info = connect()
519 if not info then return false, "Can't select card" end
520 if ulprotocol == '00' then
521 print('Writing new MFC signature',data)
522 send('CF'.._key..'6B48')
523 lib14a.disconnect()
524 connect() -- not 100% sure why it's needed, but without this blocks aren't actually written
525 local sig1 = data:sub(1, 32)
526 local sig2 = data:sub(33, 64)
528 send('CF'.._key..'CD45'..sig1)
529 send('CF'.._key..'CD46'..sig2)
530 send('CF'.._key..'CD475C8FF9990DA270F0F8694B791BEA7BCC')
531 else
532 print('Writing new MFUL signature',data)
533 local b,c
534 local cmd = 'A2F%d%s'
535 local j = 2
536 -- set maximum read/write blocks to 251; signature is stored in blocks 242-249
537 send("CF".._key.."6B".."FB")
538 lib14a.disconnect()
539 connect() -- not 100% sure why it's needed, but without this blocks aren't actually written
540 for i = 1, #data, 8 do
541 b = data:sub(i,i+7)
542 c = cmd:format(j,b)
543 local resp = send(c)
544 if resp ~= '0A' then lib14a.disconnect(); return nil, oops('Failed to write signature') end
545 j = j + 1
548 lib14a.disconnect()
549 return true, 'Ok'
552 -- Enable/Disable GTU Mode
553 -- 00: pre-write, 01: restore mode, 02: disabled, 03: disabled, high speed R/W mode for Ultralight
554 local function write_gtu(gtu)
555 if gtu == nil then return nil, 'empty GTU string' end
556 if #gtu == 0 then return nil, 'empty GTU string' end
557 if #gtu ~= 2 then return nil, 'type wrong length. Should be 1 hex byte' end
558 local info = connect()
559 if not info then return false, "Can't select card" end
560 if gtu == '00' then
561 print('Enabling GTU Pre-Write')
562 send('CF'.._key..'32'..gtu)
563 elseif gtu == '01' or gtu == '04' then
564 print('Enabling GTU Restore Mode')
565 send('CF'.._key..'32'..gtu)
566 elseif gtu == '02' then
567 print('Disabled GTU')
568 send('CF'.._key..'32'..gtu)
569 elseif gtu == '03' then
570 print('Disabled GTU, high speed R/W mode for Ultralight')
571 send('CF'.._key..'32'..gtu)
572 else
573 print('Failed to set GTU mode')
575 lib14a.disconnect()
576 return true, 'Ok'
579 -- Write ATS
580 -- First hexbyte is length. 00 to disable ATS. 16 hexbytes for ATS
581 local function write_ats(atsuser)
582 if atsuser == nil then return nil, 'empty ATS string' end
583 if #atsuser == 0 then return nil, 'empty ATS string' end
584 if #atsuser > 34 then return nil, 'type wrong length. Should be <1b length><0-16b ATS> hex byte' end
585 local atscardlen = atsuser:sub(1,2)
586 local atscardlendecimal = tonumber(atscardlen, 16)
587 local atsf = string.sub(atsuser, 3)
588 if (#atsf / 2) ~= atscardlendecimal then
589 oops('Given length of ATS ('..atscardlendecimal..') does not match the ATS_length ('..(#atsf / 2)..')')
590 return true, 'Ok'
591 else
592 local info = connect()
593 if not info then return false, "Can't select card" end
594 print('Writing '..atscardlendecimal..' ATS bytes of '..atsf)
595 send("CF".._key.."34"..atsuser)
597 lib14a.disconnect()
598 return true, 'Ok'
601 -- Change UL/MFC protocol
602 local function write_ulp(ulp)
603 if ulp == nil then return nil, 'empty ULP string' end
604 if #ulp == 0 then return nil, 'empty ULP string' end
605 if #ulp > 2 then return nil, 'type wrong length. Should be 1 hex byte' end
606 local info = connect()
607 if not info then return false, "Can't select card" end
608 if ulp == '00' then
609 print('Changing card to Mifare Classic Protocol')
610 send("CF".._key.."69"..ulp)
611 elseif ulp == '01' then
612 print('Changing card to Ultralight Protocol')
613 send("CF".._key.."69"..ulp)
614 else
615 oops('Protocol needs to be either 00 or 01')
617 lib14a.disconnect()
618 return true, 'Ok'
621 -- Change UL Mode Type
622 local function write_ulm(ulm)
623 if ulm == nil then return nil, 'empty ULM string' end
624 if #ulm == 0 then return nil, 'empty ULM string' end
625 if #ulm > 2 then return nil, 'type wrong length. Should be 1 hex byte' end
626 local info = connect()
627 if not info then return false, "Can't select card" end
628 if ulm == '00' then
629 print('Changing card UL mode to Ultralight EV1')
630 send("CF".._key.."6A"..ulm)
631 elseif ulm == '01' then
632 print('Changing card UL mode to NTAG')
633 send("CF".._key.."6A"..ulm)
634 elseif ulm == '02' then
635 print('Changing card UL mode to Ultralight-C')
636 send("CF".._key.."6A"..ulm)
637 elseif ulm == '03' then
638 print('Changing card UL mode to Ultralight')
639 send("CF".._key.."6A"..ulm)
640 else
641 oops('UL mode needs to be either 00, 01, 02, 03')
643 lib14a.disconnect()
644 return true, 'Ok'
647 -- Write maximum read/write block number,
648 local function write_maxRWblk(data)
649 -- input number check
650 if data == nil then return nil, 'empty block number' end
651 if #data == 0 then return nil, 'empty block number' end
652 if #data ~= 2 then return nil, 'block number wrong length. Should be 1 hex byte' end
654 print('Set max R/W block', data)
655 local info = connect()
656 if not info then return false, "Can't select card" end
657 local resp
658 -- set maximum read/write block
659 resp = send("CF".._key.."6B"..data)
660 lib14a.disconnect()
661 if resp ~= '9000FD07' then return nil, 'Failed to write maximum read/write block'
662 else
663 return true, 'Ok'
667 -- Set type for magic card presets.
668 local function set_type(tagtype)
669 -- tagtype checks
670 if type(tagtype) == 'string' then tagtype = tonumber(tagtype, 10) end
671 if tagtype == nil then return nil, oops('empty tagtype') end
672 -- Setting Mifare mini S20 4-byte
673 if tagtype == 1 then
674 print('Setting: Ultimate Magic card to Mifare mini S20 4-byte')
675 connect()
676 send("CF".._key.."F000000000000002000978009102DABC19101011121314151604000900")
677 lib14a.disconnect()
678 write_uid('04112233')
679 write_maxRWblk('13')
680 -- Setting Mifare mini S20 7-byte
681 elseif tagtype == 2 then
682 print('Setting: Ultimate Magic card to Mifare mini S20 7-byte')
683 connect()
684 send("CF".._key.."F000010000000002000978009102DABC19101011121314151644000900")
685 lib14a.disconnect()
686 write_uid('04112233445566')
687 write_maxRWblk('13')
688 -- Setting Mifare mini S20 10-byte
689 elseif tagtype == 3 then
690 print('Setting: Ultimate Magic card to Mifare mini S20 10-byte')
691 connect()
692 send("CF".._key.."F000020000000002000978009102DABC19101011121314151684000900")
693 lib14a.disconnect()
694 write_uid('04112233445566778899')
695 write_maxRWblk('13')
696 -- Setting Mifare 1k S50 4--byte
697 elseif tagtype == 4 then
698 print('Setting: Ultimate Magic card to Mifare 1k S50 4-byte')
699 connect()
700 send("CF".._key.."F000000000000002000978009102DABC19101011121314151604000800")
701 lib14a.disconnect()
702 write_uid('04112233')
703 write_maxRWblk('3F')
704 -- Setting Mifare 1k S50 7-byte
705 elseif tagtype == 5 then
706 print('Setting: Ultimate Magic card to Mifare 1k S50 7-byte')
707 connect()
708 send("CF".._key.."F000010000000002000978009102DABC19101011121314151644000800")
709 lib14a.disconnect()
710 write_uid('04112233445566')
711 write_maxRWblk('3F')
712 -- Setting Mifare 1k S50 10-byte
713 elseif tagtype == 6 then
714 print('Setting: Ultimate Magic card to Mifare 1k S50 10-byte')
715 connect()
716 send("CF".._key.."F000020000000002000978009102DABC19101011121314151684000800")
717 lib14a.disconnect()
718 write_uid('04112233445566778899')
719 write_maxRWblk('3F')
720 -- Setting Mifare 4k S70 4-byte
721 elseif tagtype == 7 then
722 print('Setting: Ultimate Magic card to Mifare 4k S70 4-byte')
723 connect()
724 send("CF".._key.."F000000000000002000978009102DABC19101011121314151602001800")
725 lib14a.disconnect()
726 write_uid('04112233')
727 write_maxRWblk('FF')
728 -- Setting Mifare 4k S70 7-byte
729 elseif tagtype == 8 then
730 print('Setting: Ultimate Magic card to Mifare 4k S70 7-byte')
731 connect()
732 send("CF".._key.."F000010000000002000978009102DABC19101011121314151642001800")
733 lib14a.disconnect()
734 write_uid('04112233445566')
735 write_maxRWblk('FF')
736 -- Setting Mifare 4k S70 10-byte
737 elseif tagtype == 9 then
738 print('Setting: Ultimate Magic card to Mifare 4k S70 10-byte')
739 connect()
740 send("CF".._key.."F000020000000002000978009102DABC19101011121314151682001800")
741 lib14a.disconnect()
742 write_uid('04112233445566778899')
743 write_maxRWblk('FF')
744 -- Setting UL
745 elseif tagtype == 10 then
746 print('Setting: Ultimate Magic card to UL')
747 connect()
748 send("CF".._key.."F0010100000000030A0A78008102DBA0C119402AB5BA4D321A44000003")
749 lib14a.disconnect()
750 write_uid('04112233445566')
751 write_otp('00000000') -- Setting OTP to default 00 00 00 00
752 write_version('0000000000000000') -- UL-C does not have a version
753 -- Setting UL-C
754 elseif tagtype == 11 then
755 print('Setting: Ultimate Magic card to UL-C')
756 connect()
757 send("CF".._key.."F0010100000000030A0A78008102DBA0C119402AB5BA4D321A44000002")
758 print('Setting default permissions and 3des key')
759 send('A22A30000000') -- Auth0 page 48/0x30 and above need authentication
760 send('A22B80000000') -- Auth1 read and write access restricted
761 send('A22C42524541') -- Default 3des key
762 send('A22D4B4D4549')
763 send('A22E46594F55')
764 send('A22F43414E21')
765 lib14a.disconnect()
766 write_uid('04112233445566')
767 write_otp('00000000') -- Setting OTP to default 00 00 00 00
768 write_version('0000000000000000') -- UL-C does not have a version
769 elseif tagtype == 12 then
770 print('Setting: Ultimate Magic card to UL-EV1 48')
771 connect()
772 send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000000")
773 -- Setting UL-Ev1 default config bl 16,17
774 send('a2E5FFFFFFFF') -- A2F0 block does not align correctly to actual pwd block
775 send('a2E6FFFFFFFF') -- A2F1 block does not align correctly to actual pack block
776 send('a210000000FF')
777 send('a21100050000')
778 lib14a.disconnect()
779 write_uid('04112233445566')
780 write_otp('00000000') -- Setting OTP to default 00 00 00 00
781 write_version('0004030101000b03') -- UL-EV1 (48) 00 04 03 01 01 00 0b 03
782 elseif tagtype == 13 then
783 print('Setting: Ultimate Magic card to UL-EV1 128')
784 connect()
785 send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000000")
786 -- Setting UL-Ev1 default config bl 37,38
787 send('a2E5FFFFFFFF') -- A2F0 block does not align correctly to actual pwd block
788 send('a2E6FFFFFFFF') -- A2F1 block does not align correctly to actual pack block
789 send('a225000000FF')
790 send('a22600050000')
791 lib14a.disconnect()
792 write_uid('04112233445566')
793 write_otp('00000000') -- Setting OTP to default 00 00 00 00
794 write_version('0004030101000e03') -- UL-EV1 (128) 00 04 03 01 01 00 0e 03
795 elseif tagtype == 15 then
796 print('Setting: Ultimate Magic card to NTAG 210')
797 connect()
798 send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001")
799 -- Setting NTAG210 default CC block456
800 send('a203e1100600')
801 send('a2040300fe00')
802 send('a20500000000')
803 -- Setting cfg1/cfg2
804 send('a210000000FF')
805 send('a21100050000')
806 lib14a.disconnect()
807 write_uid('04E10CDA993C80')
808 write_version('0004040101000b03') -- NTAG210 00 04 04 01 01 00 0b 03
809 elseif tagtype == 16 then
810 print('Setting: Ultimate Magic card to NTAG 212')
811 connect()
812 send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001")
813 -- Setting NTAG212 default CC block456
814 send('a203e1101000')
815 send('a2040103900a')
816 send('a205340300fe')
817 -- Setting cfg1/cfg2
818 send('a225000000FF')
819 send('a22600050000')
820 lib14a.disconnect()
821 write_uid('04E10CDA993C80')
822 write_version('0004040101000E03') -- NTAG212 00 04 04 01 01 00 0E 03
823 elseif tagtype == 17 then
824 print('Setting: Ultimate Magic card to NTAG 213')
825 connect()
826 send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001")
827 -- Setting NTAG213 default CC block456
828 send('a203e1101200')
829 send('a2040103a00c')
830 send('a205340300fe')
831 -- setting cfg1/cfg2
832 send('a229000000ff')
833 send('a22a00050000')
834 lib14a.disconnect()
835 write_uid('04E10CDA993C80')
836 write_version('0004040201000F03') -- NTAG213 00 04 04 02 01 00 0f 03
837 elseif tagtype == 18 then
838 print('Setting: Ultimate Magic card to NTAG 215')
839 connect()
840 send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001")
841 -- Setting NTAG215 default CC block456
842 send('a203e1103e00')
843 send('a2040300fe00')
844 send('a20500000000')
845 -- setting cfg1/cfg2
846 send('a283000000ff')
847 send('a28400050000')
848 lib14a.disconnect()
849 write_uid('04E10CDA993C80')
850 write_version('0004040201001103') -- NTAG215 00 04 04 02 01 00 11 03
851 elseif tagtype == 19 then
852 print('Setting: Ultimate Magic card to NTAG 216')
853 connect()
854 send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001")
855 -- Setting NTAG216 default CC block456
856 send('a203e1106d00')
857 send('a2040300fe00')
858 send('a20500000000')
859 -- setting cfg1/cfg2
860 send('a2e3000000ff')
861 send('a2e400050000')
862 lib14a.disconnect()
863 write_uid('04E10CDA993C80')
864 write_version('0004040201001303') -- NTAG216 00 04 04 02 01 00 13 03
865 elseif tagtype == 20 then
866 print('Setting: Ultimate Magic card to NTAG I2C 1K')
867 connect()
868 send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001")
869 -- Setting NTAG I2C 1K default CC block456
870 send('a203e1106D00')
871 send('a2040300fe00')
872 send('a20500000000')
873 lib14a.disconnect()
874 write_uid('04E10CDA993C80')
875 write_version('0004040502011303') -- NTAG_I2C_1K 00 04 04 05 02 01 13 03
876 elseif tagtype == 21 then
877 print('Setting: Ultimate Magic card to NTAG I2C 2K')
878 connect()
879 send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001")
880 -- Setting NTAG I2C 2K default CC block456
881 send('a203e110EA00')
882 send('a2040300fe00')
883 send('a20500000000')
884 lib14a.disconnect()
885 write_uid('04E10CDA993C80')
886 write_version('0004040502011503') -- NTAG_I2C_2K 00 04 04 05 02 01 15 03
887 elseif tagtype == 22 then
888 print('Setting: Ultimate Magic card to NTAG I2C plus 1K')
889 connect()
890 send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001")
891 -- Setting NTAG I2C 1K default CC block456
892 send('a203e1106D00')
893 send('a2040300fe00')
894 send('a20500000000')
895 lib14a.disconnect()
896 write_uid('04E10CDA993C80')
897 write_version('0004040502021303') -- NTAG_I2C_1K 00 04 04 05 02 02 13 03
898 elseif tagtype == 23 then
899 print('Setting: Ultimate Magic card to NTAG I2C plus 2K')
900 connect()
901 send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001")
902 -- Setting NTAG I2C 2K default CC block456
903 send('a203e1106D00')
904 send('a2040300fe00')
905 send('a20500000000')
906 write_uid('04E10CDA993C80')
907 write_version('0004040502021503') -- NTAG_I2C_2K 00 04 04 05 02 02 15 03
908 elseif tagtype == 24 then
909 print('Setting: Ultimate Magic card to NTAG 213F')
910 connect()
911 send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001")
912 -- Setting NTAG213 default CC block456
913 send('a203e1101200')
914 send('a2040103a00c')
915 send('a205340300fe')
916 -- setting cfg1/cfg2
917 send('a229000000ff')
918 send('a22a00050000')
919 lib14a.disconnect()
920 write_uid('04E10CDA993C80')
921 write_version('0004040401000F03') -- NTAG213F 00 04 04 04 01 00 0f 03
922 elseif tagtype == 25 then
923 print('Setting: Ultimate Magic card to NTAG 216F')
924 connect()
925 send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001")
926 -- Setting NTAG216 default CC block456
927 send('a203e1106d00')
928 send('a2040300fe00')
929 send('a20500000000')
930 -- setting cfg1/cfg2
931 send('a2e3000000ff')
932 send('a2e400050000')
933 lib14a.disconnect()
934 write_uid('04E10CDA993C80')
935 write_version('0004040401001303') -- NTAG216F 00 04 04 04 01 00 13 03
936 else
937 oops('No matching tag types')
939 lib14a.disconnect()
940 if resp == '04' then
941 return nil, 'Failed to set type'
942 else
943 return true, 'Ok'
947 -- returns true if b is the index of a sector trailer
948 local function mfIsSectorTrailer(b)
949 n=b+1
950 if (n < 32*4 ) then
951 if (n % 4 == 0) then return true
952 else return false
956 if (n % 16 == 0) then return true
959 return false
962 -- wipe tag
963 local function wipe(wtype)
964 local info = connect()
965 if not info then return false, "Can't select card" end
966 if wtype == '0' then
967 print('Starting Mifare Wipe')
968 send("CF".._key.."F000000000000002000978009102DABC19101011121314151604000800")
969 send("CF".._key.."CD000102030404080400000000000000BEAF")
970 local err, msg, resp
971 local cmd_empty = 'CF'.._key..'CD%02X00000000000000000000000000000000'
972 local cmd_trail = 'CF'.._key..'CD%02XFFFFFFFFFFFFFF078069FFFFFFFFFFFF'
973 for b = 1, 0xFF do
974 if mfIsSectorTrailer(b) then
975 local cmd = (cmd_trail):format(b)
976 resp = send(cmd)
977 else
978 local cmd = (cmd_empty):format(b)
979 resp = send(cmd)
981 if resp == nil then
982 io.write('\nwrote block '..b, ' failed\n')
983 err = true
984 else
985 io.write('.')
987 io.flush()
989 print('\n')
990 err, msg = set_type(4)
991 if err == nil then return err, msg end
992 lib14a.disconnect()
993 return true, 'Ok'
994 elseif wtype == '1' then
995 print('Starting Ultralight Wipe')
996 local err, msg, resp
997 local cmd_empty = 'A2%02X00000000'
998 local cmd_cfg1 = 'A2%02X000000FF'
999 local cmd_cfg2 = 'A2%02X00050000'
1000 print('Wiping tag')
1001 local info = connect()
1002 if not info then return false, "Can't select card" end
1003 send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001FB")
1004 for b = 3, 0xFB do
1005 --configuration block 0
1006 if b == 0x29 or b == 0x83 or b == 0xe3 then
1007 local cmd = (cmd_cfg1):format(b)
1008 resp = send(cmd)
1009 --configuration block 1
1010 elseif b == 0x2a or b == 0x84 or b == 0xe4 then
1011 local cmd = (cmd_cfg2):format(b)
1012 resp = send(cmd)
1013 else
1014 resp = send(cmd_empty:format(b))
1016 if resp == '04' or #resp == 0 then
1017 io.write('\nwrote block '..b, ' failed\n')
1018 err = true
1019 else
1020 io.write('.')
1022 io.flush()
1024 io.write('\r\n')
1025 lib14a.disconnect()
1026 print('\n')
1027 if err then return nil, "Tag locked down or misconfigured maximum read/write blocks, "..err_lock end
1028 -- set NTAG213 default values
1029 err, msg = set_type(17)
1030 if err == nil then return err, msg end
1031 --set UID
1032 err, msg = write_uid('04E10CDA993C80')
1033 if err == nil then return err, msg end
1034 --set NTAG pwd
1035 err, msg = write_ntagpwd('FFFFFFFF')
1036 if err == nil then return err, msg end
1037 --set pack
1038 err, msg = write_pack('0000')
1039 if err == nil then return err, msg end
1040 --set signature
1041 err, msg = write_signature('8B76052EE42F5567BEB53238B3E3F9950707C0DCC956B5C5EFCFDB709B2D82B3')
1042 if err == nil then return err, msg end
1043 lib14a.disconnect()
1044 return true, 'Ok'
1045 else oops('Use 0 for Mifare wipe or 1 for Ultralight wipe')
1049 -- The main entry point
1050 function main(args)
1051 print()
1052 local err, msg
1053 if #args == 0 then return help() end
1054 -- Read the parameters
1055 for o, a in getopt.getopt(args, 'hck:u:t:p:a:s:o:v:q:g:z:n:m:w:b:') do
1056 -- help
1057 if o == "h" then return help() end
1058 -- set Ultimate Magic Card Key for read write
1059 if o == "k" then err, msg = set_key(a) end
1060 -- configuration
1061 if o == "c" then err, msg = read_config() end
1062 -- wipe tag
1063 if o == "w" then err, msg = wipe(a) end
1064 -- write uid
1065 if o == "u" then err, msg = write_uid(a) end
1066 -- write type/version
1067 if o == "t" then err, msg = set_type(a) end
1068 -- write NTAG pwd
1069 if o == "p" then err, msg = write_ntagpwd(a) end
1070 -- write pack
1071 if o == "a" then err, msg = write_pack(a) end
1072 -- write signature
1073 if o == "s" then err, msg = write_signature(a) end
1074 -- write otp
1075 if o == "o" then err, msg = write_otp(a) end
1076 -- write version
1077 if o == "v" then err, msg = write_version(a) end
1078 -- write atqa/sak
1079 if o == "q" then err, msg = write_atqasak(a) end
1080 -- write gtu mode
1081 if o == "g" then err, msg = write_gtu(a) end
1082 -- write ats
1083 if o == "z" then err, msg = write_ats(a) end
1084 -- write UL mode
1085 if o == "m" then err, msg = write_ulm(a) end
1086 -- write UL protocol
1087 if o == "n" then err, msg = write_ulp(a) end
1088 -- write max r/w block
1089 if o == "b" then err, msg = write_maxRWblk(a) end
1090 if err == nil then return oops(msg) end
1093 main(args)