Move old windows binairies to /tags/windows/binairies

This commit is contained in:
romuald@libnfc.org 2012-09-23 10:26:11 +00:00
parent 4ddf2de7b2
commit 6fd0cc444f
42 changed files with 0 additions and 6445 deletions

View File

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

339
COPYING
View File

@ -1,339 +0,0 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

View File

View File

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

339
LICENSE
View File

@ -1,339 +0,0 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

View File

@ -1,4 +0,0 @@
SUBDIRS = src
#pkgconfigdir = $(libdir)/pkgconfig
#pkgconfig_DATA = libnfc.pc

0
NEWS
View File

54
README
View File

@ -1,54 +0,0 @@
README
======
Compiling:
automake
autoconf
./configure
make
Running (most basic):
./mfcuk -C -R 0:A -v 2
PACKAGE
-------
MiFare Classic Universal toolKit (MFCUK)
TOOL(S)
-------
Mifare Classic DarkSide Key Recovery Tool (mfcuk_keyrecovery_darkside.c) (previously known as zv_mf_dark_side)
...
LICENSE
-------
GPL. See MFCUK_LICENSE for more information.
BIBLIOGRPAHY (no specific order)
---------------------------------
1. [WPMCC09] - "Wirelessly Pickpocketing a Mifare Classic Card"
2. [ESO08] - "2008-esorics.pdf"
3. [ESOSL08] - "2008-esorics-slides-updated.pdf"
4. [KON08] - "2008-koning-thesis.pdf"
5. [VER08] - "2008-verdult-thesis.pdf"
6. [PATMC] - "A Practical Attack on the MIFARE Classic.pdf"
7. [NCOURFIDSEC09] - "mifare_courtois_rfidsec09.pdf"
8. [MFCLTRB09] - "MifareClassicTroubles.ppt"
9. [TEEP08] - "p2008-teepe-classic_mistakes.pdf"
10. [RFIDSANJ] - "RFID Attacks_WCA_San_Jose.pdf"
11. [ROSS] - "rossum-mifare.pdf"
12. [PLOTZ08] - "SAR-PR-2008-21_.pdf"
13. [ROSSSASG] - "SASG35_Peter_v_Rossum_Mifare.pdf"
14. [DARK2009] - "THE DARK SIDE OF SECURITY BY OBSCURITY and Cloning MiFare Classic Rail and Building Passes, Anywhere, Anytime"
KUDOS and HATS-OFF to (no specific order) (for all the knowledge, time spent researching and all the things)
---------------------
- 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
- Roel and RConty @ libnfc/proxmark - these guys are true advisers, helpful. Thanks for providing a powerfull platform for NFC
- N.Curtois - also a crypto-artist in differential analysis. The 29bit prefix attack is pure genius of theoretical analysis.
- RU University Staff for working out different aspects and papers for Crypto1 analysis
- Nohl, Plotz, Evans - how the "F" did you get those slicers and microscopes :))?
- Milosch M et al. - for pushing the limits for open-source hardware (OpenPCD and OpenPICC)
- Jonathan Westhues - for giving the open-source community the: Proxmark schematics/sources and RFID knowledge
- Nethemba team - for first open-source/GPL nested authentication attack key recovery implementation in MFOC
- hat, schwa226, pgrahamm, marcus2608, phadom - for useful samples, advices, traces and all the things

21
TODO
View File

@ -1,21 +0,0 @@
TODO
====
PACKAGE
-------
MiFare Classic Universal toolKit (MFCUK)
TOOL(S)
-------
Mifare Classic DarkSide Key Recovery Tool (mfcuk_keyrecovery_darkside.c) (previously known as zv_mf_dark_side)
...
ITEMS
=====
0. Integrate with MFOC into MFCUK
1. Improve the performance (though not bad)
2. Optimize bits operations
3. Remove dead-code/commented block after testing
4. Proper error handling in some cases (not critical errors, but nice to have checks in place)
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
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

BIN
binaries/r55/libnfc.dll Normal file

Binary file not shown.

BIN
binaries/r55/libnfc.lib Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,46 +0,0 @@
AC_INIT([mfcuk], [0.3.3], [zveriu@gmail.com])
AC_CONFIG_MACRO_DIR([m4])
AC_PROG_CC
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_SRCDIR([src/mfcuk.c])
AM_INIT_AUTOMAKE
m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
# Checks for pkg-config modules.
LIBNFC_REQUIRED_VERSION=1.5.1
PKG_CHECK_MODULES([LIBNFC], [libnfc >= $LIBNFC_REQUIRED_VERSION], [], [AC_MSG_ERROR([libnfc >= $LIBNFC_REQUIRED_VERSION is mandatory.])])
PKG_CONFIG_REQUIRES="libnfc"
AC_SUBST([PKG_CONFIG_REQUIRES])
# Checks for typedefs, structures, and compiler characteristics.
AC_HEADER_STDBOOL
AC_TYPE_SIZE_T
AC_TYPE_UINT16_T
AC_TYPE_UINT32_T
AC_TYPE_UINT64_T
AC_TYPE_UINT8_T
# Checks for library functions.
AC_FUNC_MALLOC
AC_FUNC_REALLOC
AC_CHECK_FUNCS([memset strchr])
# Checks for endianness convertion
AC_CHECK_HEADERS([endian.h sys/endian.h CoreFoundation/CoreFoundation.h])
AC_CHECK_HEADERS([byteswap.h])
AC_DEFINE([_XOPEN_SOURCE], [600], [Define to 500 if Single Unix conformance is wanted, 600 for sixth revision.])
# Help us to write great code ;-)
CFLAGS="$CFLAGS -Wall -pedantic -Wextra -std=c99"
AC_CONFIG_FILES([Makefile
src/Makefile])
AC_OUTPUT

View File

@ -1,9 +0,0 @@
AM_CFLAGS = @LIBNFC_CFLAGS@
AM_LDFLAGS = @LIBNFC_LIBS@
bin_PROGRAMS = mfcuk
noinst_HEADERS = crapto1.h mifare.h nfc-utils.h mfcuk_mifare.h mfcuk_finger.h mfcuk_utils.h xgetopt.h mfcuk.h
mfcuk_SOURCES = crapto1.c crypto1.c mifare.c nfc-utils.c mfcuk_mifare.c mfcuk_finger.c mfcuk_utils.c xgetopt.c mfcuk.c
# dist_man_MANS = mfcuk.1

View File

@ -1,6 +0,0 @@
MAIN_FILE=mfcuk_keyrecovery_darkside
LIBNFC=libnfc
CFLAGS=`pkg-config --cflags ${LIBNFC}`
CFLAGS_LIBNFC=`pkg-config --cflags libnfc | cut -d ' ' -f 1`/${LIBNFC}
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

View File

