Browse Source

init

master
Robin Thoni 9 years ago
commit
16faebfce6

+ 7
- 0
AUTHORS View File

@@ -0,0 +1,7 @@
1
+= Author
2
+Andrei Costin <zveriu@gmail.com>, http://andreicostin.com
3
+
4
+= Contributors
5
+
6
+Romuald Conty <romuald@libnfc.org> - porting to libnfc 1.3.x, 1.4.x, 1.5.x
7
+Nethemba Core Team	<mifare@nethemba.com> - core AC, AM, configure and packaging

+ 339
- 0
COPYING View File

@@ -0,0 +1,339 @@
1
+		    GNU GENERAL PUBLIC LICENSE
2
+		       Version 2, June 1991
3
+
4
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
5
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6
+ Everyone is permitted to copy and distribute verbatim copies
7
+ of this license document, but changing it is not allowed.
8
+
9
+			    Preamble
10
+
11
+  The licenses for most software are designed to take away your
12
+freedom to share and change it.  By contrast, the GNU General Public
13
+License is intended to guarantee your freedom to share and change free
14
+software--to make sure the software is free for all its users.  This
15
+General Public License applies to most of the Free Software
16
+Foundation's software and to any other program whose authors commit to
17
+using it.  (Some other Free Software Foundation software is covered by
18
+the GNU Lesser General Public License instead.)  You can apply it to
19
+your programs, too.
20
+
21
+  When we speak of free software, we are referring to freedom, not
22
+price.  Our General Public Licenses are designed to make sure that you
23
+have the freedom to distribute copies of free software (and charge for
24
+this service if you wish), that you receive source code or can get it
25
+if you want it, that you can change the software or use pieces of it
26
+in new free programs; and that you know you can do these things.
27
+
28
+  To protect your rights, we need to make restrictions that forbid
29
+anyone to deny you these rights or to ask you to surrender the rights.
30
+These restrictions translate to certain responsibilities for you if you
31
+distribute copies of the software, or if you modify it.
32
+
33
+  For example, if you distribute copies of such a program, whether
34
+gratis or for a fee, you must give the recipients all the rights that
35
+you have.  You must make sure that they, too, receive or can get the
36
+source code.  And you must show them these terms so they know their
37
+rights.
38
+
39
+  We protect your rights with two steps: (1) copyright the software, and
40
+(2) offer you this license which gives you legal permission to copy,
41
+distribute and/or modify the software.
42
+
43
+  Also, for each author's protection and ours, we want to make certain
44
+that everyone understands that there is no warranty for this free
45
+software.  If the software is modified by someone else and passed on, we
46
+want its recipients to know that what they have is not the original, so
47
+that any problems introduced by others will not reflect on the original
48
+authors' reputations.
49
+
50
+  Finally, any free program is threatened constantly by software
51
+patents.  We wish to avoid the danger that redistributors of a free
52
+program will individually obtain patent licenses, in effect making the
53
+program proprietary.  To prevent this, we have made it clear that any
54
+patent must be licensed for everyone's free use or not licensed at all.
55
+
56
+  The precise terms and conditions for copying, distribution and
57
+modification follow.
58
+
59
+		    GNU GENERAL PUBLIC LICENSE
60
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
61
+
62
+  0. This License applies to any program or other work which contains
63
+a notice placed by the copyright holder saying it may be distributed
64
+under the terms of this General Public License.  The "Program", below,
65
+refers to any such program or work, and a "work based on the Program"
66
+means either the Program or any derivative work under copyright law:
67
+that is to say, a work containing the Program or a portion of it,
68
+either verbatim or with modifications and/or translated into another
69
+language.  (Hereinafter, translation is included without limitation in
70
+the term "modification".)  Each licensee is addressed as "you".
71
+
72
+Activities other than copying, distribution and modification are not
73
+covered by this License; they are outside its scope.  The act of
74
+running the Program is not restricted, and the output from the Program
75
+is covered only if its contents constitute a work based on the
76
+Program (independent of having been made by running the Program).
77
+Whether that is true depends on what the Program does.
78
+
79
+  1. You may copy and distribute verbatim copies of the Program's
80
+source code as you receive it, in any medium, provided that you
81
+conspicuously and appropriately publish on each copy an appropriate
82
+copyright notice and disclaimer of warranty; keep intact all the
83
+notices that refer to this License and to the absence of any warranty;
84
+and give any other recipients of the Program a copy of this License
85
+along with the Program.
86
+
87
+You may charge a fee for the physical act of transferring a copy, and
88
+you may at your option offer warranty protection in exchange for a fee.
89
+
90
+  2. You may modify your copy or copies of the Program or any portion
91
+of it, thus forming a work based on the Program, and copy and
92
+distribute such modifications or work under the terms of Section 1
93
+above, provided that you also meet all of these conditions:
94
+
95
+    a) You must cause the modified files to carry prominent notices
96
+    stating that you changed the files and the date of any change.
97
+
98
+    b) You must cause any work that you distribute or publish, that in
99
+    whole or in part contains or is derived from the Program or any
100
+    part thereof, to be licensed as a whole at no charge to all third
101
+    parties under the terms of this License.
102
+
103
+    c) If the modified program normally reads commands interactively
104
+    when run, you must cause it, when started running for such
105
+    interactive use in the most ordinary way, to print or display an
106
+    announcement including an appropriate copyright notice and a
107
+    notice that there is no warranty (or else, saying that you provide
108
+    a warranty) and that users may redistribute the program under
109
+    these conditions, and telling the user how to view a copy of this
110
+    License.  (Exception: if the Program itself is interactive but
111
+    does not normally print such an announcement, your work based on
112
+    the Program is not required to print an announcement.)
113
+
114
+These requirements apply to the modified work as a whole.  If
115
+identifiable sections of that work are not derived from the Program,
116
+and can be reasonably considered independent and separate works in
117
+themselves, then this License, and its terms, do not apply to those
118
+sections when you distribute them as separate works.  But when you
119
+distribute the same sections as part of a whole which is a work based
120
+on the Program, the distribution of the whole must be on the terms of
121
+this License, whose permissions for other licensees extend to the
122
+entire whole, and thus to each and every part regardless of who wrote it.
123
+
124
+Thus, it is not the intent of this section to claim rights or contest
125
+your rights to work written entirely by you; rather, the intent is to
126
+exercise the right to control the distribution of derivative or
127
+collective works based on the Program.
128
+
129
+In addition, mere aggregation of another work not based on the Program
130
+with the Program (or with a work based on the Program) on a volume of
131
+a storage or distribution medium does not bring the other work under
132
+the scope of this License.
133
+
134
+  3. You may copy and distribute the Program (or a work based on it,
135
+under Section 2) in object code or executable form under the terms of
136
+Sections 1 and 2 above provided that you also do one of the following:
137
+
138
+    a) Accompany it with the complete corresponding machine-readable
139
+    source code, which must be distributed under the terms of Sections
140
+    1 and 2 above on a medium customarily used for software interchange; or,
141
+
142
+    b) Accompany it with a written offer, valid for at least three
143
+    years, to give any third party, for a charge no more than your
144
+    cost of physically performing source distribution, a complete
145
+    machine-readable copy of the corresponding source code, to be
146
+    distributed under the terms of Sections 1 and 2 above on a medium
147
+    customarily used for software interchange; or,
148
+
149
+    c) Accompany it with the information you received as to the offer
150
+    to distribute corresponding source code.  (This alternative is
151
+    allowed only for noncommercial distribution and only if you
152
+    received the program in object code or executable form with such
153
+    an offer, in accord with Subsection b above.)
154
+
155
+The source code for a work means the preferred form of the work for
156
+making modifications to it.  For an executable work, complete source
157
+code means all the source code for all modules it contains, plus any
158
+associated interface definition files, plus the scripts used to
159
+control compilation and installation of the executable.  However, as a
160
+special exception, the source code distributed need not include
161
+anything that is normally distributed (in either source or binary
162
+form) with the major components (compiler, kernel, and so on) of the
163
+operating system on which the executable runs, unless that component
164
+itself accompanies the executable.
165
+
166
+If distribution of executable or object code is made by offering
167
+access to copy from a designated place, then offering equivalent
168
+access to copy the source code from the same place counts as
169
+distribution of the source code, even though third parties are not
170
+compelled to copy the source along with the object code.
171
+
172
+  4. You may not copy, modify, sublicense, or distribute the Program
173
+except as expressly provided under this License.  Any attempt
174
+otherwise to copy, modify, sublicense or distribute the Program is
175
+void, and will automatically terminate your rights under this License.
176
+However, parties who have received copies, or rights, from you under
177
+this License will not have their licenses terminated so long as such
178
+parties remain in full compliance.
179
+
180
+  5. You are not required to accept this License, since you have not
181
+signed it.  However, nothing else grants you permission to modify or
182
+distribute the Program or its derivative works.  These actions are
183
+prohibited by law if you do not accept this License.  Therefore, by
184
+modifying or distributing the Program (or any work based on the
185
+Program), you indicate your acceptance of this License to do so, and
186
+all its terms and conditions for copying, distributing or modifying
187
+the Program or works based on it.
188
+
189
+  6. Each time you redistribute the Program (or any work based on the
190
+Program), the recipient automatically receives a license from the
191
+original licensor to copy, distribute or modify the Program subject to
192
+these terms and conditions.  You may not impose any further
193
+restrictions on the recipients' exercise of the rights granted herein.
194
+You are not responsible for enforcing compliance by third parties to
195
+this License.
196
+
197
+  7. If, as a consequence of a court judgment or allegation of patent
198
+infringement or for any other reason (not limited to patent issues),
199
+conditions are imposed on you (whether by court order, agreement or
200
+otherwise) that contradict the conditions of this License, they do not
201
+excuse you from the conditions of this License.  If you cannot
202
+distribute so as to satisfy simultaneously your obligations under this
203
+License and any other pertinent obligations, then as a consequence you
204
+may not distribute the Program at all.  For example, if a patent
205
+license would not permit royalty-free redistribution of the Program by
206
+all those who receive copies directly or indirectly through you, then
207
+the only way you could satisfy both it and this License would be to
208
+refrain entirely from distribution of the Program.
209
+
210
+If any portion of this section is held invalid or unenforceable under
211
+any particular circumstance, the balance of the section is intended to
212
+apply and the section as a whole is intended to apply in other
213
+circumstances.
214
+
215
+It is not the purpose of this section to induce you to infringe any
216
+patents or other property right claims or to contest validity of any
217
+such claims; this section has the sole purpose of protecting the
218
+integrity of the free software distribution system, which is
219
+implemented by public license practices.  Many people have made
220
+generous contributions to the wide range of software distributed
221
+through that system in reliance on consistent application of that
222
+system; it is up to the author/donor to decide if he or she is willing
223
+to distribute software through any other system and a licensee cannot
224
+impose that choice.
225
+
226
+This section is intended to make thoroughly clear what is believed to
227
+be a consequence of the rest of this License.
228
+
229
+  8. If the distribution and/or use of the Program is restricted in
230
+certain countries either by patents or by copyrighted interfaces, the
231
+original copyright holder who places the Program under this License
232
+may add an explicit geographical distribution limitation excluding
233
+those countries, so that distribution is permitted only in or among
234
+countries not thus excluded.  In such case, this License incorporates
235
+the limitation as if written in the body of this License.
236
+
237
+  9. The Free Software Foundation may publish revised and/or new versions
238
+of the General Public License from time to time.  Such new versions will
239
+be similar in spirit to the present version, but may differ in detail to
240
+address new problems or concerns.
241
+
242
+Each version is given a distinguishing version number.  If the Program
243
+specifies a version number of this License which applies to it and "any
244
+later version", you have the option of following the terms and conditions
245
+either of that version or of any later version published by the Free
246
+Software Foundation.  If the Program does not specify a version number of
247
+this License, you may choose any version ever published by the Free Software
248
+Foundation.
249
+
250
+  10. If you wish to incorporate parts of the Program into other free
251
+programs whose distribution conditions are different, write to the author
252
+to ask for permission.  For software which is copyrighted by the Free
253
+Software Foundation, write to the Free Software Foundation; we sometimes
254
+make exceptions for this.  Our decision will be guided by the two goals
255
+of preserving the free status of all derivatives of our free software and
256
+of promoting the sharing and reuse of software generally.
257
+
258
+			    NO WARRANTY
259
+
260
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
261
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
262
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
263
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
264
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
265
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
266
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
267
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
268
+REPAIR OR CORRECTION.
269
+
270
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
271
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
272
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
273
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
274
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
275
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
276
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
277
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
278
+POSSIBILITY OF SUCH DAMAGES.
279
+
280
+		     END OF TERMS AND CONDITIONS
281
+
282
+	    How to Apply These Terms to Your New Programs
283
+
284
+  If you develop a new program, and you want it to be of the greatest
285
+possible use to the public, the best way to achieve this is to make it
286
+free software which everyone can redistribute and change under these terms.
287
+
288
+  To do so, attach the following notices to the program.  It is safest
289
+to attach them to the start of each source file to most effectively
290
+convey the exclusion of warranty; and each file should have at least
291
+the "copyright" line and a pointer to where the full notice is found.
292
+
293
+    <one line to give the program's name and a brief idea of what it does.>
294
+    Copyright (C) <year>  <name of author>
295
+
296
+    This program is free software; you can redistribute it and/or modify
297
+    it under the terms of the GNU General Public License as published by
298
+    the Free Software Foundation; either version 2 of the License, or
299
+    (at your option) any later version.
300
+
301
+    This program is distributed in the hope that it will be useful,
302
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
303
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
304
+    GNU General Public License for more details.
305
+
306
+    You should have received a copy of the GNU General Public License along
307
+    with this program; if not, write to the Free Software Foundation, Inc.,
308
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
309
+
310
+Also add information on how to contact you by electronic and paper mail.
311
+
312
+If the program is interactive, make it output a short notice like this
313
+when it starts in an interactive mode:
314
+
315
+    Gnomovision version 69, Copyright (C) year name of author
316
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
317
+    This is free software, and you are welcome to redistribute it
318
+    under certain conditions; type `show c' for details.
319
+
320
+The hypothetical commands `show w' and `show c' should show the appropriate
321
+parts of the General Public License.  Of course, the commands you use may
322
+be called something other than `show w' and `show c'; they could even be
323
+mouse-clicks or menu items--whatever suits your program.
324
+
325
+You should also get your employer (if you work as a programmer) or your
326
+school, if any, to sign a "copyright disclaimer" for the program, if
327
+necessary.  Here is a sample; alter the names:
328
+
329
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
330
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
331
+
332
+  <signature of Ty Coon>, 1 April 1989
333
+  Ty Coon, President of Vice
334
+
335
+This General Public License does not permit incorporating your program into
336
+proprietary programs.  If your program is a subroutine library, you may
337
+consider it more useful to permit linking proprietary applications with the
338
+library.  If this is what you want to do, use the GNU Lesser General
339
+Public License instead of this License.

+ 0
- 0
ChangeLog View File


+ 5
- 0
INSTALL View File

@@ -0,0 +1,5 @@
1
+If you use a development version (SVN), you have to run:
2
+autoreconf -is
3
+./configure
4
+make
5
+

+ 339
- 0
LICENSE View File

@@ -0,0 +1,339 @@
1
+		    GNU GENERAL PUBLIC LICENSE
2
+		       Version 2, June 1991
3
+
4
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
5
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6
+ Everyone is permitted to copy and distribute verbatim copies
7
+ of this license document, but changing it is not allowed.
8
+
9
+			    Preamble
10
+
11
+  The licenses for most software are designed to take away your
12
+freedom to share and change it.  By contrast, the GNU General Public
13
+License is intended to guarantee your freedom to share and change free
14
+software--to make sure the software is free for all its users.  This
15
+General Public License applies to most of the Free Software
16
+Foundation's software and to any other program whose authors commit to
17
+using it.  (Some other Free Software Foundation software is covered by
18
+the GNU Lesser General Public License instead.)  You can apply it to
19
+your programs, too.
20
+
21
+  When we speak of free software, we are referring to freedom, not
22
+price.  Our General Public Licenses are designed to make sure that you
23
+have the freedom to distribute copies of free software (and charge for
24
+this service if you wish), that you receive source code or can get it
25
+if you want it, that you can change the software or use pieces of it
26
+in new free programs; and that you know you can do these things.
27
+
28
+  To protect your rights, we need to make restrictions that forbid
29
+anyone to deny you these rights or to ask you to surrender the rights.
30
+These restrictions translate to certain responsibilities for you if you
31
+distribute copies of the software, or if you modify it.
32
+
33
+  For example, if you distribute copies of such a program, whether
34
+gratis or for a fee, you must give the recipients all the rights that
35
+you have.  You must make sure that they, too, receive or can get the
36
+source code.  And you must show them these terms so they know their
37
+rights.
38
+
39
+  We protect your rights with two steps: (1) copyright the software, and
40
+(2) offer you this license which gives you legal permission to copy,
41
+distribute and/or modify the software.
42
+
43
+  Also, for each author's protection and ours, we want to make certain
44
+that everyone understands that there is no warranty for this free
45
+software.  If the software is modified by someone else and passed on, we
46
+want its recipients to know that what they have is not the original, so
47
+that any problems introduced by others will not reflect on the original
48
+authors' reputations.
49
+
50
+  Finally, any free program is threatened constantly by software
51
+patents.  We wish to avoid the danger that redistributors of a free
52
+program will individually obtain patent licenses, in effect making the
53
+program proprietary.  To prevent this, we have made it clear that any
54
+patent must be licensed for everyone's free use or not licensed at all.
55
+
56
+  The precise terms and conditions for copying, distribution and
57
+modification follow.
58
+
59
+		    GNU GENERAL PUBLIC LICENSE
60
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
61
+
62
+  0. This License applies to any program or other work which contains
63
+a notice placed by the copyright holder saying it may be distributed
64
+under the terms of this General Public License.  The "Program", below,
65
+refers to any such program or work, and a "work based on the Program"
66
+means either the Program or any derivative work under copyright law:
67
+that is to say, a work containing the Program or a portion of it,
68
+either verbatim or with modifications and/or translated into another
69
+language.  (Hereinafter, translation is included without limitation in
70
+the term "modification".)  Each licensee is addressed as "you".
71
+
72
+Activities other than copying, distribution and modification are not
73
+covered by this License; they are outside its scope.  The act of
74
+running the Program is not restricted, and the output from the Program
75
+is covered only if its contents constitute a work based on the
76
+Program (independent of having been made by running the Program).
77
+Whether that is true depends on what the Program does.
78
+
79
+  1. You may copy and distribute verbatim copies of the Program's
80
+source code as you receive it, in any medium, provided that you
81
+conspicuously and appropriately publish on each copy an appropriate
82
+copyright notice and disclaimer of warranty; keep intact all the
83
+notices that refer to this License and to the absence of any warranty;
84
+and give any other recipients of the Program a copy of this License
85
+along with the Program.
86
+
87
+You may charge a fee for the physical act of transferring a copy, and
88
+you may at your option offer warranty protection in exchange for a fee.
89
+
90
+  2. You may modify your copy or copies of the Program or any portion
91
+of it, thus forming a work based on the Program, and copy and
92
+distribute such modifications or work under the terms of Section 1
93
+above, provided that you also meet all of these conditions:
94
+
95
+    a) You must cause the modified files to carry prominent notices
96
+    stating that you changed the files and the date of any change.
97
+
98
+    b) You must cause any work that you distribute or publish, that in
99
+    whole or in part contains or is derived from the Program or any
100
+    part thereof, to be licensed as a whole at no charge to all third
101
+    parties under the terms of this License.
102
+
103
+    c) If the modified program normally reads commands interactively
104
+    when run, you must cause it, when started running for such
105
+    interactive use in the most ordinary way, to print or display an
106
+    announcement including an appropriate copyright notice and a
107
+    notice that there is no warranty (or else, saying that you provide
108
+    a warranty) and that users may redistribute the program under
109
+    these conditions, and telling the user how to view a copy of this
110
+    License.  (Exception: if the Program itself is interactive but
111
+    does not normally print such an announcement, your work based on
112
+    the Program is not required to print an announcement.)
113
+
114
+These requirements apply to the modified work as a whole.  If
115
+identifiable sections of that work are not derived from the Program,
116
+and can be reasonably considered independent and separate works in
117
+themselves, then this License, and its terms, do not apply to those
118
+sections when you distribute them as separate works.  But when you
119
+distribute the same sections as part of a whole which is a work based
120
+on the Program, the distribution of the whole must be on the terms of
121
+this License, whose permissions for other licensees extend to the
122
+entire whole, and thus to each and every part regardless of who wrote it.
123
+
124
+Thus, it is not the intent of this section to claim rights or contest
125
+your rights to work written entirely by you; rather, the intent is to
126
+exercise the right to control the distribution of derivative or
127
+collective works based on the Program.
128
+
129
+In addition, mere aggregation of another work not based on the Program
130
+with the Program (or with a work based on the Program) on a volume of
131
+a storage or distribution medium does not bring the other work under
132
+the scope of this License.
133
+
134
+  3. You may copy and distribute the Program (or a work based on it,
135
+under Section 2) in object code or executable form under the terms of
136
+Sections 1 and 2 above provided that you also do one of the following:
137
+
138
+    a) Accompany it with the complete corresponding machine-readable
139
+    source code, which must be distributed under the terms of Sections
140
+    1 and 2 above on a medium customarily used for software interchange; or,
141
+
142
+    b) Accompany it with a written offer, valid for at least three
143
+    years, to give any third party, for a charge no more than your
144
+    cost of physically performing source distribution, a complete
145
+    machine-readable copy of the corresponding source code, to be
146
+    distributed under the terms of Sections 1 and 2 above on a medium
147
+    customarily used for software interchange; or,
148
+
149
+    c) Accompany it with the information you received as to the offer
150
+    to distribute corresponding source code.  (This alternative is
151
+    allowed only for noncommercial distribution and only if you
152
+    received the program in object code or executable form with such
153
+    an offer, in accord with Subsection b above.)
154
+
155
+The source code for a work means the preferred form of the work for
156
+making modifications to it.  For an executable work, complete source
157
+code means all the source code for all modules it contains, plus any
158
+associated interface definition files, plus the scripts used to
159
+control compilation and installation of the executable.  However, as a
160
+special exception, the source code distributed need not include
161
+anything that is normally distributed (in either source or binary
162
+form) with the major components (compiler, kernel, and so on) of the
163
+operating system on which the executable runs, unless that component
164
+itself accompanies the executable.
165
+
166
+If distribution of executable or object code is made by offering
167
+access to copy from a designated place, then offering equivalent
168
+access to copy the source code from the same place counts as
169
+distribution of the source code, even though third parties are not
170
+compelled to copy the source along with the object code.
171
+
172
+  4. You may not copy, modify, sublicense, or distribute the Program
173
+except as expressly provided under this License.  Any attempt
174
+otherwise to copy, modify, sublicense or distribute the Program is
175
+void, and will automatically terminate your rights under this License.
176
+However, parties who have received copies, or rights, from you under
177
+this License will not have their licenses terminated so long as such
178
+parties remain in full compliance.
179
+
180
+  5. You are not required to accept this License, since you have not
181
+signed it.  However, nothing else grants you permission to modify or
182
+distribute the Program or its derivative works.  These actions are
183
+prohibited by law if you do not accept this License.  Therefore, by
184
+modifying or distributing the Program (or any work based on the
185
+Program), you indicate your acceptance of this License to do so, and
186
+all its terms and conditions for copying, distributing or modifying
187
+the Program or works based on it.
188
+
189
+  6. Each time you redistribute the Program (or any work based on the
190
+Program), the recipient automatically receives a license from the
191
+original licensor to copy, distribute or modify the Program subject to
192
+these terms and conditions.  You may not impose any further
193
+restrictions on the recipients' exercise of the rights granted herein.
194
+You are not responsible for enforcing compliance by third parties to
195
+this License.
196
+
197
+  7. If, as a consequence of a court judgment or allegation of patent
198
+infringement or for any other reason (not limited to patent issues),
199
+conditions are imposed on you (whether by court order, agreement or
200
+otherwise) that contradict the conditions of this License, they do not
201
+excuse you from the conditions of this License.  If you cannot
202
+distribute so as to satisfy simultaneously your obligations under this
203
+License and any other pertinent obligations, then as a consequence you
204
+may not distribute the Program at all.  For example, if a patent
205
+license would not permit royalty-free redistribution of the Program by
206
+all those who receive copies directly or indirectly through you, then
207
+the only way you could satisfy both it and this License would be to
208
+refrain entirely from distribution of the Program.
209
+
210
+If any portion of this section is held invalid or unenforceable under
211
+any particular circumstance, the balance of the section is intended to
212
+apply and the section as a whole is intended to apply in other
213
+circumstances.
214
+
215
+It is not the purpose of this section to induce you to infringe any
216
+patents or other property right claims or to contest validity of any
217
+such claims; this section has the sole purpose of protecting the
218
+integrity of the free software distribution system, which is
219
+implemented by public license practices.  Many people have made
220
+generous contributions to the wide range of software distributed
221
+through that system in reliance on consistent application of that
222
+system; it is up to the author/donor to decide if he or she is willing
223
+to distribute software through any other system and a licensee cannot
224
+impose that choice.
225
+
226
+This section is intended to make thoroughly clear what is believed to
227
+be a consequence of the rest of this License.
228
+
229
+  8. If the distribution and/or use of the Program is restricted in
230
+certain countries either by patents or by copyrighted interfaces, the
231
+original copyright holder who places the Program under this License
232
+may add an explicit geographical distribution limitation excluding
233
+those countries, so that distribution is permitted only in or among
234
+countries not thus excluded.  In such case, this License incorporates
235
+the limitation as if written in the body of this License.
236
+
237
+  9. The Free Software Foundation may publish revised and/or new versions
238
+of the General Public License from time to time.  Such new versions will
239
+be similar in spirit to the present version, but may differ in detail to
240
+address new problems or concerns.
241
+
242
+Each version is given a distinguishing version number.  If the Program
243
+specifies a version number of this License which applies to it and "any
244
+later version", you have the option of following the terms and conditions
245
+either of that version or of any later version published by the Free
246
+Software Foundation.  If the Program does not specify a version number of
247
+this License, you may choose any version ever published by the Free Software
248
+Foundation.
249
+
250
+  10. If you wish to incorporate parts of the Program into other free
251
+programs whose distribution conditions are different, write to the author
252
+to ask for permission.  For software which is copyrighted by the Free
253
+Software Foundation, write to the Free Software Foundation; we sometimes
254
+make exceptions for this.  Our decision will be guided by the two goals
255
+of preserving the free status of all derivatives of our free software and
256
+of promoting the sharing and reuse of software generally.
257
+
258
+			    NO WARRANTY
259
+
260
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
261
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
262
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
263
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
264
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
265
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
266
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
267
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
268
+REPAIR OR CORRECTION.
269
+
270
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
271
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
272
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
273
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
274
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
275
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
276
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
277
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
278
+POSSIBILITY OF SUCH DAMAGES.
279
+
280
+		     END OF TERMS AND CONDITIONS
281
+
282
+	    How to Apply These Terms to Your New Programs
283
+
284
+  If you develop a new program, and you want it to be of the greatest
285
+possible use to the public, the best way to achieve this is to make it
286
+free software which everyone can redistribute and change under these terms.
287
+
288
+  To do so, attach the following notices to the program.  It is safest
289
+to attach them to the start of each source file to most effectively
290
+convey the exclusion of warranty; and each file should have at least
291
+the "copyright" line and a pointer to where the full notice is found.
292
+
293
+    <one line to give the program's name and a brief idea of what it does.>
294
+    Copyright (C) <year>  <name of author>
295
+
296
+    This program is free software; you can redistribute it and/or modify
297
+    it under the terms of the GNU General Public License as published by
298
+    the Free Software Foundation; either version 2 of the License, or
299
+    (at your option) any later version.
300
+
301
+    This program is distributed in the hope that it will be useful,
302
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
303
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
304
+    GNU General Public License for more details.
305
+
306
+    You should have received a copy of the GNU General Public License along
307
+    with this program; if not, write to the Free Software Foundation, Inc.,
308
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
309
+
310
+Also add information on how to contact you by electronic and paper mail.
311
+
312
+If the program is interactive, make it output a short notice like this
313
+when it starts in an interactive mode:
314
+
315
+    Gnomovision version 69, Copyright (C) year name of author
316
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
317
+    This is free software, and you are welcome to redistribute it
318
+    under certain conditions; type `show c' for details.
319
+
320
+The hypothetical commands `show w' and `show c' should show the appropriate
321
+parts of the General Public License.  Of course, the commands you use may
322
+be called something other than `show w' and `show c'; they could even be
323
+mouse-clicks or menu items--whatever suits your program.
324
+
325
+You should also get your employer (if you work as a programmer) or your
326
+school, if any, to sign a "copyright disclaimer" for the program, if
327
+necessary.  Here is a sample; alter the names:
328
+
329
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
330
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
331
+
332
+  <signature of Ty Coon>, 1 April 1989
333
+  Ty Coon, President of Vice
334
+
335
+This General Public License does not permit incorporating your program into
336
+proprietary programs.  If your program is a subroutine library, you may
337
+consider it more useful to permit linking proprietary applications with the
338
+library.  If this is what you want to do, use the GNU Lesser General
339
+Public License instead of this License.

