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