@ -1,487 +0,0 @@
/* crapto1.c
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, US$
Copyright (C) 2008-2008 bla <blapost@gmail.com>
*/
#include "crapto1.h"
#include <stdlib.h>
#if !defined LOWMEM && defined __GNUC__
static uint8_t filterlut[1 << 20];
static void __attribute__((constructor)) fill_lut()
{
uint32_t i;
for(i = 0; i < 1 << 20; ++i)
filterlut[i] = filter(i);
}
#define filter(x) (filterlut[(x) & 0xfffff])
#endif
static void quicksort(uint32_t* const start, uint32_t* const stop)
{
uint32_t *it = start + 1, *rit = stop;
if(it > rit)
return;
while(it < rit)
if(*it <= *start)
++it;
else if(*rit > *start)
--rit;
else
*it ^= (*it ^= *rit, *rit ^= *it);
if(*rit >= *start)
--rit;
if(rit != start)
*rit ^= (*rit ^= *start, *start ^= *rit);
quicksort(start, rit - 1);
quicksort(rit + 1, stop);
}
/** binsearch
* Binary search for the first occurence of *stop's MSB in sorted [start,stop]
*/
static inline uint32_t*
binsearch(uint32_t *start, uint32_t *stop)
{
uint32_t mid, val = *stop & 0xff000000;
while(start != stop)
if(start[mid = (stop - start) >> 1] > val)
stop = &start[mid];
else
start += mid + 1;
return start;
}
/** update_contribution
* helper, calculates the partial linear feedback contributions and puts in MSB
*/
static inline void
update_contribution(uint32_t *item, const uint32_t mask1, const uint32_t mask2)
{
uint32_t p = *item >> 25;
p = p << 1 | parity(*item & mask1);
p = p << 1 | parity(*item & mask2);
*item = p << 24 | (*item & 0xffffff);
}
/** extend_table
* using a bit of the keystream extend the table of possible lfsr states
*/
static inline void
extend_table(uint32_t *tbl, uint32_t **end, int bit, int m1, int m2, uint32_t in)
{
in <<= 24;
for(*tbl <<= 1; tbl <= *end; *++tbl <<= 1)
if(filter(*tbl) ^ filter(*tbl | 1)) {
*tbl |= filter(*tbl) ^ bit;
update_contribution(tbl, m1, m2);
*tbl ^= in;
} else if(filter(*tbl) == bit) {
*++*end = tbl[1];
tbl[1] = tbl[0] | 1;
update_contribution(tbl, m1, m2);
*tbl++ ^= in;
update_contribution(tbl, m1, m2);
*tbl ^= in;
} else
*tbl-- = *(*end)--;
}
/** extend_table_simple
* using a bit of the keystream extend the table of possible lfsr states
*/
static inline void
extend_table_simple(uint32_t *tbl, uint32_t **end, int bit)
{
for(*tbl <<= 1; tbl <= *end; *++tbl <<= 1)
if(filter(*tbl) ^ filter(*tbl | 1)) {
*tbl |= filter(*tbl) ^ bit;
} else if(filter(*tbl) == bit) {
*++*end = *++tbl;
*tbl = tbl[-1] | 1;
} else
*tbl-- = *(*end)--;
}
/** recover
* recursively narrow down the search space, 4 bits of keystream at a time
*/
static struct Crypto1State*
recover(uint32_t *o_head, uint32_t *o_tail, uint32_t oks,
uint32_t *e_head, uint32_t *e_tail, uint32_t eks, int rem,
struct Crypto1State *sl, uint32_t in)
{
uint32_t *o, *e, i;
if(rem == -1) {
for(e = e_head; e <= e_tail; ++e) {
*e = *e << 1 ^ parity(*e & LF_POLY_EVEN) ^ !!(in & 4);
for(o = o_head; o <= o_tail; ++o, ++sl) {
sl->even = *o;
sl->odd = *e ^ parity(*o & LF_POLY_ODD);
sl[1].odd = sl[1].even = 0;
}
}
return sl;
}
for(i = 0; i < 4 && rem--; i++) {
extend_table(o_head, &o_tail, (oks >>= 1) & 1,
LF_POLY_EVEN << 1 | 1, LF_POLY_ODD << 1, 0);
if(o_head > o_tail)
return sl;
extend_table(e_head, &e_tail, (eks >>= 1) & 1,
LF_POLY_ODD, LF_POLY_EVEN << 1 | 1, (in >>= 2) & 3);
if(e_head > e_tail)
return sl;
}
quicksort(o_head, o_tail);
quicksort(e_head, e_tail);
while(o_tail >= o_head && e_tail >= e_head)
if(((*o_tail ^ *e_tail) >> 24) == 0) {
o_tail = binsearch(o_head, o = o_tail);
e_tail = binsearch(e_head, e = e_tail);
sl = recover(o_tail--, o, oks,
e_tail--, e, eks, rem, sl, in);
}
else if(*o_tail > *e_tail)
o_tail = binsearch(o_head, o_tail) - 1;
else
e_tail = binsearch(e_head, e_tail) - 1;
return sl;
}
/** lfsr_recovery
* recover the state of the lfsr given 32 bits of the keystream
* additionally you can use the in parameter to specify the value
* that was fed into the lfsr at the time the keystream was generated
*/
struct Crypto1State* lfsr_recovery32(uint32_t ks2, uint32_t in)
{
struct Crypto1State *statelist;
uint32_t *odd_head = 0, *odd_tail = 0, oks = 0;
uint32_t *even_head = 0, *even_tail = 0, eks = 0;
int i;
for(i = 31; i >= 0; i -= 2)
oks = oks << 1 | BEBIT(ks2, i);
for(i = 30; i >= 0; i -= 2)
eks = eks << 1 | BEBIT(ks2, i);
odd_head = odd_tail = malloc(sizeof(uint32_t) << 21);
even_head = even_tail = malloc(sizeof(uint32_t) << 21);
statelist = malloc(sizeof(struct Crypto1State) << 18);
if(!odd_tail-- || !even_tail-- || !statelist)
goto out;
statelist->odd = statelist->even = 0;
for(i = 1 << 20; i >= 0; --i) {
if(filter(i) == (oks & 1))
*++odd_tail = i;
if(filter(i) == (eks & 1))
*++even_tail = i;
}
for(i = 0; i < 4; i++) {
extend_table_simple(odd_head, &odd_tail, (oks >>= 1) & 1);
extend_table_simple(even_head, &even_tail, (eks >>= 1) & 1);
}
in = (in >> 16 & 0xff) | (in << 16) | (in & 0xff00);
recover(odd_head, odd_tail, oks,
even_head, even_tail, eks, 11, statelist, in << 1);
out:
free(odd_head);
free(even_head);
return statelist;
}
static const uint32_t S1[] = { 0x62141, 0x310A0, 0x18850, 0x0C428, 0x06214,
0x0310A, 0x85E30, 0xC69AD, 0x634D6, 0xB5CDE, 0xDE8DA, 0x6F46D, 0xB3C83,
0x59E41, 0xA8995, 0xD027F, 0x6813F, 0x3409F, 0x9E6FA};
static const uint32_t S2[] = { 0x3A557B00, 0x5D2ABD80, 0x2E955EC0, 0x174AAF60,
0x0BA557B0, 0x05D2ABD8, 0x0449DE68, 0x048464B0, 0x42423258, 0x278192A8,
0x156042D0, 0x0AB02168, 0x43F89B30, 0x61FC4D98, 0x765EAD48, 0x7D8FDD20,
0x7EC7EE90, 0x7F63F748, 0x79117020};
static const uint32_t T1[] = {
0x4F37D, 0x279BE, 0x97A6A, 0x4BD35, 0x25E9A, 0x12F4D, 0x097A6, 0x80D66,
0xC4006, 0x62003, 0xB56B4, 0x5AB5A, 0xA9318, 0xD0F39, 0x6879C, 0xB057B,
0x582BD, 0x2C15E, 0x160AF, 0x8F6E2, 0xC3DC4, 0xE5857, 0x72C2B, 0x39615,
0x98DBF, 0xC806A, 0xE0680, 0x70340, 0x381A0, 0x98665, 0x4C332, 0xA272C};
static const uint32_t T2[] = { 0x3C88B810, 0x5E445C08, 0x2982A580, 0x14C152C0,
0x4A60A960, 0x253054B0, 0x52982A58, 0x2FEC9EA8, 0x1156C4D0, 0x08AB6268,
0x42F53AB0, 0x217A9D58, 0x161DC528, 0x0DAE6910, 0x46D73488, 0x25CB11C0,
0x52E588E0, 0x6972C470, 0x34B96238, 0x5CFC3A98, 0x28DE96C8, 0x12CFC0E0,
0x4967E070, 0x64B3F038, 0x74F97398, 0x7CDC3248, 0x38CE92A0, 0x1C674950,
0x0E33A4A8, 0x01B959D0, 0x40DCACE8, 0x26CEDDF0};
static const uint32_t C1[] = { 0x846B5, 0x4235A, 0x211AD};
static const uint32_t C2[] = { 0x1A822E0, 0x21A822E0, 0x21A822E0};
/** Reverse 64 bits of keystream into possible cipher states
* Variation mentioned in the paper. Somewhat optimized version
*/
struct Crypto1State* lfsr_recovery64(uint32_t ks2, uint32_t ks3)
{
struct Crypto1State *statelist, *sl;
uint8_t oks[32], eks[32], hi[32];
uint32_t low = 0, win = 0;
uint32_t *tail, table[1 << 16];
int i, j;
sl = statelist = malloc(sizeof(struct Crypto1State) << 4);
if(!sl)
return 0;
sl->odd = sl->even = 0;
for(i = 30; i >= 0; i -= 2) {
oks[i >> 1] = BIT(ks2, i ^ 24);
oks[16 + (i >> 1)] = BIT(ks3, i ^ 24);
}
for(i = 31; i >= 0; i -= 2) {
eks[i >> 1] = BIT(ks2, i ^ 24);
eks[16 + (i >> 1)] = BIT(ks3, i ^ 24);
}
for(i = 0xfffff; i >= 0; --i) {
if (filter(i) != oks[0])
continue;
*(tail = table) = i;
for(j = 1; tail >= table && j < 29; ++j)
extend_table_simple(table, &tail, oks[j]);
if(tail < table)
continue;
for(j = 0; j < 19; ++j)
low = low << 1 | parity(i & S1[j]);
for(j = 0; j < 32; ++j)
hi[j] = parity(i & T1[j]);
for(; tail >= table; --tail) {
for(j = 0; j < 3; ++j) {
*tail = *tail << 1;
*tail |= parity((i & C1[j]) ^ (*tail & C2[j]));
if(filter(*tail) != oks[29 + j])
goto continue2;
}
for(j = 0; j < 19; ++j)
win = win << 1 | parity(*tail & S2[j]);
win ^= low;
for(j = 0; j < 32; ++j) {
win = win << 1 ^ hi[j] ^ parity(*tail & T2[j]);
if(filter(win) != eks[j])
goto continue2;
}
*tail = *tail << 1 | parity(LF_POLY_EVEN & *tail);
sl->odd = *tail ^ parity(LF_POLY_ODD & win);
sl->even = win;
++sl;
sl->odd = sl->even = 0;
continue2:;
}
}
return statelist;
}
/** lfsr_rollback_bit
* Rollback the shift register in order to get previous states
*/
uint8_t lfsr_rollback_bit(struct Crypto1State *s, uint32_t in, int fb)
{
int out;
uint8_t ret;
s->odd &= 0xffffff;
s->odd ^= (s->odd ^= s->even, s->even ^= s->odd);
out = s->even & 1;
out ^= LF_POLY_EVEN & (s->even >>= 1);
out ^= LF_POLY_ODD & s->odd;
out ^= !!in;
out ^= (ret = filter(s->odd)) & !!fb;
s->even |= parity(out) << 23;
return ret;
}
/** lfsr_rollback_byte
* Rollback the shift register in order to get previous states
*/
uint8_t lfsr_rollback_byte(struct Crypto1State *s, uint32_t in, int fb)
{
int i;
uint8_t ret = 0;
for (i = 7; i >= 0; --i)
ret |= lfsr_rollback_bit(s, BIT(in, i), fb) << i;
return ret;
}
/** lfsr_rollback_word
* Rollback the shift register in order to get previous states
*/
uint32_t lfsr_rollback_word(struct Crypto1State *s, uint32_t in, int fb)
{
int i;
uint32_t ret = 0;
for (i = 31; i >= 0; --i)
ret |= lfsr_rollback_bit(s, BEBIT(in, i), fb) << (i ^ 24);
return ret;
}
/** nonce_distance
* x,y valid tag nonces, then prng_successor(x, nonce_distance(x, y)) = y
*/
static uint16_t *dist = 0;
int nonce_distance(uint32_t from, uint32_t to)
{
uint16_t x, i;
if(!dist) {
dist = malloc(2 << 16);
if(!dist)
return -1;
for (x = i = 1; i; ++i) {
dist[(x & 0xff) << 8 | x >> 8] = i;
x = x >> 1 | (x ^ x >> 2 ^ x >> 3 ^ x >> 5) << 15;
}
}
return (65535 + dist[to >> 16] - dist[from >> 16]) % 65535;
}
static uint32_t fastfwd[2][8] = {
{ 0, 0x4BC53, 0xECB1, 0x450E2, 0x25E29, 0x6E27A, 0x2B298, 0x60ECB},
{ 0, 0x1D962, 0x4BC53, 0x56531, 0xECB1, 0x135D3, 0x450E2, 0x58980}};
/** lfsr_prefix_ks
*
* Is an exported helper function from the common prefix attack
* Described in the "dark side" paper. It returns an -1 terminated array
* of possible partial(21 bit) secret state.
* The required keystream(ks) needs to contain the keystream that was used to
* encrypt the NACK which is observed when varying only the 4 last bits of Nr
* only correct iff [NR_3] ^ NR_3 does not depend on Nr_3
*/
uint32_t *lfsr_prefix_ks(uint8_t ks[8], int isodd)
{
uint32_t c, entry, *candidates = malloc(4 << 21);
int i, size = (1 << 21) - 1;
if(!candidates)
return 0;
for(i = 0; i <= size; ++i)
candidates[i] = i;
for(c = 0; c < 8; ++c)
for(i = 0;i <= size; ++i) {
entry = candidates[i] ^ fastfwd[isodd][c];
if(filter(entry >> 1) != BIT(ks[c], isodd) ||
filter(entry) != BIT(ks[c], isodd + 2))
candidates[i--] = candidates[size--];
}
candidates[size + 1] = -1;
return candidates;
}
/** check_pfx_parity
* helper function which eliminates possible secret states using parity bits
*/
static struct Crypto1State*
check_pfx_parity(uint32_t prefix, uint32_t rresp, uint8_t parities[8][8],
uint32_t odd, uint32_t even, struct Crypto1State* sl)
{
uint32_t ks1, nr, ks2, rr, ks3, c, good = 1;
for(c = 0; good && c < 8; ++c) {
sl->odd = odd ^ fastfwd[1][c];
sl->even = even ^ fastfwd[0][c];
lfsr_rollback_bit(sl, 0, 0);
lfsr_rollback_bit(sl, 0, 0);
ks3 = lfsr_rollback_bit(sl, 0, 0);
ks2 = lfsr_rollback_word(sl, 0, 0);
ks1 = lfsr_rollback_word(sl, prefix | c << 5, 1);
nr = ks1 ^ (prefix | c << 5);
rr = ks2 ^ rresp;
good &= parity(nr & 0x000000ff) ^ parities[c][3] ^ BIT(ks2, 24);
good &= parity(rr & 0xff000000) ^ parities[c][4] ^ BIT(ks2, 16);
good &= parity(rr & 0x00ff0000) ^ parities[c][5] ^ BIT(ks2, 8);
good &= parity(rr & 0x0000ff00) ^ parities[c][6] ^ BIT(ks2, 0);
good &= parity(rr & 0x000000ff) ^ parities[c][7] ^ ks3;
}
return sl + good;
}
/** lfsr_common_prefix
* Implentation of the common prefix attack.
* Requires the 29 bit constant prefix used as reader nonce (pfx)
* The reader response used (rr)
* The keystream used to encrypt the observed NACK's (ks)
* The parity bits (par)
* It returns a zero terminated list of possible cipher states after the
* tag nonce was fed in
*/
struct Crypto1State*
lfsr_common_prefix(uint32_t pfx, uint32_t rr, uint8_t ks[8], uint8_t par[8][8])
{
struct Crypto1State *statelist, *s;
uint32_t *odd, *even, *o, *e, top;
odd = lfsr_prefix_ks(ks, 1);
even = lfsr_prefix_ks(ks, 0);
s = statelist = malloc((sizeof *statelist) << 20);
if(!s || !odd || !even) {
free(odd);
free(even);
free(statelist);
return 0;
}
for(o = odd; *o + 1; ++o)
for(e = even; *e + 1; ++e)
for(top = 0; top < 64; ++top) {
*o += 1 << 21;
*e += (!(top & 7) + 1) << 21;
s = check_pfx_parity(pfx, rr, par, *o, *e, s);
}
s->odd = s->even = 0;
free(odd);
free(even);
return statelist;
}

View File

