much nicer dump of MAD and data
[perl-Mifare-MAD.git] / mifare-mad.pl
1 #!/usr/bin/perl
2
3 use warnings;
4 use strict;
5
6 # based on AN10787
7 # MIFARE Application Directory (MAD)
8 # http://www.nxp.com/acrobat_download2/other/identification/MAD_overview.pdf
9
10 use Data::Dump qw(dump);
11
12 my $debug = $ENV{DEBUG} || 0;
13
14 my $function_clusters;
15 my $mad_id;
16
17 while(<DATA>) {
18         chomp;
19         next if m/^#?\s*$/;
20         my ( $code, $function ) = split(/\s+/,$_,2);
21         my $h = '[0-9A-F]';
22         if ( $code =~ m/^($h{2})-($h{2})$/ ) {
23                 foreach my $c ( hex($1) .. hex($2) ) {
24                         $function_clusters->{ unpack('HH',$c) } = $function;
25                 }
26         } elsif ( $code =~ m/^($h{2})$/ ) {
27                 $function_clusters->{ lc $code } = $function;
28         } elsif ( $code =~ m/^($h{4})$/ ) {
29                 $mad_id->{ lc $1 } = $function;
30         } else {
31                 die "can't parse __DATA__ line $.\n$_\n";
32         }
33 }
34
35 if ( $debug ) {
36         warn "# function_clusters ",dump($function_clusters);
37         warn "# mad_id ", dump($mad_id);
38 }
39
40 local $/ = undef;
41 my $card = <>;
42
43 die "expected 4096 bytes, got ",length($card), " bytes\n"
44         unless length $card == 4096;
45
46 foreach my $i ( 0 .. 15 ) {
47         my $v = unpack('v',(substr($card, 0x10 + ( $i * 2 ), 2)));
48         my $cluster_id = unpack('HH', (( $v & 0xff00 ) >> 8) );
49         my $full_id = sprintf "%04x",$v;
50         printf "MAD sector %-2d %04x [%s]\n%s\n", $i, $v
51                 , $function_clusters->{ $cluster_id }
52                 , $mad_id->{$full_id} || "FIXME: add $full_id from MAD_overview.pdf to __DATA__ at end of $0"
53                 ;
54
55         foreach my $j ( 0 .. 3 ) {
56                 my $offset = 0x40 * $i + $j * 0x10;
57                 my $block = substr($card, $offset, 0x10);
58                 printf "%04x %s\n", $offset, unpack('H*',$block);
59         }
60
61         if ( $v == 0x0004 ) {
62                 # RLE encoded card holder information
63                 my $data = substr( $card, 0x40 * $i, 0x30);
64                 my $o = 0;
65                 my $types = {
66                         0b00 => 'surname',
67                         0b01 => 'given name',
68                         0b10 => 'sex',
69                         0b11 => 'any',
70                 };
71                 while ( substr($data,$o,1) ne "\x00" ) {
72                         my $len = ord(substr($data,$o,1));
73                         my $type = ( $len & 0b11000000 ) >> 6;
74                         $len     =   $len & 0b00111111;
75                         my $dump = substr($data,$o+1,$len-1);
76                         $dump = '0x' . unpack('H*', $dump) if $type == 0b11; # any
77                         printf "%-10s %2d %s\n", $types->{$type}, $len, $dump;
78                         $o += $len + 1;
79                 }
80         }
81
82         print "\n";
83
84 }
85
86 __DATA__
87 00    card administration
88 01-07 miscellaneous applications
89 08    airlines
90 09    ferry trafic
91 10    railway services
92 12    transport
93 18    city traffic
94 19    Czech Railways
95 20    bus services
96 21    multi modal transit
97 28    taxi
98 30    road toll
99 38    company services
100 40    city card services
101 47-48 access control & security
102 49    VIGIK
103 4A    Ministry of Defence, Netherlands
104 4B    Bosch Telecom, Germany
105 4A    Ministry of Defence, Netherlands
106 4C    European Union Institutions
107 50    ski ticketing
108 51-54 access control & security
109 58    academic services
110 60    food
111 68    non food trade
112 70    hotel
113 75    airport services
114 78    car rental
115 79    Dutch government
116 80    administration services
117 88    electronic purse
118 90    television
119 91    cruise ship
120 95    IOPTA
121 97    Metering
122 98    telephone
123 A0    health services
124 A8    warehouse
125 B0    electronic trade
126 B8    banking
127 C0    entertainment & sports
128 C8    car parking
129 C9    Fleet Management
130 D0    fuel, gasoline
131 D8    info services
132 E0    press
133 E1    NFC Forum
134 E8    computer
135 F0    mail
136 F8-FF miscellaneous applications
137
138 0000    sector free
139 0001    sector defective
140 0002    sector reserved
141 0003    DIR continuted
142 0004    card holder
143
144 0015 - card administration MIKROELEKTRONIKA spol.s.v.MIKROELEKTRONIKA spol.s.v.o. worldwide 1 01.02.2007 Card publisher info
145 0016 - card administration Mikroelektronika spol.s.r.o., Kpt.Mikroelektronika spol.s.r.o., Kpt. PoEurope    1 10.10.2007 Issuer information
146
147 071C - miscellaneous applications MIKROELEKTRONIKA spol.s.r. MIKROELEKTRONIKA spol.s.r.o., Europe       1 01.12.2008 Customer profile
148 071D - miscellaneous applications ZAGREBACKI Holding d.o.o. MIKROELEKTRONIKA spol.s.r.o. EUROPE,Croatia 1 01.04.2009 Customer profile
149 071E - miscellaneous applications ZAGREBACKI Holding d.o.o. MIKROELEKTRONIKA spol.s.r.o. EUROPE,Croatia 1 01.04.2009 Bonus counter
150
151 1835 - city traffic KORID LK, spol.s.r.o.       KORID LK, spol.s.r.o.        Europe         2 08.09.2008 Eticket
152 1836 - city traffic MIKROELEKTRONIKA spol.s.r. MIKROELEKTRONIKA spol.s.r.o., Europe         1 01.12.2008 Prepaid coupon 1S
153 1837 - city traffic ZAGREBACKI Holding d.o.o. MIKROELEKTRONIKA spol.s.r.o.   EUROPE,Croatia 1 01.04.2009 Prepaid coupon
154 1838 - city traffic MIKROELEKTRONIKA spol.s.r. MIKROELEKTRONIKA spol.s.r.o.  Europe         1 01.05.2009 Prepaid coupon
155 1839 - city traffic Mikroelektronika spol.s r.o Mikroelektronika spol.s r.o  EUROPE,Czech R 1 01.08.2009 Prepaid coupon
156 183B - city traffic UNICARD S.A.                UNICARD S.A.                 Poland        15 01.01.2010 city traffic services
157
158 2061 - bus services Mikroelektronika spol.s r.o. Mikroelektronika spol.s r.o. Europe     1 01.08.2008 Electronic ticket
159 2062 - bus services ZAGREBACKI Holding d.o.o. MIKROELEKTRONIKA spol.s.r.o EUROPE,Croatia 1 01.04.2009 Electronic tiicket
160 2063 - bus services MIKROELEKTRONIKA spol.s.r. MIKROELEKTRONIKA spol.s.r.o. Europe       3 01.05.2009 electronic ticket
161
162 887B - electronic purse ZAGREBACKI Holding d.o.o. MIKROELEKTRONIKA spol.s.r.o. EUROPE,Croatia  4 01.04.2009 Electronic purse
163 887C - electronic purse MIKROELEKTRONIKA spol.s.r. MIKROELEKTRONIKA spol.s.r.o. Europe         4 01.05.2009 electronic purse
164 887D - electronic purse Mikroelektronika spol.s r.o Mikroelektronika spol.s r.o EUROPE,Czech R 4 01.08.2009 Electronic purse
165