+ 10
- 0
Makefile.am View File

@@ -0,0 +1,10 @@
1
+SUBDIRS = src
2
+
3
+style:
4
+	find . -name "*.[ch]" -exec perl -pi -e 's/[ \t]+$$//' {} \;
5
+	find . -name "*.[ch]" -exec astyle --formatted --mode=c --suffix=none \
6
+		--indent=spaces=2 --indent-switches --indent-preprocessor \
7
+		--keep-one-line-blocks --max-instatement-indent=60 \
8
+		--brackets=linux --pad-oper --unpad-paren --pad-header \
9
+		--align-pointer=name {} \;
10
+

+ 0
- 0
NEWS View File


+ 54
- 0
README View File

@@ -0,0 +1,54 @@
1
+README
2
+======
3
+
4
+Compiling:
5
+    automake
6
+    autoconf
7
+    ./configure
8
+    make
9
+
10
+Running (most basic):
11
+    ./mfcuk -C -R 0:A -v 2
12
+
13
+PACKAGE
14
+-------
15
+MiFare Classic Universal toolKit (MFCUK)
16
+
17
+TOOL(S)
18
+-------
19
+Mifare Classic DarkSide Key Recovery Tool (mfcuk_keyrecovery_darkside.c) (previously known as zv_mf_dark_side)
20
+...
21
+
22
+LICENSE
23
+-------
24
+GPL. See MFCUK_LICENSE for more information.
25
+
26
+
27
+BIBLIOGRPAHY (no specific order)
28
+---------------------------------
29
+1. [WPMCC09] - "Wirelessly Pickpocketing a Mifare Classic Card"
30
+2. [ESO08] - "2008-esorics.pdf"
31
+3. [ESOSL08] - "2008-esorics-slides-updated.pdf"
32
+4. [KON08] - "2008-koning-thesis.pdf"
33
+5. [VER08] - "2008-verdult-thesis.pdf"
34
+6. [PATMC] - "A Practical Attack on the MIFARE Classic.pdf"
35
+7. [NCOURFIDSEC09] - "mifare_courtois_rfidsec09.pdf"
36
+8. [MFCLTRB09] - "MifareClassicTroubles.ppt"
37
+9. [TEEP08] - "p2008-teepe-classic_mistakes.pdf"
38
+10. [RFIDSANJ] - "RFID Attacks_WCA_San_Jose.pdf"
39
+11. [ROSS] - "rossum-mifare.pdf"
40
+12. [PLOTZ08] - "SAR-PR-2008-21_.pdf"
41
+13. [ROSSSASG] - "SASG35_Peter_v_Rossum_Mifare.pdf"
42
+14. [DARK2009] - "THE DARK SIDE OF SECURITY BY OBSCURITY and Cloning MiFare Classic Rail and Building Passes, Anywhere, Anytime"
43
+
44
+KUDOS and HATS-OFF to (no specific order) (for all the knowledge, time spent researching and all the things)
45
+---------------------
46
+ - blapost@gmail.com - this man is a genius and a technical artist. crapto1 3.1 is the horse power of this tool. PS: you somehow resemble I.C.Wiener anonymous&smart hacker
47
+ - Roel and RConty @ libnfc/proxmark - these guys are true advisers, helpful. Thanks for providing a powerfull platform for NFC
48
+ - N.Curtois - also a crypto-artist in differential analysis. The 29bit prefix attack is pure genius of theoretical analysis.
49
+ - RU University Staff for working out different aspects and papers for Crypto1 analysis
50
+ - Nohl, Plotz, Evans - how the "F" did you get those slicers and microscopes :))?
51
+ - Milosch M et al. - for pushing the limits for open-source hardware (OpenPCD and OpenPICC)
52
+ - Jonathan Westhues - for giving the open-source community the: Proxmark schematics/sources and RFID knowledge
53
+ - Nethemba team - for first open-source/GPL nested authentication attack key recovery implementation in MFOC
54
+ - hat, schwa226, pgrahamm, marcus2608, phadom - for useful samples, advices, traces and all the things

+ 21
- 0
TODO View File

@@ -0,0 +1,21 @@
1
+TODO
2
+====
3
+
4
+PACKAGE
5
+-------
6
+MiFare Classic Universal toolKit (MFCUK)
7
+
8
+TOOL(S)
9
+-------
10
+Mifare Classic DarkSide Key Recovery Tool (mfcuk_keyrecovery_darkside.c) (previously known as zv_mf_dark_side)
11
+...
12
+
13
+ITEMS
14
+=====
15
+0. Integrate with MFOC into MFCUK
16
+1. Improve the performance (though not bad)
17
+2. Optimize bits operations
18
+3. Remove dead-code/commented block after testing
19
+4. Proper error handling in some cases (not critical errors, but nice to have checks in place)
20
+5. Periodically save the state (or most important part of it at least) such as of Nt/Nr arrays, etc., so that it can later be resumed on the same card
21
+6. Calibration methodology and routine for MFCUK to determine best field on/off delays so that it generates the lowest entropy for tag's Nt values

+ 51
- 0
configure.ac View File

@@ -0,0 +1,51 @@
1
+AC_INIT([mfcuk], [0.3.8], [zveriu@gmail.com])
2
+
3
+AC_CONFIG_MACRO_DIR([m4])
4
+
5
+AC_PROG_CC
6
+
7
+AC_CONFIG_HEADERS([config.h])
8
+
9
+AM_INIT_AUTOMAKE
10
+
11
+m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
12
+
13
+# Checks for pkg-config modules.
14
+LIBNFC_REQUIRED_VERSION=1.7.0
15
+PKG_CHECK_MODULES([libnfc], [libnfc >= $LIBNFC_REQUIRED_VERSION], [], [AC_MSG_ERROR([libnfc >= $LIBNFC_REQUIRED_VERSION is mandatory.])])
16
+
17
+PKG_CONFIG_REQUIRES="libnfc"
18
+AC_SUBST([PKG_CONFIG_REQUIRES])
19
+
20
+# Checks for typedefs, structures, and compiler characteristics.
21
+AC_C_INLINE
22
+AC_HEADER_STDBOOL
23
+AC_TYPE_SIZE_T
24
+AC_TYPE_UINT16_T
25
+AC_TYPE_UINT32_T
26
+AC_TYPE_UINT64_T
27
+AC_TYPE_UINT8_T
28
+
29
+# Checks for library functions.
30
+AC_FUNC_MALLOC
31
+AC_FUNC_REALLOC
32
+
33
+AC_CHECK_HEADERS([sys/time.h])
34
+AC_CHECK_FUNCS([memset strchr strtoul])
35
+
36
+# Checks for endianness convertion
37
+AC_CHECK_HEADERS([endian.h sys/endian.h CoreFoundation/CoreFoundation.h])
38
+if test $ac_cv_header_endian_h = "no" -a $ac_cv_header_sys_endian_h = "no" -a $ac_cv_header_CoreFoundation_CoreFoundation_h = "no"; then
39
+  AC_MSG_ERROR(["Can't locate usable header file for endianness convertions."]);
40
+fi
41
+
42
+AC_CHECK_HEADERS([byteswap.h])
43
+
44
+AC_DEFINE([_XOPEN_SOURCE], [600], [Define to 500 if Single Unix conformance is wanted, 600 for sixth revision.])
45
+
46
+# Help us to write great code ;-)
47
+CFLAGS="$CFLAGS -Wall -pedantic -Wextra -std=c99"
48
+
49
+AC_CONFIG_FILES([Makefile
50
+                 src/Makefile])
51
+AC_OUTPUT

+ 10
- 0
src/Makefile.am View File

@@ -0,0 +1,10 @@
1
+AM_CFLAGS  = @libnfc_CFLAGS@
2
+
3
+bin_PROGRAMS = mfcuk
4
+
5
+noinst_HEADERS = crapto1.h mifare.h nfc-utils.h mfcuk_mifare.h mfcuk_finger.h mfcuk_utils.h xgetopt.h mfcuk.h
6
+
7
+mfcuk_SOURCES = crapto1.c crypto1.c mifare.c nfc-utils.c mfcuk_mifare.c mfcuk_finger.c mfcuk_utils.c xgetopt.c mfcuk.c 
8
+mfcuk_LDADD = @libnfc_LIBS@
9
+
10
+# dist_man_MANS = mfcuk.1

+ 6
- 0
src/build_cygwin.sh View File

@@ -0,0 +1,6 @@
1
+MAIN_FILE=mfcuk_keyrecovery_darkside
2
+LIBNFC=libnfc
3
+CFLAGS=`pkg-config --cflags ${LIBNFC}`
4
+CFLAGS_LIBNFC=`pkg-config --cflags libnfc | cut -d ' ' -f 1`/${LIBNFC}
5
+
6
+gcc ./${MAIN_FILE}.c ./mfcuk_mifare.c ./mfcuk_utils.c ./mfcuk_finger.c ./crapto1.c ./crypto1.c ./bin/libnfc.lib ${CFLAGS} ${CFLAGS_LIBNFC} -o ./bin/${MAIN_FILE}_cygwin.exe

+ 491
- 0
src/crapto1.c View File