@ -1,90 +0,0 @@
/* crapto1.h
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, US$
Copyright (C) 2008-2009 bla <blapost@gmail.com>
*/
#ifndef CRAPTO1_INCLUDED
#define CRAPTO1_INCLUDED
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
struct Crypto1State {uint32_t odd, even;};
struct Crypto1State* crypto1_create(uint64_t);
void crypto1_destroy(struct Crypto1State*);
void crypto1_get_lfsr(struct Crypto1State*, uint64_t*);
uint8_t crypto1_bit(struct Crypto1State*, uint8_t, int);
uint8_t crypto1_byte(struct Crypto1State*, uint8_t, int);
uint32_t crypto1_word(struct Crypto1State*, uint32_t, int);
uint32_t prng_successor(uint32_t x, uint32_t n);
struct Crypto1State* lfsr_recovery32(uint32_t ks2, uint32_t in);
struct Crypto1State* lfsr_recovery64(uint32_t ks2, uint32_t ks3);
void lfsr_rollback(struct Crypto1State* s, uint32_t in, int fb);
int nonce_distance(uint32_t from, uint32_t to);
#define FOREACH_VALID_NONCE(N, FILTER, FSIZE)\
uint32_t __n = 0,__M = 0, N = 0;\
int __i;\
for(; __n < 1 << 16; N = prng_successor(__M = ++__n, 16))\
for(__i = FSIZE - 1; __i >= 0; __i--)\
if(BIT(FILTER, __i) ^ parity(__M & 0xFF01))\
break;\
else if(__i)\
__M = prng_successor(__M, (__i == 7) ? 48 : 8);\
else
#define LF_POLY_ODD (0x29CE5C)
#define LF_POLY_EVEN (0x870804)
#define BIT(x, n) ((x) >> (n) & 1)
#define BEBIT(x, n) BIT(x, (n) ^ 24)
static inline int parity(uint32_t x)
{
#if !defined __i386__ || !defined __GNUC__
x ^= x >> 16;
x ^= x >> 8;
x ^= x >> 4;
return BIT(0x6996, x & 0xf);
#else
__asm__(
"movl %1, %%eax\n"
"mov %%ax, %%cx\n"
"shrl $0x10, %%eax\n"
"xor %%ax, %%cx\n"
"xor %%ch, %%cl\n"
"setpo %%al\n"
"movzx %%al, %0\n": "=r"(x) : "r"(x): "eax","ecx"
);
return x;
#endif
}
static inline int filter(uint32_t const x)
{
uint32_t f;
f = 0xf22c0 >> (x & 0xf) & 16;
f |= 0x6c9c0 >> (x >> 4 & 0xf) & 8;
f |= 0x3c8b0 >> (x >> 8 & 0xf) & 4;
f |= 0x1e458 >> (x >> 12 & 0xf) & 2;
f |= 0x0d938 >> (x >> 16 & 0xf) & 1;
return BIT(0xEC57E80A, f);
}
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,93 +0,0 @@
/* crypto1.c
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, US
Copyright (C) 2008-2008 bla <blapost@gmail.com>
*/
#include "crapto1.h"
#include <stdlib.h>
#define SWAPENDIAN(x)\
(x = (x >> 8 & 0xff00ff) | (x & 0xff00ff) << 8, x = x >> 16 | x << 16)
struct Crypto1State * crypto1_create(uint64_t key)
{
struct Crypto1State *s = malloc(sizeof(*s));
int i;
for(i = 47;s && i > 0; i -= 2) {
s->odd = s->odd << 1 | BIT(key, (i - 1) ^ 7);
s->even = s->even << 1 | BIT(key, i ^ 7);
}
return s;
}
void crypto1_destroy(struct Crypto1State *state)
{
free(state);
}
void crypto1_get_lfsr(struct Crypto1State *state, uint64_t *lfsr)
{
int i;
for(*lfsr = 0, i = 23; i >= 0; --i) {
*lfsr = *lfsr << 1 | BIT(state->odd, i ^ 3);
*lfsr = *lfsr << 1 | BIT(state->even, i ^ 3);
}
}
uint8_t crypto1_bit(struct Crypto1State *s, uint8_t in, int is_encrypted)
{
uint32_t feedin;
uint8_t ret = filter(s->odd);
feedin = ret & !!is_encrypted;
feedin ^= !!in;
feedin ^= LF_POLY_ODD & s->odd;
feedin ^= LF_POLY_EVEN & s->even;
s->even = s->even << 1 | parity(feedin);
s->odd ^= (s->odd ^= s->even, s->even ^= s->odd);
return ret;
}
uint8_t crypto1_byte(struct Crypto1State *s, uint8_t in, int is_encrypted)
{
uint8_t i, ret = 0;
for (i = 0; i < 8; ++i)
ret |= crypto1_bit(s, BIT(in, i), is_encrypted) << i;
return ret;
}
uint32_t crypto1_word(struct Crypto1State *s, uint32_t in, int is_encrypted)
{
uint32_t i, ret = 0;
for (i = 0; i < 32; ++i)
ret |= crypto1_bit(s, BEBIT(in, i), is_encrypted) << (i ^ 24);
return ret;
}
/* prng_successor
* helper used to obscure the keystream during authentication
*/
uint32_t prng_successor(uint32_t x, uint32_t n)
{
SWAPENDIAN(x);
while(n--)
x = x >> 1 | (x >> 16 ^ x >> 18 ^ x >> 19 ^ x >> 21) << 31;
return SWAPENDIAN(x);
}

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -1,120 +0,0 @@
/*
Package:
MiFare Classic Universal toolKit (MFCUK)
Filename:
mfcuk_keyrecovery_darkside.h
Description:
MFCUK DarkSide Key Recovery specific typedefs and defines
Contact, bug-reports:
http://andreicostin.com/
mailto:zveriu@gmail.com
License:
GPL2 (see below), Copyright (C) 2009, Andrei Costin
* @file mfcuk_keyrecovery_darkside.h
* @brief
*/
/*
VERSION HISTORY
--------------------------------------------------------------------------------
| Number : 0.1
| dd/mm/yyyy : 23/11/2009
| Author : zveriu@gmail.com, http://andreicostin.com
| Description: Moved bulk of defines and things from "mfcuk_keyrecovery_darkside.c"
--------------------------------------------------------------------------------
*/
/*
LICENSE
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _MFCUK_KEYRECOVERY_DARKSIDE_H_
#define _MFCUK_KEYRECOVERY_DARKSIDE_H_
// Define package and executable related info
#define BUILD_NAME "Mifare Classic DarkSide Key Recovery Tool"
#define BUILD_VERSION "0.3"
#define BUILD_AUTHOR "Andrei Costin, zveriu@gmail.com, http://andreicostin.com"
// Define return statuses
#define MFCUK_SUCCESS 0x0
#define MFCUK_OK_KEY_RECOVERED (MFCUK_SUCCESS+1)
#define MFCUK_FAIL_AUTH (MFCUK_OK_KEY_RECOVERED+1)
#define MFCUK_FAIL_CRAPTO (MFCUK_FAIL_AUTH+1)
#define MFCUK_FAIL_TAGTYPE_INVALID (MFCUK_FAIL_CRAPTO+1)
#define MFCUK_FAIL_KEYTYPE_INVALID (MFCUK_FAIL_TAGTYPE_INVALID+1)
#define MFCUK_FAIL_BLOCK_INVALID (MFCUK_FAIL_KEYTYPE_INVALID+1)
#define MFCUK_FAIL_SECTOR_INVALID (MFCUK_FAIL_BLOCK_INVALID+1)
#define MFCUK_FAIL_COMM (MFCUK_FAIL_SECTOR_INVALID+1)
#define MFCUK_FAIL_MEMORY (MFCUK_FAIL_COMM+1)
// There are 4 bytes in ACBITS, use each byte as below
#define ACTIONS_KEY_A 0 // Specifies the byte index where actions for key A are stored
#define RESULTS_KEY_A 1 // Specifies the byte index where results for key A are stored
#define ACTIONS_KEY_B 2 // Specifies the byte index where actions for key B are stored
#define RESULTS_KEY_B 3 // Specifies the byte index where results for key B are stored
// The action/result byte can contain any combination of these
#define ACTIONS_VERIFY 0x1 // Specifies whether the key should be first verified
#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
#define ACTIONS_KEYSET 0x4 // Specifies whether the key was set from command line rather that should be loaded from the eventual -i/-I dump
// Implementation specific, since we are not 100% sure we can fix the tag nonce
// Suppose from 2^32, only MAX 2^16 tag nonces will appear given current SLEEP_ values
#define MAX_TAG_NONCES 65536
// Maximum possible states allocated and returned by lsfr_common_prefix(). Used this value in the looping
#define MAX_COMMON_PREFIX_STATES (1<<20)
// 10 ms, though {WPMCC09} claims 30 us is enough
#define SLEEP_AT_FIELD_OFF 10
// 50 ms, seems pretty good constant, though if you don't like it - make it even 3.1415..., we don't care
#define SLEEP_AFTER_FIELD_ON 50
// Since the 29 bits of {Nr} are constant, darkside varies only "last" (0xFFFFFF1F) 3 bits, thus we have 8 possible parity bits arrays
#define MFCUK_DARKSIDE_MAX_LEVELS 8
#define MFCUK_DARKSIDE_START_NR 0xDEADBEEF
#define MFCUK_DARKSIDE_START_AR 0xFACECAFE
typedef struct tag_nonce_entry
{
uint32_t tagNonce; // Tag nonce we target for fixation
byte_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
uint32_t num_of_appearances; // For statistics, how many times this tag nonce appeared for the given SLEEP_ values
// STAGE1 data for "dark side" and lsfr_common_prefix()
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
uint32_t spoofNrEnc; // {Nr} value which we will be using to make the tag respond with 4 bits
uint32_t spoofArEnc; // PARAM: used as rr
uint8_t spoofParBitsEnc; // parity bits we are trying to guess for the first time
uint8_t spoofNackEnc; // store here the encrypted NACK returned first time we match the parity bits
uint8_t spoofKs; // store here the keystream ks used for encryptying spoofNackEnc, specifically spoofKs = spoofNackEnc ^ 0x5
// STAGE2 data for "dark side" and lsfr_common_prefix()
int current_out_of_8; // starting from -1 until we find parity for chosen spoofNrEnc,spoofArEnc
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
uint32_t nrEnc[MFCUK_DARKSIDE_MAX_LEVELS]; // the 29 bits constant prefix, varying only 3 bits, thus 8 possible values
uint32_t arEnc[MFCUK_DARKSIDE_MAX_LEVELS]; // the same reader response as spoofArEnc; redundant but... :)
uint8_t ks[MFCUK_DARKSIDE_MAX_LEVELS]; // PARAM: used as ks, obtained as (ks[i] = nackEnc[i] ^ 0x5)
uint8_t nackEnc[MFCUK_DARKSIDE_MAX_LEVELS]; // store here the encrypted 4 bits values which tag responded
uint8_t parBits[MFCUK_DARKSIDE_MAX_LEVELS]; // store here the values based on spoofParBitsEnc, varying only last 5 bits
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]
} tag_nonce_entry_t;
#endif // _MFCUK_KEYRECOVERY_DARKSIDE_H_

View File

@ -1,216 +0,0 @@
/*
LICENSE
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
Package:
MiFare Classic Universal toolKit (MFCUK)
Package version:
0.1
Filename:
mfcuk_finger.c
Description:
MFCUK fingerprinting and specific data-decoding functionality.
License:
GPL2, Copyright (C) 2009, Andrei Costin
* @file mfcuk_finger.c
* @brief MFCUK fingerprinting and specific data-decoding functionality.
* @todo add proper error codes
*/
#include "mfcuk_finger.h"
mfcuk_finger_tmpl_entry mfcuk_finger_db[] =
{
{ "./data/tmpls_fingerprints/mfcuk_tmpl_skgt.mfd", "Sofia SKGT", mfcuk_finger_default_comparator, mfcuk_finger_skgt_decoder, NULL },
{ "./data/tmpls_fingerprints/mfcuk_tmpl_ratb.mfd", "Bucharest RATB", mfcuk_finger_default_comparator, mfcuk_finger_default_decoder, NULL },
{ "./data/tmpls_fingerprints/mfcuk_tmpl_oyster.mfd", "London OYSTER", mfcuk_finger_default_comparator, mfcuk_finger_default_decoder, NULL },
};
int mfcuk_finger_db_entries = sizeof(mfcuk_finger_db)/sizeof(mfcuk_finger_db[0]);
int mfcuk_finger_default_decoder(mifare_classic_tag *dump)
{
if (!dump)
{
fprintf(stderr, "ERROR: cannot decode a NULL pointer :)\n");
return 0;
}
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]);
printf("TYPE:\t%02x\n", dump->amb[0].mbm.btUnknown);
return 1;
}
// Yes, I know C++ class inheritance would perfectly fit the decoders/comparators... Though C is more to my heart. Anyone to rewrite in C++?
int mfcuk_finger_skgt_decoder(mifare_classic_tag *dump)
{
unsigned char *dump_ptr = NULL;
unsigned short car_number = 0;
if (!dump)
{
fprintf(stderr, "ERROR: cannot decode a NULL pointer :)\n");
return 0;
}
dump_ptr = (unsigned char *) dump;
printf("Bulgaria/Sofia/SKGT public transport card information decoder (info credits to Andy)\n");
mfcuk_finger_default_decoder(dump);
printf("LAST TRAVEL DATA\n");
// TODO: get proper information
return 1;
}
int mfcuk_finger_default_comparator(mifare_classic_tag *dump, mfcuk_finger_template *tmpl, float *score)
{
int max_bytes = 0;
int i;
int num_bytes_tomatch = 0;
int num_bytes_matched = 0;
if ( (!dump) || (!tmpl) || (!score) )
{
return 0;
}
if (IS_MIFARE_CLASSIC_1K_TAG(dump))
{
max_bytes = MIFARE_CLASSIC_BYTES_PER_BLOCK * MIFARE_CLASSIC_1K_MAX_BLOCKS;
}
else if (IS_MIFARE_CLASSIC_4K_TAG(dump))
{
max_bytes = MIFARE_CLASSIC_BYTES_PER_BLOCK * MIFARE_CLASSIC_4K_MAX_BLOCKS;
}
else
{
return 0;
}
for (i=0; i<max_bytes; i++)
{
if ( ((char *)(&tmpl->mask))[i] == 0x0 )
{
continue;
}
num_bytes_tomatch++;
if ( ((char *)(&tmpl->values))[i] == ((char *)dump)[i] )
{
num_bytes_matched++;
}
}
if (num_bytes_tomatch == 0)
{
return 0;
}
else
{
*score = (float)(num_bytes_matched)/num_bytes_tomatch;
}
return 1;
}
int mfcuk_finger_load()
{
int i;
mifare_classic_tag mask;
mifare_classic_tag values;
FILE *fp = NULL;
size_t result = 0;
mfcuk_finger_template *tmpl_new = NULL;
int template_loaded_count = 0;
for (i = 0; i<mfcuk_finger_db_entries; i++)
{
fp = fopen(mfcuk_finger_db[i].tmpl_filename, "rb");
if (!fp)
{
fprintf(stderr, "WARN: cannot open template file '%s'\n", mfcuk_finger_db[i].tmpl_filename);
continue;
}
// If not read exactly 1 record, something is wrong
if ( (result = fread((void *)(&mask), sizeof(mask), 1, fp)) != 1)
{
fprintf(stderr, "WARN: cannot read MASK from template file '%s'\n", mfcuk_finger_db[i].tmpl_filename);
fclose(fp);
continue;
}
// If not read exactly 1 record, something is wrong
if ( (result = fread((void *)(&values), sizeof(values), 1, fp)) != 1)
{
fprintf(stderr, "WARN: cannot read VALUES template file '%s'\n", mfcuk_finger_db[i].tmpl_filename);
fclose(fp);
continue;
}
if (mfcuk_finger_db[i].tmpl_data == NULL)
{
if ( (tmpl_new = (mfcuk_finger_template *) malloc(sizeof(mfcuk_finger_template))) == NULL)
{
fprintf(stderr, "WARN: cannot allocate memory to template record %d\n", i);
fclose(fp);
continue;
}
memcpy( &(tmpl_new->mask), &(mask), sizeof(mask));
memcpy( &(tmpl_new->values), &(values), sizeof(values));
mfcuk_finger_db[i].tmpl_data = tmpl_new;
template_loaded_count++;
}
if (fp)
{
fclose(fp);
fp = NULL;
}
}
return template_loaded_count;
}
int mfcuk_finger_unload()
{
int i;
for (i = 0; i<mfcuk_finger_db_entries; i++)
{
if (mfcuk_finger_db[i].tmpl_data != NULL)
{
free(mfcuk_finger_db[i].tmpl_data);
mfcuk_finger_db[i].tmpl_data = NULL;
}
}
return 1;
}

View File

@ -1,76 +0,0 @@
/*
LICENSE
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
Package:
MiFare Classic Universal toolKit (MFCUK)
Package version:
0.1
Filename:
mfcuk_finger.h
Description:
MFCUK fingerprinting and specific data-decoding functionality.
License:
GPL2, Copyright (C) 2009, Andrei Costin
* @file mfcuk_finger.h
* @brief MFCUK fingerprinting and specific data-decoding functionality.
*/
#ifndef _MFCUK_FINGER_H_
#define _MFCUK_FINGER_H_
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "mfcuk_mifare.h"
// Wrapping an ugly template into an externally pleasant name. To implement proper template later.
typedef struct _mfcuk_finger_template_
{
mifare_classic_tag mask;
mifare_classic_tag values;
} mfcuk_finger_template;
// Function type definition, to be used for custom decoders/comparators
typedef int (*mfcuk_finger_comparator) (mifare_classic_tag *dump, mfcuk_finger_template *tmpl, float *score);
typedef int (*mfcuk_finger_decoder) (mifare_classic_tag *dump);
// Naive implementation of a self-contained fingerprint database entry
typedef struct _mfcuk_finger_tmpl_entry_
{
char *tmpl_filename;
char *tmpl_name;
mfcuk_finger_comparator tmpl_comparison_func;
mfcuk_finger_decoder tmpl_decoder_func;
mfcuk_finger_template *tmpl_data;
} mfcuk_finger_tmpl_entry;
int mfcuk_finger_default_comparator(mifare_classic_tag *dump, mfcuk_finger_template *tmpl, float *score);
int mfcuk_finger_default_decoder(mifare_classic_tag *dump);
int mfcuk_finger_skgt_decoder(mifare_classic_tag *dump);
// "Housekeeping" functions
int mfcuk_finger_load();
int mfcuk_finger_unload();
#endif

View File

