7 # MIFARE Application Directory (MAD)
8 # http://www.nxp.com/acrobat_download2/other/identification/MAD_overview.pdf
10 use Data::Dump qw(dump);
12 my $debug = $ENV{DEBUG} || 0;
14 my $function_clusters;
20 my ( $code, $function ) = split(/\s+/,$_,2);
22 if ( $code =~ m/^($h{2})-($h{2})$/ ) {
23 foreach my $c ( hex($1) .. hex($2) ) {
24 $function_clusters->{ unpack('HH',$c) } = $function;
26 } elsif ( $code =~ m/^($h{2})$/ ) {
27 $function_clusters->{ lc $code } = $function;
28 } elsif ( $code =~ m/^($h{4})$/ ) {
29 $mad_id->{ lc $1 } = $function;
31 die "can't parse __DATA__ line $.\n$_\n";
35 my $access_condition_data = {
36 0b000 => 'R:AB W:AB I:AB DTR:AB',
37 0b010 => 'R:AB W:-- I:-- DTR:--',
38 0b100 => 'R:AB W:-B I:-- DTR:--',
39 0b110 => 'R:AB W:-B I:-B DTR:AB',
40 0b001 => 'R:AB W:-- I:-- DTR:AB',
41 0b011 => 'R:-B W:-B I:-- DTR:--',
42 0b101 => 'R:-B W:-- I:-- DTR:--',
43 0b111 => 'R:-- W:-- I:-- DTR:--',
46 my $access_condition_trailer = {
47 0b000 => 'R/W: KEYSECXA:-/A ACCESS COND:A-/- KEYSECXB:A/A',
48 0b010 => 'R/W: KEYSECXA:-/- ACCESS COND:A-/- KEYSECXB:A/-',
49 0b100 => 'R/W: KEYSECXA:-/B ACCESS COND:AB/- KEYSECXB:-/B',
50 0b110 => 'R/W: KEYSECXA:-/- ACCESS COND:AB/- KEYSECXB:-/-',
51 0b001 => 'R/W: KEYSECXA:-/A ACCESS COND:A-/A KEYSECXB:A/A',
52 0b011 => 'R/W: KEYSECXA:-/B ACCESS COND:AB/B KEYSECXB:-/B',
53 0b101 => 'R/W: KEYSECXA:-/- ACCESS COND:AB/B KEYSECXB:-/-',
54 0b111 => 'R/W: KEYSECXA:-/- ACCESS COND:AB/- KEYSECXB:-/-',
59 warn "# function_clusters ",dump($function_clusters);
60 warn "# mad_id ", dump($mad_id);
66 die "expected 4096 bytes, got ",length($card), " bytes\n"
67 unless length $card == 4096;
69 foreach my $i ( 0 .. 15 ) {
74 printf "manufacturer block\nSerial number: %s\nCB: %s\nmanufacturer data: %s\n"
75 , unpack('H*',substr($card,0,4))
76 , unpack('H*',substr($card,4,1))
77 , unpack('H*',substr($card,5,11))
80 my $v = unpack('v',(substr($card, 0x10 + ( $i * 2 ), 2)));
81 my $cluster_id = unpack('HH', (( $v & 0xff00 ) >> 8) );
82 my $full_id = sprintf "%04x",$v;
83 printf "MAD sector %-2d %04x [%s]\n%s\n", $i, $v
84 , $function_clusters->{ $cluster_id }
85 , $mad_id->{$full_id} || "FIXME: add $full_id from MAD_overview.pdf to __DATA__ at end of $0"
89 # RLE encoded card holder information
90 my $data = substr( $card, $pos, 0x30);
98 while ( substr($data,$o,1) ne "\x00" ) {
99 my $len = ord(substr($data,$o,1));
100 my $type = ( $len & 0b11000000 ) >> 6;
101 $len = $len & 0b00111111;
102 my $dump = substr($data,$o+1,$len-1);
103 $dump = '0x' . unpack('H*', $dump) if $type == 0b11; # any
104 printf "%-10s %2d %s\n", $types->{$type}, $len, $dump;
107 } elsif ( $v == 0x0015 ) {
108 printf "Card number: %s\n", unpack('h*',substr($card,$pos + 0x04,6));
113 my $c1 = ( ord(substr($card,$pos+0x37,1)) & 0xf0 ) >> 4;
114 my $c2 = ( ord(substr($card,$pos+0x38,1)) & 0x0f );
115 my $c3 = ( ord(substr($card,$pos+0x38,1)) & 0xf0 ) >> 4;
117 foreach my $j ( 0 .. 3 ) {
118 my $offset = $pos + $j * 0x10;
119 my $block = substr($card, $offset, 0x10);
122 = ( ( $c1 & $mask ) * 4 )
123 + ( ( $c2 & $mask ) * 2 )
124 + ( ( $c3 & $mask ) * 1 )
128 printf "%04x %s %03b %s\n", $offset, unpack('H*',$block)
130 , $j < 3 ? $access_condition_data->{$cond} : $access_condition_trailer->{$cond}
135 printf "KEY A:%s | %s | B:%s\n"
136 ,unpack('H*',substr($card,$pos+0x30 ,6))
137 ,unpack('H*',substr($card,$pos+0x30+6 ,4))
138 ,unpack('H*',substr($card,$pos+0x30+10,6))
146 00 card administration
147 01-07 miscellaneous applications
155 21 multi modal transit
159 40 city card services
160 47-48 access control & security
162 4A Ministry of Defence, Netherlands
163 4B Bosch Telecom, Germany
164 4A Ministry of Defence, Netherlands
165 4C European Union Institutions
167 51-54 access control & security
175 80 administration services
186 C0 entertainment & sports
195 F8-FF miscellaneous applications
198 0001 sector is defect, e.g. access keys are destroyed or unknown
199 0002 sector is reserved
200 0003 sector contains additional directory info (useful only for future cards)
201 0004 sector contains card holder information in ASCII format.
202 0005 sector not applicable (above memory size)
204 0015 - card administration MIKROELEKTRONIKA spol.s.v.MIKROELEKTRONIKA spol.s.v.o. worldwide 1 01.02.2007 Card publisher info
205 0016 - card administration Mikroelektronika spol.s.r.o., Kpt.Mikroelektronika spol.s.r.o., Kpt. PoEurope 1 10.10.2007 Issuer information
207 071C - miscellaneous applications MIKROELEKTRONIKA spol.s.r. MIKROELEKTRONIKA spol.s.r.o., Europe 1 01.12.2008 Customer profile
208 071D - miscellaneous applications ZAGREBACKI Holding d.o.o. MIKROELEKTRONIKA spol.s.r.o. EUROPE,Croatia 1 01.04.2009 Customer profile
209 071E - miscellaneous applications ZAGREBACKI Holding d.o.o. MIKROELEKTRONIKA spol.s.r.o. EUROPE,Croatia 1 01.04.2009 Bonus counter
211 1835 - city traffic KORID LK, spol.s.r.o. KORID LK, spol.s.r.o. Europe 2 08.09.2008 Eticket
212 1836 - city traffic MIKROELEKTRONIKA spol.s.r. MIKROELEKTRONIKA spol.s.r.o., Europe 1 01.12.2008 Prepaid coupon 1S
213 1837 - city traffic ZAGREBACKI Holding d.o.o. MIKROELEKTRONIKA spol.s.r.o. EUROPE,Croatia 1 01.04.2009 Prepaid coupon
214 1838 - city traffic MIKROELEKTRONIKA spol.s.r. MIKROELEKTRONIKA spol.s.r.o. Europe 1 01.05.2009 Prepaid coupon
215 1839 - city traffic Mikroelektronika spol.s r.o Mikroelektronika spol.s r.o EUROPE,Czech R 1 01.08.2009 Prepaid coupon
216 183B - city traffic UNICARD S.A. UNICARD S.A. Poland 15 01.01.2010 city traffic services
218 2061 - bus services Mikroelektronika spol.s r.o. Mikroelektronika spol.s r.o. Europe 1 01.08.2008 Electronic ticket
219 2062 - bus services ZAGREBACKI Holding d.o.o. MIKROELEKTRONIKA spol.s.r.o EUROPE,Croatia 1 01.04.2009 Electronic tiicket
220 2063 - bus services MIKROELEKTRONIKA spol.s.r. MIKROELEKTRONIKA spol.s.r.o. Europe 3 01.05.2009 electronic ticket
222 887B - electronic purse ZAGREBACKI Holding d.o.o. MIKROELEKTRONIKA spol.s.r.o. EUROPE,Croatia 4 01.04.2009 Electronic purse
223 887C - electronic purse MIKROELEKTRONIKA spol.s.r. MIKROELEKTRONIKA spol.s.r.o. Europe 4 01.05.2009 electronic purse
224 887D - electronic purse Mikroelektronika spol.s r.o Mikroelektronika spol.s r.o EUROPE,Czech R 4 01.08.2009 Electronic purse