Improve naming consistency.
Ensure all MIFARE related names and structures start with "mifare_" or "MIFARE_".
This commit is contained in:
parent
faac4ae5d8
commit
1ce3db3ca6
26 changed files with 178 additions and 174 deletions
94
HACKING
94
HACKING
|
@ -1,94 +0,0 @@
|
||||||
Hello hackers!
|
|
||||||
|
|
||||||
General remarks about contributing
|
|
||||||
----------------------------------
|
|
||||||
|
|
||||||
Contributions to the libfreefare are welcome! Here are some directions to get
|
|
||||||
you started:
|
|
||||||
|
|
||||||
1. Install Cutter
|
|
||||||
Cutter is a cool unit test framework for C code. You will need it to run
|
|
||||||
the regression tests suite (`make check') and ensure that your code does
|
|
||||||
not break other features.
|
|
||||||
http://cutter.sourceforge.net/
|
|
||||||
To cover all tests you'll need several blank cards:
|
|
||||||
* MIFARE Classic 4k with default keys (FFFFFFFFFF)
|
|
||||||
* MIFARE DESFire EV1 4k with default PICC key (0000000000000000)
|
|
||||||
* MIFARE Ultralight
|
|
||||||
* MIFARE Ultralight C with default key (BREAKMEIFYOUCAN!)
|
|
||||||
After "make check", you can run sub-sets of tests directly with cutter:
|
|
||||||
$ cutter -n /ultralight/ test
|
|
||||||
$ cutter -n /classic/ test
|
|
||||||
$ cutter -n /desfire/ test
|
|
||||||
|
|
||||||
|
|
||||||
2. Follow style conventions
|
|
||||||
The source code of the library trend to follow some conventions so that it
|
|
||||||
is consistent in style and thus easier to read. Basically, it follows
|
|
||||||
FreeBSD's style(9); adding 4-space indentation and 8-space tabs (which you
|
|
||||||
should configure in your editor, e.g. `:set sw=4 ts=8' in vim). You are
|
|
||||||
also advised to `:set cinoptions=t0(0:0` so that you don't have to care
|
|
||||||
about indentation anymore. For more details, please read the style(9) man
|
|
||||||
page from FreeBSD's website:
|
|
||||||
http://www.freebsd.org/cgi/man.cgi?query=style
|
|
||||||
|
|
||||||
3. Write tests
|
|
||||||
I told you cutter is lovely in #1 so you really should use it! If you
|
|
||||||
want to contribute code, write test: only code with appropriate tests will
|
|
||||||
be considered. And remember that TDD (Test Driven Development) is cool
|
|
||||||
and writing all tests at the end deeply depressing, so test early, test
|
|
||||||
often!
|
|
||||||
|
|
||||||
|
|
||||||
Adding support for a new type of card
|
|
||||||
-------------------------------------
|
|
||||||
|
|
||||||
Adding a new supported card to the libfreefare requires a few modification in
|
|
||||||
multiple places. Here is a list of the things to do in order to have the
|
|
||||||
infrastructure ready for hacking the new card support:
|
|
||||||
- Edit libfreefare/freefare.h:
|
|
||||||
- Add your tag to the `freefare_tag_type' enum;
|
|
||||||
- Add a <tag>_connect() and a <tag>_disconnect() function prototype;
|
|
||||||
- Edit libfreefare/freefare.3:
|
|
||||||
- Add your tag to the `freefare_tag_type' enum documentation;
|
|
||||||
- Edit libfreefare/freefare_internal.h:
|
|
||||||
- Add a new <tag>_tag struct. It's very first member SHALL be `struct
|
|
||||||
freefare_tag __tag';
|
|
||||||
- Add a <tag>_tag_new() and a <tag>_tag_free() function prototype;
|
|
||||||
- Add a ASSERT_<TAG>() macro to check the tag's type;
|
|
||||||
- Add a <TAG>() macro to cast a generic tag to your type.
|
|
||||||
- Edit libfreefare/freefare.c:
|
|
||||||
- Add your tag type to the supported_tags array;
|
|
||||||
- Edit the freefare_get_tags() function so that it calls <tag>_tag_new()
|
|
||||||
when it finds your tag;
|
|
||||||
- Edit the freefare_free_tags() function so that it calls
|
|
||||||
<tag>_tag_free() to free your tags;
|
|
||||||
- Create libfreefare/<tag>.c and implement all that's missing:
|
|
||||||
- <tag>_tag_new() MUST allocate all data-structure the tag may need to
|
|
||||||
use during it's lifetime. We do not want to have any function to fail
|
|
||||||
later because the running system is out of resources. Buffers for
|
|
||||||
cryptographic operations on random amount of data MAY however be
|
|
||||||
(re)allocated on demand, in such case refrain from shrinking
|
|
||||||
unnecessarily the buffer size.
|
|
||||||
- <tag>_connect() SHOULD initialise data allocated by <tag>_tag_new().
|
|
||||||
Keep in mind that a single tag may be disconnected from and connected
|
|
||||||
to again, without being freed in the meantime. Since all memory
|
|
||||||
allocations are done in <tag>_tag_new(), your code SHOULD only care
|
|
||||||
about initialising these data structures;
|
|
||||||
- <tag>_disconnect() MAY do more that just send a disconnect command to
|
|
||||||
the tag. At time of writing I have no idea what it could be but who
|
|
||||||
knows...
|
|
||||||
- <tag>_tag_free() SHALL free all resources allocated for the tag
|
|
||||||
(surprising, isn't it?)
|
|
||||||
|
|
||||||
|
|
||||||
Various guidelines
|
|
||||||
------------------
|
|
||||||
|
|
||||||
- If a given card has different cryptographic modes, you SHOULD use
|
|
||||||
switch/cases to handle specific branches of code, even when applicable to
|
|
||||||
only one cypher. The idea is that if you don't provide support for all
|
|
||||||
cryptographic schemes, or if an evolution of the card provides more
|
|
||||||
cryptographic possibilities, when adding support for a new cypher, the
|
|
||||||
compiler can warn the developer about unhandled values in switch
|
|
||||||
statements. Please refer to the MIFARE DESFire code for an example.
|
|
98
HACKING.md
Normal file
98
HACKING.md
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
Hello hackers!
|
||||||
|
|
||||||
|
# General remarks about contributing
|
||||||
|
|
||||||
|
Contributions to the libfreefare are welcome! Here are some directions to get
|
||||||
|
you started:
|
||||||
|
|
||||||
|
## Install Cutter
|
||||||
|
|
||||||
|
[Cutter](http://cutter.sourceforge.net/) is a cool unit test framework for C
|
||||||
|
code. You will need it to run the regression tests suite (`make check`) and
|
||||||
|
ensure that your code does not break other features.
|
||||||
|
|
||||||
|
To cover all tests you'll need several blank cards:
|
||||||
|
|
||||||
|
* MIFARE Classic 4k with default keys (`FFFFFFFFFF`)
|
||||||
|
* MIFARE DESFire EV1 4k with default PICC key (`0000000000000000`)
|
||||||
|
* MIFARE Ultralight
|
||||||
|
* MIFARE Ultralight C with default key (`BREAKMEIFYOUCAN!`)
|
||||||
|
|
||||||
|
After "make check", you can run sub-sets of tests directly with cutter:
|
||||||
|
|
||||||
|
~~~
|
||||||
|
$ cutter -n /ultralight/ test
|
||||||
|
$ cutter -n /classic/ test
|
||||||
|
$ cutter -n /desfire/ test
|
||||||
|
~~~
|
||||||
|
|
||||||
|
## Follow style conventions
|
||||||
|
|
||||||
|
The source code of the library trend to follow some conventions so that it is
|
||||||
|
consistent in style and thus easier to read. Basically, it follows [FreeBSD's
|
||||||
|
style(9)](http://www.freebsd.org/cgi/man.cgi?query=style); adding 4-space
|
||||||
|
indentation and 8-space tabs (which you should configure in your editor, e.g.
|
||||||
|
`:set sw=4 ts=8` in vim). You are also advised to `:set cinoptions=t0(0:0` so
|
||||||
|
that you don't have to care about indentation anymore. For more details, please
|
||||||
|
read the [style(9) man page from FreeBSD's
|
||||||
|
website](http://www.freebsd.org/cgi/man.cgi?query=style).
|
||||||
|
|
||||||
|
## Write tests
|
||||||
|
|
||||||
|
I already told you cutter is lovely, so you really should use it! If you want
|
||||||
|
to contribute code, write test: only code with appropriate tests will be
|
||||||
|
considered. And remember that
|
||||||
|
[TDD](http://en.wikipedia.org/wiki/Test-driven_development) (Test Driven
|
||||||
|
Development) is cool and writing all tests at the end deeply depressing, so
|
||||||
|
test early, test often!
|
||||||
|
|
||||||
|
# Adding support for a new type of card
|
||||||
|
|
||||||
|
Adding a new supported card to the libfreefare requires a few modification in
|
||||||
|
multiple places. Here is a list of the things to do in order to have the
|
||||||
|
infrastructure ready for hacking the new card support:
|
||||||
|
|
||||||
|
- Edit `libfreefare/freefare.h`:
|
||||||
|
- Add your tag to the `freefare_tag_type` enum;
|
||||||
|
- Add a `<tag>_connect()` and a `<tag>_disconnect()` function prototype;
|
||||||
|
- Edit `libfreefare/freefare.3`:
|
||||||
|
- Add your tag to the `freefare_tag_type' enum documentation;
|
||||||
|
- Edit `libfreefare/freefare_internal.h`:
|
||||||
|
- Add a new `<tag>_tag struct`. It's very first member SHALL be `struct
|
||||||
|
freefare_tag __tag`;
|
||||||
|
- Add a `<tag>_tag_new()` and a `<tag>_tag_free()` function prototype;
|
||||||
|
- Add a `ASSERT_<TAG>()` macro to check the tag's type;
|
||||||
|
- Add a `<TAG>()` macro to cast a generic tag to your type.
|
||||||
|
- Edit `libfreefare/freefare.c`:
|
||||||
|
- Add your tag type to the supported_tags array;
|
||||||
|
- Edit the `freefare_get_tags()` function so that it calls `<tag>_tag_new()`
|
||||||
|
when it finds your tag;
|
||||||
|
- Edit the `freefare_free_tags()` function so that it calls
|
||||||
|
`<tag>_tag_free()` to free your tags;
|
||||||
|
- Create `libfreefare/<tag>.c` and implement all that's missing:
|
||||||
|
- `<tag>_tag_new()` MUST allocate all data-structure the tag may need to
|
||||||
|
use during it's lifetime. We do not want to have any function to fail
|
||||||
|
later because the running system is out of resources. Buffers for
|
||||||
|
cryptographic operations on random amount of data MAY however be
|
||||||
|
(re)allocated on demand, in such case refrain from shrinking
|
||||||
|
unnecessarily the buffer size.
|
||||||
|
- `<tag>_connect()` SHOULD initialise data allocated by `<tag>_tag_new()`.
|
||||||
|
Keep in mind that a single tag may be disconnected from and connected
|
||||||
|
to again, without being freed in the meantime. Since all memory
|
||||||
|
allocations are done in `<tag>_tag_new()`, your code SHOULD only care
|
||||||
|
about initialising these data structures;
|
||||||
|
- `<tag>_disconnect()` MAY do more that just send a disconnect command to
|
||||||
|
the tag. At time of writing I have no idea what it could be but who
|
||||||
|
knows...
|
||||||
|
- `<tag>_tag_free()` SHALL free all resources allocated for the tag
|
||||||
|
(surprising, isn't it?)
|
||||||
|
|
||||||
|
# Various guidelines
|
||||||
|
|
||||||
|
- If a given card has different cryptographic modes, you SHOULD use
|
||||||
|
switch/cases to handle specific branches of code, even when applicable to
|
||||||
|
only one cypher. The idea is that if you don't provide support for all
|
||||||
|
cryptographic schemes, or if an evolution of the card provides more
|
||||||
|
cryptographic possibilities, when adding support for a new cypher, the
|
||||||
|
compiler can warn the developer about unhandled values in switch
|
||||||
|
statements. Please refer to the MIFARE DESFire code for an example.
|
|
@ -215,8 +215,8 @@ main(int argc, char *argv[])
|
||||||
|
|
||||||
for (int i = 0; (!error) && tags[i]; i++) {
|
for (int i = 0; (!error) && tags[i]; i++) {
|
||||||
switch (freefare_get_tag_type (tags[i])) {
|
switch (freefare_get_tag_type (tags[i])) {
|
||||||
case CLASSIC_1K:
|
case MIFARE_CLASSIC_1K:
|
||||||
case CLASSIC_4K:
|
case MIFARE_CLASSIC_4K:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
continue;
|
continue;
|
||||||
|
@ -240,11 +240,11 @@ main(int argc, char *argv[])
|
||||||
at_block = 0;
|
at_block = 0;
|
||||||
|
|
||||||
if (format_options.fast) {
|
if (format_options.fast) {
|
||||||
printf (START_FORMAT_N, (tt == CLASSIC_1K) ? 1 : 2);
|
printf (START_FORMAT_N, (tt == MIFARE_CLASSIC_1K) ? 1 : 2);
|
||||||
if (!try_format_sector (tags[i], 0x00))
|
if (!try_format_sector (tags[i], 0x00))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (tt == CLASSIC_4K)
|
if (tt == MIFARE_CLASSIC_4K)
|
||||||
if (!try_format_sector (tags[i], 0x10))
|
if (!try_format_sector (tags[i], 0x10))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -252,12 +252,12 @@ main(int argc, char *argv[])
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
switch (tt) {
|
switch (tt) {
|
||||||
case CLASSIC_1K:
|
case MIFARE_CLASSIC_1K:
|
||||||
mod_block = 4;
|
mod_block = 4;
|
||||||
if (!format_mifare_classic_1k (tags[i]))
|
if (!format_mifare_classic_1k (tags[i]))
|
||||||
error = 1;
|
error = 1;
|
||||||
break;
|
break;
|
||||||
case CLASSIC_4K:
|
case MIFARE_CLASSIC_4K:
|
||||||
mod_block = 10;
|
mod_block = 10;
|
||||||
if (!format_mifare_classic_4k (tags[i]))
|
if (!format_mifare_classic_4k (tags[i]))
|
||||||
error = 1;
|
error = 1;
|
||||||
|
|
|
@ -139,8 +139,8 @@ main(int argc, char *argv[])
|
||||||
|
|
||||||
for (int i = 0; (!error) && tags[i]; i++) {
|
for (int i = 0; (!error) && tags[i]; i++) {
|
||||||
switch (freefare_get_tag_type (tags[i])) {
|
switch (freefare_get_tag_type (tags[i])) {
|
||||||
case CLASSIC_1K:
|
case MIFARE_CLASSIC_1K:
|
||||||
case CLASSIC_4K:
|
case MIFARE_CLASSIC_4K:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -229,8 +229,8 @@ main(int argc, char *argv[])
|
||||||
|
|
||||||
for (int i = 0; (!error) && tags[i]; i++) {
|
for (int i = 0; (!error) && tags[i]; i++) {
|
||||||
switch (freefare_get_tag_type (tags[i])) {
|
switch (freefare_get_tag_type (tags[i])) {
|
||||||
case CLASSIC_1K:
|
case MIFARE_CLASSIC_1K:
|
||||||
case CLASSIC_4K:
|
case MIFARE_CLASSIC_4K:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
continue;
|
continue;
|
||||||
|
@ -257,13 +257,13 @@ main(int argc, char *argv[])
|
||||||
|
|
||||||
if (write_ndef) {
|
if (write_ndef) {
|
||||||
switch (freefare_get_tag_type (tags[i])) {
|
switch (freefare_get_tag_type (tags[i])) {
|
||||||
case CLASSIC_4K:
|
case MIFARE_CLASSIC_4K:
|
||||||
if (!search_sector_key (tags[i], 0x10, &(card_write_keys[0x10].key), &(card_write_keys[0x10].type))) {
|
if (!search_sector_key (tags[i], 0x10, &(card_write_keys[0x10].key), &(card_write_keys[0x10].type))) {
|
||||||
error = 1;
|
error = 1;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
case CLASSIC_1K:
|
case MIFARE_CLASSIC_1K:
|
||||||
if (!search_sector_key (tags[i], 0x00, &(card_write_keys[0x00].key), &(card_write_keys[0x00].type))) {
|
if (!search_sector_key (tags[i], 0x00, &(card_write_keys[0x00].key), &(card_write_keys[0x00].type))) {
|
||||||
error = 1;
|
error = 1;
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -277,7 +277,7 @@ main(int argc, char *argv[])
|
||||||
if (!error) {
|
if (!error) {
|
||||||
/* Ensure the auth key is always a B one. If not, change it! */
|
/* Ensure the auth key is always a B one. If not, change it! */
|
||||||
switch (freefare_get_tag_type (tags[i])) {
|
switch (freefare_get_tag_type (tags[i])) {
|
||||||
case CLASSIC_4K:
|
case MIFARE_CLASSIC_4K:
|
||||||
if (card_write_keys[0x10].type != MFC_KEY_B) {
|
if (card_write_keys[0x10].type != MFC_KEY_B) {
|
||||||
if( 0 != fix_mad_trailer_block (device, tags[i], 0x10, card_write_keys[0x10].key, card_write_keys[0x10].type)) {
|
if( 0 != fix_mad_trailer_block (device, tags[i], 0x10, card_write_keys[0x10].key, card_write_keys[0x10].type)) {
|
||||||
error = 1;
|
error = 1;
|
||||||
|
@ -287,7 +287,7 @@ main(int argc, char *argv[])
|
||||||
card_write_keys[0x10].type = MFC_KEY_B;
|
card_write_keys[0x10].type = MFC_KEY_B;
|
||||||
}
|
}
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
case CLASSIC_1K:
|
case MIFARE_CLASSIC_1K:
|
||||||
if (card_write_keys[0x00].type != MFC_KEY_B) {
|
if (card_write_keys[0x00].type != MFC_KEY_B) {
|
||||||
if( 0 != fix_mad_trailer_block (device, tags[i], 0x00, card_write_keys[0x00].key, card_write_keys[0x00].type)) {
|
if( 0 != fix_mad_trailer_block (device, tags[i], 0x00, card_write_keys[0x00].key, card_write_keys[0x00].type)) {
|
||||||
error = 1;
|
error = 1;
|
||||||
|
@ -336,7 +336,7 @@ main(int argc, char *argv[])
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// Create a MAD and mark unaccessible sectors in the card
|
// Create a MAD and mark unaccessible sectors in the card
|
||||||
if (!(mad = mad_new ((freefare_get_tag_type (tags[i]) == CLASSIC_4K) ? 2 : 1))) {
|
if (!(mad = mad_new ((freefare_get_tag_type (tags[i]) == MIFARE_CLASSIC_4K) ? 2 : 1))) {
|
||||||
perror ("mad_new");
|
perror ("mad_new");
|
||||||
error = 1;
|
error = 1;
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -344,10 +344,10 @@ main(int argc, char *argv[])
|
||||||
|
|
||||||
MifareClassicSectorNumber max_s = 0;
|
MifareClassicSectorNumber max_s = 0;
|
||||||
switch (freefare_get_tag_type (tags[i])) {
|
switch (freefare_get_tag_type (tags[i])) {
|
||||||
case CLASSIC_1K:
|
case MIFARE_CLASSIC_1K:
|
||||||
max_s = 15;
|
max_s = 15;
|
||||||
break;
|
break;
|
||||||
case CLASSIC_4K:
|
case MIFARE_CLASSIC_4K:
|
||||||
max_s = 39;
|
max_s = 39;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -63,7 +63,7 @@ main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; (!error) && tags[i]; i++) {
|
for (int i = 0; (!error) && tags[i]; i++) {
|
||||||
if (DESFIRE != freefare_get_tag_type (tags[i]))
|
if (MIFARE_DESFIRE != freefare_get_tag_type (tags[i]))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
int res;
|
int res;
|
||||||
|
|
|
@ -119,7 +119,7 @@ main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; (!error) && tags[i]; i++) {
|
for (int i = 0; (!error) && tags[i]; i++) {
|
||||||
if (DESFIRE != freefare_get_tag_type (tags[i]))
|
if (MIFARE_DESFIRE != freefare_get_tag_type (tags[i]))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
char *tag_uid = freefare_get_tag_uid (tags[i]);
|
char *tag_uid = freefare_get_tag_uid (tags[i]);
|
||||||
|
|
|
@ -111,7 +111,7 @@ main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; (!error) && tags[i]; i++) {
|
for (int i = 0; (!error) && tags[i]; i++) {
|
||||||
if (DESFIRE != freefare_get_tag_type (tags[i]))
|
if (MIFARE_DESFIRE != freefare_get_tag_type (tags[i]))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
char *tag_uid = freefare_get_tag_uid (tags[i]);
|
char *tag_uid = freefare_get_tag_uid (tags[i]);
|
||||||
|
|
|
@ -97,7 +97,7 @@ main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; (!error) && tags[i]; i++) {
|
for (int i = 0; (!error) && tags[i]; i++) {
|
||||||
if (DESFIRE != freefare_get_tag_type (tags[i]))
|
if (MIFARE_DESFIRE != freefare_get_tag_type (tags[i]))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
char *tag_uid = freefare_get_tag_uid (tags[i]);
|
char *tag_uid = freefare_get_tag_uid (tags[i]);
|
||||||
|
|
|
@ -107,7 +107,7 @@ main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; (!error) && tags[i]; i++) {
|
for (int i = 0; (!error) && tags[i]; i++) {
|
||||||
if (DESFIRE != freefare_get_tag_type (tags[i]))
|
if (MIFARE_DESFIRE != freefare_get_tag_type (tags[i]))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
char *tag_uid = freefare_get_tag_uid (tags[i]);
|
char *tag_uid = freefare_get_tag_uid (tags[i]);
|
||||||
|
|
|
@ -107,7 +107,7 @@ main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; (!error) && tags[i]; i++) {
|
for (int i = 0; (!error) && tags[i]; i++) {
|
||||||
if (DESFIRE != freefare_get_tag_type (tags[i]))
|
if (MIFARE_DESFIRE != freefare_get_tag_type (tags[i]))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
char *tag_uid = freefare_get_tag_uid (tags[i]);
|
char *tag_uid = freefare_get_tag_uid (tags[i]);
|
||||||
|
|
|
@ -61,7 +61,7 @@ main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; (!error) && tags[i]; i++) {
|
for (int i = 0; (!error) && tags[i]; i++) {
|
||||||
if (DESFIRE != freefare_get_tag_type (tags[i]))
|
if (MIFARE_DESFIRE != freefare_get_tag_type (tags[i]))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
int res;
|
int res;
|
||||||
|
|
|
@ -147,7 +147,7 @@ main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; (!error) && tags[i]; i++) {
|
for (int i = 0; (!error) && tags[i]; i++) {
|
||||||
if (DESFIRE != freefare_get_tag_type (tags[i]))
|
if (MIFARE_DESFIRE != freefare_get_tag_type (tags[i]))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
char *tag_uid = freefare_get_tag_uid (tags[i]);
|
char *tag_uid = freefare_get_tag_uid (tags[i]);
|
||||||
|
|
|
@ -176,7 +176,7 @@ main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; (!error) && tags[i]; i++) {
|
for (int i = 0; (!error) && tags[i]; i++) {
|
||||||
if (DESFIRE != freefare_get_tag_type (tags[i]))
|
if (MIFARE_DESFIRE != freefare_get_tag_type (tags[i]))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
char *tag_uid = freefare_get_tag_uid (tags[i]);
|
char *tag_uid = freefare_get_tag_uid (tags[i]);
|
||||||
|
|
|
@ -57,8 +57,8 @@ main (int argc, char *argv[])
|
||||||
|
|
||||||
for (int i = 0; (!error) && tags[i]; i++) {
|
for (int i = 0; (!error) && tags[i]; i++) {
|
||||||
switch (freefare_get_tag_type (tags[i])) {
|
switch (freefare_get_tag_type (tags[i])) {
|
||||||
case ULTRALIGHT:
|
case MIFARE_ULTRALIGHT:
|
||||||
case ULTRALIGHT_C:
|
case MIFARE_ULTRALIGHT_C:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
continue;
|
continue;
|
||||||
|
@ -66,7 +66,7 @@ main (int argc, char *argv[])
|
||||||
|
|
||||||
char *tag_uid = freefare_get_tag_uid (tags[i]);
|
char *tag_uid = freefare_get_tag_uid (tags[i]);
|
||||||
printf ("Tag with UID %s is a %s\n", tag_uid, freefare_get_tag_friendly_name (tags[i]));
|
printf ("Tag with UID %s is a %s\n", tag_uid, freefare_get_tag_friendly_name (tags[i]));
|
||||||
if (freefare_get_tag_type (tags[i]) == ULTRALIGHT_C) {
|
if (freefare_get_tag_type (tags[i]) == MIFARE_ULTRALIGHT_C) {
|
||||||
FreefareTag tag = tags[i];
|
FreefareTag tag = tags[i];
|
||||||
int res;
|
int res;
|
||||||
MifareDESFireKey key;
|
MifareDESFireKey key;
|
||||||
|
|
|
@ -50,11 +50,11 @@ Mifare card manipulation library (libfreefare, \-lfreefare)
|
||||||
.Fn freefare_get_tags "nfc_device_t *device"
|
.Fn freefare_get_tags "nfc_device_t *device"
|
||||||
.Bd -literal
|
.Bd -literal
|
||||||
enum freefare_tag_type {
|
enum freefare_tag_type {
|
||||||
CLASSIC_1K,
|
MIFARE_CLASSIC_1K,
|
||||||
CLASSIC_4K,
|
MIFARE_CLASSIC_4K,
|
||||||
DESFIRE,
|
MIFARE_DESFIRE,
|
||||||
ULTRALIGHT,
|
MIFARE_ULTRALIGHT,
|
||||||
ULTRALIGHT_C,
|
MIFARE_ULTRALIGHT_C,
|
||||||
};
|
};
|
||||||
.Ed
|
.Ed
|
||||||
.Ft "enum freefare_tag_type"
|
.Ft "enum freefare_tag_type"
|
||||||
|
|
|
@ -27,17 +27,17 @@
|
||||||
#define NXP_MANUFACTURER_CODE 0x04
|
#define NXP_MANUFACTURER_CODE 0x04
|
||||||
|
|
||||||
struct supported_tag supported_tags[] = {
|
struct supported_tag supported_tags[] = {
|
||||||
{ CLASSIC_1K, "Mifare Classic 1k", NMT_ISO14443A, 0x08, 0, 0, { 0x00 }, NULL },
|
{ MIFARE_CLASSIC_1K, "Mifare Classic 1k", NMT_ISO14443A, 0x08, 0, 0, { 0x00 }, NULL },
|
||||||
{ CLASSIC_1K, "Mifare Classic 1k (Emulated)", NMT_ISO14443A, 0x28, 0, 0, { 0x00 }, NULL },
|
{ MIFARE_CLASSIC_1K, "Mifare Classic 1k (Emulated)", NMT_ISO14443A, 0x28, 0, 0, { 0x00 }, NULL },
|
||||||
{ CLASSIC_1K, "Mifare Classic 1k (Emulated)", NMT_ISO14443A, 0x68, 0, 0, { 0x00 }, NULL },
|
{ MIFARE_CLASSIC_1K, "Mifare Classic 1k (Emulated)", NMT_ISO14443A, 0x68, 0, 0, { 0x00 }, NULL },
|
||||||
{ CLASSIC_1K, "Infineon Mifare Classic 1k", NMT_ISO14443A, 0x88, 0, 0, { 0x00 }, NULL },
|
{ MIFARE_CLASSIC_1K, "Infineon Mifare Classic 1k", NMT_ISO14443A, 0x88, 0, 0, { 0x00 }, NULL },
|
||||||
{ CLASSIC_4K, "Mifare Classic 4k", NMT_ISO14443A, 0x18, 0, 0, { 0x00 }, NULL },
|
{ MIFARE_CLASSIC_4K, "Mifare Classic 4k", NMT_ISO14443A, 0x18, 0, 0, { 0x00 }, NULL },
|
||||||
{ CLASSIC_4K, "Mifare Classic 4k (Emulated)", NMT_ISO14443A, 0x38, 0, 0, { 0x00 }, NULL },
|
{ MIFARE_CLASSIC_4K, "Mifare Classic 4k (Emulated)", NMT_ISO14443A, 0x38, 0, 0, { 0x00 }, NULL },
|
||||||
{ DESFIRE, "Mifare DESFire", NMT_ISO14443A, 0x20, 5, 4, { 0x75, 0x77, 0x81, 0x02 /*, 0xXX */ }, NULL},
|
{ MIFARE_DESFIRE, "Mifare DESFire", NMT_ISO14443A, 0x20, 5, 4, { 0x75, 0x77, 0x81, 0x02 /*, 0xXX */ }, NULL},
|
||||||
{ DESFIRE, "Cyanogenmod card emulation", NMT_ISO14443A, 0x60, 4, 3, { 0x78, 0x33, 0x88 /*, 0xXX */ }, NULL},
|
{ MIFARE_DESFIRE, "Cyanogenmod card emulation", NMT_ISO14443A, 0x60, 4, 3, { 0x78, 0x33, 0x88 /*, 0xXX */ }, NULL},
|
||||||
{ DESFIRE, "Android HCE", NMT_ISO14443A, 0x60, 4, 3, { 0x78, 0x80, 0x70 /*, 0xXX */ }, NULL},
|
{ MIFARE_DESFIRE, "Android HCE", NMT_ISO14443A, 0x60, 4, 3, { 0x78, 0x80, 0x70 /*, 0xXX */ }, NULL},
|
||||||
{ ULTRALIGHT_C, "Mifare UltraLightC", NMT_ISO14443A, 0x00, 0, 0, { 0x00 }, is_mifare_ultralightc_on_reader },
|
{ MIFARE_ULTRALIGHT_C, "Mifare UltraLightC", NMT_ISO14443A, 0x00, 0, 0, { 0x00 }, is_mifare_ultralightc_on_reader },
|
||||||
{ ULTRALIGHT, "Mifare UltraLight", NMT_ISO14443A, 0x00, 0, 0, { 0x00 }, NULL },
|
{ MIFARE_ULTRALIGHT, "Mifare UltraLight", NMT_ISO14443A, 0x00, 0, 0, { 0x00 }, NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -73,15 +73,15 @@ freefare_tag_new (nfc_device *device, nfc_target target)
|
||||||
|
|
||||||
/* Allocate memory for the found MIFARE target */
|
/* Allocate memory for the found MIFARE target */
|
||||||
switch (tag_info->type) {
|
switch (tag_info->type) {
|
||||||
case CLASSIC_1K:
|
case MIFARE_CLASSIC_1K:
|
||||||
case CLASSIC_4K:
|
case MIFARE_CLASSIC_4K:
|
||||||
tag = mifare_classic_tag_new ();
|
tag = mifare_classic_tag_new ();
|
||||||
break;
|
break;
|
||||||
case DESFIRE:
|
case MIFARE_DESFIRE:
|
||||||
tag = mifare_desfire_tag_new ();
|
tag = mifare_desfire_tag_new ();
|
||||||
break;
|
break;
|
||||||
case ULTRALIGHT:
|
case MIFARE_ULTRALIGHT:
|
||||||
case ULTRALIGHT_C:
|
case MIFARE_ULTRALIGHT_C:
|
||||||
tag = mifare_ultralight_tag_new ();
|
tag = mifare_ultralight_tag_new ();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -213,15 +213,15 @@ freefare_free_tag (FreefareTag tag)
|
||||||
{
|
{
|
||||||
if (tag) {
|
if (tag) {
|
||||||
switch (tag->tag_info->type) {
|
switch (tag->tag_info->type) {
|
||||||
case CLASSIC_1K:
|
case MIFARE_CLASSIC_1K:
|
||||||
case CLASSIC_4K:
|
case MIFARE_CLASSIC_4K:
|
||||||
mifare_classic_tag_free (tag);
|
mifare_classic_tag_free (tag);
|
||||||
break;
|
break;
|
||||||
case DESFIRE:
|
case MIFARE_DESFIRE:
|
||||||
mifare_desfire_tag_free (tag);
|
mifare_desfire_tag_free (tag);
|
||||||
break;
|
break;
|
||||||
case ULTRALIGHT:
|
case MIFARE_ULTRALIGHT:
|
||||||
case ULTRALIGHT_C:
|
case MIFARE_ULTRALIGHT_C:
|
||||||
mifare_ultralight_tag_free (tag);
|
mifare_ultralight_tag_free (tag);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -235,7 +235,7 @@ freefare_strerror (FreefareTag tag)
|
||||||
if (nfc_device_get_last_error (tag->device) < 0) {
|
if (nfc_device_get_last_error (tag->device) < 0) {
|
||||||
p = nfc_strerror (tag->device);
|
p = nfc_strerror (tag->device);
|
||||||
} else {
|
} else {
|
||||||
if (tag->tag_info->type == DESFIRE) {
|
if (tag->tag_info->type == MIFARE_DESFIRE) {
|
||||||
if (MIFARE_DESFIRE (tag)->last_pcd_error) {
|
if (MIFARE_DESFIRE (tag)->last_pcd_error) {
|
||||||
p = mifare_desfire_error_lookup (MIFARE_DESFIRE (tag)->last_pcd_error);
|
p = mifare_desfire_error_lookup (MIFARE_DESFIRE (tag)->last_pcd_error);
|
||||||
} else if (MIFARE_DESFIRE (tag)->last_picc_error) {
|
} else if (MIFARE_DESFIRE (tag)->last_picc_error) {
|
||||||
|
|
|
@ -29,16 +29,16 @@
|
||||||
#endif // __cplusplus
|
#endif // __cplusplus
|
||||||
|
|
||||||
enum freefare_tag_type {
|
enum freefare_tag_type {
|
||||||
// MINI,
|
// MIFARE_MINI,
|
||||||
CLASSIC_1K,
|
MIFARE_CLASSIC_1K,
|
||||||
CLASSIC_4K,
|
MIFARE_CLASSIC_4K,
|
||||||
DESFIRE,
|
MIFARE_DESFIRE,
|
||||||
// PLUS_S2K,
|
// MIFARE_PLUS_S2K,
|
||||||
// PLUS_S4K,
|
// MIFARE_PLUS_S4K,
|
||||||
// PLUS_X2K,
|
// MIFARE_PLUS_X2K,
|
||||||
// PLUS_X4K,
|
// MIFARE_PLUS_X4K,
|
||||||
ULTRALIGHT,
|
MIFARE_ULTRALIGHT,
|
||||||
ULTRALIGHT_C,
|
MIFARE_ULTRALIGHT_C,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct freefare_tag;
|
struct freefare_tag;
|
||||||
|
|
|
@ -262,10 +262,10 @@ struct mifare_ultralight_tag {
|
||||||
#define ASSERT_ACTIVE(tag) do { if (!tag->active) return errno = ENXIO, -1; } while (0)
|
#define ASSERT_ACTIVE(tag) do { if (!tag->active) return errno = ENXIO, -1; } while (0)
|
||||||
#define ASSERT_INACTIVE(tag) do { if (tag->active) return errno = ENXIO, -1; } while (0)
|
#define ASSERT_INACTIVE(tag) do { if (tag->active) return errno = ENXIO, -1; } while (0)
|
||||||
|
|
||||||
#define ASSERT_MIFARE_CLASSIC(tag) do { if ((tag->tag_info->type != CLASSIC_1K) && (tag->tag_info->type != CLASSIC_4K)) return errno = ENODEV, -1; } while (0)
|
#define ASSERT_MIFARE_CLASSIC(tag) do { if ((tag->tag_info->type != MIFARE_CLASSIC_1K) && (tag->tag_info->type != MIFARE_CLASSIC_4K)) return errno = ENODEV, -1; } while (0)
|
||||||
#define ASSERT_MIFARE_DESFIRE(tag) do { if (tag->tag_info->type != DESFIRE) return errno = ENODEV, -1; } while (0)
|
#define ASSERT_MIFARE_DESFIRE(tag) do { if (tag->tag_info->type != MIFARE_DESFIRE) return errno = ENODEV, -1; } while (0)
|
||||||
#define IS_MIFARE_ULTRALIGHT_C(tag) (tag->tag_info->type == ULTRALIGHT_C)
|
#define IS_MIFARE_ULTRALIGHT_C(tag) (tag->tag_info->type == MIFARE_ULTRALIGHT_C)
|
||||||
#define ASSERT_MIFARE_ULTRALIGHT(tag) do { if ((tag->tag_info->type != ULTRALIGHT) && (! IS_MIFARE_ULTRALIGHT_C(tag))) return errno = ENODEV, -1; } while (0)
|
#define ASSERT_MIFARE_ULTRALIGHT(tag) do { if ((tag->tag_info->type != MIFARE_ULTRALIGHT) && (! IS_MIFARE_ULTRALIGHT_C(tag))) return errno = ENODEV, -1; } while (0)
|
||||||
#define ASSERT_MIFARE_ULTRALIGHT_C(tag) do { if (! IS_MIFARE_ULTRALIGHT_C(tag)) return errno = ENODEV, -1; } while (0)
|
#define ASSERT_MIFARE_ULTRALIGHT_C(tag) do { if (! IS_MIFARE_ULTRALIGHT_C(tag)) return errno = ENODEV, -1; } while (0)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -72,7 +72,7 @@ mifare_desfire_error_lookup (uint8_t code)
|
||||||
uint8_t
|
uint8_t
|
||||||
mifare_desfire_last_pcd_error (FreefareTag tag)
|
mifare_desfire_last_pcd_error (FreefareTag tag)
|
||||||
{
|
{
|
||||||
if (tag->tag_info->type != DESFIRE)
|
if (tag->tag_info->type != MIFARE_DESFIRE)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return MIFARE_DESFIRE (tag)->last_pcd_error;
|
return MIFARE_DESFIRE (tag)->last_pcd_error;
|
||||||
|
@ -81,7 +81,7 @@ mifare_desfire_last_pcd_error (FreefareTag tag)
|
||||||
uint8_t
|
uint8_t
|
||||||
mifare_desfire_last_picc_error (FreefareTag tag)
|
mifare_desfire_last_picc_error (FreefareTag tag)
|
||||||
{
|
{
|
||||||
if (tag->tag_info->type != DESFIRE)
|
if (tag->tag_info->type != MIFARE_DESFIRE)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return MIFARE_DESFIRE (tag)->last_picc_error;
|
return MIFARE_DESFIRE (tag)->last_picc_error;
|
||||||
|
|
|
@ -50,8 +50,8 @@ cut_setup (void)
|
||||||
|
|
||||||
tag = NULL;
|
tag = NULL;
|
||||||
for (int i=0; tags[i]; i++) {
|
for (int i=0; tags[i]; i++) {
|
||||||
if ((freefare_get_tag_type(tags[i]) == CLASSIC_1K) ||
|
if ((freefare_get_tag_type(tags[i]) == MIFARE_CLASSIC_1K) ||
|
||||||
(freefare_get_tag_type(tags[i]) == CLASSIC_4K)) {
|
(freefare_get_tag_type(tags[i]) == MIFARE_CLASSIC_4K)) {
|
||||||
tag = tags[i];
|
tag = tags[i];
|
||||||
res = mifare_classic_connect (tag);
|
res = mifare_classic_connect (tag);
|
||||||
cut_assert_equal_int (0, res, cut_message ("mifare_classic_connect() failed"));
|
cut_assert_equal_int (0, res, cut_message ("mifare_classic_connect() failed"));
|
||||||
|
|
|
@ -51,7 +51,7 @@ cut_setup (void)
|
||||||
|
|
||||||
tag = NULL;
|
tag = NULL;
|
||||||
for (int i=0; tags[i]; i++) {
|
for (int i=0; tags[i]; i++) {
|
||||||
if (freefare_get_tag_type(tags[i]) == DESFIRE) {
|
if (freefare_get_tag_type(tags[i]) == MIFARE_DESFIRE) {
|
||||||
tag = tags[i];
|
tag = tags[i];
|
||||||
res = mifare_desfire_connect (tag);
|
res = mifare_desfire_connect (tag);
|
||||||
cut_assert_equal_int (0, res, cut_message ("mifare_desfire_connect() failed"));
|
cut_assert_equal_int (0, res, cut_message ("mifare_desfire_connect() failed"));
|
||||||
|
|
|
@ -51,7 +51,7 @@ cut_setup (void)
|
||||||
|
|
||||||
tag = NULL;
|
tag = NULL;
|
||||||
for (int i=0; tags[i]; i++) {
|
for (int i=0; tags[i]; i++) {
|
||||||
if (freefare_get_tag_type(tags[i]) == DESFIRE) {
|
if (freefare_get_tag_type(tags[i]) == MIFARE_DESFIRE) {
|
||||||
tag = tags[i];
|
tag = tags[i];
|
||||||
res = mifare_desfire_connect (tag);
|
res = mifare_desfire_connect (tag);
|
||||||
cut_assert_equal_int (0, res, cut_message ("mifare_desfire_connect() failed"));
|
cut_assert_equal_int (0, res, cut_message ("mifare_desfire_connect() failed"));
|
||||||
|
|
|
@ -51,8 +51,8 @@ cut_setup (void)
|
||||||
|
|
||||||
tag = NULL;
|
tag = NULL;
|
||||||
for (int i=0; tags[i]; i++) {
|
for (int i=0; tags[i]; i++) {
|
||||||
if ((freefare_get_tag_type(tags[i]) == ULTRALIGHT) ||
|
if ((freefare_get_tag_type(tags[i]) == MIFARE_ULTRALIGHT) ||
|
||||||
(freefare_get_tag_type(tags[i]) == ULTRALIGHT_C)) {
|
(freefare_get_tag_type(tags[i]) == MIFARE_ULTRALIGHT_C)) {
|
||||||
tag = tags[i];
|
tag = tags[i];
|
||||||
res = mifare_ultralight_connect (tag);
|
res = mifare_ultralight_connect (tag);
|
||||||
cut_assert_equal_int (0, res, cut_message ("mifare_ultralight_connect() failed"));
|
cut_assert_equal_int (0, res, cut_message ("mifare_ultralight_connect() failed"));
|
||||||
|
|
|
@ -124,7 +124,7 @@ test_mifare_classic_mad (void)
|
||||||
* | |\/| |/ _ \| |) \ V // /
|
* | |\/| |/ _ \| |) \ V // /
|
||||||
* |_| |_/_/ \_\___/ \_//___|
|
* |_| |_/_/ \_\___/ \_//___|
|
||||||
*/
|
*/
|
||||||
if (freefare_get_tag_type (tag) != CLASSIC_4K) {
|
if (freefare_get_tag_type (tag) != MIFARE_CLASSIC_4K) {
|
||||||
cut_omit ("MADv2 requires a MIFARE Classic 4K to be tested");
|
cut_omit ("MADv2 requires a MIFARE Classic 4K to be tested");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -178,7 +178,7 @@ test_mifare_ultralightc_authenticate (void)
|
||||||
int res;
|
int res;
|
||||||
MifareDESFireKey key;
|
MifareDESFireKey key;
|
||||||
|
|
||||||
if (tag->tag_info->type == ULTRALIGHT_C) {
|
if (tag->tag_info->type == MIFARE_ULTRALIGHT_C) {
|
||||||
uint8_t key1_3des_data[16] = { 0x49, 0x45, 0x4D, 0x4B, 0x41, 0x45, 0x52, 0x42, 0x21, 0x4E, 0x41, 0x43, 0x55, 0x4F, 0x59, 0x46 };
|
uint8_t key1_3des_data[16] = { 0x49, 0x45, 0x4D, 0x4B, 0x41, 0x45, 0x52, 0x42, 0x21, 0x4E, 0x41, 0x43, 0x55, 0x4F, 0x59, 0x46 };
|
||||||
key = mifare_desfire_3des_key_new (key1_3des_data);
|
key = mifare_desfire_3des_key_new (key1_3des_data);
|
||||||
res = mifare_ultralightc_authenticate (tag, key);
|
res = mifare_ultralightc_authenticate (tag, key);
|
||||||
|
|
Loading…
Reference in a new issue