@ -1,560 +0,0 @@
/*
Package:
MiFare Classic Universal toolKit (MFCUK)
Package version:
0.1
Filename:
mfcuk_mifare.c
Description:
MFCUK defines and function implementation file extending
mainly libnfc's "mifare.h" interface/functionality.
Contact, bug-reports:
http://andreicostin.com/
mailto:zveriu@gmail.com
License:
GPL2 (see below), Copyright (C) 2009, Andrei Costin
* @file mfcuk_mifare.c
* @brief
*/
/*
VERSION HISTORY
--------------------------------------------------------------------------------
| Number : 0.1
| dd/mm/yyyy : 23/11/2009
| Author : zveriu@gmail.com, http://andreicostin.com
| Description: Moved bulk of defines and functions from "mfcuk_keyrecovery_darkside.c"
--------------------------------------------------------------------------------
*/
/*
LICENSE
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "mfcuk_mifare.h"
// Default keys used as a *BIG* mistake in many applications - especially System Integrators should pay attention!
byte_t mfcuk_default_keys[][MIFARE_CLASSIC_KEY_BYTELENGTH] =
{
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // Place-holder for current key to verify
{0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
{0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5},
{0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x4d, 0x3a, 0x99, 0xc3, 0x51, 0xdd},
{0x1a, 0x98, 0x2c, 0x7e, 0x45, 0x9a},
{0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7},
{0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff},
};
int mfcuk_default_keys_num = sizeof(mfcuk_default_keys)/sizeof(mfcuk_default_keys[0]);
bool is_valid_block(byte_t bTagType, uint32_t uiBlock)
{
if ( IS_MIFARE_CLASSIC_1K(bTagType) && (uiBlock < MIFARE_CLASSIC_1K_MAX_BLOCKS) )
{
return true;
}
if ( IS_MIFARE_CLASSIC_4K(bTagType) && (uiBlock < MIFARE_CLASSIC_4K_MAX_BLOCKS) )
{
return true;
}
return false;
}
bool is_valid_sector(byte_t bTagType, uint32_t uiSector)
{
if ( IS_MIFARE_CLASSIC_1K(bTagType) && (uiSector < MIFARE_CLASSIC_1K_MAX_SECTORS) )
{
return true;
}
if ( IS_MIFARE_CLASSIC_4K(bTagType) && (uiSector < MIFARE_CLASSIC_4K_MAX_SECTORS) )
{
return true;
}
return false;
}
bool is_first_block(byte_t bTagType, uint32_t uiBlock)
{
if ( !is_valid_block(bTagType, uiBlock) )
{
return false;
}
// Test if we are in the small or big sectors
if (uiBlock < MIFARE_CLASSIC_4K_MAX_BLOCKS1)
{
// For Mifare Classic 1K, it will enter always here
return ( (uiBlock) % (MIFARE_CLASSIC_4K_BLOCKS_PER_SECTOR1) == 0 );
}
else
{
// This branch will enter only for Mifare Classic 4K big sectors
return ( (uiBlock) % (MIFARE_CLASSIC_4K_BLOCKS_PER_SECTOR2) == 0 );
}
// Should not reach here, but... never know
return false;
}
bool is_trailer_block(byte_t bTagType, uint32_t uiBlock)
{
if ( !is_valid_block(bTagType, uiBlock) )
{
return false;
}
// Test if we are in the small or big sectors
if (uiBlock < MIFARE_CLASSIC_4K_MAX_BLOCKS1)
{
// For Mifare Classic 1K, it will enter always here
return ( (uiBlock+1) % (MIFARE_CLASSIC_4K_BLOCKS_PER_SECTOR1) == 0 );
}
else
{
// This branch will enter only for Mifare Classic 4K big sectors
return ( (uiBlock+1) % (MIFARE_CLASSIC_4K_BLOCKS_PER_SECTOR2) == 0 );
}
// Should not reach here, but... never know
return false;
}
uint32_t get_first_block(byte_t bTagType, uint32_t uiBlock)
{
if ( !is_valid_block(bTagType, uiBlock) )
{
return MIFARE_CLASSIC_INVALID_BLOCK;
}
// Test if we are in the small or big sectors
if (uiBlock < MIFARE_CLASSIC_4K_MAX_BLOCKS1)
{
// Integer divide, then integer multiply
return (uiBlock/MIFARE_CLASSIC_4K_BLOCKS_PER_SECTOR1) * MIFARE_CLASSIC_4K_BLOCKS_PER_SECTOR1;
}
else
{
uint32_t tmp = uiBlock - MIFARE_CLASSIC_4K_MAX_BLOCKS1;
return MIFARE_CLASSIC_4K_MAX_BLOCKS1 + (tmp/MIFARE_CLASSIC_4K_BLOCKS_PER_SECTOR2) * MIFARE_CLASSIC_4K_BLOCKS_PER_SECTOR2;
}
// Should not reach here, but... never know
return MIFARE_CLASSIC_INVALID_BLOCK;
}
uint32_t get_trailer_block(byte_t bTagType, uint32_t uiBlock)
{
if ( !is_valid_block(bTagType, uiBlock) )
{
return MIFARE_CLASSIC_INVALID_BLOCK;
}
// Test if we are in the small or big sectors
if (uiBlock < MIFARE_CLASSIC_4K_MAX_BLOCKS1)
{
// Integer divide, then integer multiply
return (uiBlock/MIFARE_CLASSIC_4K_BLOCKS_PER_SECTOR1) * MIFARE_CLASSIC_4K_BLOCKS_PER_SECTOR1 + (MIFARE_CLASSIC_4K_BLOCKS_PER_SECTOR1-1);
}
else
{
uint32_t tmp = uiBlock - MIFARE_CLASSIC_4K_MAX_BLOCKS1;
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);
}
// Should not reach here, but... never know
return MIFARE_CLASSIC_INVALID_BLOCK;
}
bool is_big_sector(byte_t bTagType, uint32_t uiSector)
{
if ( !is_valid_sector(bTagType, uiSector) )
{
return false;
}
if (uiSector >= MIFARE_CLASSIC_4K_MAX_SECTORS1)
{
return true;
}
return false;
}
uint32_t get_first_block_for_sector(byte_t bTagType, uint32_t uiSector)
{
if ( !is_valid_sector(bTagType, uiSector) )
{
return MIFARE_CLASSIC_INVALID_BLOCK;
}
if (uiSector < MIFARE_CLASSIC_4K_MAX_SECTORS1)
{
// For Mifare Classic 1K, it will enter always here
return (uiSector * MIFARE_CLASSIC_4K_BLOCKS_PER_SECTOR1);
}
else
{
// For Mifare Classic 4K big sectors it will enter always here
uint32_t tmp = uiSector - MIFARE_CLASSIC_4K_MAX_SECTORS1;
return MIFARE_CLASSIC_4K_MAX_BLOCKS1 + (tmp * MIFARE_CLASSIC_4K_BLOCKS_PER_SECTOR2);
}
// Should not reach here, but... never know
return MIFARE_CLASSIC_INVALID_BLOCK;
}
uint32_t get_trailer_block_for_sector(byte_t bTagType, uint32_t uiSector)
{
if ( !is_valid_sector(bTagType, uiSector) )
{
return MIFARE_CLASSIC_INVALID_BLOCK;
}
if (uiSector < MIFARE_CLASSIC_4K_MAX_SECTORS1)
{
// For Mifare Classic 1K, it will enter always here
return (uiSector * MIFARE_CLASSIC_4K_BLOCKS_PER_SECTOR1) + (MIFARE_CLASSIC_4K_BLOCKS_PER_SECTOR1-1);
}
else
{
// For Mifare Classic 4K big sectors it will enter always here
uint32_t tmp = uiSector - MIFARE_CLASSIC_4K_MAX_SECTORS1;
return MIFARE_CLASSIC_4K_MAX_BLOCKS1 + (tmp * MIFARE_CLASSIC_4K_BLOCKS_PER_SECTOR2) + (MIFARE_CLASSIC_4K_BLOCKS_PER_SECTOR2-1);
}
// Should not reach here, but... never know
return MIFARE_CLASSIC_INVALID_BLOCK;
}
uint32_t get_sector_for_block(byte_t bTagType, uint32_t uiBlock)
{
if ( !is_valid_block(bTagType, uiBlock) )
{
return MIFARE_CLASSIC_INVALID_BLOCK;
}
// Test if we are in the small or big sectors
if (uiBlock < MIFARE_CLASSIC_4K_MAX_BLOCKS1)
{
// For Mifare Classic 1K, it will enter always here
return (uiBlock/MIFARE_CLASSIC_4K_BLOCKS_PER_SECTOR1);
}
else
{
uint32_t tmp = uiBlock - MIFARE_CLASSIC_4K_MAX_BLOCKS1;
return MIFARE_CLASSIC_4K_MAX_SECTORS1 + (tmp/MIFARE_CLASSIC_4K_BLOCKS_PER_SECTOR2);
}
// Should not reach here, but... never know
return MIFARE_CLASSIC_INVALID_BLOCK;
}
bool is_first_sector(byte_t bTagType, uint32_t uiSector)
{
// TODO: write code
return false;
}
bool is_first_big_sector(byte_t bTagType, uint32_t uiSector)
{
// TODO: write code
return false;
}
bool is_first_small_sector(byte_t bTagType, uint32_t uiSector)
{
// TODO: write code
return false;
}
bool is_last_sector(byte_t bTagType, uint32_t uiSector)
{
// TODO: write code
return false;
}
bool is_last_big_sector(byte_t bTagType, uint32_t uiSector)
{
// TODO: write code
return false;
}
bool is_last_small_sector(byte_t bTagType, uint32_t uiSector)
{
// TODO: write code
return false;
}
// Test case function for checking correct functionality of the block/sector is_ ang get_ functions
void test_mifare_classic_blocks_sectors_functions(byte_t bTagType)
{
uint32_t i;
uint32_t max_blocks, max_sectors;
if ( IS_MIFARE_CLASSIC_1K(bTagType) )
{
printf("\nMIFARE CLASSIC 1K\n");
max_blocks = MIFARE_CLASSIC_1K_MAX_BLOCKS;
max_sectors = MIFARE_CLASSIC_1K_MAX_SECTORS;
}
else if ( IS_MIFARE_CLASSIC_4K(bTagType) )
{
printf("\nMIFARE CLASSIC 4K\n");
max_blocks = MIFARE_CLASSIC_4K_MAX_BLOCKS;
max_sectors = MIFARE_CLASSIC_4K_MAX_SECTORS;
}
else
{
return;
}
// Include one invalid block, that is why we add +1
for (i = 0; i<max_blocks+1; i++)
{
printf("BLOCK %d\n", i);
printf("\t is_valid_block: %c\n", (is_valid_block(bTagType, i)?'Y':'N') );
printf("\t is_first_block: %c\n", (is_first_block(bTagType, i)?'Y':'N') );
printf("\t is_trailer_block: %c\n", (is_trailer_block(bTagType, i)?'Y':'N') );
printf("\t get_first_block: %d\n", get_first_block(bTagType, i));
printf("\t get_trailer_block: %d\n", get_trailer_block(bTagType, i));
printf("\t get_sector_for_block: %d\n", get_sector_for_block(bTagType, i));
}
// Include one invalid sector, that is why we add +1
for (i = 0; i<max_sectors+1; i++)
{
printf("SECTOR %d\n", i);
printf("\t is_valid_sector: %c\n", (is_valid_sector(bTagType, i)?'Y':'N') );
printf("\t is_big_sector: %c\n", (is_big_sector(bTagType, i)?'Y':'N') );
printf("\t get_first_block_for_sector: %d\n", get_first_block_for_sector(bTagType, i) );
printf("\t get_trailer_block_for_sector: %d\n", get_trailer_block_for_sector(bTagType, i) );
}
}
bool mfcuk_save_tag_dump(char *filename, mifare_classic_tag *tag)
{
FILE *fp;
size_t result;
fp = fopen(filename, "wb");
if (!fp)
{
return false;
}
// Expect to write 1 record
result = fwrite((void *) tag, sizeof(*tag), 1, fp);
// If not written exactly 1 record, something is wrong
if (result != 1)
{
fclose(fp);
return false;
}
fclose(fp);
return true;
}
bool mfcuk_save_tag_dump_ext(char *filename, mifare_classic_tag_ext *tag_ext)
{
FILE *fp;
size_t result;
fp = fopen(filename, "wb");
if (!fp)
{
return false;
}
// Expect to write 1 record
result = fwrite((void *) tag_ext, sizeof(*tag_ext), 1, fp);
// If not written exactly 1 record, something is wrong
if (result != 1)
{
fclose(fp);
return false;
}
fclose(fp);
return true;
}
bool mfcuk_load_tag_dump(char *filename, mifare_classic_tag *tag)
{
FILE *fp;
size_t result;
fp = fopen(filename, "rb");
if (!fp)
{
return false;
}
// Expect to read 1 record
result = fread((void *) tag, sizeof(*tag), 1, fp);
// If not read exactly 1 record, something is wrong
if (result != 1)
{
fclose(fp);
return false;
}
fclose(fp);
return true;
}
bool mfcuk_load_tag_dump_ext(char *filename, mifare_classic_tag_ext *tag_ext)
{
FILE *fp;
size_t result;
fp = fopen(filename, "rb");
if (!fp)
{
return false;
}
// Expect to read 1 record
result = fread((void *) tag_ext, sizeof(*tag_ext), 1, fp);
// If not read exactly 1 record, something is wrong
if (result != sizeof(*tag_ext))
{
fclose(fp);
return false;
}
fclose(fp);
return true;
}
void print_mifare_classic_tag_keys(const char *title, mifare_classic_tag *tag)
{
uint32_t i, max_blocks, trailer_block;
byte_t bTagType;
mifare_classic_block_trailer *ptr_trailer = NULL;
if (!tag)
{
return;
}
bTagType = tag->amb->mbm.btUnknown;
if ( !IS_MIFARE_CLASSIC_1K(bTagType) && !IS_MIFARE_CLASSIC_4K(bTagType) )
{
return;
}
printf("%s - UID %02x %02x %02x %02x - TYPE 0x%02x (%s)\n",
title, tag->amb->mbm.abtUID[0], tag->amb->mbm.abtUID[1], tag->amb->mbm.abtUID[2], tag->amb->mbm.abtUID[3], bTagType,
(IS_MIFARE_CLASSIC_1K(bTagType)?(MIFARE_CLASSIC_1K_NAME):(IS_MIFARE_CLASSIC_4K(bTagType)?(MIFARE_CLASSIC_4K_NAME):(MIFARE_CLASSIC_UNKN_NAME)))
);
printf("-------------------------------------------------------\n");
printf("Sector\t| Key A\t| AC bits\t| Key B\n");
printf("-------------------------------------------------------\n");
if ( IS_MIFARE_CLASSIC_1K(tag->amb->mbm.btUnknown) )
{
max_blocks = MIFARE_CLASSIC_1K_MAX_BLOCKS;
}
else
{
max_blocks = MIFARE_CLASSIC_4K_MAX_BLOCKS;
}
for (i=0; i<max_blocks; i++)
{
trailer_block = get_trailer_block(bTagType, i);
if ( !is_valid_block(bTagType, trailer_block) )
{
break;
}
ptr_trailer = (mifare_classic_block_trailer *) ((char *)tag + (trailer_block * MIFARE_CLASSIC_BYTES_PER_BLOCK) );
printf("%d\t| %02x%02x%02x%02x%02x%02x\t| %02x%02x%02x%02x\t| %02x%02x%02x%02x%02x%02x\n",
get_sector_for_block(bTagType, trailer_block),
ptr_trailer->abtKeyA[0], ptr_trailer->abtKeyA[1], ptr_trailer->abtKeyA[2],
ptr_trailer->abtKeyA[3], ptr_trailer->abtKeyA[4], ptr_trailer->abtKeyA[5],
ptr_trailer->abtAccessBits[0], ptr_trailer->abtAccessBits[1], ptr_trailer->abtAccessBits[2], ptr_trailer->abtAccessBits[3],
ptr_trailer->abtKeyB[0], ptr_trailer->abtKeyB[1], ptr_trailer->abtKeyB[2],
ptr_trailer->abtKeyB[3], ptr_trailer->abtKeyB[4], ptr_trailer->abtKeyB[5]
);
// Go beyond current trailer block, i.e. go to next sector
i = trailer_block;
}
printf("\n");
return;
}
bool mfcuk_key_uint64_to_arr(const uint64_t *ui64Key, byte_t *arr6Key)
{
int i;
if ( !ui64Key || !arr6Key )
{
return false;
}
for (i = 0; i<MIFARE_CLASSIC_KEY_BYTELENGTH; i++)
{
arr6Key[i] = (byte_t) (((*ui64Key) >> 8*(MIFARE_CLASSIC_KEY_BYTELENGTH - i - 1)) & 0xFF);
}
return true;
}
bool mfcuk_key_arr_to_uint64(const byte_t *arr6Key, uint64_t *ui64Key)
{
uint64_t key = 0;
int i;
if ( !ui64Key || !arr6Key )
{
return false;
}
for (i = 0; i<MIFARE_CLASSIC_KEY_BYTELENGTH; i++, key <<= 8)
{
key |= arr6Key[i];
}
key >>= 8;
*ui64Key = key;
return true;
}

View File

@ -1,145 +0,0 @@
/*
Package:
MiFare Classic Universal toolKit (MFCUK)
Package version:
0.1
Filename:
mfcuk_mifare.h
Description:
MFCUK defines and function prototypes header file extending
mainly libnfc's "mifare.h" interface/functionality.
Contact, bug-reports:
http://andreicostin.com/
mailto:zveriu@gmail.com
License:
GPL2 (see below), Copyright (C) 2009, Andrei Costin
* @file mfcuk_mifare.h
* @brief
*/
/*
VERSION HISTORY
--------------------------------------------------------------------------------
| Number : 0.1
| dd/mm/yyyy : 23/11/2009
| Author : zveriu@gmail.com, http://andreicostin.com
| Description: Moved bulk of defines and functions from "mfcuk_keyrecovery_darkside.c"
--------------------------------------------------------------------------------
*/
/*
LICENSE
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _MFCUK_MIFARE_H_
#define _MFCUK_MIFARE_H_
#include <stdio.h>
#include <stdlib.h>
#include <nfc/nfc.h>
#include "mifare.h"
#define MIFARE_CLASSIC_UID_BYTELENGTH 4 // Length of a Mifare Classic UID in bytes
#define MIFARE_CLASSIC_KEY_BYTELENGTH 6 // Length of a Mifare Classic key in bytes
#define MIFARE_CLASSIC_1K_NAME "MC1K"
#define MIFARE_CLASSIC_4K_NAME "MC4K"
#define MIFARE_CLASSIC_UNKN_NAME "UNKN"
#define MIFARE_CLASSIC_1K 0x08 // MF1ICS50 Functional Specifications - 0x08
#define MIFARE_CLASSIC_4K 0x18 // MF1ICS70 Functional Specifications - 0x18
#define MIFARE_DESFIRE 0x20 // XXXXXXXX Functional Specifications - 0x20
#define MIFARE_CLASSIC_1K_RATB 0x88 // Infineon Licensed Mifare 1K = 0x88 (thanks JPS)
#define MIFARE_CLASSIC_4K_SKGT 0x98 // Infineon Licensed Mifare 4K = 0x98???
#define IS_MIFARE_CLASSIC_1K(ats_sak) ( ((ats_sak) == MIFARE_CLASSIC_1K) || ((ats_sak) == MIFARE_CLASSIC_1K_RATB) )
#define IS_MIFARE_CLASSIC_4K(ats_sak) ( ((ats_sak) == MIFARE_CLASSIC_4K) || ((ats_sak) == MIFARE_CLASSIC_4K_SKGT) )
#define IS_MIFARE_DESFIRE(ats_sak) ( ((ats_sak) == MIFARE_DESFIRE) )
#define IS_MIFARE_CLASSIC_1K_TAG(tag) IS_MIFARE_CLASSIC_1K(tag->amb[0].mbm.btUnknown)
#define IS_MIFARE_CLASSIC_4K_TAG(tag) IS_MIFARE_CLASSIC_4K(tag->amb[0].mbm.btUnknown)
#define IS_MIFARE_DESFIRE_TAG(tag) IS_MIFARE_DESFIRE(tag->amb[0].mbm.btUnknown)
#define MIFARE_CLASSIC_BYTES_PER_BLOCK 16 // Common for Mifare Classic 1K and Mifare Classic 4K
#define MIFARE_CLASSIC_INVALID_BLOCK 0xFFFFFFFF
#define MIFARE_CLASSIC_1K_MAX_SECTORS 16
#define MIFARE_CLASSIC_1K_BLOCKS_PER_SECTOR 4
#define MIFARE_CLASSIC_1K_MAX_BLOCKS ( (MIFARE_CLASSIC_1K_MAX_SECTORS) * (MIFARE_CLASSIC_1K_BLOCKS_PER_SECTOR) )
#define MIFARE_CLASSIC_4K_MAX_SECTORS1 32
#define MIFARE_CLASSIC_4K_BLOCKS_PER_SECTOR1 MIFARE_CLASSIC_1K_BLOCKS_PER_SECTOR // Possibly NXP made it for Mifare 1K backward compatibility
#define MIFARE_CLASSIC_4K_MAX_BLOCKS1 ( (MIFARE_CLASSIC_4K_MAX_SECTORS1) * (MIFARE_CLASSIC_4K_BLOCKS_PER_SECTOR1) )
#define MIFARE_CLASSIC_4K_MAX_SECTORS2 8
#define MIFARE_CLASSIC_4K_BLOCKS_PER_SECTOR2 16
#define MIFARE_CLASSIC_4K_MAX_BLOCKS2 ( (MIFARE_CLASSIC_4K_MAX_SECTORS2) * (MIFARE_CLASSIC_4K_BLOCKS_PER_SECTOR2) )
#define MIFARE_CLASSIC_4K_MAX_SECTORS ( (MIFARE_CLASSIC_4K_MAX_SECTORS1) + (MIFARE_CLASSIC_4K_MAX_SECTORS2) )
#define MIFARE_CLASSIC_4K_MAX_BLOCKS ( (MIFARE_CLASSIC_4K_MAX_BLOCKS1) + (MIFARE_CLASSIC_4K_MAX_BLOCKS2) )
#define MFCUK_EXTENDED_DESCRIPTION_LENGTH 128
// Define an extended type of dump, basically a wrapper dump around basic tag dump
typedef struct {
uint32_t uid; // looks redundant, but it is easier to use dmp.uid instead of dmp.amb.mbm.abtUID[0]...[3]
byte_t type; // ATS/SAK from ti.tia.btSak, example 0x08h for Mifare 1K, 0x18h for Mifare 4K
char datetime[14]; // non-zero-terminated date-time of dump in format YYYYMMDDH24MISS, example 20091114231541 - 14 Nov 2009, 11:15:41 PM
char description[MFCUK_EXTENDED_DESCRIPTION_LENGTH]; // a description of the tag dump, example "RATB_DUMP_BEFORE_PAY"
mifare_classic_tag tag_basic;
} mifare_classic_tag_ext;
// Define type of keys (A or B) in NXP notation
typedef enum {
keyA = 0x60,
keyB = 0x61,
} mifare_key_type;
// Default keys used as a *BIG* mistake in many applications - especially System Integrators should pay attention!
extern byte_t mfcuk_default_keys[][MIFARE_CLASSIC_KEY_BYTELENGTH];
extern int mfcuk_default_keys_num;
bool is_valid_block(byte_t bTagType, uint32_t uiBlock);
bool is_valid_sector(byte_t bTagType, uint32_t uiSector);
bool is_first_block(byte_t bTagType, uint32_t uiBlock);
bool is_trailer_block(byte_t bTagType, uint32_t uiBlock);
uint32_t get_first_block(byte_t bTagType, uint32_t uiBlock);
uint32_t get_trailer_block(byte_t bTagType, uint32_t uiBlock);
bool is_big_sector(byte_t bTagType, uint32_t uiSector);
uint32_t get_first_block_for_sector(byte_t bTagType, uint32_t uiSector);
uint32_t get_trailer_block_for_sector(byte_t bTagType, uint32_t uiSector);
uint32_t get_sector_for_block(byte_t bTagType, uint32_t uiBlock);
bool is_first_sector(byte_t bTagType, uint32_t uiSector);
bool is_first_big_sector(byte_t bTagType, uint32_t uiSector);
bool is_first_small_sector(byte_t bTagType, uint32_t uiSector);
bool is_last_sector(byte_t bTagType, uint32_t uiSector);
bool is_last_big_sector(byte_t bTagType, uint32_t uiSector);
bool is_last_small_sector(byte_t bTagType, uint32_t uiSector);
void test_mifare_classic_blocks_sectors_functions(byte_t bTagType);
bool mfcuk_save_tag_dump(char *filename, mifare_classic_tag *tag);
bool mfcuk_save_tag_dump_ext(char *filename, mifare_classic_tag_ext *tag_ext);
bool mfcuk_load_tag_dump(char *filename, mifare_classic_tag *tag);
bool mfcuk_load_tag_dump_ext(char *filename, mifare_classic_tag_ext *tag_ext);
void print_mifare_classic_tag_keys(const char *title, mifare_classic_tag *tag);
bool mfcuk_key_uint64_to_arr(const uint64_t *ui64Key, byte_t *arr6Key);
bool mfcuk_key_arr_to_uint64(const byte_t *arr6Key, uint64_t *ui64Key);
#endif // _MFCUK_MIFARE_H_

View File

@ -1,81 +0,0 @@
/*
Package:
MiFare Classic Universal toolKit (MFCUK)
Package version:
0.1
Filename:
mfcuk_utils.c
Description:
MFCUK common utility functions implementation.
License:
GPL2 (see below), Copyright (C) 2009, Andrei Costin
* @file mfcuk_utils.c
* @brief
*/
/*
VERSION HISTORY
--------------------------------------------------------------------------------
| Number : 0.1
| dd/mm/yyyy : 23/11/2009
| Author : zveriu@gmail.com, http://andreicostin.com
| Description: Moved bulk of defines and prototypes from "mfcuk_keyrecovery_darkside.c"
--------------------------------------------------------------------------------
*/
/*
LICENSE
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "mfcuk_utils.h"
#ifdef __STDC__
struct timeval global_timeout;
#endif
/*
http://www.velocityreviews.com/forums/t451319-advice-required-on-my-ascii-to-hex-conversion-c.html
Basically, converting a hex digit into a hex nibble (4 binary digits) algorithm looks like;
char xdigit; // hex digit to convert [0-9A-Fa-f]
xdigit = tolower(xdigit); // make it lowercase [0-9a-f]
xdigit -= '0'; // if it was a [0-9] digit, it's the value now
if(xdigit > 9) // if it was a [a-f] digit, compensate for that
xdigit = xdigit + '0' - 'a';
The below code is just an optimization of the algorithm. Maxim Yegorushkin
*/
/*inline*/
int is_hex(char c)
{
return (c >= '0' && c <= '9') || ((c | 0x20) >= 'a' && (c | 0x20) <= 'f');
}
/*inline*/
unsigned char hex2bin(unsigned char h, unsigned char l)
{
h |= 0x20; // to lower
h -= 0x30;
h -= -(h > 9) & 0x27;
l |= 0x20;
l -= 0x30;
l -= -(l > 9) & 0x27;
return h << 4 | l;
}