@@ -0,0 +1,491 @@
1
+/*  crapto1.c
2
+
3
+    This program is free software; you can redistribute it and/or
4
+    modify it under the terms of the GNU General Public License
5
+    as published by the Free Software Foundation; either version 2
6
+    of the License, or (at your option) any later version.
7
+
8
+    This program is distributed in the hope that it will be useful,
9
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
+    GNU General Public License for more details.
12
+
13
+    You should have received a copy of the GNU General Public License
14
+    along with this program; if not, write to the Free Software
15
+    Foundation, Inc., 51 Franklin Street, Fifth Floor,
16
+    Boston, MA  02110-1301, US$
17
+
18
+    Copyright (C) 2008-2008 bla <blapost@gmail.com>
19
+*/
20
+#include "crapto1.h"
21
+#include <stdlib.h>
22
+
23
+#if !defined LOWMEM && defined __GNUC__
24
+static uint8_t filterlut[1 << 20];
25
+static void __attribute__((constructor)) fill_lut(void)
26
+{
27
+  uint32_t i;
28
+  for (i = 0; i < 1 << 20; ++i)
29
+    filterlut[i] = filter(i);
30
+}
31
+#define filter(x) (filterlut[(x) & 0xfffff])
32
+#endif
33
+
34
+static void quicksort(uint32_t *const start, uint32_t *const stop)
35
+{
36
+  uint32_t *it = start + 1, *rit = stop;
37
+
38
+  if (it > rit)
39
+    return;
40
+
41
+  while (it < rit)
42
+    if (*it <= *start)
43
+      ++it;
44
+    else if (*rit > *start)
45
+      --rit;
46
+    else
47
+      *it ^= (*it ^= *rit, *rit ^= *it);
48
+
49
+  if (*rit >= *start)
50
+    --rit;
51
+  if (rit != start)
52
+    *rit ^= (*rit ^= *start, *start ^= *rit);
53
+
54
+  quicksort(start, rit - 1);
55
+  quicksort(rit + 1, stop);
56
+}
57
+/** binsearch
58
+ * Binary search for the first occurence of *stop's MSB in sorted [start,stop]
59
+ */
60
+static inline uint32_t *
61
+binsearch(uint32_t *start, uint32_t *stop)
62
+{
63
+  uint32_t mid, val = *stop & 0xff000000;
64
+  while (start != stop)
65
+    if (start[mid = (stop - start) >> 1] > val)
66
+      stop = &start[mid];
67
+    else
68
+      start += mid + 1;
69
+
70
+  return start;
71
+}
72
+
73
+/** update_contribution
74
+ * helper, calculates the partial linear feedback contributions and puts in MSB
75
+ */
76
+static inline void
77
+update_contribution(uint32_t *item, const uint32_t mask1, const uint32_t mask2)
78
+{
79
+  uint32_t p = *item >> 25;
80
+
81
+  p = p << 1 | parity(*item & mask1);
82
+  p = p << 1 | parity(*item & mask2);
83
+  *item = p << 24 | (*item & 0xffffff);
84
+}
85
+
86
+/** extend_table
87
+ * using a bit of the keystream extend the table of possible lfsr states
88
+ */
89
+static inline void
90
+extend_table(uint32_t *tbl, uint32_t **end, int bit, int m1, int m2, uint32_t in)
91
+{
92
+  in <<= 24;
93
+  for (*tbl <<= 1; tbl <= *end; *++tbl <<= 1)
94
+    if (filter(*tbl) ^ filter(*tbl | 1)) {
95
+      *tbl |= filter(*tbl) ^ bit;
96
+      update_contribution(tbl, m1, m2);
97
+      *tbl ^= in;
98
+    } else if (filter(*tbl) == bit) {
99
+      *++*end = tbl[1];
100
+      tbl[1] = tbl[0] | 1;
101
+      update_contribution(tbl, m1, m2);
102
+      *tbl++ ^= in;
103
+      update_contribution(tbl, m1, m2);
104
+      *tbl ^= in;
105
+    } else
106
+      *tbl-- = *(*end)--;
107
+}
108
+/** extend_table_simple
109
+ * using a bit of the keystream extend the table of possible lfsr states
110
+ */
111
+static inline void
112
+extend_table_simple(uint32_t *tbl, uint32_t **end, int bit)
113
+{
114
+  for (*tbl <<= 1; tbl <= *end; *++tbl <<= 1)
115
+    if (filter(*tbl) ^ filter(*tbl | 1)) {
116
+      *tbl |= filter(*tbl) ^ bit;
117
+    } else if (filter(*tbl) == bit) {
118
+      *++*end = *++tbl;
119
+      *tbl = tbl[-1] | 1;
120
+    } else
121
+      *tbl-- = *(*end)--;
122
+}
123
+/** recover
124
+ * recursively narrow down the search space, 4 bits of keystream at a time
125
+ */
126
+static struct Crypto1State *
127
+recover(uint32_t *o_head, uint32_t *o_tail, uint32_t oks,
128
+        uint32_t *e_head, uint32_t *e_tail, uint32_t eks, int rem,
129
+        struct Crypto1State *sl, uint32_t in) {
130
+  uint32_t *o, *e, i;
131
+
132
+  if (rem == -1) {
133
+    for (e = e_head; e <= e_tail; ++e) {
134
+      *e = *e << 1 ^ parity(*e & LF_POLY_EVEN) ^ !!(in & 4);
135
+      for (o = o_head; o <= o_tail; ++o, ++sl) {
136
+        sl->even = *o;
137
+        sl->odd = *e ^ parity(*o & LF_POLY_ODD);
138
+        sl[1].odd = sl[1].even = 0;
139
+      }
140
+    }
141
+    return sl;
142
+  }
143
+
144
+  for (i = 0; i < 4 && rem--; i++) {
145
+    extend_table(o_head, &o_tail, (oks >>= 1) & 1,
146
+                 LF_POLY_EVEN << 1 | 1, LF_POLY_ODD << 1, 0);
147
+    if (o_head > o_tail)
148
+      return sl;
149
+
150
+    extend_table(e_head, &e_tail, (eks >>= 1) & 1,
151
+                 LF_POLY_ODD, LF_POLY_EVEN << 1 | 1, (in >>= 2) & 3);
152
+    if (e_head > e_tail)
153
+      return sl;
154
+  }
155
+
156
+  quicksort(o_head, o_tail);
157
+  quicksort(e_head, e_tail);
158
+
159
+  while (o_tail >= o_head && e_tail >= e_head)
160
+    if (((*o_tail ^ *e_tail) >> 24) == 0) {
161
+      o_tail = binsearch(o_head, o = o_tail);
162
+      e_tail = binsearch(e_head, e = e_tail);
163
+      sl = recover(o_tail--, o, oks,
164
+                   e_tail--, e, eks, rem, sl, in);
165
+    } else if (*o_tail > *e_tail)
166
+      o_tail = binsearch(o_head, o_tail) - 1;
167
+    else
168
+      e_tail = binsearch(e_head, e_tail) - 1;
169
+
170
+  return sl;
171
+}
172
+/** lfsr_recovery
173
+ * recover the state of the lfsr given 32 bits of the keystream
174
+ * additionally you can use the in parameter to specify the value
175
+ * that was fed into the lfsr at the time the keystream was generated
176
+ */
177
+struct Crypto1State *lfsr_recovery32(uint32_t ks2, uint32_t in) {
178
+  struct Crypto1State *statelist;
179
+  uint32_t *odd_head = 0, *odd_tail = 0, oks = 0;
180
+  uint32_t *even_head = 0, *even_tail = 0, eks = 0;
181
+  int i;
182
+
183
+  for (i = 31; i >= 0; i -= 2)
184
+    oks = oks << 1 | BEBIT(ks2, i);
185
+  for (i = 30; i >= 0; i -= 2)
186
+    eks = eks << 1 | BEBIT(ks2, i);
187
+
188
+  odd_head = odd_tail = malloc(sizeof(uint32_t) << 21);
189
+  even_head = even_tail = malloc(sizeof(uint32_t) << 21);
190
+  statelist =  malloc(sizeof(struct Crypto1State) << 18);
191
+  if (!odd_tail-- || !even_tail-- || !statelist)
192
+    goto out;
193
+
194
+  statelist->odd = statelist->even = 0;
195
+
196
+  for (i = 1 << 20; i >= 0; --i) {
197
+    if (filter(i) == (oks & 1))
198
+      *++odd_tail = i;
199
+    if (filter(i) == (eks & 1))
200
+      *++even_tail = i;
201
+  }
202
+
203
+  for (i = 0; i < 4; i++) {
204
+    extend_table_simple(odd_head,  &odd_tail, (oks >>= 1) & 1);
205
+    extend_table_simple(even_head, &even_tail, (eks >>= 1) & 1);
206
+  }
207
+
208
+  in = (in >> 16 & 0xff) | (in << 16) | (in & 0xff00);
209
+  recover(odd_head, odd_tail, oks,
210
+          even_head, even_tail, eks, 11, statelist, in << 1);
211
+
212
+out:
213
+  free(odd_head);
214
+  free(even_head);
215
+  return statelist;
216
+}
217
+
218
+static const uint32_t S1[] = {     0x62141, 0x310A0, 0x18850, 0x0C428, 0x06214,
219
+                                   0x0310A, 0x85E30, 0xC69AD, 0x634D6, 0xB5CDE, 0xDE8DA, 0x6F46D, 0xB3C83,
220
+                                   0x59E41, 0xA8995, 0xD027F, 0x6813F, 0x3409F, 0x9E6FA
221
+                             };
222
+static const uint32_t S2[] = {  0x3A557B00, 0x5D2ABD80, 0x2E955EC0, 0x174AAF60,
223
+                                0x0BA557B0, 0x05D2ABD8, 0x0449DE68, 0x048464B0, 0x42423258, 0x278192A8,
224
+                                0x156042D0, 0x0AB02168, 0x43F89B30, 0x61FC4D98, 0x765EAD48, 0x7D8FDD20,
225
+                                0x7EC7EE90, 0x7F63F748, 0x79117020
226
+                             };
227
+static const uint32_t T1[] = {
228
+  0x4F37D, 0x279BE, 0x97A6A, 0x4BD35, 0x25E9A, 0x12F4D, 0x097A6, 0x80D66,
229
+  0xC4006, 0x62003, 0xB56B4, 0x5AB5A, 0xA9318, 0xD0F39, 0x6879C, 0xB057B,
230
+  0x582BD, 0x2C15E, 0x160AF, 0x8F6E2, 0xC3DC4, 0xE5857, 0x72C2B, 0x39615,
231
+  0x98DBF, 0xC806A, 0xE0680, 0x70340, 0x381A0, 0x98665, 0x4C332, 0xA272C
232
+};
233
+static const uint32_t T2[] = {  0x3C88B810, 0x5E445C08, 0x2982A580, 0x14C152C0,
234
+                                0x4A60A960, 0x253054B0, 0x52982A58, 0x2FEC9EA8, 0x1156C4D0, 0x08AB6268,
235
+                                0x42F53AB0, 0x217A9D58, 0x161DC528, 0x0DAE6910, 0x46D73488, 0x25CB11C0,
236
+                                0x52E588E0, 0x6972C470, 0x34B96238, 0x5CFC3A98, 0x28DE96C8, 0x12CFC0E0,
237
+                                0x4967E070, 0x64B3F038, 0x74F97398, 0x7CDC3248, 0x38CE92A0, 0x1C674950,
238
+                                0x0E33A4A8, 0x01B959D0, 0x40DCACE8, 0x26CEDDF0
239
+                             };
240
+static const uint32_t C1[] = { 0x846B5, 0x4235A, 0x211AD};
241
+static const uint32_t C2[] = { 0x1A822E0, 0x21A822E0, 0x21A822E0};
242
+/** Reverse 64 bits of keystream into possible cipher states
243
+ * Variation mentioned in the paper. Somewhat optimized version
244
+ */
245
+struct Crypto1State *lfsr_recovery64(uint32_t ks2, uint32_t ks3) {
246
+  struct Crypto1State *statelist, *sl;
247
+  uint8_t oks[32], eks[32], hi[32];
248
+  uint32_t low = 0,  win = 0;
249
+  uint32_t *tail, table[1 << 16];
250
+  int i, j;
251
+
252
+  sl = statelist = malloc(sizeof(struct Crypto1State) << 4);
253
+  if (!sl)
254
+    return 0;
255
+  sl->odd = sl->even = 0;
256
+
257
+  for (i = 30; i >= 0; i -= 2) {
258
+    oks[i >> 1] = BIT(ks2, i ^ 24);
259
+    oks[16 + (i >> 1)] = BIT(ks3, i ^ 24);
260
+  }
261
+  for (i = 31; i >= 0; i -= 2) {
262
+    eks[i >> 1] = BIT(ks2, i ^ 24);
263
+    eks[16 + (i >> 1)] = BIT(ks3, i ^ 24);
264
+  }
265
+
266
+  for (i = 0xfffff; i >= 0; --i) {
267
+    if (filter(i) != oks[0])
268
+      continue;
269
+
270
+    *(tail = table) = i;
271
+    for (j = 1; tail >= table && j < 29; ++j)
272
+      extend_table_simple(table, &tail, oks[j]);
273
+
274
+    if (tail < table)
275
+      continue;
276
+
277
+    for (j = 0; j < 19; ++j)
278
+      low = low << 1 | parity(i & S1[j]);
279
+    for (j = 0; j < 32; ++j)
280
+      hi[j] = parity(i & T1[j]);
281
+
282
+    for (; tail >= table; --tail) {
283
+      for (j = 0; j < 3; ++j) {
284
+        *tail = *tail << 1;
285
+        *tail |= parity((i & C1[j]) ^(*tail & C2[j]));
286
+        if (filter(*tail) != oks[29 + j])
287
+          goto continue2;
288
+      }
289
+
290
+      for (j = 0; j < 19; ++j)
291
+        win = win << 1 | parity(*tail & S2[j]);
292
+
293
+      win ^= low;
294
+      for (j = 0; j < 32; ++j) {
295
+        win = win << 1 ^ hi[j] ^ parity(*tail & T2[j]);
296
+        if (filter(win) != eks[j])
297
+          goto continue2;
298
+      }
299
+
300
+      *tail = *tail << 1 | parity(LF_POLY_EVEN & *tail);
301
+      sl->odd = *tail ^ parity(LF_POLY_ODD & win);
302
+      sl->even = win;
303
+      ++sl;
304
+      sl->odd = sl->even = 0;
305
+continue2:
306
+      ;
307
+    }
308
+  }
309
+  return statelist;
310
+}
311
+
312
+uint8_t lfsr_rollback_bit(struct Crypto1State *s, uint32_t in, int fb);
313
+uint8_t lfsr_rollback_byte(struct Crypto1State *s, uint32_t in, int fb);
314
+uint32_t *lfsr_prefix_ks(uint8_t ks[8], int isodd);
315
+
316
+/** lfsr_rollback_bit
317
+ * Rollback the shift register in order to get previous states
318
+ */
319
+uint8_t lfsr_rollback_bit(struct Crypto1State *s, uint32_t in, int fb)
320
+{
321
+  int out;
322
+  uint8_t ret;
323
+
324
+  s->odd &= 0xffffff;
325
+  s->odd ^= (s->odd ^= s->even, s->even ^= s->odd);
326
+
327
+  out = s->even & 1;
328
+  out ^= LF_POLY_EVEN & (s->even >>= 1);
329
+  out ^= LF_POLY_ODD & s->odd;
330
+  out ^= !!in;
331
+  out ^= (ret = filter(s->odd)) & !!fb;
332
+
333
+  s->even |= parity(out) << 23;
334
+  return ret;
335
+}
336
+/** lfsr_rollback_byte
337
+ * Rollback the shift register in order to get previous states
338
+ */
339
+uint8_t lfsr_rollback_byte(struct Crypto1State *s, uint32_t in, int fb)
340
+{
341
+  int i;
342
+  uint8_t ret = 0;
343
+  for (i = 7; i >= 0; --i)
344
+    ret |= lfsr_rollback_bit(s, BIT(in, i), fb) << i;
345
+  return ret;
346
+}
347
+/** lfsr_rollback_word
348
+ * Rollback the shift register in order to get previous states
349
+ */
350
+uint32_t lfsr_rollback_word(struct Crypto1State *s, uint32_t in, int fb)
351
+{
352
+  int i;
353
+  uint32_t ret = 0;
354
+  for (i = 31; i >= 0; --i)
355
+    ret |= lfsr_rollback_bit(s, BEBIT(in, i), fb) << (i ^ 24);
356
+  return ret;
357
+}
358
+
359
+/** nonce_distance
360
+ * x,y valid tag nonces, then prng_successor(x, nonce_distance(x, y)) = y
361
+ */
362
+static uint16_t *dist = 0;
363
+int nonce_distance(uint32_t from, uint32_t to)
364
+{
365
+  uint16_t x, i;
366
+  if (!dist) {
367
+    dist = malloc(2 << 16);
368
+    if (!dist)
369
+      return -1;
370
+    for (x = i = 1; i; ++i) {
371
+      dist[(x & 0xff) << 8 | x >> 8] = i;
372
+      x = x >> 1 | (x ^ x >> 2 ^ x >> 3 ^ x >> 5) << 15;
373
+    }
374
+  }
375
+  return (65535 + dist[to >> 16] - dist[from >> 16]) % 65535;
376
+}
377
+
378
+
379
+static uint32_t fastfwd[2][8] = {
380
+  { 0, 0x4BC53, 0xECB1, 0x450E2, 0x25E29, 0x6E27A, 0x2B298, 0x60ECB},
381
+  { 0, 0x1D962, 0x4BC53, 0x56531, 0xECB1, 0x135D3, 0x450E2, 0x58980}
382
+};
383
+
384
+
385
+/** lfsr_prefix_ks
386
+ *
387
+ * Is an exported helper function from the common prefix attack
388
+ * Described in the "dark side" paper. It returns an -1 terminated array
389
+ * of possible partial(21 bit) secret state.
390
+ * The required keystream(ks) needs to contain the keystream that was used to
391
+ * encrypt the NACK which is observed when varying only the 4 last bits of Nr
392
+ * only correct iff [NR_3] ^ NR_3 does not depend on Nr_3
393
+ */
394
+uint32_t *lfsr_prefix_ks(uint8_t ks[8], int isodd)
395
+{
396
+  uint32_t c, entry, *candidates = malloc(4 << 21);
397
+  int i, size = (1 << 21) - 1;
398
+
399
+  if (!candidates)
400
+    return 0;
401
+
402
+  for (i = 0; i <= size; ++i)
403
+    candidates[i] = i;
404
+
405
+  for (c = 0;  c < 8; ++c)
406
+    for (i = 0; i <= size; ++i) {
407
+      entry = candidates[i] ^ fastfwd[isodd][c];
408
+
409
+      if (filter(entry >> 1) != BIT(ks[c], isodd) ||
410
+          filter(entry) != BIT(ks[c], isodd + 2))
411
+        candidates[i--] = candidates[size--];
412
+    }
413
+
414
+  candidates[size + 1] = -1;
415
+
416
+  return candidates;
417
+}
418
+
419
+/** check_pfx_parity
420
+ * helper function which eliminates possible secret states using parity bits
421
+ */
422
+static struct Crypto1State *
423
+check_pfx_parity(uint32_t prefix, uint32_t rresp, uint8_t parities[8][8],
424
+                 uint32_t odd, uint32_t even, struct Crypto1State *sl) {
425
+  uint32_t ks1, nr, ks2, rr, ks3, c, good = 1;
426
+
427
+  for (c = 0; good && c < 8; ++c) {
428
+    sl->odd = odd ^ fastfwd[1][c];
429
+    sl->even = even ^ fastfwd[0][c];
430
+
431
+    lfsr_rollback_bit(sl, 0, 0);
432
+    lfsr_rollback_bit(sl, 0, 0);
433
+
434
+    ks3 = lfsr_rollback_bit(sl, 0, 0);
435
+    ks2 = lfsr_rollback_word(sl, 0, 0);
436
+    ks1 = lfsr_rollback_word(sl, prefix | c << 5, 1);
437
+
438
+    nr = ks1 ^(prefix | c << 5);
439
+    rr = ks2 ^ rresp;
440
+
441
+    good &= parity(nr & 0x000000ff) ^ parities[c][3] ^ BIT(ks2, 24);
442
+    good &= parity(rr & 0xff000000) ^ parities[c][4] ^ BIT(ks2, 16);
443
+    good &= parity(rr & 0x00ff0000) ^ parities[c][5] ^ BIT(ks2,  8);
444
+    good &= parity(rr & 0x0000ff00) ^ parities[c][6] ^ BIT(ks2,  0);
445
+    good &= parity(rr & 0x000000ff) ^ parities[c][7] ^ ks3;
446
+  }
447
+
448
+  return sl + good;
449
+}
450
+
451
+
452
+/** lfsr_common_prefix
453
+ * Implentation of the common prefix attack.
454
+ * Requires the 29 bit constant prefix used as reader nonce (pfx)
455
+ * The reader response used (rr)
456
+ * The keystream used to encrypt the observed NACK's (ks)
457
+ * The parity bits (par)
458
+ * It returns a zero terminated list of possible cipher states after the
459
+ * tag nonce was fed in
460
+ */
461
+struct Crypto1State *
462
+lfsr_common_prefix(uint32_t pfx, uint32_t rr, uint8_t ks[8], uint8_t par[8][8]) {
463
+  struct Crypto1State *statelist, *s;
464
+  uint32_t *odd, *even, *o, *e, top;
465
+
466
+  odd = lfsr_prefix_ks(ks, 1);
467
+  even = lfsr_prefix_ks(ks, 0);
468
+
469
+  s = statelist = malloc((sizeof *statelist) << 20);
470
+  if (!s || !odd || !even) {
471
+    free(odd);
472
+    free(even);
473
+    free(statelist);
474
+    return 0;
475
+  }
476
+
477
+  for (o = odd; *o + 1; ++o)
478
+    for (e = even; *e + 1; ++e)
479
+      for (top = 0; top < 64; ++top) {
480
+        *o += 1 << 21;
481
+        *e += (!(top & 7) + 1) << 21;
482
+        s = check_pfx_parity(pfx, rr, par, *o, *e, s);
483
+      }
484
+
485
+  s->odd = s->even = 0;
486
+
487
+  free(odd);
488
+  free(even);
489
+
490
+  return statelist;
491
+}

+ 90
- 0
src/crapto1.h View File

@@ -0,0 +1,90 @@
1
+/*  crapto1.h
2
+
3
+    This program is free software; you can redistribute it and/or
4
+    modify it under the terms of the GNU General Public License
5
+    as published by the Free Software Foundation; either version 2
6
+    of the License, or (at your option) any later version.
7
+
8
+    This program is distributed in the hope that it will be useful,
9
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
+    GNU General Public License for more details.
12
+
13
+    You should have received a copy of the GNU General Public License
14
+    along with this program; if not, write to the Free Software
15
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
16
+    MA  02110-1301, US$
17
+
18
+    Copyright (C) 2008-2009 bla <blapost@gmail.com>
19
+*/
20
+#ifndef CRAPTO1_INCLUDED
21
+#define CRAPTO1_INCLUDED
22
+#include <stdint.h>
23
+#ifdef __cplusplus
24
+extern "C" {
25
+#endif
26
+
27
+  struct Crypto1State {uint32_t odd, even;};
28
+  struct Crypto1State *crypto1_create(uint64_t);
29
+  void crypto1_destroy(struct Crypto1State *);
30
+  void crypto1_get_lfsr(struct Crypto1State *, uint64_t *);
31
+  uint8_t crypto1_bit(struct Crypto1State *, uint8_t, int);
32
+  uint8_t crypto1_byte(struct Crypto1State *, uint8_t, int);
33
+  uint32_t crypto1_word(struct Crypto1State *, uint32_t, int);
34
+  uint32_t prng_successor(uint32_t x, uint32_t n);
35
+
36
+  struct Crypto1State *lfsr_common_prefix(uint32_t pfx, uint32_t rr, uint8_t ks[8], uint8_t par[8][8]);
37
+  struct Crypto1State *lfsr_recovery32(uint32_t ks2, uint32_t in);
38
+  struct Crypto1State *lfsr_recovery64(uint32_t ks2, uint32_t ks3);
39
+
40
+  void lfsr_rollback(struct Crypto1State *s, uint32_t in, int fb);
41
+  uint32_t lfsr_rollback_word(struct Crypto1State *s, uint32_t in, int fb);
42
+  int nonce_distance(uint32_t from, uint32_t to);
43
+#define FOREACH_VALID_NONCE(N, FILTER, FSIZE)\
44
+  uint32_t __n = 0,__M = 0, N = 0;\
45
+  int __i;\
46
+  for(; __n < 1 << 16; N = prng_successor(__M = ++__n, 16))\
47
+    for(__i = FSIZE - 1; __i >= 0; __i--)\
48
+      if(BIT(FILTER, __i) ^ parity(__M & 0xFF01))\
49
+        break;\
50
+      else if(__i)\
51
+        __M = prng_successor(__M, (__i == 7) ? 48 : 8);\
52
+      else
53
+
54
+#define LF_POLY_ODD (0x29CE5C)
55
+#define LF_POLY_EVEN (0x870804)
56
+#define BIT(x, n) ((x) >> (n) & 1)
57
+#define BEBIT(x, n) BIT(x, (n) ^ 24)
58
+  static inline int parity(uint32_t x)
59
+  {
60
+#if !defined __i386__ || !defined __GNUC__
61
+    x ^= x >> 16;
62
+    x ^= x >> 8;
63
+    x ^= x >> 4;
64
+    return BIT(0x6996, x & 0xf);
65
+#else
66
+    __asm__("movl %1, %%eax\n"
67
+            "mov %%ax, %%cx\n"
68
+            "shrl $0x10, %%eax\n"
69
+            "xor %%ax, %%cx\n"
70
+            "xor %%ch, %%cl\n"
71
+            "setpo %%al\n"
72
+            "movzx %%al, %0\n": "=r"(x) : "r"(x): "eax", "ecx");
73
+    return x;
74
+#endif
75
+  }
76
+  static inline int filter(uint32_t const x)
77
+  {
78
+    uint32_t f;
79
+
80
+    f  = 0xf22c0 >> (x       & 0xf) & 16;
81
+    f |= 0x6c9c0 >> (x >>  4 & 0xf) &  8;
82
+    f |= 0x3c8b0 >> (x >>  8 & 0xf) &  4;
83
+    f |= 0x1e458 >> (x >> 12 & 0xf) &  2;
84
+    f |= 0x0d938 >> (x >> 16 & 0xf) &  1;
85
+    return BIT(0xEC57E80A, f);
86
+  }
87
+#ifdef __cplusplus
88
+}
89
+#endif
90
+#endif

+ 92
- 0
src/crypto1.c View File

@@ -0,0 +1,92 @@
1
+/*  crypto1.c
2
+
3
+    This program is free software; you can redistribute it and/or
4
+    modify it under the terms of the GNU General Public License
5
+    as published by the Free Software Foundation; either version 2
6
+    of the License, or (at your option) any later version.
7
+
8
+    This program is distributed in the hope that it will be useful,
9
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
+    GNU General Public License for more details.
12
+
13
+    You should have received a copy of the GNU General Public License
14
+    along with this program; if not, write to the Free Software
15
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
16
+    MA  02110-1301, US
17
+
18
+    Copyright (C) 2008-2008 bla <blapost@gmail.com>
19
+*/
20
+#include "crapto1.h"
21
+#include <stdlib.h>
22
+
23
+#define SWAPENDIAN(x)\
24
+  (x = (x >> 8 & 0xff00ff) | (x & 0xff00ff) << 8, x = x >> 16 | x << 16)
25
+
26
+struct Crypto1State *crypto1_create(uint64_t key) {
27
+  struct Crypto1State *s = malloc(sizeof(*s));
28
+  int i;
29
+
30
+  for (i = 47; s && i > 0; i -= 2) {
31
+    s->odd  = s->odd  << 1 | BIT(key, (i - 1) ^ 7);
32
+    s->even = s->even << 1 | BIT(key, i ^ 7);
33
+  }
34
+  return s;
35
+}
36
+void crypto1_destroy(struct Crypto1State *state)
37
+{
38
+  free(state);
39
+}
40
+void crypto1_get_lfsr(struct Crypto1State *state, uint64_t *lfsr)
41
+{
42
+  int i;
43
+  for (*lfsr = 0, i = 23; i >= 0; --i) {
44
+    *lfsr = *lfsr << 1 | BIT(state->odd, i ^ 3);
45
+    *lfsr = *lfsr << 1 | BIT(state->even, i ^ 3);
46
+  }
47
+}
48
+uint8_t crypto1_bit(struct Crypto1State *s, uint8_t in, int is_encrypted)
49
+{
50
+  uint32_t feedin;
51
+  uint8_t ret = filter(s->odd);
52
+
53
+  feedin  = ret & !!is_encrypted;
54
+  feedin ^= !!in;
55
+  feedin ^= LF_POLY_ODD & s->odd;
56
+  feedin ^= LF_POLY_EVEN & s->even;
57
+  s->even = s->even << 1 | parity(feedin);
58
+
59
+  s->odd ^= (s->odd ^= s->even, s->even ^= s->odd);
60
+
61
+  return ret;
62
+}
63
+uint8_t crypto1_byte(struct Crypto1State *s, uint8_t in, int is_encrypted)
64
+{
65
+  uint8_t i, ret = 0;
66
+
67
+  for (i = 0; i < 8; ++i)
68
+    ret |= crypto1_bit(s, BIT(in, i), is_encrypted) << i;
69
+
70
+  return ret;
71
+}
72
+uint32_t crypto1_word(struct Crypto1State *s, uint32_t in, int is_encrypted)
73
+{
74
+  uint32_t i, ret = 0;
75
+
76
+  for (i = 0; i < 32; ++i)
77
+    ret |= crypto1_bit(s, BEBIT(in, i), is_encrypted) << (i ^ 24);
78
+
79
+  return ret;
80
+}
81
+
82
+/* prng_successor
83
+ * helper used to obscure the keystream during authentication
84
+ */
85
+uint32_t prng_successor(uint32_t x, uint32_t n)
86
+{
87
+  SWAPENDIAN(x);
88
+  while (n--)
89
+    x = x >> 1 | (x >> 16 ^ x >> 18 ^ x >> 19 ^ x >> 21) << 31;
90
+
91
+  return SWAPENDIAN(x);
92
+}

