42b21ff42f
Because we are libfreefare and not libmifare, the generic tag type should not be so specific.
94 lines
4.4 KiB
Text
94 lines
4.4 KiB
Text
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 Ultralight
|
|
* MIFARE Ultralight C with default key (BREAKMEIFYOUCAN!)
|
|
* MIFARE Classic 4k with default keys (FFFFFFFFFF)
|
|
* DESFire EV1 4k with default PICC key (0000000000000000)
|
|
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.
|