View File

@ -1,104 +0,0 @@
/*
Package:
MiFare Classic Universal toolKit (MFCUK)
Package version:
0.1
Filename:
mfcuk_utils.h
Description:
MFCUK common utility functions prototypes.
License:
GPL2 (see below), Copyright (C) 2009, Andrei Costin
* @file mfcuk_utils.h/
* @brief
*/
/*
VERSION HISTORY
--------------------------------------------------------------------------------
| Number : 0.1
| dd/mm/yyyy : 23/11/2009
| Author : zveriu@gmail.com, http://andreicostin.com
| Description: Moved bulk of defines and prototypes from "mfcuk_keyrecovery_darkside.c"
--------------------------------------------------------------------------------
*/
/*
LICENSE
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _MFCUK_UTILS_H_
#define _MFCUK_UTILS_H_
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef WIN32
#define NOMINMAX
#include "windows.h"
#include "xgetopt.h"
#elif __STDC__
#include <unistd.h>
#include <sys/time.h>
#include <sys/types.h>
#endif
// "Portable" sleep(miliseconds)
#ifdef WIN32
#define sleep(x) Sleep(x)
#elif __STDC__
extern struct timeval global_timeout;
#define sleep(x) { global_timeout.tv_usec = 1000 * (x); select(0,NULL,NULL,NULL,&global_timeout); }
#endif
// "Portable" clear_screen() - NOTE: system performance penalty introduced
#ifdef WIN32
#define clear_screen() system("cls")
#elif __STDC__
#define clear_screen() system("sh -c clear")
#endif
/**
* @fn int is_hex(char c)
* @brief Checks if an ASCII character is a valid hexadecimal base digit
* @param c The ASCII character to be checked
* @return Returns true (non-zero) or false (zero)
*
* Checks if an ASCII character is a valid hexadecimal base digit.
* Used for hex2bin() functionality.
*/
int is_hex(char c);
/**
* @fn unsigned char hex2bin(unsigned char h, unsigned char l)
* @brief Converts from two nibbles (4 bits) into the corresponding byte
* @param h The HIGH (left-most in human reading) nibble of two-char hex representation of a byte
* @param l The LOW (right-most in human reading) nibble of two-char hex representation of a byte
* @return Returns the byte which is formed from the two-char hex representation of it
*
* Converts from two nibbles (4 bits) into the corresponding byte.
* Uses the algorithm and implementation from here:
* http://www.velocityreviews.com/forums/t451319-advice-required-on-my-ascii-to-hex-conversion-c.html
*/
unsigned char hex2bin(unsigned char h, unsigned char l);
#endif // _MFCUK_UTILS_H_