+ 51
- 0
src/data/logs_proxmark3/trace1.txt View File

@@ -0,0 +1,51 @@
1
+ + 561882:  1 :     26    
2
+ +     64:  2 : TAG 04  00    
3
+ +  10217:  2 :     93  20    
4
+ +     64:  5 : TAG 9c  59  9b  32  6c    
5
+ +  12313:  9 :     93  70  9c  59  9b  32  6c  6b  30    
6
+ +     64:  3 : TAG 08  b6  dd    
7
+ + 923318:  4 :     60  00  f5  7b    
8
+ +    112:  4 : TAG 82  a4  16  6c    
9
+ +   6985:  8 :     a1  e4! 58  ce! 6e  ea! 41  e0!       !crc
10
+ +     64:  4 : TAG 5c! ad  f4  39!   
11
+ + 811513:  4 :     8e  0e! 5d! b9        !crc
12
+ +    112:  4 : TAG 5a! 92  0d! 85!   
13
+ +   6946:  8 :     98! d7  6b! 77  d6  c6  e8  70        !crc
14
+ +     64:  4 : TAG ca  7e! 0b! 63!   
15
+ + 670868:  4 :     3e! 70  9c! 8a        !crc
16
+ +    112:  4 : TAG 36! 41  24! 79    
17
+ +   9505:  8 :     1b! 8c  3a! 48! 83  5a  4a! 27        !crc
18
+ +     64:  4 : TAG 40! 6a! 99! 4b    
19
+ + 905612:  4 :     c9  7c  64! 13!       !crc
20
+ +    112:  4 : TAG b5! ab! 1d! 2b    
21
+ +   6936:  8 :     7e! d2  5c! ca! 4b! 50! 88! c4        !crc
22
+ +     64:  4 : TAG bf  dd  01  be!   
23
+ + 987853:  4 :     56  98  49  d6!       !crc
24
+ +     72: 18 : TAG 09  bf! f5! f6! fc! b9! 5e! 51! 07  ac  f6  72  f8  73  3b! 1b  73! ad!       !crc
25
+ +  94864:  4 :     5c! 7b  24! 02        !crc
26
+ +     72: 18 : TAG a0  1f! 0b! b7  0d! ba  c9  e7! fa! 36! 47  d2  a0! 01! 40! 87  ff  95!       !crc
27
+ +  94827:  4 :     c9  90  dc! a3        !crc
28
+ +     72: 18 : TAG df  b8! 7a  bc! 17! 99  82! 5c  55  d5! 98! 68  8b  f8  e7  89  dc  42!       !crc
29
+ +  99081:  4 :     9f! d5  0f! d8!       !crc
30
+ +     72: 18 : TAG ca! 40  fa! 34  82  cc  3e  de  1f! 7f  f7! f0  62! 18! 77! 34  30  07        !crc
31
+ +  93995:  4 :     ad  7f! 3e  0c!       !crc
32
+ +     72: 18 : TAG f4! 2b  17! 4c  a2! 5a  0c! a0! d8  03! 05  cc  cc  4c  1f  12! 0c! 78!       !crc
33
+ +  94857:  4 :     f1! b4  f0  3b!       !crc
34
+ +     72: 18 : TAG 8f  da  ca  17! 42  8e  24  c9! 8e  fb! 38! aa! 39  e2! dd  dd! a8  a6        !crc
35
+ +  94850:  4 :     c4  03! 7b! 9a        !crc
36
+ +     72: 18 : TAG 9f! 42! 42  49! cd  d1! 3d! fd  8e  8f  d3  8d! d5! ca! ef! 15  84  c9!       !crc
37
+ +  93961:  4 :     33! 3b! ae  0a!       !crc
38
+ +     72: 18 : TAG 74  ed! 58  46! e7  cc  48  d1! 5a  4b  b0! 3a! c1  79! 8a! bf! e7! 42        !crc
39
+ +  93193:  4 :     f6  ec! 36  91!       !crc
40
+ +     72: 18 : TAG 79! 63  89! 21! 24  1e  3e! 03! a8! c3! 9b  95! a1  ad! 6c! 34  52  94        !crc
41
+ +  94866:  4 :     ad! 5c! 47  c5!       !crc
42
+ +     72: 18 : TAG 68  d4  9d  c2! 2b  18  46! f7  e8! 28  ea  03  a4  df  d5! 9f  23  00!       !crc
43
+ +  93994:  4 :     41  4c! 40! 11        !crc
44
+ +     72: 18 : TAG b1  95  17! 84! ac  fc! 31  b8! 02  40  97! ec! 4c  19  6f  e9  f0! 8c!       !crc
45
+ +  94818:  4 :     b8! b5! 5c! 74!       !crc
46
+ +     72: 18 : TAG c6  03  b9  92! 7d! eb! 13  8a  56  b7  9c  7c  07  3d! 6a  95! 7e! 44        !crc
47
+
48
+# http://www.proxmark.org/forum/post/550/#p550
49
+# UID = 0x9c599b32
50
+# KEY = 0xffffffffffff
51
+# 0x9c599b32 0x82a4166c 0xa1e458ce 0x6eea41e0 0x5cadf439

+ 124
- 0
src/data/logs_proxmark3/trace2.txt View File

@@ -0,0 +1,124 @@
1
+ +      0:   0: TAG 00!   
2
+ + 337281:    :     30  00  02  a8    
3
+ +   5032:    :     50  00  57  cd    
4
+ +   9952:    :     52    
5
+ + 141825:    :     30  00  02  a8    
6
+ +   5040:    :     50  00  57  cd    
7
+ +  10528:    :     52    
8
+ +   7624:    :     93  20    
9
+ +     64:   0: TAG ca  fd  ca  13  ee    
10
+ +  10656:    :     93  70  ca  fd  ca  13  ee  8e  ea    
11
+ +     64:   0: TAG 08  b6  dd    
12
+ +  89345:    :     30  00  02  a8    
13
+ +     72:   0: TAG 04    
14
+ +   4976:    :     50  00  57  cd    
15
+ +   9952:    :     52    
16
+ +     64:   0: TAG 04  00    
17
+ +   7720:    :     93  20    
18
+ +     64:   0: TAG ca  fd  ca  13  ee    
19
+ +  14120:    :     93  70  ca  fd  ca  13  ee  8e  ea    
20
+ +     64:   0: TAG 08  b6  dd    
21
+ + 105352:    :     30  00  02  a8    
22
+ +     72:   0: TAG 04    
23
+ +  21952:    :     50  00  57  cd    
24
+ +   9944:    :     52    
25
+ +     64:   0: TAG 04  00    
26
+ +  14448:    :     93  20    
27
+ +     64:   0: TAG ca  fd  ca  13  ee    
28
+ +  10736:    :     93  70  ca  fd  ca  13  ee  8e  ea    
29
+ +     64:   0: TAG 08  b6  dd    
30
+ + 124904:    :     30  00  02  a8    
31
+ +     72:   0: TAG 04    
32
+ +   4968:    :     50  00  57  cd    
33
+ +  10346:    :     52    
34
+ +     64:   0: TAG 04  00    
35
+ +   7272:    :     93  20    
36
+ +     64:   0: TAG ca  fd  ca  13  ee    
37
+ +  13240:    :     93  70  ca  fd  ca  13  ee  8e  ea    
38
+ +     64:   0: TAG 08  b6  dd    
39
+ +  89320:    :     30  00  02  a8    
40
+ +     72:   0: TAG 04    
41
+ +   5000:    :     50  00  57  cd    
42
+ +  10784:    :     52    
43
+ +     64:   0: TAG 04  00    
44
+ +   7680:    :     93  20    
45
+ +     64:   0: TAG ca  fd  ca  13  ee    
46
+ +  11560:    :     93  70  ca  fd  ca  13  ee  8e  ea    
47
+ +     64:   0: TAG 08  b6  dd    
48
+ +  89305:    :     30  00  02  a8    
49
+ +     72:   0: TAG 04    
50
+ +   4960:    :     50  00  57  cd    
51
+ +  10040:    :     52    
52
+ +     64:   0: TAG 04  00    
53
+ +  43208:    :     93  20    
54
+ +     64:   0: TAG ca  fd  ca  13  ee    
55
+ +  10696:    :     93  70  ca  fd  ca  13  ee  8e  ea    
56
+ +     64:   0: TAG 08  b6  dd    
57
+ +  89305:    :     30  00  02  a8    
58
+ +     72:   0: TAG 04    
59
+ +   4984:    :     50  00  57  cd    
60
+ +  10824:    :     52    
61
+ +     64:   0: TAG 04  00    
62
+ +   9352:    :     93  20    
63
+ +     64:   0: TAG ca  fd  ca  13  ee    
64
+ +  10680:    :     93  70  ca  fd  ca  13  ee  8e  ea    
65
+ +     64:   0: TAG 08  b6  dd    
66
+ +  90184:    :     30  00  02  a8    
67
+ +     72:   0: TAG 04    
68
+ +   4984:    :     50  00  57  cd    
69
+ +   9944:    :     52    
70
+ +     64:   0: TAG 04  00    
71
+ + 102224:    :     93  20    
72
+ +     64:   0: TAG ca  fd  ca  13  ee    
73
+ + 939902:    :     93  70  ca  fd  ca  13  ee  8e  ea    
74
+ +     64:   0: TAG 08  b6  dd    
75
+ + 752874:    :     60  00  f5  7b    
76
+ +    112:   0: TAG e9  01  a1  69    
77
+ +  10352:    :     71  03  4a  be  f9  2f  51  2f      !crc
78
+ +     64:   0: TAG 99  25! ef! 9d!   
79
+ + 864094:    :     dc  9f  f9  65      !crc
80
+ +     72:   0: TAG e5  82  07  a2! e1  ea  c5  cd  14  85! aa! 97! 58! 17  0e  b5  ab! ff      !crc
81
+ + 312194:    :     4b  de  1d  e9      !crc
82
+ +     72:   0: TAG 04  0a! 1c! ad  54! 3e  ed  03! 60! 82  42  e4  da! 83! 98! 22  14! f2      !crc
83
+ + 290616:    :     cc  06  39  d7      !crc
84
+ +     72:   0: TAG 0a  a3  f1  86  34  8f  9d! 1f! 4d! 7e! f1! 56  8e  9f  ee  32! 88  89      !crc
85
+ + 204658:    :     80  f4  eb  55      !crc
86
+ +     72:   0: TAG 9d  6e  88  db! fc  88  14! fa  af  dd  10! cc  74  81! 71  52  fd! d9      !crc
87
+ + 543394:    :     26  f0  ea  aa      !crc
88
+ +     72:   0: TAG d5! a1! ed  8d  73! fe! 3e  94  56  db! 39! ad! dc! ff  9c! a3  f2  24!     !crc
89
+ + 299722:    :     56  00  9a  4d      !crc
90
+ +     72:   0: TAG 58! cf  13  c4  78  50! 0f! b8  73  1c  33! 25  23  12  1e  a2! 4a  32!     !crc
91
+ + 215834:    :     db  a2  ec  42      !crc
92
+ +     72:   0: TAG 78  3f! 30! 02  64  85  63! fe! 81! 9e  27  70  f7  cc  b0  77  ce! 4b      !crc
93
+ +  97112:    :     a5  78  3e  3d      !crc
94
+ +     72:   0: TAG ef! fd! 47! 36  e5  c3! c1  96  c5  97  7b! 3d! ce! ab! 6e! 5e  bd  8b      !crc
95
+ +  87752:    :     a1  9b  41  09      !crc
96
+ +     72:   0: TAG e5! e1! 28  7d! ee  ae! 60  d7  29  96! d7! a1! 6e  4e  da! 66! 93  bd!     !crc
97
+ +  89104:    :     70  ff  99  6c      !crc
98
+ +     72:   0: TAG 17  97  04  0a! 92! 66! 7d  e7! 62  a8  b5! 56  d4  a1  ab! b8  70  4e!     !crc
99
+ +  87928:    :     5e  6c  03  09      !crc
100
+ +     72:   0: TAG c5! da  86  a4  a0  24! ab  da! f3  d9  95! f3! 2d! 8e! b7! 07  a5! e6      !crc
101
+ +  88434:    :     2e  91  6d  54      !crc
102
+ +     72:   0: TAG b4  37  84  6b! fd! c8  71  f9  bf! a1! 96! af! 85! d3  b9! f0! 5b! 57!     !crc
103
+ +  87648:    :     25  ad  12  4f      !crc
104
+ +     72:   0: TAG 7a! 21! 36  81  d1! eb  d6! 39! 04! b7  28! 3f! b1  19! 2e  b2  b4  23!     !crc
105
+ +  87649:    :     f1  94  78  4b      !crc
106
+ +     72:   0: TAG 5f! e4  b5  6c  c1  3f  ce  e4  49  d0! e0! 78  bc  46! 92  0f  7a! e5!     !crc
107
+ + 104544:    :     01  6b  c7  c4      !crc
108
+ +     72:   0: TAG 95! 78! ca  79! ab! 32  47  8d! 1c! 81! 3d! 26  85  5e  f3  02  71  3f!     !crc
109
+ +  99737:    :     f6  67  6d  48      !crc
110
+ +     72:   0: TAG 4b! 6e  fa  87  51  7d  92  a2! fb! 1b! 1d  62! f8! 7b! 2d! cf! c1  20      !crc
111
+ + 360330:    :     b8  59  c0  94      !crc
112
+ +     72:   0: TAG b0! 05  25! 4b! 94  8d! 75  62  70! 85  77! e7  a6  1f! 9e! 54  07! d5!     !crc
113
+ + 443146:    :     7f  3a  fa  6a      !crc
114
+ +     72:   0: TAG ac  c9  81! b4! de  ee! e5! 0b! 73! 79! 6c  fe! d8  53  00! e1  3c! f0      !crc
115
+ + 198008:    :     47  e6  ec  f7      !crc
116
+ +     72:   0: TAG a6  b1! 1e! 8e! 86! ee  d0  4a  4c  ee  34  df  6b  e6! da  45! d6! ed      !crc
117
+ + 455019:    :     49  13  9c  fb      !crc
118
+ +     72:   0: TAG 31! 1d  7d  21! 22! e3  af! bc  ce  6e! 6c! 9f  48  c1! 16! 28! f3! 18      !crc
119
+ + 223097:    :     ff  43  e9  35      !crc
120
+ +     72:   0: TAG e5! 41  d7  99! 46  8d! ff  e7! 1e! 22  32! d0  93! 9e  a1  c5  5c! 32!     !crc
121
+
122
+# http://www.proxmark.org/forum/topic/385/error-with-mifarecrackpy/
123
+# real uid is:    ca  fd  ca  13
124
+# 0xcafdca13 0xe901a169 0x71034abe 0xf92f512f 0x9925ef9d

+ 30
- 0
src/data/logs_proxmark3/trace3.txt View File

@@ -0,0 +1,30 @@
1
+ +2770194:    :     26    
2
+ +     64:   0: TAG 04  00    
3
+ +   1432:    :     93  20    
4
+ +     64:   0: TAG 5e  c2  1c  61  e1    
5
+ +   2168:    :     93  70  5e  c2  1c  61  e1  d5  65    
6
+ +     64:   0: TAG 08  b6  dd    
7
+ +  31064:    :     60  08  bd  f7    
8
+ +    112:   0: TAG d7  b2  ae  bd   
9
+ +   1976:    :     60  d1  57  7f  aa  02  78  ea      !crc
10
+ + 599060:    :     26    
11
+ +     64:   0: TAG 04  00    
12
+ +   1424:    :     93  20    
13
+ +     64:   0: TAG 5e  c2  1c  61  e1    
14
+ +   2168:    :     93  70  5e  c2  1c  61  e1  d5  65    
15
+ +     64:   0: TAG 08  b6  dd    
16
+ +  31160:    :     60  08  bd  f7    
17
+ +    112:   0: TAG cc  ec  00  cd   
18
+ +   1976:    :     86  ae  b4  79  69  34  ed  50      !crc
19
+ + 545300:    :     26    
20
+ +     64:   0: TAG 04  00    
21
+ +   1440:    :     93  20    
22
+ +     64:   0: TAG 5e  c2  1c  61  e1    
23
+ +   2168:    :     93  70  5e  c2  1c  61  e1  d5  65    
24
+ +     64:   0: TAG 08  b6  dd    
25
+ +  31144:    :     60  08  bd  f7    
26
+ +    112:   0: TAG 9c  6a  3c  1e   
27
+ +   1976:    :     33  aa  1e  4c  8a  a1  58  ed      !crc
28
+
29
+# http://www.proxmark.org/forum/post/2346/#p2346
30
+# 0x5ec21c61 0xd7b2aebd 0x60d1577f  0xaa0278ea 0x26

BIN
src/data/tmpls_fingerprints/mfcuk_tmpl_oyster.mfd View File


BIN
src/data/tmpls_fingerprints/mfcuk_tmpl_ratb.mfd View File


BIN
src/data/tmpls_fingerprints/mfcuk_tmpl_skgt.mfd View File


+ 1733
- 0
src/mfcuk.c
File diff suppressed because it is too large
View File


+ 119
- 0
src/mfcuk.h View File

@@ -0,0 +1,119 @@
1
+/*
2
+ Package:
3
+    MiFare Classic Universal toolKit (MFCUK)
4
+
5
+ Filename:
6
+    mfcuk_keyrecovery_darkside.h
7
+
8
+ Description:
9
+    MFCUK DarkSide Key Recovery specific typedefs and defines
10
+
11
+ Contact, bug-reports:
12
+    http://andreicostin.com/
13
+    mailto:zveriu@gmail.com
14
+
15
+ License:
16
+    GPL2 (see below), Copyright (C) 2009, Andrei Costin
17
+
18
+ * @file mfcuk_keyrecovery_darkside.h
19
+ * @brief
20
+*/
21
+
22
+/*
23
+ VERSION HISTORY
24
+--------------------------------------------------------------------------------
25
+| Number     : 0.1
26
+| dd/mm/yyyy : 23/11/2009
27
+| Author     : zveriu@gmail.com, http://andreicostin.com
28
+| Description: Moved bulk of defines and things from "mfcuk_keyrecovery_darkside.c"
29
+--------------------------------------------------------------------------------
30
+*/
31
+
32
+/*
33
+ LICENSE
34
+
35
+ This program is free software: you can redistribute it and/or modify
36
+ it under the terms of the GNU General Public License as published by
37
+ the Free Software Foundation, either version 2 of the License, or
38
+ (at your option) any later version.
39
+
40
+ This program is distributed in the hope that it will be useful,
41
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
42
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
43
+ GNU General Public License for more details.
44
+
45
+ You should have received a copy of the GNU General Public License
46
+ along with this program.  If not, see <http://www.gnu.org/licenses/>.
47
+*/
48
+
49
+#ifndef _MFCUK_KEYRECOVERY_DARKSIDE_H_
50
+#define _MFCUK_KEYRECOVERY_DARKSIDE_H_
51
+
52
+// Define package and executable related info
53
+#define BUILD_NAME      "Mifare Classic DarkSide Key Recovery Tool"
54
+#define BUILD_VERSION   "0.3"
55
+#define BUILD_AUTHOR    "Andrei Costin, zveriu@gmail.com, http://andreicostin.com"
56
+
57
+// Define return statuses
58
+#define MFCUK_SUCCESS                 0x0
59
+#define MFCUK_OK_KEY_RECOVERED        (MFCUK_SUCCESS+1)
60
+#define MFCUK_FAIL_AUTH               (MFCUK_OK_KEY_RECOVERED+1)
61
+#define MFCUK_FAIL_CRAPTO             (MFCUK_FAIL_AUTH+1)
62
+#define MFCUK_FAIL_TAGTYPE_INVALID    (MFCUK_FAIL_CRAPTO+1)
63
+#define MFCUK_FAIL_KEYTYPE_INVALID    (MFCUK_FAIL_TAGTYPE_INVALID+1)
64
+#define MFCUK_FAIL_BLOCK_INVALID      (MFCUK_FAIL_KEYTYPE_INVALID+1)
65
+#define MFCUK_FAIL_SECTOR_INVALID     (MFCUK_FAIL_BLOCK_INVALID+1)
66
+#define MFCUK_FAIL_COMM               (MFCUK_FAIL_SECTOR_INVALID+1)
67
+#define MFCUK_FAIL_MEMORY             (MFCUK_FAIL_COMM+1)
68
+
69
+// There are 4 bytes in ACBITS, use each byte as below
70
+#define ACTIONS_KEY_A           0 // Specifies the byte index where actions for key A are stored
71
+#define RESULTS_KEY_A           1 // Specifies the byte index where results for key A are stored
72
+#define ACTIONS_KEY_B           2 // Specifies the byte index where actions for key B are stored
73
+#define RESULTS_KEY_B           3 // Specifies the byte index where results for key B are stored
74
+
75
+// The action/result byte can contain any combination of these
76
+#define ACTIONS_VERIFY          0x1 // Specifies whether the key should be first verified
77
+#define ACTIONS_RECOVER         0x2 // Specifies whether the key should be recovered. If a key has verify action and the key was verified, RESULTS_ byte will indicate that and recovery will not take place
78
+#define ACTIONS_KEYSET          0x4 // Specifies whether the key was set from command line rather that should be loaded from the eventual -i/-I dump
79
+
80
+// Implementation specific, since we are not 100% sure we can fix the tag nonce
81
+// Suppose from 2^32, only MAX 2^16 tag nonces will appear given current SLEEP_ values
82
+#define MAX_TAG_NONCES                  65536
83
+// Maximum possible states allocated and returned by lsfr_common_prefix(). Used this value in the looping
84
+#define MAX_COMMON_PREFIX_STATES        (1<<20)
85
+// 10 ms, though {WPMCC09} claims 30 us is enough
86
+#define SLEEP_AT_FIELD_OFF              10
87
+// 50 ms, seems pretty good constant, though if you don't like it - make it even 3.1415..., we don't care
88
+#define SLEEP_AFTER_FIELD_ON            50
89
+// Since the 29 bits of {Nr} are constant, darkside varies only "last" (0xFFFFFF1F) 3 bits, thus we have 8 possible parity bits arrays
90
+#define MFCUK_DARKSIDE_MAX_LEVELS       8
91
+
92
+#define MFCUK_DARKSIDE_START_NR         0xDEADBEEF
93
+#define MFCUK_DARKSIDE_START_AR         0xFACECAFE
94
+
95
+typedef struct tag_nonce_entry {
96
+  uint32_t tagNonce; // Tag nonce we target for fixation
97
+  uint8_t spoofFlag; // No spoofing until we have a successful auth with this tagNonce. Once we have, we want to spoof to get the encrypted 0x5 value
98
+  uint32_t num_of_appearances; // For statistics, how many times this tag nonce appeared for the given SLEEP_ values
99
+
100
+  // STAGE1 data for "dark side" and lsfr_common_prefix()
101
+  uint32_t spoofNrPfx; // PARAM: used as pfx, calculated from (spoofNrEnc & 0xFFFFFF1F). BUG: weird way to denote "first 29 prefix bits" in "dark side" paper. Perhaps I see the world different
102
+  uint32_t spoofNrEnc; // {Nr} value which we will be using to make the tag respond with 4 bits
103
+  uint32_t spoofArEnc; // PARAM: used as rr
104
+  uint8_t spoofParBitsEnc; // parity bits we are trying to guess for the first time
105
+  uint8_t spoofNackEnc; // store here the encrypted NACK returned first time we match the parity bits
106
+  uint8_t spoofKs; // store here the keystream ks used for encryptying spoofNackEnc, specifically spoofKs = spoofNackEnc ^ 0x5
107
+
108
+  // STAGE2 data for "dark side" and lsfr_common_prefix()
109
+  int current_out_of_8; // starting from -1 until we find parity for chosen spoofNrEnc,spoofArEnc
110
+  uint8_t parBitsCrntCombination[MFCUK_DARKSIDE_MAX_LEVELS]; // Loops over 32 combinations of the last 5 parity bits which generated the 4 bit NACK in STAGE1
111
+  uint32_t nrEnc[MFCUK_DARKSIDE_MAX_LEVELS]; // the 29 bits constant prefix, varying only 3 bits, thus 8 possible values
112
+  uint32_t arEnc[MFCUK_DARKSIDE_MAX_LEVELS]; // the same reader response as spoofArEnc; redundant but... :)
113
+  uint8_t ks[MFCUK_DARKSIDE_MAX_LEVELS]; // PARAM: used as ks, obtained as (ks[i] = nackEnc[i] ^ 0x5)
114
+  uint8_t nackEnc[MFCUK_DARKSIDE_MAX_LEVELS]; // store here the encrypted 4 bits values which tag responded
115
+  uint8_t parBits[MFCUK_DARKSIDE_MAX_LEVELS]; // store here the values based on spoofParBitsEnc, varying only last 5 bits
116
+  uint8_t parBitsArr[MFCUK_DARKSIDE_MAX_LEVELS][8]; // PARAM: used as par, contains value of parBits byte-bit values just splitted out one bit per byte thus second pair of braces [8]
117
+} tag_nonce_entry_t;
118
+
119
+#endif // _MFCUK_KEYRECOVERY_DARKSIDE_H_

