2015-05-12 13:29:21 +02:00
|
|
|
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).
|
|
|
|
|
2018-03-07 20:54:04 +01:00
|
|
|
For style correction install package `astyle`. Then run `make style`.
|
|
|
|
|
2015-05-12 13:29:21 +02:00
|
|
|
## 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.
|