View File

@ -1,130 +0,0 @@
/*-
* Public platform independent Near Field Communication (NFC) library examples
*
* Copyright (C) 2009, Roel Verdult
* Copyright (C) 2010, Romuald Conty, Romain Tartière
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1) Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2 )Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Note that this license only applies on the examples, NFC library itself is under LGPL
*
*/
#include "mifare.h"
#include <string.h>
#include <nfc/nfc.h>
/**
* @brief Execute a MIFARE Classic Command
* @return Returns true if action was successfully performed; otherwise returns false.
* @param pmp Some commands need additional information. This information should be supplied in the mifare_param union.
*
* The specified MIFARE command will be executed on the tag. There are different commands possible, they all require the destination block number.
* @note There are three different types of information (Authenticate, Data and Value).
*
* First an authentication must take place using Key A or B. It requires a 48 bit Key (6 bytes) and the UID.
* They are both used to initialize the internal cipher-state of the PN53X chip (http://libnfc.org/hardware/pn53x-chip).
* After a successful authentication it will be possible to execute other commands (e.g. Read/Write).
* The MIFARE Classic Specification (http://www.nxp.com/acrobat/other/identification/M001053_MF1ICS50_rev5_3.pdf) explains more about this process.
*/
bool
nfc_initiator_mifare_cmd (nfc_device_t * pnd, const mifare_cmd mc, const uint8_t ui8Block, mifare_param * pmp)
{
byte_t abtRx[265];
size_t szRx = sizeof(abtRx);
size_t szParamLen;
byte_t abtCmd[265];
bool bEasyFraming;
abtCmd[0] = mc; // The MIFARE Classic command
abtCmd[1] = ui8Block; // The block address (1K=0x00..0x39, 4K=0x00..0xff)
switch (mc) {
// Read and store command have no parameter
case MC_READ:
case MC_STORE:
szParamLen = 0;
break;
// Authenticate command
case MC_AUTH_A:
case MC_AUTH_B:
szParamLen = sizeof (mifare_param_auth);
break;
// Data command
case MC_WRITE:
szParamLen = sizeof (mifare_param_data);
break;
// Value command
case MC_DECREMENT:
case MC_INCREMENT:
case MC_TRANSFER:
szParamLen = sizeof (mifare_param_value);
break;
// Please fix your code, you never should reach this statement
default:
return false;
break;
}
// When available, copy the parameter bytes
if (szParamLen)
memcpy (abtCmd + 2, (byte_t *) pmp, szParamLen);
bEasyFraming = pnd->bEasyFraming;
if (!nfc_configure (pnd, NDO_EASY_FRAMING, true)) {
nfc_perror (pnd, "nfc_configure");
return false;
}
// Fire the mifare command
if (!nfc_initiator_transceive_bytes (pnd, abtCmd, 2 + szParamLen, abtRx, &szRx, NULL)) {
if (pnd->iLastError == EINVRXFRAM) {
// "Invalid received frame" AKA EINVRXFRAM, usual means we are
// authenticated on a sector but the requested MIFARE cmd (read, write)
// is not permitted by current acces bytes;
// So there is nothing to do here.
} else {
nfc_perror (pnd, "nfc_initiator_transceive_bytes");
}
nfc_configure (pnd, NDO_EASY_FRAMING, bEasyFraming);
return false;
}
if (!nfc_configure (pnd, NDO_EASY_FRAMING, bEasyFraming)) {
nfc_perror (pnd, "nfc_configure");
return false;
}
// When we have executed a read command, copy the received bytes into the param
if (mc == MC_READ) {
if (szRx == 16) {
memcpy (pmp->mpd.abtData, abtRx, 16);
} else {
return false;
}
}
// Command succesfully executed
return true;
}

View File

@ -1,139 +0,0 @@
/*-
* Public platform independent Near Field Communication (NFC) library examples
*
* Copyright (C) 2009, Roel Verdult
* Copyright (C) 2010, Romuald Conty, Romain Tartière
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1) Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2 )Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Note that this license only applies on the examples, NFC library itself is under LGPL
*
*/
/**
* @file mifaretag.h
* @brief provide samples structs and functions to manipulate MIFARE Classic and Ultralight tags using libnfc
*/
#ifndef _LIBNFC_MIFARE_H_
# define _LIBNFC_MIFARE_H_
# include <nfc/nfc-types.h>
// Compiler directive, set struct alignment to 1 byte_t for compatibility
# pragma pack(1)
typedef enum {
MC_AUTH_A = 0x60,
MC_AUTH_B = 0x61,
MC_READ = 0x30,
MC_WRITE = 0xA0,
MC_TRANSFER = 0xB0,
MC_DECREMENT = 0xC0,
MC_INCREMENT = 0xC1,
MC_STORE = 0xC2
} mifare_cmd;
// MIFARE command params
typedef struct {
byte_t abtKey[6];
byte_t abtUid[4];
} mifare_param_auth;
typedef struct {
byte_t abtData[16];
} mifare_param_data;
typedef struct {
byte_t abtValue[4];
} mifare_param_value;
typedef union {
mifare_param_auth mpa;
mifare_param_data mpd;
mifare_param_value mpv;
} mifare_param;
// Reset struct alignment to default
# pragma pack()
bool nfc_initiator_mifare_cmd (nfc_device_t * pnd, const mifare_cmd mc, const uint8_t ui8Block, mifare_param * pmp);
// Compiler directive, set struct alignment to 1 byte_t for compatibility
# pragma pack(1)
// MIFARE Classic
typedef struct {
byte_t abtUID[4];
byte_t btBCC;
byte_t btUnknown;
byte_t abtATQA[2];
byte_t abtUnknown[8];
} mifare_classic_block_manufacturer;
typedef struct {
byte_t abtData[16];
} mifare_classic_block_data;
typedef struct {
byte_t abtKeyA[6];
byte_t abtAccessBits[4];
byte_t abtKeyB[6];
} mifare_classic_block_trailer;
typedef union {
mifare_classic_block_manufacturer mbm;
mifare_classic_block_data mbd;
mifare_classic_block_trailer mbt;
} mifare_classic_block;
typedef struct {
mifare_classic_block amb[256];
} mifare_classic_tag;
// MIFARE Ultralight
typedef struct {
byte_t sn0[3];
byte_t btBCC0;
byte_t sn1[4];
byte_t btBCC1;
byte_t internal;
byte_t lock[2];
byte_t otp[4];
} mifareul_block_manufacturer;
typedef struct {
byte_t abtData[16];
} mifareul_block_data;
typedef union {
mifareul_block_manufacturer mbm;
mifareul_block_data mbd;
} mifareul_block;
typedef struct {
mifareul_block amb[4];
} mifareul_tag;
// Reset struct alignment to default
# pragma pack()
#endif // _LIBNFC_MIFARE_H_

View File