+ 187
- 0
src/mfcuk_finger.c View File

@@ -0,0 +1,187 @@
1
+/*
2
+ LICENSE
3
+
4
+ This program is free software: you can redistribute it and/or modify
5
+ it under the terms of the GNU General Public License as published by
6
+ the Free Software Foundation, either version 2 of the License, or
7
+ (at your option) any later version.
8
+
9
+ This program is distributed in the hope that it will be useful,
10
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
+ GNU General Public License for more details.
13
+
14
+ You should have received a copy of the GNU General Public License
15
+ along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
+*/
17
+
18
+/*
19
+ Package:
20
+    MiFare Classic Universal toolKit (MFCUK)
21
+
22
+ Package version:
23
+    0.1
24
+
25
+ Filename:
26
+    mfcuk_finger.c
27
+
28
+ Description:
29
+    MFCUK fingerprinting and specific data-decoding functionality.
30
+
31
+ License:
32
+    GPL2, Copyright (C) 2009, Andrei Costin
33
+
34
+ * @file mfcuk_finger.c
35
+ * @brief MFCUK fingerprinting and specific data-decoding functionality.
36
+ * @todo add proper error codes
37
+*/
38
+
39
+#include "mfcuk_finger.h"
40
+
41
+mfcuk_finger_tmpl_entry mfcuk_finger_db[] = {
42
+  { "./data/tmpls_fingerprints/mfcuk_tmpl_skgt.mfd", "Sofia SKGT", mfcuk_finger_default_comparator, mfcuk_finger_skgt_decoder, NULL },
43
+  { "./data/tmpls_fingerprints/mfcuk_tmpl_ratb.mfd", "Bucharest RATB", mfcuk_finger_default_comparator, mfcuk_finger_default_decoder, NULL },
44
+  { "./data/tmpls_fingerprints/mfcuk_tmpl_oyster.mfd", "London OYSTER", mfcuk_finger_default_comparator, mfcuk_finger_default_decoder, NULL },
45
+};
46
+
47
+int mfcuk_finger_db_entries = sizeof(mfcuk_finger_db) / sizeof(mfcuk_finger_db[0]);
48
+
49
+int mfcuk_finger_default_decoder(mifare_classic_tag *dump)
50
+{
51
+  if (!dump) {
52
+    fprintf(stderr, "ERROR: cannot decode a NULL pointer :)\n");
53
+    return 0;
54
+  }
55
+
56
+  printf("UID:\t%02x%02x%02x%02x\n", dump->amb[0].mbm.abtUID[0], dump->amb[0].mbm.abtUID[1], dump->amb[0].mbm.abtUID[2], dump->amb[0].mbm.abtUID[3]);
57
+  printf("TYPE:\t%02x\n", dump->amb[0].mbm.btUnknown);
58
+
59
+  return 1;
60
+}
61
+
62
+// Yes, I know C++ class inheritance would perfectly fit the decoders/comparators... Though C is more to my heart. Anyone to rewrite in C++?
63
+int mfcuk_finger_skgt_decoder(mifare_classic_tag *dump)
64
+{
65
+  if (!dump) {
66
+    fprintf(stderr, "ERROR: cannot decode a NULL pointer :)\n");
67
+    return 0;
68
+  }
69
+
70
+  printf("Bulgaria/Sofia/SKGT public transport card information decoder (info credits to Andy)\n");
71
+  mfcuk_finger_default_decoder(dump);
72
+
73
+  printf("LAST TRAVEL DATA\n");
74
+
75
+  // TODO: get proper information
76
+
77
+  return 1;
78
+}
79
+
80
+int mfcuk_finger_default_comparator(mifare_classic_tag *dump, mfcuk_finger_template *tmpl, float *score)
81
+{
82
+  int max_bytes = 0;
83
+  int i;
84
+  int num_bytes_tomatch = 0;
85
+  int num_bytes_matched = 0;
86
+
87
+  if ((!dump) || (!tmpl) || (!score)) {
88
+    return 0;
89
+  }
90
+
91
+  if (IS_MIFARE_CLASSIC_1K_TAG(dump)) {
92
+    max_bytes = MIFARE_CLASSIC_BYTES_PER_BLOCK * MIFARE_CLASSIC_1K_MAX_BLOCKS;
93
+  } else if (IS_MIFARE_CLASSIC_4K_TAG(dump)) {
94
+    max_bytes = MIFARE_CLASSIC_BYTES_PER_BLOCK * MIFARE_CLASSIC_4K_MAX_BLOCKS;
95
+  } else {
96
+    return 0;
97
+  }
98
+
99
+  for (i = 0; i < max_bytes; i++) {
100
+    if (((char *)(&tmpl->mask))[i] == 0x0) {
101
+      continue;
102
+    }
103
+
104
+    num_bytes_tomatch++;
105
+
106
+    if (((char *)(&tmpl->values))[i] == ((char *)dump)[i]) {
107
+      num_bytes_matched++;
108
+    }
109
+  }
110
+
111
+  if (num_bytes_tomatch == 0) {
112
+    return 0;
113
+  } else {
114
+    *score = (float)(num_bytes_matched) / num_bytes_tomatch;
115
+  }
116
+
117
+  return 1;
118
+}
119
+
120
+int mfcuk_finger_load(void)
121
+{
122
+  int i;
123
+  mifare_classic_tag mask;
124
+  mifare_classic_tag values;
125
+  FILE *fp = NULL;
126
+  size_t result = 0;
127
+  mfcuk_finger_template *tmpl_new = NULL;
128
+
129
+  int template_loaded_count = 0;
130
+  for (i = 0; i < mfcuk_finger_db_entries; i++) {
131
+    fp = fopen(mfcuk_finger_db[i].tmpl_filename, "rb");
132
+
133
+    if (!fp) {
134
+      fprintf(stderr, "WARN: cannot open template file '%s'\n", mfcuk_finger_db[i].tmpl_filename);
135
+      continue;
136
+    }
137
+
138
+    // If not read exactly 1 record, something is wrong
139
+    if ((result = fread((void *)(&mask), sizeof(mask), 1, fp)) != 1) {
140
+      fprintf(stderr, "WARN: cannot read MASK from template file '%s'\n", mfcuk_finger_db[i].tmpl_filename);
141
+      fclose(fp);
142
+      continue;
143
+    }
144
+
145
+    // If not read exactly 1 record, something is wrong
146
+    if ((result = fread((void *)(&values), sizeof(values), 1, fp)) != 1) {
147
+      fprintf(stderr, "WARN: cannot read VALUES template file '%s'\n", mfcuk_finger_db[i].tmpl_filename);
148
+      fclose(fp);
149
+      continue;
150
+    }
151
+
152
+    if (mfcuk_finger_db[i].tmpl_data == NULL) {
153
+      if ((tmpl_new = (mfcuk_finger_template *) malloc(sizeof(mfcuk_finger_template))) == NULL) {
154
+        fprintf(stderr, "WARN: cannot allocate memory to template record %d\n", i);
155
+        fclose(fp);
156
+        continue;
157
+      }
158
+
159
+      memcpy(&(tmpl_new->mask), &(mask), sizeof(mask));
160
+      memcpy(&(tmpl_new->values), &(values), sizeof(values));
161
+
162
+      mfcuk_finger_db[i].tmpl_data = tmpl_new;
163
+      template_loaded_count++;
164
+    }
165
+
166
+    if (fp) {
167
+      fclose(fp);
168
+      fp = NULL;
169
+    }
170
+  }
171
+
172
+  return template_loaded_count;
173
+}
174
+
175
+int mfcuk_finger_unload(void)
176
+{
177
+  int i;
178
+
179
+  for (i = 0; i < mfcuk_finger_db_entries; i++) {
180
+    if (mfcuk_finger_db[i].tmpl_data != NULL) {
181
+      free(mfcuk_finger_db[i].tmpl_data);
182
+      mfcuk_finger_db[i].tmpl_data = NULL;
183
+    }
184
+  }
185
+
186
+  return 1;
187
+}

+ 74
- 0
src/mfcuk_finger.h View File

@@ -0,0 +1,74 @@
1
+/*
2
+ LICENSE
3
+
4
+ This program is free software: you can redistribute it and/or modify
5
+ it under the terms of the GNU General Public License as published by
6
+ the Free Software Foundation, either version 2 of the License, or
7
+ (at your option) any later version.
8
+
9
+ This program is distributed in the hope that it will be useful,
10
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
+ GNU General Public License for more details.
13
+
14
+ You should have received a copy of the GNU General Public License
15
+ along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
+*/
17
+
18
+/*
19
+ Package:
20
+    MiFare Classic Universal toolKit (MFCUK)
21
+
22
+ Package version:
23
+    0.1
24
+
25
+ Filename:
26
+    mfcuk_finger.h
27
+
28
+ Description:
29
+    MFCUK fingerprinting and specific data-decoding functionality.
30
+
31
+ License:
32
+    GPL2, Copyright (C) 2009, Andrei Costin
33
+
34
+ * @file mfcuk_finger.h
35
+ * @brief MFCUK fingerprinting and specific data-decoding functionality.
36
+*/
37
+
38
+#ifndef _MFCUK_FINGER_H_
39
+#define _MFCUK_FINGER_H_
40
+
41
+#include <stdio.h>
42
+#include <stdlib.h>
43
+#include <string.h>
44
+
45
+#include "mfcuk_mifare.h"
46
+
47
+// Wrapping an ugly template into an externally pleasant name. To implement proper template later.
48
+typedef struct _mfcuk_finger_template_ {
49
+  mifare_classic_tag mask;
50
+  mifare_classic_tag values;
51
+} mfcuk_finger_template;
52
+
53
+// Function type definition, to be used for custom decoders/comparators
54
+typedef int (*mfcuk_finger_comparator)(mifare_classic_tag *dump, mfcuk_finger_template *tmpl, float *score);
55
+typedef int (*mfcuk_finger_decoder)(mifare_classic_tag *dump);
56
+
57
+// Naive implementation of a self-contained fingerprint database entry
58
+typedef struct _mfcuk_finger_tmpl_entry_ {
59
+  const char *tmpl_filename;
60
+  const char *tmpl_name;
61
+  mfcuk_finger_comparator tmpl_comparison_func;
62
+  mfcuk_finger_decoder tmpl_decoder_func;
63
+  mfcuk_finger_template *tmpl_data;
64
+} mfcuk_finger_tmpl_entry;
65
+
66
+int mfcuk_finger_default_comparator(mifare_classic_tag *dump, mfcuk_finger_template *tmpl, float *score);
67
+int mfcuk_finger_default_decoder(mifare_classic_tag *dump);
68
+int mfcuk_finger_skgt_decoder(mifare_classic_tag *dump);
69
+
70
+// "Housekeeping" functions
71
+int mfcuk_finger_load(void);
72
+int mfcuk_finger_unload(void);
73
+
74
+#endif

+ 463
- 0
src/mfcuk_mifare.c View File

