dd28516529eeca58303b04d481342160f9ac7729
[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         my $pos = 0x40 * $i;
56         foreach my $j ( 0 .. 3 ) {
57                 my $offset = $pos + $j * 0x10;
58                 my $block = substr($card, $offset, 0x10);
59                 printf "%04x %s\n", $offset, unpack('H*',$block);
60         }
61
62         if ( $v == 0x0004 ) {
63                 # RLE encoded card holder information
64                 my $data = substr( $card, $pos, 0x30);
65                 my $o = 0;
66                 my $types = {
67                         0b00 => 'surname',
68                         0b01 => 'given name',
69                         0b10 => 'sex',
70                         0b11 => 'any',
71                 };
72                 while ( substr($data,$o,1) ne "\x00" ) {
73                         my $len = ord(substr($data,$o,1));
74                         my $type = ( $len & 0b11000000 ) >> 6;
75                         $len     =   $len & 0b00111111;
76                         my $dump = substr($data,$o+1,$len-1);
77                         $dump = '0x' . unpack('H*', $dump) if $type == 0b11; # any
78                         printf "%-10s %2d %s\n", $types->{$type}, $len, $dump;
79                         $o += $len + 1;
80                 }
81         }
82
83         print "\n";
84
85 }
86
87 __DATA__
88 00    card administration
89 01-07 miscellaneous applications
90 08    airlines
91 09    ferry trafic
92 10    railway services
93 12    transport
94 18    city traffic
95 19    Czech Railways
96 20    bus services
97 21    multi modal transit
98 28    taxi
99 30    road toll
100 38    company services
101 40    city card services
102 47-48 access control & security
103 49    VIGIK
104 4A    Ministry of Defence, Netherlands
105 4B    Bosch Telecom, Germany
106 4A    Ministry of Defence, Netherlands
107 4C    European Union Institutions
108 50    ski ticketing
109 51-54 access control & security
110 58    academic services
111 60    food
112 68    non food trade
113 70    hotel
114 75    airport services
115 78    car rental
116 79    Dutch government
117 80    administration services
118 88    electronic purse
119 90    television
120 91    cruise ship
121 95    IOPTA
122 97    Metering
123 98    telephone
124 A0    health services
125 A8    warehouse
126 B0    electronic trade
127 B8    banking
128 C0    entertainment & sports
129 C8    car parking
130 C9    Fleet Management
131 D0    fuel, gasoline
132 D8    info services
133 E0    press
134 E1    NFC Forum
135 E8    computer
136 F0    mail
137 F8-FF miscellaneous applications
138
139 0000    sector free
140 0001    sector defective
141 0002    sector reserved
142 0003    DIR continuted
143 0004    card holder
144
145 0015 - card administration MIKROELEKTRONIKA spol.s.v.MIKROELEKTRONIKA spol.s.v.o. worldwide 1 01.02.2007 Card publisher info
146 0016 - card administration Mikroelektronika spol.s.r.o., Kpt.Mikroelektronika spol.s.r.o., Kpt. PoEurope    1 10.10.2007 Issuer information
147
148 071C - miscellaneous applications MIKROELEKTRONIKA spol.s.r. MIKROELEKTRONIKA spol.s.r.o., Europe       1 01.12.2008 Customer profile
149 071D - miscellaneous applications ZAGREBACKI Holding d.o.o. MIKROELEKTRONIKA spol.s.r.o. EUROPE,Croatia 1 01.04.2009 Customer profile
150 071E - miscellaneous applications ZAGREBACKI Holding d.o.o. MIKROELEKTRONIKA spol.s.r.o. EUROPE,Croatia 1 01.04.2009 Bonus counter
151
152 1835 - city traffic KORID LK, spol.s.r.o.       KORID LK, spol.s.r.o.        Europe         2 08.09.2008 Eticket
153 1836 - city traffic MIKROELEKTRONIKA spol.s.r. MIKROELEKTRONIKA spol.s.r.o., Europe         1 01.12.2008 Prepaid coupon 1S
154 1837 - city traffic ZAGREBACKI Holding d.o.o. MIKROELEKTRONIKA spol.s.r.o.   EUROPE,Croatia 1 01.04.2009 Prepaid coupon
155 1838 - city traffic MIKROELEKTRONIKA spol.s.r. MIKROELEKTRONIKA spol.s.r.o.  Europe         1 01.05.2009 Prepaid coupon
156 1839 - city traffic Mikroelektronika spol.s r.o Mikroelektronika spol.s r.o  EUROPE,Czech R 1 01.08.2009 Prepaid coupon
157 183B - city traffic UNICARD S.A.                UNICARD S.A.                 Poland        15 01.01.2010 city traffic services
158
159 2061 - bus services Mikroelektronika spol.s r.o. Mikroelektronika spol.s r.o. Europe     1 01.08.2008 Electronic ticket
160 2062 - bus services ZAGREBACKI Holding d.o.o. MIKROELEKTRONIKA spol.s.r.o EUROPE,Croatia 1 01.04.2009 Electronic tiicket
161 2063 - bus services MIKROELEKTRONIKA spol.s.r. MIKROELEKTRONIKA spol.s.r.o. Europe       3 01.05.2009 electronic ticket
162
163 887B - electronic purse ZAGREBACKI Holding d.o.o. MIKROELEKTRONIKA spol.s.r.o. EUROPE,Croatia  4 01.04.2009 Electronic purse
164 887C - electronic purse MIKROELEKTRONIKA spol.s.r. MIKROELEKTRONIKA spol.s.r.o. Europe         4 01.05.2009 electronic purse
165 887D - electronic purse Mikroelektronika spol.s r.o Mikroelektronika spol.s r.o EUROPE,Czech R 4 01.08.2009 Electronic purse
166