@ -1,734 +0,0 @@
/*-
* Public platform independent Near Field Communication (NFC) library examples
*
* Copyright (C) 2009, Roel Verdult
* Copyright (C) 2010, Romuald Conty, Romain Tartière
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1) Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2 )Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Note that this license only applies on the examples, NFC library itself is under LGPL
*
*/
#include <nfc/nfc.h>
#include <err.h>
#include "nfc-utils.h"
static const byte_t OddParity[256] = {
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1
};
byte_t
oddparity (const byte_t bt)
{
return OddParity[bt];
}
void
oddparity_bytes_ts (const byte_t * pbtData, const size_t szLen, byte_t * pbtPar)
{
size_t szByteNr;
// Calculate the parity bits for the command
for (szByteNr = 0; szByteNr < szLen; szByteNr++) {
pbtPar[szByteNr] = OddParity[pbtData[szByteNr]];
}
}
void
print_hex (const byte_t * pbtData, const size_t szBytes)
{
size_t szPos;
for (szPos = 0; szPos < szBytes; szPos++) {
printf ("%02x ", pbtData[szPos]);
}
printf ("\n");
}
void
print_hex_bits (const byte_t * pbtData, const size_t szBits)
{
uint8_t uRemainder;
size_t szPos;
size_t szBytes = szBits / 8;
for (szPos = 0; szPos < szBytes; szPos++) {
printf ("%02x ", pbtData[szPos]);
}
uRemainder = szBits % 8;
// Print the rest bits
if (uRemainder != 0) {
if (uRemainder < 5)
printf ("%01x (%d bits)", pbtData[szBytes], uRemainder);
else
printf ("%02x (%d bits)", pbtData[szBytes], uRemainder);
}
printf ("\n");
}
void
print_hex_par (const byte_t * pbtData, const size_t szBits, const byte_t * pbtDataPar)
{
uint8_t uRemainder;
size_t szPos;
size_t szBytes = szBits / 8;
for (szPos = 0; szPos < szBytes; szPos++) {
printf ("%02x", pbtData[szPos]);
if (OddParity[pbtData[szPos]] != pbtDataPar[szPos]) {
printf ("! ");
} else {
printf (" ");
}
}
uRemainder = szBits % 8;
// Print the rest bits, these cannot have parity bit
if (uRemainder != 0) {
if (uRemainder < 5)
printf ("%01x (%d bits)", pbtData[szBytes], uRemainder);
else
printf ("%02x (%d bits)", pbtData[szBytes], uRemainder);
}
printf ("\n");
}
#define SAK_UID_NOT_COMPLETE 0x04
#define SAK_ISO14443_4_COMPLIANT 0x20
#define SAK_ISO18092_COMPLIANT 0x40
void
print_nfc_iso14443a_info (const nfc_iso14443a_info_t nai, bool verbose)
{
printf (" ATQA (SENS_RES): ");
print_hex (nai.abtAtqa, 2);
if (verbose) {
printf("* UID size: ");
switch ((nai.abtAtqa[1] & 0xc0)>>6) {
case 0:
printf("single\n");
break;
case 1:
printf("double\n");
break;
case 2:
printf("triple\n");
break;
case 3:
printf("RFU\n");
break;
}
printf("* bit frame anticollision ");
switch (nai.abtAtqa[1] & 0x1f) {
case 0x01:
case 0x02:
case 0x04:
case 0x08:
case 0x10:
printf("supported\n");
break;
default:
printf("not supported\n");
break;
}
}
printf (" UID (NFCID%c): ", (nai.abtUid[0] == 0x08 ? '3' : '1'));
print_hex (nai.abtUid, nai.szUidLen);
if (verbose) {
if (nai.abtUid[0] == 0x08) {
printf ("* Random UID\n");
}
}
printf (" SAK (SEL_RES): ");
print_hex (&nai.btSak, 1);
if (verbose) {
if (nai.btSak & SAK_UID_NOT_COMPLETE) {
printf ("* Warning! Cascade bit set: UID not complete\n");
}
if (nai.btSak & SAK_ISO14443_4_COMPLIANT) {
printf ("* Compliant with ISO/IEC 14443-4\n");
} else {
printf ("* Not compliant with ISO/IEC 14443-4\n");
}
if (nai.btSak & SAK_ISO18092_COMPLIANT) {
printf ("* Compliant with ISO/IEC 18092\n");
} else {
printf ("* Not compliant with ISO/IEC 18092\n");
}
}
if (nai.szAtsLen) {
printf (" ATS: ");
print_hex (nai.abtAts, nai.szAtsLen);
}
if (nai.szAtsLen && verbose) {
// Decode ATS according to ISO/IEC 14443-4 (5.2 Answer to select)
const int iMaxFrameSizes[] = { 16, 24, 32, 40, 48, 64, 96, 128, 256 };
printf ("* Max Frame Size accepted by PICC: %d bytes\n", iMaxFrameSizes[nai.abtAts[0] & 0x0F]);
size_t offset = 1;
if (nai.abtAts[0] & 0x10) { // TA(1) present
byte_t TA = nai.abtAts[offset];
offset++;
printf ("* Bit Rate Capability:\n");
if (TA == 0) {
printf (" * PICC supports only 106 kbits/s in both directions\n");
}
if (TA & 1<<7) {
printf (" * Same bitrate in both directions mandatory\n");
}
if (TA & 1<<4) {
printf (" * PICC to PCD, DS=2, bitrate 212 kbits/s supported\n");
}
if (TA & 1<<5) {
printf (" * PICC to PCD, DS=4, bitrate 424 kbits/s supported\n");
}
if (TA & 1<<6) {
printf (" * PICC to PCD, DS=8, bitrate 847 kbits/s supported\n");
}
if (TA & 1<<0) {
printf (" * PCD to PICC, DR=2, bitrate 212 kbits/s supported\n");
}
if (TA & 1<<1) {
printf (" * PCD to PICC, DR=4, bitrate 424 kbits/s supported\n");
}
if (TA & 1<<2) {
printf (" * PCD to PICC, DR=8, bitrate 847 kbits/s supported\n");
}
if (TA & 1<<3) {
printf (" * ERROR unknown value\n");
}
}
if (nai.abtAts[0] & 0x20) { // TB(1) present
byte_t TB= nai.abtAts[offset];
offset++;
printf ("* Frame Waiting Time: %.4g ms\n",256.0*16.0*(1<<((TB & 0xf0) >> 4))/13560.0);
if ((TB & 0x0f) == 0) {
printf ("* No Start-up Frame Guard Time required\n");
} else {
printf ("* Start-up Frame Guard Time: %.4g ms\n",256.0*16.0*(1<<(TB & 0x0f))/13560.0);
}
}
if (nai.abtAts[0] & 0x40) { // TC(1) present
byte_t TC = nai.abtAts[offset];
offset++;
if (TC & 0x1) {
printf("* Node ADdress supported\n");
} else {
printf("* Node ADdress not supported\n");
}
if (TC & 0x2) {
printf("* Card IDentifier supported\n");
} else {
printf("* Card IDentifier not supported\n");
}
}
if (nai.szAtsLen > offset) {
printf ("* Historical bytes Tk: " );
print_hex (nai.abtAts + offset, (nai.szAtsLen - offset));
byte_t CIB = nai.abtAts[offset];
offset++;
if (CIB != 0x00 && CIB != 0x10 && (CIB & 0xf0) != 0x80) {
printf(" * Proprietary format\n");
if (CIB == 0xc1) {
printf(" * Tag byte: Mifare or virtual cards of various types\n");
byte_t L = nai.abtAts[offset];
offset++;
if (L != (nai.szAtsLen - offset)) {
printf(" * Warning: Type Identification Coding length (%i)", L);
printf(" not matching Tk length (%zi)\n", (nai.szAtsLen - offset));
}
if ((nai.szAtsLen - offset - 2) > 0) { // Omit 2 CRC bytes
byte_t CTC = nai.abtAts[offset];
offset++;
printf(" * Chip Type: ");
switch (CTC & 0xf0) {
case 0x00:
printf("(Multiple) Virtual Cards\n");
break;
case 0x10:
printf("Mifare DESFire\n");
break;
case 0x20:
printf("Mifare Plus\n");
break;
default:
printf("RFU\n");
break;
}
printf(" * Memory size: ");
switch (CTC & 0x0f) {
case 0x00:
printf("<1 kbyte\n");
break;
case 0x01:
printf("1 kbyte\n");
break;
case 0x02:
printf("2 kbyte\n");
break;
case 0x03:
printf("4 kbyte\n");
break;
case 0x04:
printf("8 kbyte\n");
break;
case 0x0f:
printf("Unspecified\n");
break;
default:
printf("RFU\n");
break;
}
}
if ((nai.szAtsLen - offset) > 0) { // Omit 2 CRC bytes
byte_t CVC = nai.abtAts[offset];
offset++;
printf(" * Chip Status: ");
switch (CVC & 0xf0) {
case 0x00:
printf("Engineering sample\n");
break;
case 0x20:
printf("Released\n");
break;
default:
printf("RFU\n");
break;
}
printf(" * Chip Generation: ");
switch (CVC & 0x0f) {
case 0x00:
printf("Generation 1\n");
break;
case 0x01:
printf("Generation 2\n");
break;
case 0x02:
printf("Generation 3\n");
break;
case 0x0f:
printf("Unspecified\n");
break;
default:
printf("RFU\n");
break;
}
}
if ((nai.szAtsLen - offset) > 0) { // Omit 2 CRC bytes
byte_t VCS = nai.abtAts[offset];
offset++;
printf(" * Specifics (Virtual Card Selection):\n");
if ((VCS & 0x09) == 0x00) {
printf(" * Only VCSL supported\n");
} else if ((VCS & 0x09) == 0x01) {
printf(" * VCS, VCSL and SVC supported\n");
}
if ((VCS & 0x0e) == 0x00) {
printf(" * SL1, SL2(?), SL3 supported\n");
} else if ((VCS & 0x0e) == 0x02) {
printf(" * SL3 only card\n");
} else if ((VCS & 0x0f) == 0x0e) {
printf(" * No VCS command supported\n");
} else if ((VCS & 0x0f) == 0x0f) {
printf(" * Unspecified\n");
} else {
printf(" * RFU\n");
}
}
}
} else {
if (CIB == 0x00) {
printf(" * Tk after 0x00 consist of optional consecutive COMPACT-TLV data objects\n");
printf(" followed by a mandatory status indicator (the last three bytes, not in TLV)\n");
printf(" See ISO/IEC 7816-4 8.1.1.3 for more info\n");
}
if (CIB == 0x10) {
printf(" * DIR data reference: %02x\n", nai.abtAts[offset]);
}
if (CIB == 0x80) {
if (nai.szAtsLen == offset) {
printf(" * No COMPACT-TLV objects found, no status found\n");
} else {
printf(" * Tk after 0x80 consist of optional consecutive COMPACT-TLV data objects;\n");
printf(" the last data object may carry a status indicator of one, two or three bytes.\n");
printf(" See ISO/IEC 7816-4 8.1.1.3 for more info\n");
}
}
}
}
}
if (verbose) {
printf("Fingerprinting based on ATQA & SAK values:\n");
uint32_t atqasak = 0;
atqasak += (((uint32_t)nai.abtAtqa[0] & 0xff)<<16);
atqasak += (((uint32_t)nai.abtAtqa[1] & 0xff)<<8);
atqasak += ((uint32_t)nai.btSak & 0xff);
bool found_possible_match = false;
switch (atqasak) {
case 0x000218:
printf("* Mifare Classic 4K\n");
found_possible_match = true;
break;
case 0x000408:
printf("* Mifare Classic 1K\n");
printf("* Mifare Plus (4-byte UID) 2K SL1\n");
found_possible_match = true;
break;
case 0x000409:
printf("* Mifare MINI\n");
found_possible_match = true;
break;
case 0x000410:
printf("* Mifare Plus (4-byte UID) 2K SL2\n");
found_possible_match = true;
break;
case 0x000411:
printf("* Mifare Plus (4-byte UID) 4K SL2\n");
found_possible_match = true;
break;
case 0x000418:
printf("* Mifare Plus (4-byte UID) 4K SL1\n");
found_possible_match = true;
break;
case 0x000420:
printf("* Mifare Plus (4-byte UID) 2K/4K SL3\n");
found_possible_match = true;
break;
case 0x004400:
printf("* Mifare Ultralight\n");
printf("* Mifare UltralightC\n");
found_possible_match = true;
break;
case 0x004208:
case 0x004408:
printf("* Mifare Plus (7-byte UID) 2K SL1\n");
found_possible_match = true;
break;
case 0x004218:
case 0x004418:
printf("* Mifare Plus (7-byte UID) 4K SL1\n");
found_possible_match = true;
break;
case 0x004210:
case 0x004410:
printf("* Mifare Plus (7-byte UID) 2K SL2\n");
found_possible_match = true;
break;
case 0x004211:
case 0x004411:
printf("* Mifare Plus (7-byte UID) 4K SL2\n");
found_possible_match = true;
break;
case 0x004220:
case 0x004420:
printf("* Mifare Plus (7-byte UID) 2K/4K SL3\n");
found_possible_match = true;
break;
case 0x034420:
printf("* Mifare DESFire / Desfire EV1\n");
found_possible_match = true;
break;
}
// Other matches not described in
// AN MIFARE Type Identification Procedure
// but seen in the field:
switch (atqasak) {
case 0x000488:
printf("* Mifare Classic 1K Infineon\n");
found_possible_match = true;
break;
case 0x000298:
printf("* Gemplus MPCOS\n");
found_possible_match = true;
break;
case 0x030428:
printf("* JCOP31\n");
found_possible_match = true;
break;
case 0x004820:
printf("* JCOP31 v2.4.1\n");
printf("* JCOP31 v2.2\n");
found_possible_match = true;
break;
case 0x000428:
printf("* JCOP31 v2.3.1\n");
found_possible_match = true;
break;
case 0x000453:
printf("* Fudan FM1208SH01\n");
found_possible_match = true;
break;
case 0x000820:
printf("* Fudan FM1208\n");
found_possible_match = true;
break;
case 0x000238:
printf("* MFC 4K emulated by Nokia 6212 Classic\n");
found_possible_match = true;
break;
case 0x000838:
printf("* MFC 4K emulated by Nokia 6131 NFC\n");
found_possible_match = true;
break;
}
if ((nai.abtAtqa[0] & 0xf0) == 0) {
switch (nai.abtAtqa[1]) {
case 0x02:
printf("* SmartMX with Mifare 4K emulation\n");
found_possible_match = true;
break;
case 0x04:
printf("* SmartMX with Mifare 1K emulation\n");
found_possible_match = true;
break;
case 0x48:
printf("* SmartMX with 7-byte UID\n");
found_possible_match = true;
break;
}
}
if (! found_possible_match) {
printf("* Unknown card, sorry\n");
}
}
}
void
print_nfc_felica_info (const nfc_felica_info_t nfi, bool verbose)
{
(void) verbose;
printf (" ID (NFCID2): ");
print_hex (nfi.abtId, 8);
printf (" Parameter (PAD): ");
print_hex (nfi.abtPad, 8);
printf (" System Code (SC): ");
print_hex (nfi.abtSysCode, 2);
}
void
print_nfc_jewel_info (const nfc_jewel_info_t nji, bool verbose)
{
(void) verbose;
printf (" ATQA (SENS_RES): ");
print_hex (nji.btSensRes, 2);
printf (" 4-LSB JEWELID: ");
print_hex (nji.btId, 4);
}
#define PI_ISO14443_4_SUPPORTED 0x01
#define PI_NAD_SUPPORTED 0x01
#define PI_CID_SUPPORTED 0x02
void
print_nfc_iso14443b_info (const nfc_iso14443b_info_t nbi, bool verbose)
{
const int iMaxFrameSizes[] = { 16, 24, 32, 40, 48, 64, 96, 128, 256 };
printf (" PUPI: ");
print_hex (nbi.abtPupi, 4);
printf (" Application Data: ");
print_hex (nbi.abtApplicationData, 4);
printf (" Protocol Info: ");
print_hex (nbi.abtProtocolInfo, 3);
if (verbose) {
printf ("* Bit Rate Capability:\n");
if (nbi.abtProtocolInfo[0] == 0) {
printf (" * PICC supports only 106 kbits/s in both directions\n");
}
if (nbi.abtProtocolInfo[0] & 1<<7) {
printf (" * Same bitrate in both directions mandatory\n");
}
if (nbi.abtProtocolInfo[0] & 1<<4) {
printf (" * PICC to PCD, 1etu=64/fc, bitrate 212 kbits/s supported\n");
}
if (nbi.abtProtocolInfo[0] & 1<<5) {
printf (" * PICC to PCD, 1etu=32/fc, bitrate 424 kbits/s supported\n");
}
if (nbi.abtProtocolInfo[0] & 1<<6) {
printf (" * PICC to PCD, 1etu=16/fc, bitrate 847 kbits/s supported\n");
}
if (nbi.abtProtocolInfo[0] & 1<<0) {
printf (" * PCD to PICC, 1etu=64/fc, bitrate 212 kbits/s supported\n");
}
if (nbi.abtProtocolInfo[0] & 1<<1) {
printf (" * PCD to PICC, 1etu=32/fc, bitrate 424 kbits/s supported\n");
}
if (nbi.abtProtocolInfo[0] & 1<<2) {
printf (" * PCD to PICC, 1etu=16/fc, bitrate 847 kbits/s supported\n");
}
if (nbi.abtProtocolInfo[0] & 1<<3) {
printf (" * ERROR unknown value\n");
}
if( (nbi.abtProtocolInfo[1] & 0xf0) <= 0x80 ) {
printf ("* Maximum frame sizes: %d bytes\n", iMaxFrameSizes[((nbi.abtProtocolInfo[1] & 0xf0) >> 4)]);
}
if((nbi.abtProtocolInfo[1] & 0x0f) == PI_ISO14443_4_SUPPORTED) {
printf ("* Protocol types supported: ISO/IEC 14443-4\n");
}
printf ("* Frame Waiting Time: %.4g ms\n",256.0*16.0*(1<<((nbi.abtProtocolInfo[2] & 0xf0) >> 4))/13560.0);
if((nbi.abtProtocolInfo[2] & (PI_NAD_SUPPORTED|PI_CID_SUPPORTED)) != 0) {
printf ("* Frame options supported: ");
if ((nbi.abtProtocolInfo[2] & PI_NAD_SUPPORTED) != 0) printf ("NAD ");
if ((nbi.abtProtocolInfo[2] & PI_CID_SUPPORTED) != 0) printf ("CID ");
printf("\n");
}
}
}
void
print_nfc_iso14443bi_info (const nfc_iso14443bi_info_t nii, bool verbose)
{
printf (" DIV: ");
print_hex (nii.abtDIV, 4);
if (verbose) {
int version = (nii.btVerLog & 0x1e)>>1;
printf (" Software Version: ");
if (version == 15) {
printf ("Undefined\n");
} else {
printf ("%i\n", version);
}
if ((nii.btVerLog & 0x80) && (nii.btConfig & 0x80)){
printf (" Wait Enable: yes");
}
}
if ((nii.btVerLog & 0x80) && (nii.btConfig & 0x40)) {
printf (" ATS: ");
print_hex (nii.abtAtr, nii.szAtrLen);
}
}
void
print_nfc_iso14443b2sr_info (const nfc_iso14443b2sr_info_t nsi, bool verbose)
{
(void) verbose;
printf (" UID: ");
print_hex (nsi.abtUID, 8);
}
void
print_nfc_iso14443b2ct_info (const nfc_iso14443b2ct_info_t nci, bool verbose)
{
(void) verbose;
uint32_t uid;
uid = (nci.abtUID[3] << 24) + (nci.abtUID[2] << 16) + (nci.abtUID[1] << 8) + nci.abtUID[0];
printf (" UID: ");
print_hex (nci.abtUID, sizeof(nci.abtUID));
printf (" UID (decimal): %010u\n", uid);
printf (" Product Code: %02X\n", nci.btProdCode);
printf (" Fab Code: %02X\n", nci.btFabCode);
}
void
print_nfc_dep_info (const nfc_dep_info_t ndi, bool verbose)
{
(void) verbose;
printf (" NFCID3: ");
print_hex (ndi.abtNFCID3, 10);
printf (" BS: %02x\n", ndi.btBS);
printf (" BR: %02x\n", ndi.btBR);
printf (" TO: %02x\n", ndi.btTO);
printf (" PP: %02x\n", ndi.btPP);
if (ndi.szGB) {
printf ("General Bytes: ");
print_hex (ndi.abtGB, ndi.szGB);
}
}
const char *
str_nfc_baud_rate (const nfc_baud_rate_t nbr)
{
switch(nbr) {
case NBR_UNDEFINED:
return "undefined baud rate";
break;
case NBR_106:
return "106 kbps";
break;
case NBR_212:
return "212 kbps";
break;
case NBR_424:
return "424 kbps";
break;
case NBR_847:
return "847 kbps";
break;
}
return "";
}
void
print_nfc_target (const nfc_target_t nt, bool verbose)
{
switch(nt.nm.nmt) {
case NMT_ISO14443A:
printf ("ISO/IEC 14443A (%s) target:\n", str_nfc_baud_rate(nt.nm.nbr));
print_nfc_iso14443a_info (nt.nti.nai, verbose);
break;
case NMT_JEWEL:
printf ("Innovision Jewel (%s) target:\n", str_nfc_baud_rate(nt.nm.nbr));
print_nfc_jewel_info (nt.nti.nji, verbose);
break;
case NMT_FELICA:
printf ("FeliCa (%s) target:\n", str_nfc_baud_rate(nt.nm.nbr));
print_nfc_felica_info (nt.nti.nfi, verbose);
break;
case NMT_ISO14443B:
printf ("ISO/IEC 14443-4B (%s) target:\n", str_nfc_baud_rate(nt.nm.nbr));
print_nfc_iso14443b_info (nt.nti.nbi, verbose);
break;
case NMT_ISO14443BI:
printf ("ISO/IEC 14443-4B' (%s) target:\n", str_nfc_baud_rate(nt.nm.nbr));
print_nfc_iso14443bi_info (nt.nti.nii, verbose);
break;
case NMT_ISO14443B2SR:
printf ("ISO/IEC 14443-2B ST SRx (%s) target:\n", str_nfc_baud_rate(nt.nm.nbr));
print_nfc_iso14443b2sr_info (nt.nti.nsi, verbose);
break;
case NMT_ISO14443B2CT:
printf ("ISO/IEC 14443-2B ASK CTx (%s) target:\n", str_nfc_baud_rate(nt.nm.nbr));
print_nfc_iso14443b2ct_info (nt.nti.nci, verbose);
break;
case NMT_DEP:
printf ("D.E.P. (%s) target:\n", str_nfc_baud_rate(nt.nm.nbr));
print_nfc_dep_info (nt.nti.ndi, verbose);
break;
}
}