@@ -0,0 +1,463 @@
1
+/*
2
+ Package:
3
+    MiFare Classic Universal toolKit (MFCUK)
4
+
5
+ Package version:
6
+    0.1
7
+
8
+ Filename:
9
+    mfcuk_mifare.c
10
+
11
+ Description:
12
+    MFCUK defines and function implementation file extending
13
+    mainly libnfc's "mifare.h" interface/functionality.
14
+
15
+ Contact, bug-reports:
16
+    http://andreicostin.com/
17
+    mailto:zveriu@gmail.com
18
+
19
+ License:
20
+    GPL2 (see below), Copyright (C) 2009, Andrei Costin
21
+
22
+ * @file mfcuk_mifare.c
23
+ * @brief
24
+*/
25
+
26
+/*
27
+ VERSION HISTORY
28
+--------------------------------------------------------------------------------
29
+| Number     : 0.1
30
+| dd/mm/yyyy : 23/11/2009
31
+| Author     : zveriu@gmail.com, http://andreicostin.com
32
+| Description: Moved bulk of defines and functions from "mfcuk_keyrecovery_darkside.c"
33
+--------------------------------------------------------------------------------
34
+*/
35
+
36
+/*
37
+ LICENSE
38
+
39
+ This program is free software: you can redistribute it and/or modify
40
+ it under the terms of the GNU General Public License as published by
41
+ the Free Software Foundation, either version 2 of the License, or
42
+ (at your option) any later version.
43
+
44
+ This program is distributed in the hope that it will be useful,
45
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
46
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
47
+ GNU General Public License for more details.
48
+
49
+ You should have received a copy of the GNU General Public License
50
+ along with this program.  If not, see <http://www.gnu.org/licenses/>.
51
+*/
52
+
53
+#include "mfcuk_mifare.h"
54
+
55
+// Default keys used as a *BIG* mistake in many applications - especially System Integrators should pay attention!
56
+uint8_t mfcuk_default_keys[][MIFARE_CLASSIC_KEY_BYTELENGTH] = {
57
+  {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // Place-holder for current key to verify
58
+  {0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
59
+  {0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5},
60
+  {0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5},
61
+  {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
62
+  {0x4d, 0x3a, 0x99, 0xc3, 0x51, 0xdd},
63
+  {0x1a, 0x98, 0x2c, 0x7e, 0x45, 0x9a},
64
+  {0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7},
65
+  {0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff},
66
+};
67
+
68
+int mfcuk_default_keys_num = sizeof(mfcuk_default_keys) / sizeof(mfcuk_default_keys[0]);
69
+
70
+bool is_valid_block(uint8_t bTagType, uint32_t uiBlock)
71
+{
72
+  if (IS_MIFARE_CLASSIC_1K(bTagType) && (uiBlock < MIFARE_CLASSIC_1K_MAX_BLOCKS)) {
73
+    return true;
74
+  }
75
+
76
+  if (IS_MIFARE_CLASSIC_4K(bTagType) && (uiBlock < MIFARE_CLASSIC_4K_MAX_BLOCKS)) {
77
+    return true;
78
+  }
79
+
80
+  return false;
81
+}
82
+
83
+bool is_valid_sector(uint8_t bTagType, uint32_t uiSector)
84
+{
85
+  if (IS_MIFARE_CLASSIC_1K(bTagType) && (uiSector < MIFARE_CLASSIC_1K_MAX_SECTORS)) {
86
+    return true;
87
+  }
88
+
89
+  if (IS_MIFARE_CLASSIC_4K(bTagType) && (uiSector < MIFARE_CLASSIC_4K_MAX_SECTORS)) {
90
+    return true;
91
+  }
92
+
93
+  return false;
94
+}
95
+
96
+bool is_first_block(uint8_t bTagType, uint32_t uiBlock)
97
+{
98
+  if (!is_valid_block(bTagType, uiBlock)) {
99
+    return false;
100
+  }
101
+
102
+  // Test if we are in the small or big sectors
103
+  if (uiBlock < MIFARE_CLASSIC_4K_MAX_BLOCKS1) {
104
+    // For Mifare Classic 1K, it will enter always here
105
+    return ((uiBlock) % (MIFARE_CLASSIC_4K_BLOCKS_PER_SECTOR1) == 0);
106
+  } else {
107
+    // This branch will enter only for Mifare Classic 4K big sectors
108
+    return ((uiBlock) % (MIFARE_CLASSIC_4K_BLOCKS_PER_SECTOR2) == 0);
109
+  }
110
+
111
+  // Should not reach here, but... never know
112
+  return false;
113
+}
114
+
115
+bool is_trailer_block(uint8_t bTagType, uint32_t uiBlock)
116
+{
117
+  if (!is_valid_block(bTagType, uiBlock)) {
118
+    return false;
119
+  }
120
+
121
+  // Test if we are in the small or big sectors
122
+  if (uiBlock < MIFARE_CLASSIC_4K_MAX_BLOCKS1) {
123
+    // For Mifare Classic 1K, it will enter always here
124
+    return ((uiBlock + 1) % (MIFARE_CLASSIC_4K_BLOCKS_PER_SECTOR1) == 0);
125
+  } else {
126
+    // This branch will enter only for Mifare Classic 4K big sectors
127
+    return ((uiBlock + 1) % (MIFARE_CLASSIC_4K_BLOCKS_PER_SECTOR2) == 0);
128
+  }
129
+
130
+  // Should not reach here, but... never know
131
+  return false;
132
+}
133
+
134
+uint32_t get_first_block(uint8_t bTagType, uint32_t uiBlock)
135
+{
136
+  if (!is_valid_block(bTagType, uiBlock)) {
137
+    return MIFARE_CLASSIC_INVALID_BLOCK;
138
+  }
139
+
140
+  // Test if we are in the small or big sectors
141
+  if (uiBlock < MIFARE_CLASSIC_4K_MAX_BLOCKS1) {
142
+    // Integer divide, then integer multiply
143
+    return (uiBlock / MIFARE_CLASSIC_4K_BLOCKS_PER_SECTOR1) * MIFARE_CLASSIC_4K_BLOCKS_PER_SECTOR1;
144
+  } else {
145
+    uint32_t tmp = uiBlock - MIFARE_CLASSIC_4K_MAX_BLOCKS1;
146
+    return MIFARE_CLASSIC_4K_MAX_BLOCKS1 + (tmp / MIFARE_CLASSIC_4K_BLOCKS_PER_SECTOR2) * MIFARE_CLASSIC_4K_BLOCKS_PER_SECTOR2;
147
+  }
148
+
149
+  // Should not reach here, but... never know
150
+  return MIFARE_CLASSIC_INVALID_BLOCK;
151
+}
152
+
153
+uint32_t get_trailer_block(uint8_t bTagType, uint32_t uiBlock)
154
+{
155
+  if (!is_valid_block(bTagType, uiBlock)) {
156
+    return MIFARE_CLASSIC_INVALID_BLOCK;
157
+  }
158
+
159
+  // Test if we are in the small or big sectors
160
+  if (uiBlock < MIFARE_CLASSIC_4K_MAX_BLOCKS1) {
161
+    // Integer divide, then integer multiply
162
+    return (uiBlock / MIFARE_CLASSIC_4K_BLOCKS_PER_SECTOR1) * MIFARE_CLASSIC_4K_BLOCKS_PER_SECTOR1 + (MIFARE_CLASSIC_4K_BLOCKS_PER_SECTOR1 - 1);
163
+  } else {
164
+    uint32_t tmp = uiBlock - MIFARE_CLASSIC_4K_MAX_BLOCKS1;
165
+    return MIFARE_CLASSIC_4K_MAX_BLOCKS1 + (tmp / MIFARE_CLASSIC_4K_BLOCKS_PER_SECTOR2) * MIFARE_CLASSIC_4K_BLOCKS_PER_SECTOR2 + (MIFARE_CLASSIC_4K_BLOCKS_PER_SECTOR2 - 1);
166
+  }
167
+
168
+  // Should not reach here, but... never know
169
+  return MIFARE_CLASSIC_INVALID_BLOCK;
170
+}
171
+
172
+bool is_big_sector(uint8_t bTagType, uint32_t uiSector)
173
+{
174
+  if (!is_valid_sector(bTagType, uiSector)) {
175
+    return false;
176
+  }
177
+
178
+  if (uiSector >= MIFARE_CLASSIC_4K_MAX_SECTORS1) {
179
+    return true;
180
+  }
181
+
182
+  return false;
183
+}
184
+
185
+uint32_t get_first_block_for_sector(uint8_t bTagType, uint32_t uiSector)
186
+{
187
+  if (!is_valid_sector(bTagType, uiSector)) {
188
+    return MIFARE_CLASSIC_INVALID_BLOCK;
189
+  }
190
+
191
+  if (uiSector < MIFARE_CLASSIC_4K_MAX_SECTORS1) {
192
+    // For Mifare Classic 1K, it will enter always here
193
+    return (uiSector * MIFARE_CLASSIC_4K_BLOCKS_PER_SECTOR1);
194
+  } else {
195
+    // For Mifare Classic 4K big sectors it will enter always here
196
+    uint32_t tmp = uiSector - MIFARE_CLASSIC_4K_MAX_SECTORS1;
197
+    return MIFARE_CLASSIC_4K_MAX_BLOCKS1 + (tmp * MIFARE_CLASSIC_4K_BLOCKS_PER_SECTOR2);
198
+  }
199
+
200
+  // Should not reach here, but... never know
201
+  return MIFARE_CLASSIC_INVALID_BLOCK;
202
+}
203
+
204
+uint32_t get_trailer_block_for_sector(uint8_t bTagType, uint32_t uiSector)
205
+{
206
+  if (!is_valid_sector(bTagType, uiSector)) {
207
+    return MIFARE_CLASSIC_INVALID_BLOCK;
208
+  }
209
+
210
+  if (uiSector < MIFARE_CLASSIC_4K_MAX_SECTORS1) {
211
+    // For Mifare Classic 1K, it will enter always here
212
+    return (uiSector * MIFARE_CLASSIC_4K_BLOCKS_PER_SECTOR1) + (MIFARE_CLASSIC_4K_BLOCKS_PER_SECTOR1 - 1);
213
+  } else {
214
+    // For Mifare Classic 4K big sectors it will enter always here
215
+    uint32_t tmp = uiSector - MIFARE_CLASSIC_4K_MAX_SECTORS1;
216
+    return MIFARE_CLASSIC_4K_MAX_BLOCKS1 + (tmp * MIFARE_CLASSIC_4K_BLOCKS_PER_SECTOR2) + (MIFARE_CLASSIC_4K_BLOCKS_PER_SECTOR2 - 1);
217
+  }
218
+
219
+  // Should not reach here, but... never know
220
+  return MIFARE_CLASSIC_INVALID_BLOCK;
221
+}
222
+
223
+uint32_t get_sector_for_block(uint8_t bTagType, uint32_t uiBlock)
224
+{
225
+  if (!is_valid_block(bTagType, uiBlock)) {
226
+    return MIFARE_CLASSIC_INVALID_BLOCK;
227
+  }
228
+
229
+  // Test if we are in the small or big sectors
230
+  if (uiBlock < MIFARE_CLASSIC_4K_MAX_BLOCKS1) {
231
+    // For Mifare Classic 1K, it will enter always here
232
+    return (uiBlock / MIFARE_CLASSIC_4K_BLOCKS_PER_SECTOR1);
233
+  } else {
234
+    uint32_t tmp = uiBlock - MIFARE_CLASSIC_4K_MAX_BLOCKS1;
235
+    return MIFARE_CLASSIC_4K_MAX_SECTORS1 + (tmp / MIFARE_CLASSIC_4K_BLOCKS_PER_SECTOR2);
236
+  }
237
+
238
+  // Should not reach here, but... never know
239
+  return MIFARE_CLASSIC_INVALID_BLOCK;
240
+}
241
+
242
+// Test case function for checking correct functionality of the block/sector is_ ang get_ functions
243
+void test_mifare_classic_blocks_sectors_functions(uint8_t bTagType)
244
+{
245
+  uint32_t i;
246
+  uint32_t max_blocks, max_sectors;
247
+
248
+  if (IS_MIFARE_CLASSIC_1K(bTagType)) {
249
+    printf("\nMIFARE CLASSIC 1K\n");
250
+    max_blocks = MIFARE_CLASSIC_1K_MAX_BLOCKS;
251
+    max_sectors = MIFARE_CLASSIC_1K_MAX_SECTORS;
252
+  } else if (IS_MIFARE_CLASSIC_4K(bTagType)) {
253
+    printf("\nMIFARE CLASSIC 4K\n");
254
+    max_blocks = MIFARE_CLASSIC_4K_MAX_BLOCKS;
255
+    max_sectors = MIFARE_CLASSIC_4K_MAX_SECTORS;
256
+  } else {
257
+    return;
258
+  }
259
+
260
+  // Include one invalid block, that is why we add +1
261
+  for (i = 0; i < max_blocks + 1; i++) {
262
+    printf("BLOCK %d\n", i);
263
+    printf("\t is_valid_block: %c\n", (is_valid_block(bTagType, i) ? 'Y' : 'N'));
264
+    printf("\t is_first_block: %c\n", (is_first_block(bTagType, i) ? 'Y' : 'N'));
265
+    printf("\t is_trailer_block: %c\n", (is_trailer_block(bTagType, i) ? 'Y' : 'N'));
266
+    printf("\t get_first_block: %d\n", get_first_block(bTagType, i));
267
+    printf("\t get_trailer_block: %d\n", get_trailer_block(bTagType, i));
268
+    printf("\t get_sector_for_block: %d\n", get_sector_for_block(bTagType, i));
269
+  }
270
+
271
+  // Include one invalid sector, that is why we add +1
272
+  for (i = 0; i < max_sectors + 1; i++) {
273
+    printf("SECTOR %d\n", i);
274
+    printf("\t is_valid_sector: %c\n", (is_valid_sector(bTagType, i) ? 'Y' : 'N'));
275
+    printf("\t is_big_sector: %c\n", (is_big_sector(bTagType, i) ? 'Y' : 'N'));
276
+    printf("\t get_first_block_for_sector: %d\n", get_first_block_for_sector(bTagType, i));
277
+    printf("\t get_trailer_block_for_sector: %d\n", get_trailer_block_for_sector(bTagType, i));
278
+  }
279
+
280
+}
281
+
282
+bool mfcuk_save_tag_dump(const char *filename, mifare_classic_tag *tag)
283
+{
284
+  FILE *fp;
285
+  size_t result;
286
+
287
+  fp = fopen(filename, "wb");
288
+  if (!fp) {
289
+    return false;
290
+  }
291
+
292
+  // Expect to write 1 record
293
+  result = fwrite((void *) tag, sizeof(*tag), 1, fp);
294
+
295
+  // If not written exactly 1 record, something is wrong
296
+  if (result != 1) {
297
+    fclose(fp);
298
+    return false;
299
+  }
300
+
301
+  fclose(fp);
302
+  return true;
303
+}
304
+
305
+bool mfcuk_save_tag_dump_ext(const char *filename, mifare_classic_tag_ext *tag_ext)
306
+{
307
+  FILE *fp;
308
+  size_t result;
309
+
310
+  fp = fopen(filename, "wb");
311
+  if (!fp) {
312
+    return false;
313
+  }
314
+
315
+  // Expect to write 1 record
316
+  result = fwrite((void *) tag_ext, sizeof(*tag_ext), 1, fp);
317
+
318
+  // If not written exactly 1 record, something is wrong
319
+  if (result != 1) {
320
+    fclose(fp);
321
+    return false;
322
+  }
323
+
324
+  fclose(fp);
325
+  return true;
326
+}
327
+
328
+bool mfcuk_load_tag_dump(const char *filename, mifare_classic_tag *tag)
329
+{
330
+  FILE *fp;
331
+  size_t result;
332
+
333
+  fp = fopen(filename, "rb");
334
+  if (!fp) {
335
+    return false;
336
+  }
337
+
338
+  // Expect to read 1 record
339
+  result = fread((void *) tag, sizeof(*tag), 1, fp);
340
+
341
+  // If not read exactly 1 record, something is wrong
342
+  if (result != 1) {
343
+    fclose(fp);
344
+    return false;
345
+  }
346
+
347
+  fclose(fp);
348
+  return true;
349
+}
350
+
351
+bool mfcuk_load_tag_dump_ext(const char *filename, mifare_classic_tag_ext *tag_ext)
352
+{
353
+  FILE *fp;
354
+  size_t result;
355
+
356
+  fp = fopen(filename, "rb");
357
+  if (!fp) {
358
+    return false;
359
+  }
360
+
361
+  // Expect to read 1 record
362
+  result = fread((void *) tag_ext, sizeof(*tag_ext), 1, fp);
363
+
364
+  // If not read exactly 1 record, something is wrong
365
+  if (result != sizeof(*tag_ext)) {
366
+    fclose(fp);
367
+    return false;
368
+  }
369
+
370
+  fclose(fp);
371
+  return true;
372
+}
373
+
374
+void print_mifare_classic_tag_keys(const char *title, mifare_classic_tag *tag)
375
+{
376
+  uint32_t i, max_blocks, trailer_block;
377
+  uint8_t bTagType;
378
+  mifare_classic_block_trailer *ptr_trailer = NULL;
379
+
380
+  if (!tag) {
381
+    return;
382
+  }
383
+
384
+  bTagType = tag->amb->mbm.btUnknown;
385
+
386
+  if (!IS_MIFARE_CLASSIC_1K(bTagType) && !IS_MIFARE_CLASSIC_4K(bTagType)) {
387
+    return;
388
+  }
389
+
390
+  printf("%s - UID %02x %02x %02x %02x - TYPE 0x%02x (%s)\n",
391
+         title, tag->amb->mbm.abtUID[0], tag->amb->mbm.abtUID[1], tag->amb->mbm.abtUID[2], tag->amb->mbm.abtUID[3], bTagType,
392
+         (IS_MIFARE_CLASSIC_1K(bTagType) ? (MIFARE_CLASSIC_1K_NAME) : (IS_MIFARE_CLASSIC_4K(bTagType) ? (MIFARE_CLASSIC_4K_NAME) : (MIFARE_CLASSIC_UNKN_NAME)))
393
+        );
394
+  printf("-------------------------------------------------------\n");
395
+  printf("Sector\t|    Key A\t|    AC bits\t|    Key B\n");
396
+  printf("-------------------------------------------------------\n");
397
+
398
+  if (IS_MIFARE_CLASSIC_1K(tag->amb->mbm.btUnknown)) {
399
+    max_blocks = MIFARE_CLASSIC_1K_MAX_BLOCKS;
400
+  } else {
401
+    max_blocks = MIFARE_CLASSIC_4K_MAX_BLOCKS;
402
+  }
403
+
404
+  for (i = 0; i < max_blocks; i++) {
405
+    trailer_block = get_trailer_block(bTagType, i);
406
+
407
+    if (!is_valid_block(bTagType, trailer_block)) {
408
+      break;
409
+    }
410
+
411
+    ptr_trailer = (mifare_classic_block_trailer *)((char *)tag + (trailer_block * MIFARE_CLASSIC_BYTES_PER_BLOCK));
412
+
413
+    printf("%d\t|  %02x%02x%02x%02x%02x%02x\t|  %02x%02x%02x%02x\t|  %02x%02x%02x%02x%02x%02x\n",
414
+           get_sector_for_block(bTagType, trailer_block),
415
+           ptr_trailer->abtKeyA[0], ptr_trailer->abtKeyA[1], ptr_trailer->abtKeyA[2],
416
+           ptr_trailer->abtKeyA[3], ptr_trailer->abtKeyA[4], ptr_trailer->abtKeyA[5],
417
+           ptr_trailer->abtAccessBits[0], ptr_trailer->abtAccessBits[1], ptr_trailer->abtAccessBits[2], ptr_trailer->abtAccessBits[3],
418
+           ptr_trailer->abtKeyB[0], ptr_trailer->abtKeyB[1], ptr_trailer->abtKeyB[2],
419
+           ptr_trailer->abtKeyB[3], ptr_trailer->abtKeyB[4], ptr_trailer->abtKeyB[5]
420
+          );
421
+
422
+    // Go beyond current trailer block, i.e. go to next sector
423
+    i = trailer_block;
424
+  }
425
+
426
+  printf("\n");
427
+
428
+  return;
429
+}
430
+
431
+bool mfcuk_key_uint64_to_arr(const uint64_t *ui64Key, uint8_t *arr6Key)
432
+{
433
+  int i;
434
+
435
+  if (!ui64Key || !arr6Key) {
436
+    return false;
437
+  }
438
+
439
+  for (i = 0; i < MIFARE_CLASSIC_KEY_BYTELENGTH; i++) {
440
+    arr6Key[i] = (uint8_t)(((*ui64Key) >> 8 * (MIFARE_CLASSIC_KEY_BYTELENGTH - i - 1)) & 0xFF);
441
+  }
442
+
443
+  return true;
444
+}
445
+
446
+bool mfcuk_key_arr_to_uint64(const uint8_t *arr6Key, uint64_t *ui64Key)
447
+{
448
+  uint64_t key = 0;
449
+  int i;
450
+
451
+  if (!ui64Key || !arr6Key) {
452
+    return false;
453
+  }
454
+
455
+  for (i = 0; i < MIFARE_CLASSIC_KEY_BYTELENGTH; i++, key <<= 8) {
456
+    key |= arr6Key[i];
457
+  }
458
+  key >>= 8;
459
+
460
+  *ui64Key = key;
461
+
462
+  return true;
463
+}

+ 145
- 0
src/mfcuk_mifare.h View File

@@ -0,0 +1,145 @@
1
+/*
2
+ Package:
3
+    MiFare Classic Universal toolKit (MFCUK)
4
+
5
+ Package version:
6
+    0.1
7
+
8
+ Filename:
9
+    mfcuk_mifare.h
10
+
11
+ Description:
12
+    MFCUK defines and function prototypes header file extending
13
+    mainly libnfc's "mifare.h" interface/functionality.
14
+
15
+ Contact, bug-reports:
16
+    http://andreicostin.com/
17
+    mailto:zveriu@gmail.com
18
+
19
+ License:
20
+    GPL2 (see below), Copyright (C) 2009, Andrei Costin
21
+
22
+ * @file mfcuk_mifare.h
23
+ * @brief
24
+*/
25
+
26
+/*
27
+ VERSION HISTORY
28
+--------------------------------------------------------------------------------
29
+| Number     : 0.1
30
+| dd/mm/yyyy : 23/11/2009
31
+| Author     : zveriu@gmail.com, http://andreicostin.com
32
+| Description: Moved bulk of defines and functions from "mfcuk_keyrecovery_darkside.c"
33
+--------------------------------------------------------------------------------
34
+*/
35
+
36
+/*
37
+ LICENSE
38
+
39
+ This program is free software: you can redistribute it and/or modify
40
+ it under the terms of the GNU General Public License as published by
41
+ the Free Software Foundation, either version 2 of the License, or
42
+ (at your option) any later version.
43
+
44
+ This program is distributed in the hope that it will be useful,
45
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
46
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
47
+ GNU General Public License for more details.
48
+
49
+ You should have received a copy of the GNU General Public License
50
+ along with this program.  If not, see <http://www.gnu.org/licenses/>.
51
+*/
52
+
53
+#ifndef _MFCUK_MIFARE_H_
54
+#define _MFCUK_MIFARE_H_
55
+
56
+#include <stdio.h>
57
+#include <stdlib.h>
58
+
59
+#include <nfc/nfc.h>
60
+#include "mifare.h"
61
+
62
+#define MIFARE_CLASSIC_UID_BYTELENGTH           4       // Length of a Mifare Classic UID in bytes
63
+#define MIFARE_CLASSIC_KEY_BYTELENGTH           6       // Length of a Mifare Classic key in bytes
64
+#define MIFARE_CLASSIC_1K_NAME                  "MC1K"
65
+#define MIFARE_CLASSIC_4K_NAME                  "MC4K"
66
+#define MIFARE_CLASSIC_UNKN_NAME                "UNKN"
67
+#define MIFARE_CLASSIC_1K                       0x08    // MF1ICS50 Functional Specifications - 0x08
68
+#define MIFARE_CLASSIC_4K                       0x18    // MF1ICS70 Functional Specifications - 0x18
69
+#define MIFARE_DESFIRE                          0x20    // XXXXXXXX Functional Specifications - 0x20
70
+#define MIFARE_CLASSIC_1K_RATB                  0x88    // Infineon Licensed Mifare 1K = 0x88 (thanks JPS)
71
+#define MIFARE_CLASSIC_4K_SKGT                  0x98    // Infineon Licensed Mifare 4K = 0x98???
72
+
73
+#define IS_MIFARE_CLASSIC_1K(ats_sak)           ( ((ats_sak) == MIFARE_CLASSIC_1K) || ((ats_sak) == MIFARE_CLASSIC_1K_RATB) )
74
+#define IS_MIFARE_CLASSIC_4K(ats_sak)           ( ((ats_sak) == MIFARE_CLASSIC_4K) || ((ats_sak) == MIFARE_CLASSIC_4K_SKGT) )
75
+#define IS_MIFARE_DESFIRE(ats_sak)              ( ((ats_sak) == MIFARE_DESFIRE) )
76
+
77
+#define IS_MIFARE_CLASSIC_1K_TAG(tag)           IS_MIFARE_CLASSIC_1K(tag->amb[0].mbm.btUnknown)
78
+#define IS_MIFARE_CLASSIC_4K_TAG(tag)           IS_MIFARE_CLASSIC_4K(tag->amb[0].mbm.btUnknown)
79
+#define IS_MIFARE_DESFIRE_TAG(tag)              IS_MIFARE_DESFIRE(tag->amb[0].mbm.btUnknown)
80
+
81
+#define MIFARE_CLASSIC_BYTES_PER_BLOCK          16 // Common for Mifare Classic 1K and Mifare Classic 4K
82
+#define MIFARE_CLASSIC_INVALID_BLOCK            0xFFFFFFFF
83
+
84
+#define MIFARE_CLASSIC_1K_MAX_SECTORS           16
85
+#define MIFARE_CLASSIC_1K_BLOCKS_PER_SECTOR     4
86
+#define MIFARE_CLASSIC_1K_MAX_BLOCKS            ( (MIFARE_CLASSIC_1K_MAX_SECTORS) * (MIFARE_CLASSIC_1K_BLOCKS_PER_SECTOR) )
87
+
88
+#define MIFARE_CLASSIC_4K_MAX_SECTORS1          32
89
+#define MIFARE_CLASSIC_4K_BLOCKS_PER_SECTOR1    MIFARE_CLASSIC_1K_BLOCKS_PER_SECTOR // Possibly NXP made it for Mifare 1K backward compatibility
90
+#define MIFARE_CLASSIC_4K_MAX_BLOCKS1           ( (MIFARE_CLASSIC_4K_MAX_SECTORS1) * (MIFARE_CLASSIC_4K_BLOCKS_PER_SECTOR1) )
91
+
92
+#define MIFARE_CLASSIC_4K_MAX_SECTORS2          8
93
+#define MIFARE_CLASSIC_4K_BLOCKS_PER_SECTOR2    16
94
+#define MIFARE_CLASSIC_4K_MAX_BLOCKS2           ( (MIFARE_CLASSIC_4K_MAX_SECTORS2) * (MIFARE_CLASSIC_4K_BLOCKS_PER_SECTOR2) )
95
+
96
+#define MIFARE_CLASSIC_4K_MAX_SECTORS           ( (MIFARE_CLASSIC_4K_MAX_SECTORS1) + (MIFARE_CLASSIC_4K_MAX_SECTORS2) )
97
+#define MIFARE_CLASSIC_4K_MAX_BLOCKS            ( (MIFARE_CLASSIC_4K_MAX_BLOCKS1) + (MIFARE_CLASSIC_4K_MAX_BLOCKS2) )
98
+
99
+#define MFCUK_EXTENDED_DESCRIPTION_LENGTH       128
100
+
101
+// Define an extended type of dump, basically a wrapper dump around basic tag dump
102
+typedef struct {
103
+  uint32_t uid;  // looks redundant, but it is easier to use dmp.uid instead of dmp.amb.mbm.abtUID[0]...[3]
104
+  uint8_t type; // ATS/SAK from ti.tia.btSak, example 0x08h for Mifare 1K, 0x18h for Mifare 4K
105
+  char datetime[14]; // non-zero-terminated date-time of dump in format YYYYMMDDH24MISS, example 20091114231541 - 14 Nov 2009, 11:15:41 PM
106
+  char description[MFCUK_EXTENDED_DESCRIPTION_LENGTH]; // a description of the tag dump, example "RATB_DUMP_BEFORE_PAY"
107
+  mifare_classic_tag tag_basic;
108
+} mifare_classic_tag_ext;
109
+
110
+// Define type of keys (A or B) in NXP notation
111
+typedef enum {
112
+  keyA = 0x60,
113
+  keyB = 0x61,
114
+} mifare_key_type;
115
+
116
+// Default keys used as a *BIG* mistake in many applications - especially System Integrators should pay attention!
117
+extern uint8_t mfcuk_default_keys[][MIFARE_CLASSIC_KEY_BYTELENGTH];
118
+extern int mfcuk_default_keys_num;
119
+
120
+bool is_valid_block(uint8_t bTagType, uint32_t uiBlock);
121
+bool is_valid_sector(uint8_t bTagType, uint32_t uiSector);
122
+bool is_first_block(uint8_t bTagType, uint32_t uiBlock);
123
+bool is_trailer_block(uint8_t bTagType, uint32_t uiBlock);
124
+uint32_t get_first_block(uint8_t bTagType, uint32_t uiBlock);
125
+uint32_t get_trailer_block(uint8_t bTagType, uint32_t uiBlock);
126
+bool is_big_sector(uint8_t bTagType, uint32_t uiSector);
127
+uint32_t get_first_block_for_sector(uint8_t bTagType, uint32_t uiSector);
128
+uint32_t get_trailer_block_for_sector(uint8_t bTagType, uint32_t uiSector);
129
+uint32_t get_sector_for_block(uint8_t bTagType, uint32_t uiBlock);
130
+bool is_first_sector(uint8_t bTagType, uint32_t uiSector);
131
+bool is_first_big_sector(uint8_t bTagType, uint32_t uiSector);
132
+bool is_first_small_sector(uint8_t bTagType, uint32_t uiSector);
133
+bool is_last_sector(uint8_t bTagType, uint32_t uiSector);
134
+bool is_last_big_sector(uint8_t bTagType, uint32_t uiSector);
135
+bool is_last_small_sector(uint8_t bTagType, uint32_t uiSector);
136
+void test_mifare_classic_blocks_sectors_functions(uint8_t bTagType);
137
+bool mfcuk_save_tag_dump(const char *filename, mifare_classic_tag *tag);
138
+bool mfcuk_save_tag_dump_ext(const char *filename, mifare_classic_tag_ext *tag_ext);
139
+bool mfcuk_load_tag_dump(const char *filename, mifare_classic_tag *tag);
140
+bool mfcuk_load_tag_dump_ext(const char *filename, mifare_classic_tag_ext *tag_ext);
141
+void print_mifare_classic_tag_keys(const char *title, mifare_classic_tag *tag);
142
+bool mfcuk_key_uint64_to_arr(const uint64_t *ui64Key, uint8_t *arr6Key);
143
+bool mfcuk_key_arr_to_uint64(const uint8_t *arr6Key, uint64_t *ui64Key);
144
+
145
+#endif // _MFCUK_MIFARE_H_

+ 81
- 0
src/mfcuk_utils.c View File

@@ -0,0 +1,81 @@
1
+/*
2
+ Package:
3
+    MiFare Classic Universal toolKit (MFCUK)
4
+
5
+ Package version:
6
+    0.1
7
+
8
+ Filename:
9
+    mfcuk_utils.c
10
+
11
+ Description:
12
+    MFCUK common utility functions implementation.
13
+
14
+ License:
15
+    GPL2 (see below), Copyright (C) 2009, Andrei Costin
16
+
17
+ * @file mfcuk_utils.c
18
+ * @brief
19
+*/
20
+
21
+/*
22
+ VERSION HISTORY
23
+--------------------------------------------------------------------------------
24
+| Number     : 0.1
25
+| dd/mm/yyyy : 23/11/2009
26
+| Author     : zveriu@gmail.com, http://andreicostin.com
27
+| Description: Moved bulk of defines and prototypes from "mfcuk_keyrecovery_darkside.c"
28
+--------------------------------------------------------------------------------
29
+*/
30
+
31
+/*
32
+ LICENSE
33
+
34
+ This program is free software: you can redistribute it and/or modify
35
+ it under the terms of the GNU General Public License as published by
36
+ the Free Software Foundation, either version 2 of the License, or
37
+ (at your option) any later version.
38
+
39
+ This program is distributed in the hope that it will be useful,
40
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
41
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
42
+ GNU General Public License for more details.
43
+
44
+ You should have received a copy of the GNU General Public License
45
+ along with this program.  If not, see <http://www.gnu.org/licenses/>.
46
+*/
47
+
48
+#include "mfcuk_utils.h"
49
+
50
+#ifdef __STDC__
51
+struct timeval global_timeout;
52
+#endif
53
+
54
+/*
55
+http://www.velocityreviews.com/forums/t451319-advice-required-on-my-ascii-to-hex-conversion-c.html
56
+Basically, converting a hex digit into a hex nibble (4 binary digits) algorithm looks like;
57
+        char xdigit; // hex digit to convert [0-9A-Fa-f]
58
+        xdigit = tolower(xdigit); // make it lowercase [0-9a-f]
59
+        xdigit -= '0'; // if it was a [0-9] digit, it's the value now
60
+        if(xdigit > 9) // if it was a [a-f] digit, compensate for that
61
+        xdigit = xdigit + '0' - 'a';
62
+The below code is just an optimization of the algorithm. Maxim Yegorushkin
63
+*/
64
+
65
+/*inline*/
66
+int is_hex(char c)
67
+{
68
+  return (c >= '0' && c <= '9') || ((c | 0x20) >= 'a' && (c | 0x20) <= 'f');
69
+}
70
+
71
+/*inline*/
72
+unsigned char hex2bin(unsigned char h, unsigned char l)
73
+{
74
+  h |= 0x20; // to lower
75
+  h -= 0x30;
76
+  h -= -(h > 9) & 0x27;
77
+  l |= 0x20;
78
+  l -= 0x30;
79
+  l -= -(l > 9) & 0x27;
80
+  return h << 4 | l;
81
+}

+ 104
- 0
src/mfcuk_utils.h View File

@@ -0,0 +1,104 @@
1
+/*
2
+ Package:
3
+    MiFare Classic Universal toolKit (MFCUK)
4
+
5
+ Package version:
6
+    0.1
7
+
8
+ Filename:
9
+    mfcuk_utils.h
10
+
11
+ Description:
12
+    MFCUK common utility functions prototypes.
13
+
14
+ License:
15
+    GPL2 (see below), Copyright (C) 2009, Andrei Costin
16
+
17
+ * @file mfcuk_utils.h/
18
+ * @brief
19
+*/
20
+
21
+/*
22
+ VERSION HISTORY
23
+--------------------------------------------------------------------------------
24
+| Number     : 0.1
25
+| dd/mm/yyyy : 23/11/2009
26
+| Author     : zveriu@gmail.com, http://andreicostin.com
27
+| Description: Moved bulk of defines and prototypes from "mfcuk_keyrecovery_darkside.c"
28
+--------------------------------------------------------------------------------
29
+*/
30
+
31
+/*
32
+ LICENSE
33
+
34
+ This program is free software: you can redistribute it and/or modify
35
+ it under the terms of the GNU General Public License as published by
36
+ the Free Software Foundation, either version 2 of the License, or
37
+ (at your option) any later version.
38
+
39
+ This program is distributed in the hope that it will be useful,
40
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
41
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
42
+ GNU General Public License for more details.
43
+
44
+ You should have received a copy of the GNU General Public License
45
+ along with this program.  If not, see <http://www.gnu.org/licenses/>.
46
+*/
47
+
48
+#ifndef _MFCUK_UTILS_H_
49
+#define _MFCUK_UTILS_H_
50
+
51
+#include <stdio.h>
52
+#include <stdlib.h>
53
+#include <string.h>
54
+
55
+#ifdef WIN32
56
+#define NOMINMAX
57
+#include "windows.h"
58
+#include "xgetopt.h"
59
+#elif __STDC__
60
+#include <unistd.h>
61
+#include <sys/time.h>
62
+#include <sys/types.h>
63
+#endif
64
+
65
+// "Portable" sleep(miliseconds)
66
+#ifdef WIN32
67
+#define sleep(x) Sleep(x)
68
+#elif __STDC__
69
+extern struct timeval global_timeout;
70
+#define sleep(x) { global_timeout.tv_usec = 1000 * (x); select(0,NULL,NULL,NULL,&global_timeout); }
71
+#endif
72
+
73
+// "Portable" clear_screen() - NOTE: system performance penalty introduced
74
+#ifdef WIN32
75
+#define clear_screen()  system("cls")
76
+#elif __STDC__
77
+#define clear_screen()  system("sh -c clear")
78
+#endif
79
+
80
+/**
81
+ * @fn int is_hex(char c)
82
+ * @brief Checks if an ASCII character is a valid hexadecimal base digit
83
+ * @param c The ASCII character to be checked
84
+ * @return Returns true (non-zero) or false (zero)
85
+ *
86
+ * Checks if an ASCII character is a valid hexadecimal base digit.
87
+ * Used for hex2bin() functionality.
88
+ */
89
+int is_hex(char c);
90
+
91
+/**
92
+ * @fn unsigned char hex2bin(unsigned char h, unsigned char l)
93
+ * @brief Converts from two nibbles (4 bits) into the corresponding byte
94
+ * @param h The HIGH (left-most in human reading) nibble of two-char hex representation of a byte
95
+ * @param l The LOW (right-most in human reading) nibble of two-char hex representation of a byte
96
+ * @return Returns the byte which is formed from the two-char hex representation of it
97
+ *
98
+ * Converts from two nibbles (4 bits) into the corresponding byte.
99
+ * Uses the algorithm and implementation from here:
100
+ * http://www.velocityreviews.com/forums/t451319-advice-required-on-my-ascii-to-hex-conversion-c.html
101
+ */
102
+unsigned char hex2bin(unsigned char h, unsigned char l);
103
+
104
+#endif // _MFCUK_UTILS_H_

+ 137
- 0
src/mifare.c View File

@@ -0,0 +1,137 @@
1
+/*-
2
+ * Public platform independent Near Field Communication (NFC) library examples
3
+ *
4
+ * Copyright (C) 2009 Roel Verdult
5
+ * Copyright (C) 2010 Romain Tartière
6
+ * Copyright (C) 2010, 2011 Romuald Conty
7
+ *
8
+ * Redistribution and use in source and binary forms, with or without
9
+ * modification, are permitted provided that the following conditions are met:
10
+ *  1) Redistributions of source code must retain the above copyright notice,
11
+ *  this list of conditions and the following disclaimer.
12
+ *  2 )Redistributions in binary form must reproduce the above copyright
13
+ *  notice, this list of conditions and the following disclaimer in the
14
+ *  documentation and/or other materials provided with the distribution.
15
+ *
16
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26
+ * POSSIBILITY OF SUCH DAMAGE.
27
+ *
28
+ * Note that this license only applies on the examples, NFC library itself is under LGPL
29
+ *
30
+ */
31
+/**
32
+ * @file mifare.c
33
+ * @brief provide samples structs and functions to manipulate MIFARE Classic and Ultralight tags using libnfc
34
+ */
35
+#include "mifare.h"
36
+
37
+#include <string.h>
38
+
39
+#include <nfc/nfc.h>
40
+
41
+/**
42
+ * @brief Execute a MIFARE Classic Command
43
+ * @return Returns true if action was successfully performed; otherwise returns false.
44
+ * @param pmp Some commands need additional information. This information should be supplied in the mifare_param union.
45
+ *
46
+ * The specified MIFARE command will be executed on the tag. There are different commands possible, they all require the destination block number.
47
+ * @note There are three different types of information (Authenticate, Data and Value).
48
+ *
49
+ * First an authentication must take place using Key A or B. It requires a 48 bit Key (6 bytes) and the UID.
50
+ * They are both used to initialize the internal cipher-state of the PN53X chip (http://libnfc.org/hardware/pn53x-chip).
51
+ * After a successful authentication it will be possible to execute other commands (e.g. Read/Write).
52
+ * The MIFARE Classic Specification (http://www.nxp.com/acrobat/other/identification/M001053_MF1ICS50_rev5_3.pdf) explains more about this process.
53
+ */
54
+bool
55
+nfc_initiator_mifare_cmd(nfc_device *pnd, const mifare_cmd mc, const uint8_t ui8Block, mifare_param *pmp)
56
+{
57
+  uint8_t  abtRx[265];
58
+  size_t  szParamLen;
59
+  uint8_t  abtCmd[265];
60
+  //bool    bEasyFraming;
61
+
62
+  abtCmd[0] = mc;               // The MIFARE Classic command
63
+  abtCmd[1] = ui8Block;         // The block address (1K=0x00..0x39, 4K=0x00..0xff)
64
+
65
+  switch (mc) {
66
+      // Read and store command have no parameter
67
+    case MC_READ:
68
+    case MC_STORE:
69
+      szParamLen = 0;
70
+      break;
71
+
72
+      // Authenticate command
73
+    case MC_AUTH_A:
74
+    case MC_AUTH_B:
75
+      szParamLen = sizeof(struct mifare_param_auth);
76
+      break;
77
+
78
+      // Data command
79
+    case MC_WRITE:
80
+      szParamLen = sizeof(struct mifare_param_data);
81
+      break;
82
+
83
+      // Value command
84
+    case MC_DECREMENT:
85
+    case MC_INCREMENT:
86
+    case MC_TRANSFER:
87
+      szParamLen = sizeof(struct mifare_param_value);
88
+      break;
89
+
90
+      // Please fix your code, you never should reach this statement
91
+    default:
92
+      return false;
93
+      break;
94
+  }
95
+
96
+  // When available, copy the parameter bytes
97
+  if (szParamLen)
98
+    memcpy(abtCmd + 2, (uint8_t *) pmp, szParamLen);
99
+
100
+  // FIXME: Save and restore bEasyFraming
101
+  // bEasyFraming = nfc_device_get_property_bool (pnd, NP_EASY_FRAMING, &bEasyFraming);
102
+  if (nfc_device_set_property_bool(pnd, NP_EASY_FRAMING, true) < 0) {
103
+    nfc_perror(pnd, "nfc_device_set_property_bool");
104
+    return false;
105
+  }
106
+  // Fire the mifare command
107
+  int res;
108
+  if ((res = nfc_initiator_transceive_bytes(pnd, abtCmd, 2 + szParamLen, abtRx, sizeof(abtRx), -1))  < 0) {
109
+    if (res == NFC_ERFTRANS) {
110
+      // "Invalid received frame",  usual means we are
111
+      // authenticated on a sector but the requested MIFARE cmd (read, write)
112
+      // is not permitted by current acces bytes;
113
+      // So there is nothing to do here.
114
+    } else {
115
+      nfc_perror(pnd, "nfc_initiator_transceive_bytes");
116
+    }
117
+    // XXX nfc_device_set_property_bool (pnd, NP_EASY_FRAMING, bEasyFraming);
118
+    return false;
119
+  }
120
+  /* XXX
121
+  if (nfc_device_set_property_bool (pnd, NP_EASY_FRAMING, bEasyFraming) < 0) {
122
+    nfc_perror (pnd, "nfc_device_set_property_bool");
123
+    return false;
124
+  }
125
+  */
126
+
127
+  // When we have executed a read command, copy the received bytes into the param
128
+  if (mc == MC_READ) {
129
+    if (res == 16) {
130
+      memcpy(pmp->mpd.abtData, abtRx, 16);
131
+    } else {
132
+      return false;
133
+    }
134
+  }
135
+  // Command succesfully executed
136
+  return true;
137
+}

+ 140
- 0
src/mifare.h View File

@@ -0,0 +1,140 @@
1
+/*-
2
+ * Public platform independent Near Field Communication (NFC) library examples
3
+ *
4
+ * Copyright (C) 2009 Roel Verdult
5
+ * Copyright (C) 2010 Romain Tartière
6
+ * Copyright (C) 2010, 2011 Romuald Conty
7
+ *
8
+ * Redistribution and use in source and binary forms, with or without
9
+ * modification, are permitted provided that the following conditions are met:
10
+ *  1) Redistributions of source code must retain the above copyright notice,
11
+ *  this list of conditions and the following disclaimer.
12
+ *  2 )Redistributions in binary form must reproduce the above copyright
13
+ *  notice, this list of conditions and the following disclaimer in the
14
+ *  documentation and/or other materials provided with the distribution.
15
+ *
16
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26
+ * POSSIBILITY OF SUCH DAMAGE.
27
+ *
28
+ * Note that this license only applies on the examples, NFC library itself is under LGPL
29
+ *
30
+ */
31
+
32
+/**
33
+ * @file mifare.h
34
+ * @brief provide samples structs and functions to manipulate MIFARE Classic and Ultralight tags using libnfc
35
+ */
36
+
37
+#ifndef _LIBNFC_MIFARE_H_
38
+#  define _LIBNFC_MIFARE_H_
39
+
40
+#  include <nfc/nfc-types.h>
41
+
42
+// Compiler directive, set struct alignment to 1 uint8_t for compatibility
43
+#  pragma pack(1)
44
+
45
+typedef enum {
46
+  MC_AUTH_A = 0x60,
47
+  MC_AUTH_B = 0x61,
48
+  MC_READ = 0x30,
49
+  MC_WRITE = 0xA0,
50
+  MC_TRANSFER = 0xB0,
51
+  MC_DECREMENT = 0xC0,
52
+  MC_INCREMENT = 0xC1,
53
+  MC_STORE = 0xC2
54
+} mifare_cmd;
55
+
56
+// MIFARE command params
57
+struct mifare_param_auth {
58
+  uint8_t  abtKey[6];
59
+  uint8_t  abtAuthUid[4];
60
+};
61
+
62
+struct mifare_param_data {
63
+  uint8_t  abtData[16];
64
+};
65
+
66
+struct mifare_param_value {
67
+  uint8_t  abtValue[4];
68
+};
69
+
70
+typedef union {
71
+  struct mifare_param_auth mpa;
72
+  struct mifare_param_data mpd;
73
+  struct mifare_param_value mpv;
74
+} mifare_param;
75
+
76
+// Reset struct alignment to default
77
+#  pragma pack()
78
+
79
+bool    nfc_initiator_mifare_cmd(nfc_device *pnd, const mifare_cmd mc, const uint8_t ui8Block, mifare_param *pmp);
80
+
81
+// Compiler directive, set struct alignment to 1 uint8_t for compatibility
82
+#  pragma pack(1)
83
+
84
+// MIFARE Classic
85
+typedef struct {
86
+  uint8_t  abtUID[4];
87
+  uint8_t  btBCC;
88
+  uint8_t  btUnknown;
89
+  uint8_t  abtATQA[2];
90
+  uint8_t  abtUnknown[8];
91
+} mifare_classic_block_manufacturer;
92
+
93
+typedef struct {
94
+  uint8_t  abtData[16];
95
+} mifare_classic_block_data;
96
+
97
+typedef struct {
98
+  uint8_t  abtKeyA[6];
99
+  uint8_t  abtAccessBits[4];
100
+  uint8_t  abtKeyB[6];
101
+} mifare_classic_block_trailer;
102
+
103
+typedef union {
104
+  mifare_classic_block_manufacturer mbm;
105
+  mifare_classic_block_data mbd;
106
+  mifare_classic_block_trailer mbt;
107
+} mifare_classic_block;
108
+
109
+typedef struct {
110
+  mifare_classic_block amb[256];
111
+} mifare_classic_tag;
112
+
113
+// MIFARE Ultralight
114
+typedef struct {
115
+  uint8_t  sn0[3];
116
+  uint8_t  btBCC0;
117
+  uint8_t  sn1[4];
118
+  uint8_t  btBCC1;
119
+  uint8_t  internal;
120
+  uint8_t  lock[2];
121
+  uint8_t  otp[4];
122
+} mifareul_block_manufacturer;
123
+
124
+typedef struct {
125
+  uint8_t  abtData[16];
126
+} mifareul_block_data;
127
+
128
+typedef union {
129
+  mifareul_block_manufacturer mbm;
130
+  mifareul_block_data mbd;
131
+} mifareul_block;
132
+
133
+typedef struct {
134
+  mifareul_block amb[4];
135
+} mifareul_tag;
136
+
137
+// Reset struct alignment to default
138
+#  pragma pack()
139
+
140
+#endif // _LIBNFC_MIFARE_H_

+ 128
- 0
src/nfc-utils.c View File

@@ -0,0 +1,128 @@
1
+/*-
2
+ * Free/Libre Near Field Communication (NFC) library
3
+ *
4
+ * Libnfc historical contributors:
5
+ * Copyright (C) 2009      Roel Verdult
6
+ * Copyright (C) 2009-2013 Romuald Conty
7
+ * Copyright (C) 2010-2012 Romain Tartière
8
+ * Copyright (C) 2010-2013 Philippe Teuwen
9
+ * Copyright (C) 2012-2013 Ludovic Rousseau
10
+ * Additional contributors of this file:
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions are met:
14
+ *  1) Redistributions of source code must retain the above copyright notice,
15
+ *  this list of conditions and the following disclaimer.
16
+ *  2 )Redistributions in binary form must reproduce the above copyright
17
+ *  notice, this list of conditions and the following disclaimer in the
18
+ *  documentation and/or other materials provided with the distribution.
19
+ *
20
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
24
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30
+ * POSSIBILITY OF SUCH DAMAGE.
31
+ *
32
+ * Note that this license only applies on the examples, NFC library itself is under LGPL
33
+ *
34
+ */
35
+/**
36
+ * @file nfc-utils.c
37
+ * @brief Provide some examples shared functions like print, parity calculation, options parsing.
38
+ */
39
+#include <nfc/nfc.h>
40
+#include <err.h>
41
+
42
+#include "nfc-utils.h"
43
+
44
+uint8_t
45
+oddparity(const uint8_t bt)
46
+{
47
+  // cf http://graphics.stanford.edu/~seander/bithacks.html#ParityParallel
48
+  return (0x9669 >> ((bt ^(bt >> 4)) & 0xF)) & 1;
49
+}
50
+
51
+void
52
+oddparity_bytes_ts(const uint8_t *pbtData, const size_t szLen, uint8_t *pbtPar)
53
+{
54
+  size_t  szByteNr;
55
+  // Calculate the parity bits for the command
56
+  for (szByteNr = 0; szByteNr < szLen; szByteNr++) {
57
+    pbtPar[szByteNr] = oddparity(pbtData[szByteNr]);
58
+  }
59
+}
60
+
61
+void
62
+print_hex(const uint8_t *pbtData, const size_t szBytes)
63
+{
64
+  size_t  szPos;
65
+
66
+  for (szPos = 0; szPos < szBytes; szPos++) {
67
+    printf("%02x  ", pbtData[szPos]);
68
+  }
69
+  printf("\n");
70
+}
71
+
72
+void
73
+print_hex_bits(const uint8_t *pbtData, const size_t szBits)
74
+{
75
+  uint8_t uRemainder;
76
+  size_t  szPos;
77
+  size_t  szBytes = szBits / 8;
78
+
79
+  for (szPos = 0; szPos < szBytes; szPos++) {
80
+    printf("%02x  ", pbtData[szPos]);
81
+  }
82
+
83
+  uRemainder = szBits % 8;
84
+  // Print the rest bits
85
+  if (uRemainder != 0) {
86
+    if (uRemainder < 5)
87
+      printf("%01x (%d bits)", pbtData[szBytes], uRemainder);
88
+    else
89
+      printf("%02x (%d bits)", pbtData[szBytes], uRemainder);
90
+  }
91
+  printf("\n");
92
+}
93
+
94
+void
95
+print_hex_par(const uint8_t *pbtData, const size_t szBits, const uint8_t *pbtDataPar)
96
+{
97
+  uint8_t uRemainder;
98
+  size_t  szPos;
99
+  size_t  szBytes = szBits / 8;
100
+
101
+  for (szPos = 0; szPos < szBytes; szPos++) {
102
+    printf("%02x", pbtData[szPos]);
103
+    if (oddparity(pbtData[szPos]) != pbtDataPar[szPos]) {
104
+      printf("! ");
105
+    } else {
106
+      printf("  ");
107
+    }
108
+  }
109
+
110
+  uRemainder = szBits % 8;
111
+  // Print the rest bits, these cannot have parity bit
112
+  if (uRemainder != 0) {
113
+    if (uRemainder < 5)
114
+      printf("%01x (%d bits)", pbtData[szBytes], uRemainder);
115
+    else
116
+      printf("%02x (%d bits)", pbtData[szBytes], uRemainder);
117
+  }
118
+  printf("\n");
119
+}
120
+
121
+void
122
+print_nfc_target(const nfc_target *pnt, bool verbose)
123
+{
124
+  char *s;
125
+  str_nfc_target(&s, pnt, verbose);
126
+  printf("%s", s);
127
+  nfc_free(s);
128
+}

+ 103
- 0
src/nfc-utils.h View File

@@ -0,0 +1,103 @@
1
+/*-
2
+ * Free/Libre Near Field Communication (NFC) library
3
+ *
4
+ * Libnfc historical contributors:
5
+ * Copyright (C) 2009      Roel Verdult
6
+ * Copyright (C) 2009-2013 Romuald Conty
7
+ * Copyright (C) 2010-2012 Romain Tartière
8
+ * Copyright (C) 2010-2013 Philippe Teuwen
9
+ * Copyright (C) 2012-2013 Ludovic Rousseau
10
+ * Additional contributors of this file:
11
+ *
12
+ * Redistribution and use in source and binary forms, with or without
13
+ * modification, are permitted provided that the following conditions are met:
14
+ *  1) Redistributions of source code must retain the above copyright notice,
15
+ *  this list of conditions and the following disclaimer.
16
+ *  2 )Redistributions in binary form must reproduce the above copyright
17
+ *  notice, this list of conditions and the following disclaimer in the
18
+ *  documentation and/or other materials provided with the distribution.
19
+ *
20
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
24
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30
+ * POSSIBILITY OF SUCH DAMAGE.
31
+ *
32
+ * Note that this license only applies on the examples, NFC library itself is under LGPL
33
+ *
34
+ */
35
+
36
+/**
37
+ * @file nfc-utils.h
38
+ * @brief Provide some examples shared functions like print, parity calculation, options parsing.
39
+ */
40
+
41
+#ifndef _EXAMPLES_NFC_UTILS_H_
42
+#  define _EXAMPLES_NFC_UTILS_H_
43
+
44
+#  include <stdlib.h>
45
+#  include <string.h>
46
+#  include <err.h>
47
+
48
+/**
49
+ * @macro DBG
50
+ * @brief Print a message of standard output only in DEBUG mode
51
+ */
52
+#ifdef DEBUG
53
+#  define DBG(...) do { \
54
+    warnx ("DBG %s:%d", __FILE__, __LINE__); \
55
+    warnx ("    " __VA_ARGS__ ); \
56
+  } while (0)
57
+#else
58
+#  define DBG(...) {}
59
+#endif
60
+
61
+/**
62
+ * @macro WARN
63
+ * @brief Print a warn message
64
+ */
65
+#ifdef DEBUG
66
+#  define WARN(...) do { \
67
+    warnx ("WARNING %s:%d", __FILE__, __LINE__); \
68
+    warnx ("    " __VA_ARGS__ ); \
69
+  } while (0)
70
+#else
71
+#  define WARN(...) warnx ("WARNING: " __VA_ARGS__ )
72
+#endif
73
+
74
+/**
75
+ * @macro ERR
76
+ * @brief Print a error message
77
+ */
78
+#ifdef DEBUG
79
+#  define ERR(...) do { \
80
+    warnx ("ERROR %s:%d", __FILE__, __LINE__); \
81
+    warnx ("    " __VA_ARGS__ ); \
82
+  } while (0)
83
+#else
84
+#  define ERR(...)  warnx ("ERROR: " __VA_ARGS__ )
85
+#endif
86
+
87
+#ifndef MIN
88
+#define MIN(a,b) (((a) < (b)) ? (a) : (b))
89
+#endif
90
+#ifndef MAX
91
+#define MAX(a,b) (((a) > (b)) ? (a) : (b))
92
+#endif
93
+
94
+uint8_t  oddparity(const uint8_t bt);
95
+void    oddparity_bytes_ts(const uint8_t *pbtData, const size_t szLen, uint8_t *pbtPar);
96
+
97
+void    print_hex(const uint8_t *pbtData, const size_t szLen);
98
+void    print_hex_bits(const uint8_t *pbtData, const size_t szBits);
99
+void    print_hex_par(const uint8_t *pbtData, const size_t szBits, const uint8_t *pbtDataPar);
100
+
101
+void    print_nfc_target(const nfc_target *pnt, bool verbose);
102
+
103
+#endif

+ 84
- 0
src/pm3_mfc_parser.py View File

@@ -0,0 +1,84 @@
1
+#!/usr/bin/python
2
+
3
+# Original source: proxmark3.org community forum
4
+
5
+import sys
6
+import os
7
+import string
8
+import commands
9
+
10
+def line_tag(line):
11
+    if string.find(line, 'TAG') > 0:
12
+        return True
13
+    
14
+    return False
15
+
16
+def line_rdr(line):
17
+    if string.find(line, 'TAG') < 1:
18
+        return True
19
+    
20
+    return False
21
+
22
+def line_bytes(line):
23
+    bytes = line[20:len(line)-1]
24
+    bytes = bytes.replace('crc', '')
25
+    bytes = bytes.replace('!', '')
26
+    bytes = bytes.replace(' ', '')
27
+    
28
+    return len(bytes)/2
29
+
30
+try:
31
+    file= open(sys.argv[1])
32
+except:
33
+    print
34
+    print '\tusage:', sys.argv[0], '<proxmark3_snoop.log>'
35
+    print
36
+    sys.exit(True)
37
+
38
+lines = file.readlines()
39
+uid = ''
40
+find_multi_sector = False
41
+
42
+for i in range(len(lines)):
43
+    if string.find(lines[i],':     93  20') > 0 and line_tag(lines[i + 1]) and line_bytes(lines[i + 1]) == 5:
44
+        find_multi_sector = False
45
+        key = ''        
46
+        
47
+        uid = lines[i + 1][20:34]
48
+        uid = uid.replace(' ', '')
49
+        print 'Found TAG UID:', uid
50
+        
51
+    if uid and (string.find(lines[i],':     60') > 0 or string.find(lines[i],':     61') > 0) and line_tag(lines[i + 1]) and line_bytes(lines[i + 1]) == 4 and line_rdr(lines[i + 2]) and line_bytes(lines[i + 2]) == 8 and line_tag(lines[i + 3]) and line_bytes(lines[i + 3]) == 4:
52
+        tag_challenge = lines[i+1][20:34]
53
+        tag_challenge = tag_challenge.replace(' ', '')
54
+        tag_challenge = tag_challenge.replace('!', '')
55
+        print 'Nt:', tag_challenge
56
+
57
+        reader_challenge_response = lines[i+2][20:50]
58
+        reader_challenge_response = reader_challenge_response.replace(' ', '')
59
+        reader_challenge_response = reader_challenge_response.replace('!', '')
60
+        print 'Nt\':', reader_challenge_response
61
+
62
+        tag_response = lines[i+3][20:34]
63
+        tag_response = tag_response.replace(' ', '')
64
+        tag_response = tag_response.replace('!', '')
65
+        print 'Nr:', tag_response
66
+
67
+        find_multi_sector = True
68
+    
69
+    # Usually, a multi-sector authentication if a sequence of R->T 4 bytes (encrypted 60 xx p1 p2 or 61 xx p1 p2) and T->R 4 bytes
70
+    if find_multi_sector and line_rdr(lines[i]) and line_bytes(lines[i]) == 4 and string.find(lines[i],':     60') < 1 and string.find(lines[i],':     61') < 1 and line_tag(lines[i + 1]) and line_bytes(lines[i + 1]) == 4:
71
+        encr_multi_sect_auth = lines[i][20:34]
72
+        encr_multi_sect_auth = encr_multi_sect_auth.replace(' ', '')
73
+        encr_multi_sect_auth = encr_multi_sect_auth.replace('!', '')
74
+        #print 'Multi-sector AUTH (candidates):', encr_multi_sect_auth
75
+        
76
+        encr_multi_sect_Nt = lines[i + 1][20:34]
77
+        encr_multi_sect_Nt = encr_multi_sect_Nt.replace(' ', '')
78
+        encr_multi_sect_Nt = encr_multi_sect_Nt.replace('!', '')
79
+        #print 'Multi-sector encrypted Nt (candidates):', encr_multi_sect_Nt
80
+        
81
+        mfcuk_P_params = './mfcuk -P ' + '0x' + uid + ':' + '0x' + tag_challenge + ':' + '0x' + reader_challenge_response[0:8] + ':' + '0x' + reader_challenge_response[8:16] + ':' + '0x' + tag_response + ':' + '0x' + encr_multi_sect_auth
82
+
83
+        print 'Executing ', mfcuk_P_params
84
+        #os.execv('./mfcuk',string.split(mfcuk_P_params))