View File

@ -1,100 +0,0 @@
/*-
* Public platform independent Near Field Communication (NFC) library examples
*
* Copyright (C) 2009, Roel Verdult
* Copyright (C) 2010, Romuald Conty, Romain Tartière
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1) Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2 )Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Note that this license only applies on the examples, NFC library itself is under LGPL
*
*/
/**
* @file nfc-utils.h
* @brief Provide some examples shared functions like print, parity calculation, options parsing.
*/
#ifndef _EXAMPLES_NFC_UTILS_H_
# define _EXAMPLES_NFC_UTILS_H_
# include <stdlib.h>
# include <string.h>
# include <err.h>
/**
* @macro DBG
* @brief Print a message of standard output only in DEBUG mode
*/
#ifdef DEBUG
# define DBG(...) do { \
warnx ("DBG %s:%d", __FILE__, __LINE__); \
warnx (" " __VA_ARGS__ ); \
} while (0)
#else
# define DBG(...) {}
#endif
/**
* @macro WARN
* @brief Print a warn message
*/
#ifdef DEBUG
# define WARN(...) do { \
warnx ("WARNING %s:%d", __FILE__, __LINE__); \
warnx (" " __VA_ARGS__ ); \
} while (0)
#else
# define WARN(...) warnx ("WARNING: " __VA_ARGS__ )
#endif
/**
* @macro ERR
* @brief Print a error message
*/
#ifdef DEBUG
# define ERR(...) do { \
warnx ("ERROR %s:%d", __FILE__, __LINE__); \
warnx (" " __VA_ARGS__ ); \
} while (0)
#else
# define ERR(...) warnx ("ERROR: " __VA_ARGS__ )
#endif
byte_t oddparity (const byte_t bt);
void oddparity_byte_ts (const byte_t * pbtData, const size_t szLen, byte_t * pbtPar);
void print_hex (const byte_t * pbtData, const size_t szLen);
void print_hex_bits (const byte_t * pbtData, const size_t szBits);
void print_hex_par (const byte_t * pbtData, const size_t szBits, const byte_t * pbtDataPar);
void print_nfc_iso14443a_info (const nfc_iso14443a_info_t nai, bool verbose);
void print_nfc_iso14443b_info (const nfc_iso14443b_info_t nbi, bool verbose);
void print_nfc_iso14443bi_info (const nfc_iso14443bi_info_t nii, bool verbose);
void print_nfc_iso14443b2sr_info (const nfc_iso14443b2sr_info_t nsi, bool verbose);
void print_nfc_iso14443b2ct_info (const nfc_iso14443b2ct_info_t nci, bool verbose);
void print_nfc_felica_info (const nfc_felica_info_t nfi, bool verbose);
void print_nfc_jewel_info (const nfc_jewel_info_t nji, bool verbose);
void print_nfc_dep_info (const nfc_dep_info_t ndi, bool verbose);
void print_nfc_target (const nfc_target_t nt, bool verbose);
#endif

View File

@ -1,84 +0,0 @@
#!/usr/bin/python
# Original source: proxmark3.org community forum
import sys
import os
import string
import commands
def line_tag(line):
if string.find(line, 'TAG') > 0:
return True
return False
def line_rdr(line):
if string.find(line, 'TAG') < 1:
return True
return False
def line_bytes(line):
bytes = line[20:len(line)-1]
bytes = bytes.replace('crc', '')
bytes = bytes.replace('!', '')
bytes = bytes.replace(' ', '')
return len(bytes)/2
try:
file= open(sys.argv[1])
except:
print
print '\tusage:', sys.argv[0], '<proxmark3_snoop.log>'
print
sys.exit(True)
lines = file.readlines()
uid = ''
find_multi_sector = False
for i in range(len(lines)):
if string.find(lines[i],': 93 20') > 0 and line_tag(lines[i + 1]) and line_bytes(lines[i + 1]) == 5:
find_multi_sector = False
key = ''
uid = lines[i + 1][20:34]
uid = uid.replace(' ', '')
print 'Found TAG UID:', uid
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:
tag_challenge = lines[i+1][20:34]
tag_challenge = tag_challenge.replace(' ', '')
tag_challenge = tag_challenge.replace('!', '')
print 'Nt:', tag_challenge
reader_challenge_response = lines[i+2][20:50]
reader_challenge_response = reader_challenge_response.replace(' ', '')
reader_challenge_response = reader_challenge_response.replace('!', '')
print 'Nt\':', reader_challenge_response
tag_response = lines[i+3][20:34]
tag_response = tag_response.replace(' ', '')
tag_response = tag_response.replace('!', '')
print 'Nr:', tag_response
find_multi_sector = True
# 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
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:
encr_multi_sect_auth = lines[i][20:34]
encr_multi_sect_auth = encr_multi_sect_auth.replace(' ', '')
encr_multi_sect_auth = encr_multi_sect_auth.replace('!', '')
#print 'Multi-sector AUTH (candidates):', encr_multi_sect_auth
encr_multi_sect_Nt = lines[i + 1][20:34]
encr_multi_sect_Nt = encr_multi_sect_Nt.replace(' ', '')
encr_multi_sect_Nt = encr_multi_sect_Nt.replace('!', '')
#print 'Multi-sector encrypted Nt (candidates):', encr_multi_sect_Nt
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
print 'Executing ', mfcuk_P_params
#os.execv('./mfcuk',string.split(mfcuk_P_params))

View File

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

View File

@ -1,223 +0,0 @@
// XGetopt.cpp Version 1.2
//
// Author: Hans Dietrich
// hdietrich2@hotmail.com
//
// Description:
// XGetopt.cpp implements getopt(), a function to parse command lines.
//
// History
// Version 1.2 - 2003 May 17
// - Added Unicode support
//
// Version 1.1 - 2002 March 10
// - Added example to XGetopt.cpp module header
//
// This software is released into the public domain.
// You are free to use it in any way you like.
//
// This software is provided "as is" with no expressed
// or implied warranty. I accept no liability for any
// damage or loss of business that this software may cause.
//
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// if you are using precompiled headers then include this line:
//#include "stdafx.h"
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// if you are not using precompiled headers then include these lines:
//#include
//#include
//#include
///////////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <string.h>
#include "xgetopt.h"
///////////////////////////////////////////////////////////////////////////////
//
// X G e t o p t . c p p
//
//
// NAME
// getopt -- parse command line options
//
// SYNOPSIS
// int getopt(int argc, char *argv[], char *optstring)
//
// extern char *optarg;
// extern int optind;
//
// DESCRIPTION
// The getopt() function parses the command line arguments. Its
// arguments argc and argv are the argument count and array as
// passed into the application on program invocation. In the case
// of Visual C++ programs, argc and argv are available via the
// variables __argc and __argv (double underscores), respectively.
// getopt returns the next option letter in argv that matches a
// letter in optstring. (Note: Unicode programs should use
// __targv instead of __argv. Also, all character and string
// literals should be enclosed in _T( ) ).
//
// optstring is a string of recognized option letters; if a letter
// is followed by a colon, the option is expected to have an argument
// that may or may not be separated from it by white space. optarg
// is set to point to the start of the option argument on return from
// getopt.
//
// Option letters may be combined, e.g., "-ab" is equivalent to
// "-a -b". Option letters are case sensitive.
//
// getopt places in the external variable optind the argv index
// of the next argument to be processed. optind is initialized
// to 0 before the first call to getopt.
//
// When all options have been processed (i.e., up to the first
// non-option argument), getopt returns EOF, optarg will point
// to the argument, and optind will be set to the argv index of
// the argument. If there are no non-option arguments, optarg
// will be set to NULL.
//
// The special option "--" may be used to delimit the end of the
// options; EOF will be returned, and "--" (and everything after it)
// will be skipped.
//
// RETURN VALUE
// For option letters contained in the string optstring, getopt
// will return the option letter. getopt returns a question mark (?)
// when it encounters an option letter not included in optstring.
// EOF is returned when processing is finished.
//
// BUGS
// 1) Long options are not supported.
// 2) The GNU double-colon extension is not supported.
// 3) The environment variable POSIXLY_CORRECT is not supported.
// 4) The + syntax is not supported.
// 5) The automatic permutation of arguments is not supported.
// 6) This implementation of getopt() returns EOF if an error is
// encountered, instead of -1 as the latest standard requires.
//
// EXAMPLE
// BOOL CMyApp::ProcessCommandLine(int argc, char *argv[])
// {
// int c;
//
// while ((c = getopt(argc, argv, _T("aBn:"))) != EOF)
// {
// switch (c)
// {
// case _T('a'):
// TRACE(_T("option a\n"));
// //
// // set some flag here
// //
// break;
//
// case _T('B'):
// TRACE( _T("option B\n"));
// //
// // set some other flag here
// //
// break;
//
// case _T('n'):
// TRACE(_T("option n: value=%d\n"), atoi(optarg));
// //
// // do something with value here
// //
// break;
//
// case _T('?'):
// TRACE(_T("ERROR: illegal option %s\n"), argv[optind-1]);
// return FALSE;
// break;
//
// default:
// TRACE(_T("WARNING: no handler for option %c\n"), c);
// return FALSE;
// break;
// }
// }
// //
// // check for non-option args here
// //
// return TRUE;
// }
//
///////////////////////////////////////////////////////////////////////////////
char *optarg; // global argument pointer
int optind = 0; // global argv index
int getopt(int argc, char *argv[], char *optstring)
{
char c = 0;
char *cp = NULL;
static char *next = NULL;
if (optind == 0)
next = NULL;
optarg = NULL;
if (next == NULL || *next == '\0')
{
if (optind == 0)
optind++;
if (optind >= argc || argv[optind][0] != '-' || argv[optind][1] == '\0')
{
optarg = NULL;
if (optind < argc)
optarg = argv[optind];
return EOF;
}
if (strcmp(argv[optind], "--") == 0)
{
optind++;
optarg = NULL;
if (optind < argc)
optarg = argv[optind];
return EOF;
}
next = argv[optind];
next++; // skip past -
optind++;
}
c = *next++;
cp = strchr(optstring, c);
if (cp == NULL || c == ':')
return '?';
cp++;
if (*cp == ':')
{
if (*next != '\0')
{
optarg = next;
next = NULL;
}
else if (optind < argc)
{
optarg = argv[optind];
optind++;
}
else
{
return '?';
}
}
return c;
}

View File

@ -1,23 +0,0 @@
// XGetopt.h Version 1.2
//
// Author: Hans Dietrich
// hdietrich2@hotmail.com
//
// This software is released into the public domain.
// You are free to use it in any way you like.
//
// This software is provided "as is" with no expressed
// or implied warranty. I accept no liability for any
// damage or loss of business that this software may cause.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef XGETOPT_H
#define XGETOPT_H
extern int optind, opterr;
extern char *optarg;
int getopt(int argc, char *argv[], char *optstring);
#endif //XGETOPT_H

View File

@ -1,43 +0,0 @@
#!/usr/bin/python
# Original source: proxmark3.org community forum
import sys
import os
import string
try:
file= open(sys.argv[1])
except:
print
print '\tusage: mifarecrack.py <proxmark3 logfile>'
print
sys.exit(True)
lines= file.readlines()
uid= ''
gotone= False
for i in range(len(lines)):
if not uid and string.find(lines[i],': 93 20') > 0:
uid= lines[i + 1][20:34]
print
print 'Found TAG UID:', uid
if string.find(lines[i],': 60') > 0 or string.find(lines[i],': 61') > 0:
gotone= True
tag_challenge= lines[i+1]
reader_challenge_response= lines[i+2]
tag_response= lines[i+3]
break
if not gotone:
print 'No crypto exchange found!'
sys.exit(True)
crackstring= './mifarecrack '+ uid
# now process challenge/response
crackstring += ' ' + tag_challenge[20:34]
crackstring += ' ' + reader_challenge_response[20:50]
crackstring += ' ' + tag_response[20:34]
print 'Executing ', crackstring
os.execv('./mifarecrack',string.split(crackstring))