+ 51
- 0
src/trace1.txt View File

@@ -0,0 +1,51 @@
1
+ + 561882:  1 :     26    
2
+ +     64:  2 : TAG 04  00    
3
+ +  10217:  2 :     93  20    
4
+ +     64:  5 : TAG 9c  59  9b  32  6c    
5
+ +  12313:  9 :     93  70  9c  59  9b  32  6c  6b  30    
6
+ +     64:  3 : TAG 08  b6  dd    
7
+ + 923318:  4 :     60  00  f5  7b    
8
+ +    112:  4 : TAG 82  a4  16  6c    
9
+ +   6985:  8 :     a1  e4! 58  ce! 6e  ea! 41  e0!       !crc
10
+ +     64:  4 : TAG 5c! ad  f4  39!   
11
+ + 811513:  4 :     8e  0e! 5d! b9        !crc
12
+ +    112:  4 : TAG 5a! 92  0d! 85!   
13
+ +   6946:  8 :     98! d7  6b! 77  d6  c6  e8  70        !crc
14
+ +     64:  4 : TAG ca  7e! 0b! 63!   
15
+ + 670868:  4 :     3e! 70  9c! 8a        !crc
16
+ +    112:  4 : TAG 36! 41  24! 79    
17
+ +   9505:  8 :     1b! 8c  3a! 48! 83  5a  4a! 27        !crc
18
+ +     64:  4 : TAG 40! 6a! 99! 4b    
19
+ + 905612:  4 :     c9  7c  64! 13!       !crc
20
+ +    112:  4 : TAG b5! ab! 1d! 2b    
21
+ +   6936:  8 :     7e! d2  5c! ca! 4b! 50! 88! c4        !crc
22
+ +     64:  4 : TAG bf  dd  01  be!   
23
+ + 987853:  4 :     56  98  49  d6!       !crc
24
+ +     72: 18 : TAG 09  bf! f5! f6! fc! b9! 5e! 51! 07  ac  f6  72  f8  73  3b! 1b  73! ad!       !crc
25
+ +  94864:  4 :     5c! 7b  24! 02        !crc
26
+ +     72: 18 : TAG a0  1f! 0b! b7  0d! ba  c9  e7! fa! 36! 47  d2  a0! 01! 40! 87  ff  95!       !crc
27
+ +  94827:  4 :     c9  90  dc! a3        !crc
28
+ +     72: 18 : TAG df  b8! 7a  bc! 17! 99  82! 5c  55  d5! 98! 68  8b  f8  e7  89  dc  42!       !crc
29
+ +  99081:  4 :     9f! d5  0f! d8!       !crc
30
+ +     72: 18 : TAG ca! 40  fa! 34  82  cc  3e  de  1f! 7f  f7! f0  62! 18! 77! 34  30  07        !crc
31
+ +  93995:  4 :     ad  7f! 3e  0c!       !crc
32
+ +     72: 18 : TAG f4! 2b  17! 4c  a2! 5a  0c! a0! d8  03! 05  cc  cc  4c  1f  12! 0c! 78!       !crc
33
+ +  94857:  4 :     f1! b4  f0  3b!       !crc
34
+ +     72: 18 : TAG 8f  da  ca  17! 42  8e  24  c9! 8e  fb! 38! aa! 39  e2! dd  dd! a8  a6        !crc
35
+ +  94850:  4 :     c4  03! 7b! 9a        !crc
36
+ +     72: 18 : TAG 9f! 42! 42  49! cd  d1! 3d! fd  8e  8f  d3  8d! d5! ca! ef! 15  84  c9!       !crc
37
+ +  93961:  4 :     33! 3b! ae  0a!       !crc
38
+ +     72: 18 : TAG 74  ed! 58  46! e7  cc  48  d1! 5a  4b  b0! 3a! c1  79! 8a! bf! e7! 42        !crc
39
+ +  93193:  4 :     f6  ec! 36  91!       !crc
40
+ +     72: 18 : TAG 79! 63  89! 21! 24  1e  3e! 03! a8! c3! 9b  95! a1  ad! 6c! 34  52  94        !crc
41
+ +  94866:  4 :     ad! 5c! 47  c5!       !crc
42
+ +     72: 18 : TAG 68  d4  9d  c2! 2b  18  46! f7  e8! 28  ea  03  a4  df  d5! 9f  23  00!       !crc
43
+ +  93994:  4 :     41  4c! 40! 11        !crc
44
+ +     72: 18 : TAG b1  95  17! 84! ac  fc! 31  b8! 02  40  97! ec! 4c  19  6f  e9  f0! 8c!       !crc
45
+ +  94818:  4 :     b8! b5! 5c! 74!       !crc
46
+ +     72: 18 : TAG c6  03  b9  92! 7d! eb! 13  8a  56  b7  9c  7c  07  3d! 6a  95! 7e! 44        !crc
47
+
48
+# http://www.proxmark.org/forum/post/550/#p550
49
+# UID = 0x9c599b32
50
+# KEY = 0xffffffffffff
51
+# 0x9c599b32 0x82a4166c 0xa1e458ce 0x6eea41e0 0x5cadf439

+ 214
- 0
src/xgetopt.c View File

@@ -0,0 +1,214 @@
1
+// XGetopt.cpp  Version 1.2
2
+//
3
+// Author:  Hans Dietrich
4
+//          hdietrich2@hotmail.com
5
+//
6
+// Description:
7
+//     XGetopt.cpp implements getopt(), a function to parse command lines.
8
+//
9
+// History
10
+//     Version 1.2 - 2003 May 17
11
+//     - Added Unicode support
12
+//
13
+//     Version 1.1 - 2002 March 10
14
+//     - Added example to XGetopt.cpp module header
15
+//
16
+// This software is released into the public domain.
17
+// You are free to use it in any way you like.
18
+//
19
+// This software is provided "as is" with no expressed
20
+// or implied warranty.  I accept no liability for any
21
+// damage or loss of business that this software may cause.
22
+//
23
+///////////////////////////////////////////////////////////////////////////////
24
+
25
+
26
+///////////////////////////////////////////////////////////////////////////////
27
+// if you are using precompiled headers then include this line:
28
+//#include "stdafx.h"
29
+///////////////////////////////////////////////////////////////////////////////
30
+
31
+
32
+///////////////////////////////////////////////////////////////////////////////
33
+// if you are not using precompiled headers then include these lines:
34
+//#include
35
+//#include
36
+//#include
37
+///////////////////////////////////////////////////////////////////////////////
38
+
39
+#include <stdio.h>
40
+#include <string.h>
41
+#include "xgetopt.h"
42
+
43
+
44
+///////////////////////////////////////////////////////////////////////////////
45
+//
46
+//  X G e t o p t . c p p
47
+//
48
+//
49
+//  NAME
50
+//       getopt -- parse command line options
51
+//
52
+//  SYNOPSIS
53
+//       int getopt(int argc, char *argv[], char *optstring)
54
+//
55
+//       extern char *optarg;
56
+//       extern int optind;
57
+//
58
+//  DESCRIPTION
59
+//       The getopt() function parses the command line arguments. Its
60
+//       arguments argc and argv are the argument count and array as
61
+//       passed into the application on program invocation.  In the case
62
+//       of Visual C++ programs, argc and argv are available via the
63
+//       variables __argc and __argv (double underscores), respectively.
64
+//       getopt returns the next option letter in argv that matches a
65
+//       letter in optstring.  (Note:  Unicode programs should use
66
+//       __targv instead of __argv.  Also, all character and string
67
+//       literals should be enclosed in _T( ) ).
68
+//
69
+//       optstring is a string of recognized option letters;  if a letter
70
+//       is followed by a colon, the option is expected to have an argument
71
+//       that may or may not be separated from it by white space.  optarg
72
+//       is set to point to the start of the option argument on return from
73
+//       getopt.
74
+//
75
+//       Option letters may be combined, e.g., "-ab" is equivalent to
76
+//       "-a -b".  Option letters are case sensitive.
77
+//
78
+//       getopt places in the external variable optind the argv index
79
+//       of the next argument to be processed.  optind is initialized
80
+//       to 0 before the first call to getopt.
81
+//
82
+//       When all options have been processed (i.e., up to the first
83
+//       non-option argument), getopt returns EOF, optarg will point
84
+//       to the argument, and optind will be set to the argv index of
85
+//       the argument.  If there are no non-option arguments, optarg
86
+//       will be set to NULL.
87
+//
88
+//       The special option "--" may be used to delimit the end of the
89
+//       options;  EOF will be returned, and "--" (and everything after it)
90
+//       will be skipped.
91
+//
92
+//  RETURN VALUE
93
+//       For option letters contained in the string optstring, getopt
94
+//       will return the option letter.  getopt returns a question mark (?)
95
+//       when it encounters an option letter not included in optstring.
96
+//       EOF is returned when processing is finished.
97
+//
98
+//  BUGS
99
+//       1)  Long options are not supported.
100
+//       2)  The GNU double-colon extension is not supported.
101
+//       3)  The environment variable POSIXLY_CORRECT is not supported.
102
+//       4)  The + syntax is not supported.
103
+//       5)  The automatic permutation of arguments is not supported.
104
+//       6)  This implementation of getopt() returns EOF if an error is
105
+//           encountered, instead of -1 as the latest standard requires.
106
+//
107
+//  EXAMPLE
108
+//       BOOL CMyApp::ProcessCommandLine(int argc, char *argv[])
109
+//       {
110
+//           int c;
111
+//
112
+//           while ((c = getopt(argc, argv, _T("aBn:"))) != EOF)
113
+//           {
114
+//               switch (c)
115
+//               {
116
+//                   case _T('a'):
117
+//                       TRACE(_T("option a\n"));
118
+//                       //
119
+//                       // set some flag here
120
+//                       //
121
+//                       break;
122
+//
123
+//                   case _T('B'):
124
+//                       TRACE( _T("option B\n"));
125
+//                       //
126
+//                       // set some other flag here
127
+//                       //
128
+//                       break;
129
+//
130
+//                   case _T('n'):
131
+//                       TRACE(_T("option n: value=%d\n"), atoi(optarg));
132
+//                       //
133
+//                       // do something with value here
134
+//                       //
135
+//                       break;
136
+//
137
+//                   case _T('?'):
138
+//                       TRACE(_T("ERROR: illegal option %s\n"), argv[optind-1]);
139
+//                       return FALSE;
140
+//                       break;
141
+//
142
+//                   default:
143
+//                       TRACE(_T("WARNING: no handler for option %c\n"), c);
144
+//                       return FALSE;
145
+//                       break;
146
+//               }
147
+//           }
148
+//           //
149
+//           // check for non-option args here
150
+//           //
151
+//           return TRUE;
152
+//       }
153
+//
154
+///////////////////////////////////////////////////////////////////////////////
155
+
156
+char	*optarg;		// global argument pointer
157
+int		optind = 0; 	// global argv index
158
+
159
+int getopt(int argc, char *argv[], char *optstring)
160
+{
161
+  char c = 0;
162
+  char *cp = NULL;
163
+
164
+  static char *next = NULL;
165
+  if (optind == 0)
166
+    next = NULL;
167
+
168
+  optarg = NULL;
169
+
170
+  if (next == NULL || *next == '\0') {
171
+    if (optind == 0)
172
+      optind++;
173
+
174
+    if (optind >= argc || argv[optind][0] != '-' || argv[optind][1] == '\0') {
175
+      optarg = NULL;
176
+      if (optind < argc)
177
+        optarg = argv[optind];
178
+      return EOF;
179
+    }
180
+
181
+    if (strcmp(argv[optind], "--") == 0) {
182
+      optind++;
183
+      optarg = NULL;
184
+      if (optind < argc)
185
+        optarg = argv[optind];
186
+      return EOF;
187
+    }
188
+
189
+    next = argv[optind];
190
+    next++;		// skip past -
191
+    optind++;
192
+  }
193
+
194
+  c = *next++;
195
+  cp = strchr(optstring, c);
196
+
197
+  if (cp == NULL || c == ':')
198
+    return '?';
199
+
200
+  cp++;
201
+  if (*cp == ':') {
202
+    if (*next != '\0') {
203
+      optarg = next;
204
+      next = NULL;
205
+    } else if (optind < argc) {
206
+      optarg = argv[optind];
207
+      optind++;
208
+    } else {
209
+      return '?';
210
+    }
211
+  }
212
+
213
+  return c;
214
+}

+ 23
- 0
src/xgetopt.h View File

@@ -0,0 +1,23 @@
1
+// XGetopt.h  Version 1.2
2
+//
3
+// Author:  Hans Dietrich
4
+//          hdietrich2@hotmail.com
5
+//
6
+// This software is released into the public domain.
7
+// You are free to use it in any way you like.
8
+//
9
+// This software is provided "as is" with no expressed
10
+// or implied warranty.  I accept no liability for any
11
+// damage or loss of business that this software may cause.
12
+//
13
+///////////////////////////////////////////////////////////////////////////////
14
+
15
+#ifndef XGETOPT_H
16
+#define XGETOPT_H
17
+
18
+extern int optind, opterr;
19
+extern char *optarg;
20
+
21
+int getopt(int argc, char *argv[], char *optstring);
22
+
23
+#endif //XGETOPT_H

+ 43
- 0
tools/proxmark3_parser.py View File

@@ -0,0 +1,43 @@
1
+#!/usr/bin/python
2
+
3
+# Original source: proxmark3.org community forum
4
+
5
+import sys
6
+import os
7
+import string
8
+
9
+try:
10
+	file= open(sys.argv[1])
11
+except:
12
+	print 
13
+	print '\tusage: mifarecrack.py <proxmark3 logfile>'
14
+	print
15
+	sys.exit(True)
16
+
17
+lines= file.readlines()
18
+uid= ''
19
+
20
+gotone= False
21
+for i in range(len(lines)):
22
+	if not uid and string.find(lines[i],':     93  20') > 0:
23
+		uid= lines[i + 1][20:34]
24
+		print
25
+		print 'Found TAG UID:', uid
26
+	if string.find(lines[i],':     60') > 0 or string.find(lines[i],':     61') > 0:
27
+		gotone= True
28
+		tag_challenge= lines[i+1]
29
+		reader_challenge_response= lines[i+2]
30
+		tag_response= lines[i+3]
31
+		break
32
+if not gotone:
33
+	print 'No crypto exchange found!'
34
+	sys.exit(True)	
35
+
36
+crackstring= './mifarecrack '+ uid
37
+
38
+# now process challenge/response
39
+crackstring += ' ' + tag_challenge[20:34]
40
+crackstring += ' ' + reader_challenge_response[20:50]
41
+crackstring += ' ' + tag_response[20:34]
42
+print 'Executing ', crackstring
43
+os.execv('./mifarecrack',string.split(crackstring))

Loading…
Cancel
Save