Merge pull request #64 from nfc-tools/style

Use astyle(1) to make style consistent
This commit is contained in:
Romain Tartière 2017-06-27 14:35:48 +02:00 committed by GitHub
commit b49692848e
68 changed files with 5956 additions and 5950 deletions

4
.gitignore vendored
View file

@ -36,6 +36,10 @@ examples/mifare-desfire-info
examples/mifare-desfire-read-ndef examples/mifare-desfire-read-ndef
examples/mifare-desfire-write-ndef examples/mifare-desfire-write-ndef
examples/mifare-ultralight-info examples/mifare-ultralight-info
examples/ntag-detect
examples/ntag-removeauth
examples/ntag-setauth
examples/ntag-write
test/test-suite.log test/test-suite.log
test/run-test.sh.log test/run-test.sh.log
test/run-test.sh.trs test/run-test.sh.trs

View file

@ -1,6 +1,8 @@
ACLOCAL_AMFLAGS = -I m4 ACLOCAL_AMFLAGS = -I m4
SUBDIRS = contrib libfreefare test examples libfreefare_subdirs = libfreefare test examples
SUBDIRS = contrib $(libfreefare_subdirs)
pkgconfigdir = $(libdir)/pkgconfig pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libfreefare.pc pkgconfig_DATA = libfreefare.pc
@ -39,3 +41,7 @@ svn-keywords:
svn-keywords-check: svn-keywords-check:
@echo "Files missing a '$$"Id"$$' vcs keyword:" @echo "Files missing a '$$"Id"$$' vcs keyword:"
@$(SVN_KEYWORDS_FILES_LIST_CMD) | xargs grep -L '\$$Id[^$$]*\$$' @$(SVN_KEYWORDS_FILES_LIST_CMD) | xargs grep -L '\$$Id[^$$]*\$$'
style:
find ${libfreefare_subdirs} -name '*.[ch]' -exec perl -pi -e 's/[ \t]+$$//' {} \;
find ${libfreefare_subdirs} -name '*.[ch]' -exec astyle --style=linux --indent=force-tab-x --lineend=linux '{}' ';'

View file

@ -23,56 +23,56 @@
#include <freefare.h> #include <freefare.h>
int int
main (void) main(void)
{ {
nfc_device *device = NULL; nfc_device *device = NULL;
FreefareTag *tags = NULL; FreefareTag *tags = NULL;
nfc_connstring devices[8]; nfc_connstring devices[8];
nfc_context *context; nfc_context *context;
nfc_init (&context); nfc_init(&context);
if (context == NULL) if (context == NULL)
errx (EXIT_FAILURE, "Unable to init libnfc (malloc)"); errx(EXIT_FAILURE, "Unable to init libnfc (malloc)");
size_t device_count = nfc_list_devices (context, devices, 8); size_t device_count = nfc_list_devices(context, devices, 8);
if (device_count <= 0) if (device_count <= 0)
errx (EXIT_FAILURE, "No NFC device found."); errx(EXIT_FAILURE, "No NFC device found.");
for (size_t d = 0; d < device_count; d++) { for (size_t d = 0; d < device_count; d++) {
device = nfc_open (context, devices[d]); device = nfc_open(context, devices[d]);
if (!device) { if (!device) {
errx (EXIT_FAILURE, "nfc_open() failed."); errx(EXIT_FAILURE, "nfc_open() failed.");
} }
tags = freefare_get_tags (device); tags = freefare_get_tags(device);
if (!tags) { if (!tags) {
nfc_close (device); nfc_close(device);
errx (EXIT_FAILURE, "Error listing FeliCa tag."); errx(EXIT_FAILURE, "Error listing FeliCa tag.");
} }
for (int i = 0; tags[i]; i++) { for (int i = 0; tags[i]; i++) {
if (FELICA != freefare_get_tag_type (tags[i])) if (FELICA != freefare_get_tag_type(tags[i]))
continue; continue;
char *uid = freefare_get_tag_uid (tags[i]); char *uid = freefare_get_tag_uid(tags[i]);
printf ("Dumping %s tag %s\n", freefare_get_tag_friendly_name (tags[i]), uid); printf("Dumping %s tag %s\n", freefare_get_tag_friendly_name(tags[i]), uid);
free (uid); free(uid);
printf ("Number\tName\tData\n"); printf("Number\tName\tData\n");
for (int block = 0x00; block < 0x0f; block++) { for (int block = 0x00; block < 0x0f; block++) {
uint8_t buffer[16]; uint8_t buffer[16];
if (felica_read (tags[i], FELICA_SC_RO, block, buffer, sizeof (buffer)) < 0) if (felica_read(tags[i], FELICA_SC_RO, block, buffer, sizeof(buffer)) < 0)
errx (EXIT_FAILURE, "Error reading block %d", block); errx(EXIT_FAILURE, "Error reading block %d", block);
if (block < 0x0e) if (block < 0x0e)
printf ("0x%02x\tS_PAD%d\t", block, block); printf("0x%02x\tS_PAD%d\t", block, block);
else else
printf ("0x%02x\tREG\t", block); printf("0x%02x\tREG\t", block);
for (int j = 0; j < 16; j++) { for (int j = 0; j < 16; j++) {
printf ("%02x ", buffer[j]); printf("%02x ", buffer[j]);
} }
printf ("\n"); printf("\n");
} }
char *block_names[] = { char *block_names[] = {
@ -84,19 +84,19 @@ main (void)
for (int block = 0x80; block < 0x89; block++) { for (int block = 0x80; block < 0x89; block++) {
uint8_t buffer[16]; uint8_t buffer[16];
if (felica_read (tags[i], FELICA_SC_RO, block, buffer, sizeof (buffer)) < 0) if (felica_read(tags[i], FELICA_SC_RO, block, buffer, sizeof(buffer)) < 0)
errx (EXIT_FAILURE, "Error reading block %d", block); errx(EXIT_FAILURE, "Error reading block %d", block);
printf ("0x%02x\t%s\t", block, block_names[block - 0x80]); printf("0x%02x\t%s\t", block, block_names[block - 0x80]);
for (int j = 0; j < valid_bytes[block - 0x80]; j++) { for (int j = 0; j < valid_bytes[block - 0x80]; j++) {
printf ("%02x ", buffer[j]); printf("%02x ", buffer[j]);
} }
printf ("\n"); printf("\n");
} }
} }
freefare_free_tags (tags); freefare_free_tags(tags);
nfc_close (device); nfc_close(device);
} }
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);

View file

@ -44,15 +44,15 @@
#define NDEF_BUFFER_SIZE 512 #define NDEF_BUFFER_SIZE 512
void void
usage (char *progname) usage(char *progname)
{ {
fprintf (stderr, "usage: %s [options]\n", progname); fprintf(stderr, "usage: %s [options]\n", progname);
fprintf (stderr, "\nAvailable options:\n"); fprintf(stderr, "\nAvailable options:\n");
fprintf (stderr, " -o FILE Write NDEF message to FILE\n"); fprintf(stderr, " -o FILE Write NDEF message to FILE\n");
} }
int int
main (int argc, char *argv[]) main(int argc, char *argv[])
{ {
int error = EXIT_SUCCESS; int error = EXIT_SUCCESS;
nfc_device *device = NULL; nfc_device *device = NULL;
@ -60,14 +60,14 @@ main (int argc, char *argv[])
int ch; int ch;
char *ndef_file = NULL; char *ndef_file = NULL;
while ((ch = getopt (argc, argv, "o:")) != -1) { while ((ch = getopt(argc, argv, "o:")) != -1) {
switch (ch) { switch (ch) {
case 'o': case 'o':
ndef_file = optarg; ndef_file = optarg;
break; break;
case '?': case '?':
usage (argv[0]); usage(argv[0]);
exit (EXIT_FAILURE); exit(EXIT_FAILURE);
} }
} }
@ -76,26 +76,26 @@ main (int argc, char *argv[])
size_t device_count; size_t device_count;
nfc_context *context; nfc_context *context;
nfc_init (&context); nfc_init(&context);
if (context == NULL) if (context == NULL)
errx (EXIT_FAILURE, "Unable to init libnfc (malloc)"); errx(EXIT_FAILURE, "Unable to init libnfc (malloc)");
device_count = nfc_list_devices (context, devices, 8); device_count = nfc_list_devices(context, devices, 8);
if (device_count <= 0) if (device_count <= 0)
errx (EXIT_FAILURE, "No NFC device found."); errx(EXIT_FAILURE, "No NFC device found.");
for (size_t d = 0; d < device_count; d++) { for (size_t d = 0; d < device_count; d++) {
device = nfc_open (context, devices[d]); device = nfc_open(context, devices[d]);
if (!device) { if (!device) {
warnx ("nfc_open() failed."); warnx("nfc_open() failed.");
error = EXIT_FAILURE; error = EXIT_FAILURE;
continue; continue;
} }
tags = freefare_get_tags (device); tags = freefare_get_tags(device);
if (!tags) { if (!tags) {
nfc_close (device); nfc_close(device);
errx (EXIT_FAILURE, "Error listing FeliCa tag."); errx(EXIT_FAILURE, "Error listing FeliCa tag.");
} }
for (int i = 0; (!error) && tags[i]; i++) { for (int i = 0; (!error) && tags[i]; i++) {
@ -106,7 +106,7 @@ main (int argc, char *argv[])
ssize_t s; ssize_t s;
// FIXME Instead of reading as much as we can, we should read until end of NDEF record (if any is found). // FIXME Instead of reading as much as we can, we should read until end of NDEF record (if any is found).
while ((ndef_space_left >= 16) && (s = felica_read (tags[i], FELICA_SC_RO, block++, p, 16)) > 0) { while ((ndef_space_left >= 16) && (s = felica_read(tags[i], FELICA_SC_RO, block++, p, 16)) > 0) {
p += s; p += s;
ndef_space_left -= s; ndef_space_left -= s;
} }
@ -127,7 +127,7 @@ main (int argc, char *argv[])
payload_length = ndef_record[2]; payload_length = ndef_record[2];
payload_length_length = 1; payload_length_length = 1;
} else { } else {
payload_length = be32toh (*(uint32_t *)(ndef_record + 2)); payload_length = be32toh(*(uint32_t *)(ndef_record + 2));
payload_length_length = 4; payload_length_length = 4;
} }
ndef_record_length += payload_length_length; ndef_record_length += payload_length_length;
@ -139,28 +139,28 @@ main (int argc, char *argv[])
ndef_message_length += ndef_record_length; ndef_message_length += ndef_record_length;
if (ndef_message_length > NDEF_BUFFER_SIZE) if (ndef_message_length > NDEF_BUFFER_SIZE)
errx (EXIT_FAILURE, "NDEF message truncated"); errx(EXIT_FAILURE, "NDEF message truncated");
} while ((ndef_record[0] & 0x40) != 0x40); } while ((ndef_record[0] & 0x40) != 0x40);
} }
if (ndef_message_length == 0) if (ndef_message_length == 0)
errx (EXIT_FAILURE, "No NDEF message found"); errx(EXIT_FAILURE, "No NDEF message found");
FILE *f; FILE *f;
if (ndef_file) if (ndef_file)
f = fopen (ndef_file, "w"); f = fopen(ndef_file, "w");
else else
f = stdout; f = stdout;
if (fwrite (ndef_message, ndef_message_length, 1, f) != 1) if (fwrite(ndef_message, ndef_message_length, 1, f) != 1)
err (EXIT_FAILURE, "Can't write NDEF message"); err(EXIT_FAILURE, "Can't write NDEF message");
fclose (f); fclose(f);
} }
freefare_free_tags (tags); freefare_free_tags(tags);
nfc_close (device); nfc_close(device);
} }
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
} }

View file

@ -35,18 +35,18 @@
MifareClassicKey default_keys[40]; MifareClassicKey default_keys[40];
MifareClassicKey default_keys_int[] = { MifareClassicKey default_keys_int[] = {
{ 0xff,0xff,0xff,0xff,0xff,0xff }, { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
{ 0xd3,0xf7,0xd3,0xf7,0xd3,0xf7 }, { 0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7 },
{ 0xa0,0xa1,0xa2,0xa3,0xa4,0xa5 }, { 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5 },
{ 0xb0,0xb1,0xb2,0xb3,0xb4,0xb5 }, { 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5 },
{ 0x4d,0x3a,0x99,0xc3,0x51,0xdd }, { 0x4d, 0x3a, 0x99, 0xc3, 0x51, 0xdd },
{ 0x1a,0x98,0x2c,0x7e,0x45,0x9a }, { 0x1a, 0x98, 0x2c, 0x7e, 0x45, 0x9a },
{ 0xaa,0xbb,0xcc,0xdd,0xee,0xff }, { 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
{ 0x00,0x00,0x00,0x00,0x00,0x00 } { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
}; };
int format_mifare_classic_1k (FreefareTag tag); int format_mifare_classic_1k(FreefareTag tag);
int format_mifare_classic_4k (FreefareTag tag); int format_mifare_classic_4k(FreefareTag tag);
int try_format_sector (FreefareTag tag, MifareClassicSectorNumber sector); int try_format_sector(FreefareTag tag, MifareClassicSectorNumber sector);
static int at_block = 0; static int at_block = 0;
static int mod_block = 10; static int mod_block = 10;
@ -60,81 +60,81 @@ struct {
}; };
static void static void
display_progress (void) display_progress(void)
{ {
at_block++; at_block++;
if (0 == (at_block % mod_block)) { if (0 == (at_block % mod_block)) {
printf ("%d", at_block); printf("%d", at_block);
fflush (stdout); fflush(stdout);
} else { } else {
printf ("."); printf(".");
fflush (stdout); fflush(stdout);
} }
} }
int int
format_mifare_classic_1k (FreefareTag tag) format_mifare_classic_1k(FreefareTag tag)
{ {
printf (START_FORMAT_N, 16); printf(START_FORMAT_N, 16);
for (int sector = 0; sector < 16; sector++) { for (int sector = 0; sector < 16; sector++) {
if (!try_format_sector (tag, sector)) if (!try_format_sector(tag, sector))
return 0; return 0;
} }
printf (DONE_FORMAT); printf(DONE_FORMAT);
return 1; return 1;
} }
int int
format_mifare_classic_4k (FreefareTag tag) format_mifare_classic_4k(FreefareTag tag)
{ {
printf (START_FORMAT_N, 32 + 8); printf(START_FORMAT_N, 32 + 8);
for (int sector = 0; sector < (32 + 8); sector++) { for (int sector = 0; sector < (32 + 8); sector++) {
if (!try_format_sector (tag, sector)) if (!try_format_sector(tag, sector))
return 0; return 0;
} }
printf (DONE_FORMAT); printf(DONE_FORMAT);
return 1; return 1;
} }
int int
try_format_sector (FreefareTag tag, MifareClassicSectorNumber sector) try_format_sector(FreefareTag tag, MifareClassicSectorNumber sector)
{ {
display_progress (); display_progress();
for (size_t i = 0; i < (sizeof (default_keys) / sizeof (MifareClassicKey)); i++) { for (size_t i = 0; i < (sizeof(default_keys) / sizeof(MifareClassicKey)); i++) {
MifareClassicBlockNumber block = mifare_classic_sector_last_block (sector); MifareClassicBlockNumber block = mifare_classic_sector_last_block(sector);
if ((0 == mifare_classic_connect (tag)) && (0 == mifare_classic_authenticate (tag, block, default_keys[i], MFC_KEY_A))) { if ((0 == mifare_classic_connect(tag)) && (0 == mifare_classic_authenticate(tag, block, default_keys[i], MFC_KEY_A))) {
if (0 == mifare_classic_format_sector (tag, sector)) { if (0 == mifare_classic_format_sector(tag, sector)) {
mifare_classic_disconnect (tag); mifare_classic_disconnect(tag);
return 1; return 1;
} else if (EIO == errno) { } else if (EIO == errno) {
err (EXIT_FAILURE, "sector %d", sector); err(EXIT_FAILURE, "sector %d", sector);
} }
mifare_classic_disconnect (tag); mifare_classic_disconnect(tag);
} }
if ((0 == mifare_classic_connect (tag)) && (0 == mifare_classic_authenticate (tag, block, default_keys[i], MFC_KEY_B))) { if ((0 == mifare_classic_connect(tag)) && (0 == mifare_classic_authenticate(tag, block, default_keys[i], MFC_KEY_B))) {
if (0 == mifare_classic_format_sector (tag, sector)) { if (0 == mifare_classic_format_sector(tag, sector)) {
mifare_classic_disconnect (tag); mifare_classic_disconnect(tag);
return 1; return 1;
} else if (EIO == errno) { } else if (EIO == errno) {
err (EXIT_FAILURE, "sector %d", sector); err(EXIT_FAILURE, "sector %d", sector);
} }
mifare_classic_disconnect (tag); mifare_classic_disconnect(tag);
} }
} }
warnx ("No known authentication key for sector %d", sector); warnx("No known authentication key for sector %d", sector);
return 0; return 0;
} }
static void static void
usage(char *progname) usage(char *progname)
{ {
fprintf (stderr, "usage: %s [-fy] [keyfile]\n", progname); fprintf(stderr, "usage: %s [-fy] [keyfile]\n", progname);
fprintf (stderr, "\nOptions:\n"); fprintf(stderr, "\nOptions:\n");
fprintf (stderr, " -f Fast format (only erase MAD)\n"); fprintf(stderr, " -f Fast format (only erase MAD)\n");
fprintf (stderr, " -y Do not ask for confirmation (dangerous)\n"); fprintf(stderr, " -y Do not ask for confirmation (dangerous)\n");
fprintf (stderr, " keyfile Use keys from dump in addition to internal default keys\n"); fprintf(stderr, " keyfile Use keys from dump in addition to internal default keys\n");
} }
int int
@ -145,47 +145,45 @@ main(int argc, char *argv[])
nfc_device *device = NULL; nfc_device *device = NULL;
FreefareTag *tags = NULL; FreefareTag *tags = NULL;
while ((ch = getopt (argc, argv, "fhy")) != -1) { while ((ch = getopt(argc, argv, "fhy")) != -1) {
switch (ch) { switch (ch) {
case 'f': case 'f':
format_options.fast = true; format_options.fast = true;
break; break;
case 'h': case 'h':
usage(argv[0]); usage(argv[0]);
exit (EXIT_SUCCESS); exit(EXIT_SUCCESS);
break; break;
case 'y': case 'y':
format_options.interactive = false; format_options.interactive = false;
break; break;
default: default:
usage(argv[0]); usage(argv[0]);
exit (EXIT_FAILURE); exit(EXIT_FAILURE);
} }
} }
// Remaining args, if any, are in argv[optind .. (argc-1)] // Remaining args, if any, are in argv[optind .. (argc-1)]
memcpy(default_keys, default_keys_int, sizeof(default_keys_int)); memcpy(default_keys, default_keys_int, sizeof(default_keys_int));
if ((argc - optind) > 0) if ((argc - optind) > 0) {
{ int i, rc;
int i, rc; char kbuffer[1024] = {0};
char kbuffer[1024] = {0}; memset(kbuffer, 0, sizeof kbuffer);
memset ( kbuffer, 0, sizeof kbuffer); FILE *fp = fopen(argv[optind], "rb");
FILE *fp = fopen(argv[optind], "rb"); if (fp == NULL)
if (fp == NULL) errx(EXIT_FAILURE, "Unable to open file");
errx(EXIT_FAILURE, "Unable to open file"); for (i = 0; (rc = getc(fp)) != EOF && i < 1024; kbuffer[i++] = rc) { }
for (i = 0; (rc = getc(fp)) != EOF && i < 1024; kbuffer[i++] = rc) { } fclose(fp);
fclose(fp);
i = sizeof(default_keys_int) / 6; i = sizeof(default_keys_int) / 6;
for(int s = 0; s<16; s++) for (int s = 0; s < 16; s++) {
{ int startblock = s * 4;
int startblock = s * 4; int pos_a = (startblock + 3) * 16;
int pos_a = (startblock + 3) * 16; int pos_b = (startblock + 3) * 16 + 10;
int pos_b = (startblock + 3) * 16 + 10; memcpy((default_keys + i++), kbuffer + pos_a, 6);
memcpy((default_keys + i++), kbuffer + pos_a, 6); memcpy((default_keys + i++), kbuffer + pos_b, 6);
memcpy((default_keys + i++), kbuffer + pos_b, 6); }
}
} }
nfc_connstring devices[8]; nfc_connstring devices[8];
@ -193,30 +191,30 @@ main(int argc, char *argv[])
size_t device_count; size_t device_count;
nfc_context *context; nfc_context *context;
nfc_init (&context); nfc_init(&context);
if (context == NULL) if (context == NULL)
errx(EXIT_FAILURE, "Unable to init libnfc (malloc)"); errx(EXIT_FAILURE, "Unable to init libnfc (malloc)");
device_count = nfc_list_devices (context, devices, 8); device_count = nfc_list_devices(context, devices, 8);
if (device_count <= 0) if (device_count <= 0)
errx (EXIT_FAILURE, "No NFC device found."); errx(EXIT_FAILURE, "No NFC device found.");
for (size_t d = 0; d < device_count; d++) { for (size_t d = 0; d < device_count; d++) {
device = nfc_open (context, devices[d]); device = nfc_open(context, devices[d]);
if (!device) { if (!device) {
warnx ("nfc_open() failed."); warnx("nfc_open() failed.");
error = EXIT_FAILURE; error = EXIT_FAILURE;
continue; continue;
} }
tags = freefare_get_tags (device); tags = freefare_get_tags(device);
if (!tags) { if (!tags) {
nfc_close (device); nfc_close(device);
errx (EXIT_FAILURE, "Error listing Mifare Classic tag."); errx(EXIT_FAILURE, "Error listing Mifare Classic tag.");
} }
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 MIFARE_CLASSIC_1K: case MIFARE_CLASSIC_1K:
case MIFARE_CLASSIC_4K: case MIFARE_CLASSIC_4K:
break; break;
@ -224,44 +222,44 @@ main(int argc, char *argv[])
continue; continue;
} }
char *tag_uid = freefare_get_tag_uid (tags[i]); char *tag_uid = freefare_get_tag_uid(tags[i]);
char buffer[BUFSIZ]; char buffer[BUFSIZ];
printf ("Found %s with UID %s. ", freefare_get_tag_friendly_name (tags[i]), tag_uid); printf("Found %s with UID %s. ", freefare_get_tag_friendly_name(tags[i]), tag_uid);
bool format = true; bool format = true;
if (format_options.interactive) { if (format_options.interactive) {
printf ("Format [yN] "); printf("Format [yN] ");
fgets (buffer, BUFSIZ, stdin); fgets(buffer, BUFSIZ, stdin);
format = ((buffer[0] == 'y') || (buffer[0] == 'Y')); format = ((buffer[0] == 'y') || (buffer[0] == 'Y'));
} else { } else {
printf ("\n"); printf("\n");
} }
if (format) { if (format) {
enum freefare_tag_type tt = freefare_get_tag_type (tags[i]); enum freefare_tag_type tt = freefare_get_tag_type(tags[i]);
at_block = 0; at_block = 0;
if (format_options.fast) { if (format_options.fast) {
printf (START_FORMAT_N, (tt == MIFARE_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 == MIFARE_CLASSIC_4K) if (tt == MIFARE_CLASSIC_4K)
if (!try_format_sector (tags[i], 0x10)) if (!try_format_sector(tags[i], 0x10))
break; break;
printf (DONE_FORMAT); printf(DONE_FORMAT);
continue; continue;
} }
switch (tt) { switch (tt) {
case MIFARE_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 MIFARE_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;
break; break;
default: default:
@ -270,13 +268,13 @@ main(int argc, char *argv[])
} }
} }
free (tag_uid); free(tag_uid);
} }
freefare_free_tags (tags); freefare_free_tags(tags);
nfc_close (device); nfc_close(device);
} }
nfc_exit (context); nfc_exit(context);
exit (error); exit(error);
} }

View file

@ -56,10 +56,10 @@ struct {
static void static void
usage(char *progname) usage(char *progname)
{ {
fprintf (stderr, "usage: %s -o FILE\n", progname); fprintf(stderr, "usage: %s -o FILE\n", progname);
fprintf (stderr, "\nOptions:\n"); fprintf(stderr, "\nOptions:\n");
fprintf (stderr, " -y Do not ask for confirmation\n"); fprintf(stderr, " -y Do not ask for confirmation\n");
fprintf (stderr, " -o Extract NDEF message if available in FILE\n"); fprintf(stderr, " -o Extract NDEF message if available in FILE\n");
} }
int int
@ -72,11 +72,11 @@ main(int argc, char *argv[])
int ch; int ch;
char *ndef_output = NULL; char *ndef_output = NULL;
while ((ch = getopt (argc, argv, "hyo:")) != -1) { while ((ch = getopt(argc, argv, "hyo:")) != -1) {
switch (ch) { switch (ch) {
case 'h': case 'h':
usage(argv[0]); usage(argv[0]);
exit (EXIT_SUCCESS); exit(EXIT_SUCCESS);
break; break;
case 'y': case 'y':
read_options.interactive = false; read_options.interactive = false;
@ -86,30 +86,30 @@ main(int argc, char *argv[])
break; break;
case '?': case '?':
if (optopt == 'o') if (optopt == 'o')
fprintf (stderr, "Option -%c requires an argument.\n", optopt); fprintf(stderr, "Option -%c requires an argument.\n", optopt);
/* FALLTHROUGH */ /* FALLTHROUGH */
default: default:
usage (argv[0]); usage(argv[0]);
exit (EXIT_FAILURE); exit(EXIT_FAILURE);
} }
} }
if (ndef_output == NULL) { if (ndef_output == NULL) {
usage (argv[0]); usage(argv[0]);
exit (EXIT_FAILURE); exit(EXIT_FAILURE);
} }
FILE* message_stream = NULL; FILE *message_stream = NULL;
FILE* ndef_stream = NULL; FILE *ndef_stream = NULL;
if ((strlen (ndef_output) == 1) && (ndef_output[0] == '-')) { if ((strlen(ndef_output) == 1) && (ndef_output[0] == '-')) {
message_stream = stderr; message_stream = stderr;
ndef_stream = stdout; ndef_stream = stdout;
} else { } else {
message_stream = stdout; message_stream = stdout;
ndef_stream = fopen(ndef_output, "wb"); ndef_stream = fopen(ndef_output, "wb");
if (!ndef_stream) { if (!ndef_stream) {
fprintf (stderr, "Could not open file %s.\n", ndef_output); fprintf(stderr, "Could not open file %s.\n", ndef_output);
exit (EXIT_FAILURE); exit(EXIT_FAILURE);
} }
} }
@ -117,30 +117,30 @@ main(int argc, char *argv[])
size_t device_count; size_t device_count;
nfc_context *context; nfc_context *context;
nfc_init (&context); nfc_init(&context);
if (context == NULL) if (context == NULL)
errx(EXIT_FAILURE, "Unable to init libnfc (malloc)"); errx(EXIT_FAILURE, "Unable to init libnfc (malloc)");
device_count= nfc_list_devices (context, devices, 8); device_count = nfc_list_devices(context, devices, 8);
if (device_count <= 0) if (device_count <= 0)
errx (EXIT_FAILURE, "No NFC device found."); errx(EXIT_FAILURE, "No NFC device found.");
for (size_t d = 0; d < device_count; d++) { for (size_t d = 0; d < device_count; d++) {
device = nfc_open (context, devices[d]); device = nfc_open(context, devices[d]);
if (!device) { if (!device) {
warnx ("nfc_open() failed."); warnx("nfc_open() failed.");
error = EXIT_FAILURE; error = EXIT_FAILURE;
continue; continue;
} }
tags = freefare_get_tags (device); tags = freefare_get_tags(device);
if (!tags) { if (!tags) {
nfc_close (device); nfc_close(device);
errx (EXIT_FAILURE, "Error listing MIFARE classic tag."); errx(EXIT_FAILURE, "Error listing MIFARE classic tag.");
} }
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 MIFARE_CLASSIC_1K: case MIFARE_CLASSIC_1K:
case MIFARE_CLASSIC_4K: case MIFARE_CLASSIC_4K:
break; break;
@ -148,100 +148,100 @@ main(int argc, char *argv[])
continue; continue;
} }
char *tag_uid = freefare_get_tag_uid (tags[i]); char *tag_uid = freefare_get_tag_uid(tags[i]);
char buffer[BUFSIZ]; char buffer[BUFSIZ];
fprintf (message_stream, "Found %s with UID %s. ", freefare_get_tag_friendly_name (tags[i]), tag_uid); fprintf(message_stream, "Found %s with UID %s. ", freefare_get_tag_friendly_name(tags[i]), tag_uid);
bool read_ndef = true; bool read_ndef = true;
if (read_options.interactive) { if (read_options.interactive) {
fprintf (message_stream, "Read NDEF [yN] "); fprintf(message_stream, "Read NDEF [yN] ");
fgets (buffer, BUFSIZ, stdin); fgets(buffer, BUFSIZ, stdin);
read_ndef = ((buffer[0] == 'y') || (buffer[0] == 'Y')); read_ndef = ((buffer[0] == 'y') || (buffer[0] == 'Y'));
} else { } else {
fprintf (message_stream, "\n"); fprintf(message_stream, "\n");
} }
if (read_ndef) { if (read_ndef) {
// NFCForum card has a MAD, load it. // NFCForum card has a MAD, load it.
if (0 == mifare_classic_connect (tags[i])) { if (0 == mifare_classic_connect(tags[i])) {
} else { } else {
nfc_perror (device, "mifare_classic_connect"); nfc_perror(device, "mifare_classic_connect");
error = EXIT_FAILURE; error = EXIT_FAILURE;
goto error; goto error;
} }
if ((mad = mad_read (tags[i]))) { if ((mad = mad_read(tags[i]))) {
// Dump the NFCForum application using MAD information // Dump the NFCForum application using MAD information
uint8_t buffer[4096]; uint8_t buffer[4096];
ssize_t len; ssize_t len;
if ((len = mifare_application_read (tags[i], mad, mad_nfcforum_aid, buffer, sizeof(buffer), mifare_classic_nfcforum_public_key_a, MFC_KEY_A)) != -1) { if ((len = mifare_application_read(tags[i], mad, mad_nfcforum_aid, buffer, sizeof(buffer), mifare_classic_nfcforum_public_key_a, MFC_KEY_A)) != -1) {
uint8_t tlv_type; uint8_t tlv_type;
uint16_t tlv_data_len; uint16_t tlv_data_len;
uint8_t * tlv_data; uint8_t *tlv_data;
uint8_t * pbuffer = buffer; uint8_t *pbuffer = buffer;
decode_tlv: decode_tlv:
tlv_data = tlv_decode (pbuffer, &tlv_type, &tlv_data_len); tlv_data = tlv_decode(pbuffer, &tlv_type, &tlv_data_len);
switch (tlv_type) { switch (tlv_type) {
case 0x00: case 0x00:
fprintf (message_stream, "NFC Forum application contains a \"NULL TLV\", Skipping...\n"); // According to [ANNFC1K4K], we skip this Tag to read further TLV blocks. fprintf(message_stream, "NFC Forum application contains a \"NULL TLV\", Skipping...\n"); // According to [ANNFC1K4K], we skip this Tag to read further TLV blocks.
pbuffer += tlv_record_length(pbuffer, NULL, NULL); pbuffer += tlv_record_length(pbuffer, NULL, NULL);
if (pbuffer >= buffer + sizeof(buffer)) { if (pbuffer >= buffer + sizeof(buffer)) {
error = EXIT_FAILURE;
goto error;
}
goto decode_tlv;
break;
case 0x03:
fprintf (message_stream, "NFC Forum application contains a \"NDEF Message TLV\".\n");
break;
case 0xFD:
fprintf (message_stream, "NFC Forum application contains a \"Proprietary TLV\", Skipping...\n"); // According to [ANNFC1K4K], we can skip this TLV to read further TLV blocks.
pbuffer += tlv_record_length(pbuffer, NULL, NULL);
if (pbuffer >= buffer + sizeof(buffer)) {
error = EXIT_FAILURE;
goto error;
}
goto decode_tlv;
break;
case 0xFE:
fprintf (stderr, "NFC Forum application contains a \"Terminator TLV\", no available data.\n");
error = EXIT_FAILURE; error = EXIT_FAILURE;
goto error; goto error;
break; }
default: goto decode_tlv;
fprintf (stderr, "NFC Forum application contains an invalid TLV.\n"); break;
case 0x03:
fprintf(message_stream, "NFC Forum application contains a \"NDEF Message TLV\".\n");
break;
case 0xFD:
fprintf(message_stream, "NFC Forum application contains a \"Proprietary TLV\", Skipping...\n"); // According to [ANNFC1K4K], we can skip this TLV to read further TLV blocks.
pbuffer += tlv_record_length(pbuffer, NULL, NULL);
if (pbuffer >= buffer + sizeof(buffer)) {
error = EXIT_FAILURE; error = EXIT_FAILURE;
goto error; goto error;
break; }
goto decode_tlv;
break;
case 0xFE:
fprintf(stderr, "NFC Forum application contains a \"Terminator TLV\", no available data.\n");
error = EXIT_FAILURE;
goto error;
break;
default:
fprintf(stderr, "NFC Forum application contains an invalid TLV.\n");
error = EXIT_FAILURE;
goto error;
break;
} }
if (fwrite (tlv_data, 1, tlv_data_len, ndef_stream) != tlv_data_len) { if (fwrite(tlv_data, 1, tlv_data_len, ndef_stream) != tlv_data_len) {
fprintf (stderr, "Could not write to file.\n"); fprintf(stderr, "Could not write to file.\n");
error = EXIT_FAILURE; error = EXIT_FAILURE;
goto error; goto error;
} }
free (tlv_data); free(tlv_data);
} else { } else {
fprintf (stderr, "No NFC Forum application.\n"); fprintf(stderr, "No NFC Forum application.\n");
error = EXIT_FAILURE; error = EXIT_FAILURE;
goto error; goto error;
} }
} else { } else {
fprintf (stderr, "No MAD detected.\n"); fprintf(stderr, "No MAD detected.\n");
error = EXIT_FAILURE; error = EXIT_FAILURE;
goto error; goto error;
} }
free (mad); free(mad);
} }
error: error:
free (tag_uid); free(tag_uid);
} }
fclose (ndef_stream); fclose(ndef_stream);
freefare_free_tags (tags); freefare_free_tags(tags);
nfc_close (device); nfc_close(device);
} }
nfc_exit (context); nfc_exit(context);
exit (error); exit(error);
} }

View file

@ -33,14 +33,14 @@
#define MIN(a,b) ((a < b) ? a: b) #define MIN(a,b) ((a < b) ? a: b)
MifareClassicKey default_keys[] = { MifareClassicKey default_keys[] = {
{ 0xff,0xff,0xff,0xff,0xff,0xff }, { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
{ 0xd3,0xf7,0xd3,0xf7,0xd3,0xf7 }, { 0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7 },
{ 0xa0,0xa1,0xa2,0xa3,0xa4,0xa5 }, { 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5 },
{ 0xb0,0xb1,0xb2,0xb3,0xb4,0xb5 }, { 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5 },
{ 0x4d,0x3a,0x99,0xc3,0x51,0xdd }, { 0x4d, 0x3a, 0x99, 0xc3, 0x51, 0xdd },
{ 0x1a,0x98,0x2c,0x7e,0x45,0x9a }, { 0x1a, 0x98, 0x2c, 0x7e, 0x45, 0x9a },
{ 0xaa,0xbb,0xcc,0xdd,0xee,0xff }, { 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
{ 0x00,0x00,0x00,0x00,0x00,0x00 } { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
}; };
struct mifare_classic_key_and_type { struct mifare_classic_key_and_type {
@ -69,54 +69,54 @@ uint8_t *ndef_msg;
size_t ndef_msg_len; size_t ndef_msg_len;
static int static int
search_sector_key (FreefareTag tag, MifareClassicSectorNumber sector, MifareClassicKey *key, MifareClassicKeyType *key_type) search_sector_key(FreefareTag tag, MifareClassicSectorNumber sector, MifareClassicKey *key, MifareClassicKeyType *key_type)
{ {
MifareClassicBlockNumber block = mifare_classic_sector_last_block (sector); MifareClassicBlockNumber block = mifare_classic_sector_last_block(sector);
/* /*
* FIXME: We should not assume that if we have full access to trailer block * FIXME: We should not assume that if we have full access to trailer block
* we also have a full access to data blocks. * we also have a full access to data blocks.
*/ */
mifare_classic_disconnect (tag); mifare_classic_disconnect(tag);
for (size_t i = 0; i < (sizeof (default_keys) / sizeof (MifareClassicKey)); i++) { for (size_t i = 0; i < (sizeof(default_keys) / sizeof(MifareClassicKey)); i++) {
if ((0 == mifare_classic_connect (tag)) && (0 == mifare_classic_authenticate (tag, block, default_keys[i], MFC_KEY_A))) { if ((0 == mifare_classic_connect(tag)) && (0 == mifare_classic_authenticate(tag, block, default_keys[i], MFC_KEY_A))) {
if ((1 == mifare_classic_get_trailer_block_permission (tag, block, MCAB_WRITE_KEYA, MFC_KEY_A)) && if ((1 == mifare_classic_get_trailer_block_permission(tag, block, MCAB_WRITE_KEYA, MFC_KEY_A)) &&
(1 == mifare_classic_get_trailer_block_permission (tag, block, MCAB_WRITE_ACCESS_BITS, MFC_KEY_A)) && (1 == mifare_classic_get_trailer_block_permission(tag, block, MCAB_WRITE_ACCESS_BITS, MFC_KEY_A)) &&
(1 == mifare_classic_get_trailer_block_permission (tag, block, MCAB_WRITE_KEYB, MFC_KEY_A))) { (1 == mifare_classic_get_trailer_block_permission(tag, block, MCAB_WRITE_KEYB, MFC_KEY_A))) {
memcpy (key, &default_keys[i], sizeof (MifareClassicKey)); memcpy(key, &default_keys[i], sizeof(MifareClassicKey));
*key_type = MFC_KEY_A; *key_type = MFC_KEY_A;
return 1; return 1;
} }
} }
mifare_classic_disconnect (tag); mifare_classic_disconnect(tag);
if ((0 == mifare_classic_connect (tag)) && (0 == mifare_classic_authenticate (tag, block, default_keys[i], MFC_KEY_B))) { if ((0 == mifare_classic_connect(tag)) && (0 == mifare_classic_authenticate(tag, block, default_keys[i], MFC_KEY_B))) {
if ((1 == mifare_classic_get_trailer_block_permission (tag, block, MCAB_WRITE_KEYA, MFC_KEY_B)) && if ((1 == mifare_classic_get_trailer_block_permission(tag, block, MCAB_WRITE_KEYA, MFC_KEY_B)) &&
(1 == mifare_classic_get_trailer_block_permission (tag, block, MCAB_WRITE_ACCESS_BITS, MFC_KEY_B)) && (1 == mifare_classic_get_trailer_block_permission(tag, block, MCAB_WRITE_ACCESS_BITS, MFC_KEY_B)) &&
(1 == mifare_classic_get_trailer_block_permission (tag, block, MCAB_WRITE_KEYB, MFC_KEY_B))) { (1 == mifare_classic_get_trailer_block_permission(tag, block, MCAB_WRITE_KEYB, MFC_KEY_B))) {
memcpy (key, &default_keys[i], sizeof (MifareClassicKey)); memcpy(key, &default_keys[i], sizeof(MifareClassicKey));
*key_type = MFC_KEY_B; *key_type = MFC_KEY_B;
return 1; return 1;
} }
} }
mifare_classic_disconnect (tag); mifare_classic_disconnect(tag);
} }
warnx ("No known authentication key for sector 0x%02x\n", sector); warnx("No known authentication key for sector 0x%02x\n", sector);
return 0; return 0;
} }
static int static int
fix_mad_trailer_block (nfc_device *device, FreefareTag tag, MifareClassicSectorNumber sector, MifareClassicKey key, MifareClassicKeyType key_type) fix_mad_trailer_block(nfc_device *device, FreefareTag tag, MifareClassicSectorNumber sector, MifareClassicKey key, MifareClassicKeyType key_type)
{ {
MifareClassicBlock block; MifareClassicBlock block;
mifare_classic_trailer_block (&block, mad_public_key_a, 0x0, 0x1, 0x1, 0x6, 0x00, default_keyb); mifare_classic_trailer_block(&block, mad_public_key_a, 0x0, 0x1, 0x1, 0x6, 0x00, default_keyb);
if (mifare_classic_authenticate (tag, mifare_classic_sector_last_block (sector), key, key_type) < 0) { if (mifare_classic_authenticate(tag, mifare_classic_sector_last_block(sector), key, key_type) < 0) {
nfc_perror (device, "fix_mad_trailer_block mifare_classic_authenticate"); nfc_perror(device, "fix_mad_trailer_block mifare_classic_authenticate");
return -1; return -1;
} }
if (mifare_classic_write (tag, mifare_classic_sector_last_block (sector), block) < 0) { if (mifare_classic_write(tag, mifare_classic_sector_last_block(sector), block) < 0) {
nfc_perror (device, "mifare_classic_write"); nfc_perror(device, "mifare_classic_write");
return -1; return -1;
} }
return 0; return 0;
@ -125,10 +125,10 @@ fix_mad_trailer_block (nfc_device *device, FreefareTag tag, MifareClassicSectorN
static void static void
usage(char *progname) usage(char *progname)
{ {
fprintf (stderr, "usage: %s -i FILE\n", progname); fprintf(stderr, "usage: %s -i FILE\n", progname);
fprintf (stderr, "\nOptions:\n"); fprintf(stderr, "\nOptions:\n");
fprintf (stderr, " -y Do not ask for confirmation\n"); fprintf(stderr, " -y Do not ask for confirmation\n");
fprintf (stderr, " -i Use FILE as NDEF message to write on card (\"-\" = stdin)\n"); fprintf(stderr, " -i Use FILE as NDEF message to write on card (\"-\" = stdin)\n");
} }
int int
@ -142,11 +142,11 @@ main(int argc, char *argv[])
int ch; int ch;
char *ndef_input = NULL; char *ndef_input = NULL;
while ((ch = getopt (argc, argv, "hyi:")) != -1) { while ((ch = getopt(argc, argv, "hyi:")) != -1) {
switch (ch) { switch (ch) {
case 'h': case 'h':
usage(argv[0]); usage(argv[0]);
exit (EXIT_SUCCESS); exit(EXIT_SUCCESS);
break; break;
case 'y': case 'y':
write_options.interactive = false; write_options.interactive = false;
@ -156,81 +156,81 @@ main(int argc, char *argv[])
break; break;
case '?': case '?':
if (optopt == 'i') if (optopt == 'i')
fprintf (stderr, "Option -%c requires an argument.\n", optopt); fprintf(stderr, "Option -%c requires an argument.\n", optopt);
/* FALLTHROUGH */ /* FALLTHROUGH */
default: default:
usage (argv[0]); usage(argv[0]);
exit (EXIT_FAILURE); exit(EXIT_FAILURE);
} }
} }
if (ndef_input == NULL) { if (ndef_input == NULL) {
ndef_msg = (uint8_t*)ndef_default_msg; ndef_msg = (uint8_t *)ndef_default_msg;
ndef_msg_len = sizeof(ndef_default_msg); ndef_msg_len = sizeof(ndef_default_msg);
} else { } else {
FILE* ndef_stream = NULL; FILE *ndef_stream = NULL;
if ((strlen (ndef_input) == 1) && (ndef_input[0] == '-')) { if ((strlen(ndef_input) == 1) && (ndef_input[0] == '-')) {
// FIXME stdin as input have to be readed and buffered in ndef_msg // FIXME stdin as input have to be readed and buffered in ndef_msg
ndef_stream = stdin; ndef_stream = stdin;
fprintf (stderr, "stdin as NDEF is not implemented"); fprintf(stderr, "stdin as NDEF is not implemented");
exit (EXIT_FAILURE); exit(EXIT_FAILURE);
} else { } else {
ndef_stream = fopen(ndef_input, "rb"); ndef_stream = fopen(ndef_input, "rb");
if (!ndef_stream) { if (!ndef_stream) {
fprintf (stderr, "Could not open file %s.\n", ndef_input); fprintf(stderr, "Could not open file %s.\n", ndef_input);
exit (EXIT_FAILURE); exit(EXIT_FAILURE);
} }
fseek(ndef_stream, 0L, SEEK_END); fseek(ndef_stream, 0L, SEEK_END);
ndef_msg_len = ftell(ndef_stream); ndef_msg_len = ftell(ndef_stream);
fseek(ndef_stream, 0L, SEEK_SET); fseek(ndef_stream, 0L, SEEK_SET);
if (!(ndef_msg = malloc (ndef_msg_len))) { if (!(ndef_msg = malloc(ndef_msg_len))) {
err (EXIT_FAILURE, "malloc"); err(EXIT_FAILURE, "malloc");
} }
if (fread (ndef_msg, 1, ndef_msg_len, ndef_stream) != ndef_msg_len) { if (fread(ndef_msg, 1, ndef_msg_len, ndef_stream) != ndef_msg_len) {
fprintf (stderr, "Could not read NDEF from file: %s\n", ndef_input); fprintf(stderr, "Could not read NDEF from file: %s\n", ndef_input);
fclose (ndef_stream); fclose(ndef_stream);
free (ndef_msg); free(ndef_msg);
exit (EXIT_FAILURE); exit(EXIT_FAILURE);
} }
fclose (ndef_stream); fclose(ndef_stream);
} }
} }
printf ("NDEF file is %zu bytes long.\n", ndef_msg_len); printf("NDEF file is %zu bytes long.\n", ndef_msg_len);
struct mifare_classic_key_and_type *card_write_keys; struct mifare_classic_key_and_type *card_write_keys;
if (!(card_write_keys = malloc (40 * sizeof (*card_write_keys)))) { if (!(card_write_keys = malloc(40 * sizeof(*card_write_keys)))) {
err (EXIT_FAILURE, "malloc"); err(EXIT_FAILURE, "malloc");
} }
nfc_connstring devices[8]; nfc_connstring devices[8];
size_t device_count; size_t device_count;
nfc_context *context; nfc_context *context;
nfc_init (&context); nfc_init(&context);
if (context == NULL) if (context == NULL)
errx(EXIT_FAILURE, "Unable to init libnfc (malloc)"); errx(EXIT_FAILURE, "Unable to init libnfc (malloc)");
device_count = nfc_list_devices (context, devices, 8); device_count = nfc_list_devices(context, devices, 8);
if (device_count <= 0) if (device_count <= 0)
errx (EXIT_FAILURE, "No NFC device found."); errx(EXIT_FAILURE, "No NFC device found.");
for (size_t d = 0; d < device_count; d++) { for (size_t d = 0; d < device_count; d++) {
device = nfc_open (context, devices[d]); device = nfc_open(context, devices[d]);
if (!device) { if (!device) {
warnx ("nfc_open() failed."); warnx("nfc_open() failed.");
error = EXIT_FAILURE; error = EXIT_FAILURE;
continue; continue;
} }
tags = freefare_get_tags (device); tags = freefare_get_tags(device);
if (!tags) { if (!tags) {
nfc_close (device); nfc_close(device);
errx (EXIT_FAILURE, "Error listing MIFARE classic tag."); errx(EXIT_FAILURE, "Error listing MIFARE classic tag.");
} }
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 MIFARE_CLASSIC_1K: case MIFARE_CLASSIC_1K:
case MIFARE_CLASSIC_4K: case MIFARE_CLASSIC_4K:
break; break;
@ -238,35 +238,35 @@ main(int argc, char *argv[])
continue; continue;
} }
char *tag_uid = freefare_get_tag_uid (tags[i]); char *tag_uid = freefare_get_tag_uid(tags[i]);
char buffer[BUFSIZ]; char buffer[BUFSIZ];
printf ("Found %s with UID %s. ", freefare_get_tag_friendly_name (tags[i]), tag_uid); printf("Found %s with UID %s. ", freefare_get_tag_friendly_name(tags[i]), tag_uid);
bool write_ndef = true; bool write_ndef = true;
if (write_options.interactive) { if (write_options.interactive) {
printf ("Write NDEF [yN] "); printf("Write NDEF [yN] ");
fgets (buffer, BUFSIZ, stdin); fgets(buffer, BUFSIZ, stdin);
write_ndef = ((buffer[0] == 'y') || (buffer[0] == 'Y')); write_ndef = ((buffer[0] == 'y') || (buffer[0] == 'Y'));
} else { } else {
printf ("\n"); printf("\n");
} }
for (int n = 0; n < 40; n++) { for (int n = 0; n < 40; n++) {
memcpy(card_write_keys[n].key, transport_key, sizeof (transport_key)); memcpy(card_write_keys[n].key, transport_key, sizeof(transport_key));
card_write_keys[n].type = MFC_KEY_A; card_write_keys[n].type = MFC_KEY_A;
} }
if (write_ndef) { if (write_ndef) {
switch (freefare_get_tag_type (tags[i])) { switch (freefare_get_tag_type(tags[i])) {
case MIFARE_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 MIFARE_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;
} }
@ -278,24 +278,24 @@ 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 MIFARE_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;
goto error; goto error;
} }
memcpy (&(card_write_keys[0x10].key), &default_keyb, sizeof (MifareClassicKey)); memcpy(&(card_write_keys[0x10].key), &default_keyb, sizeof(MifareClassicKey));
card_write_keys[0x10].type = MFC_KEY_B; card_write_keys[0x10].type = MFC_KEY_B;
} }
/* fallthrough */ /* fallthrough */
case MIFARE_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;
goto error; goto error;
} }
memcpy (&(card_write_keys[0x00].key), &default_keyb, sizeof (MifareClassicKey)); memcpy(&(card_write_keys[0x00].key), &default_keyb, sizeof(MifareClassicKey));
card_write_keys[0x00].type = MFC_KEY_B; card_write_keys[0x00].type = MFC_KEY_B;
} }
break; break;
@ -306,7 +306,7 @@ main(int argc, char *argv[])
} }
size_t encoded_size; size_t encoded_size;
uint8_t *tlv_data = tlv_encode (3, ndef_msg, ndef_msg_len, &encoded_size); uint8_t *tlv_data = tlv_encode(3, ndef_msg, ndef_msg_len, &encoded_size);
/* /*
* At his point, we should have collected all information needed to * At his point, we should have collected all information needed to
@ -314,38 +314,38 @@ main(int argc, char *argv[])
*/ */
// If the card already has a MAD, load it. // If the card already has a MAD, load it.
if ((mad = mad_read (tags[i]))) { if ((mad = mad_read(tags[i]))) {
// If our application already exists, erase it. // If our application already exists, erase it.
MifareClassicSectorNumber *sectors, *p; MifareClassicSectorNumber *sectors, *p;
sectors = p = mifare_application_find (mad, mad_nfcforum_aid); sectors = p = mifare_application_find(mad, mad_nfcforum_aid);
if (sectors) { if (sectors) {
while (*p) { while (*p) {
if (mifare_classic_authenticate (tags[i], mifare_classic_sector_last_block(*p), default_keyb, MFC_KEY_B) < 0) { if (mifare_classic_authenticate(tags[i], mifare_classic_sector_last_block(*p), default_keyb, MFC_KEY_B) < 0) {
nfc_perror (device, "mifare_classic_authenticate"); nfc_perror(device, "mifare_classic_authenticate");
error = 1; error = 1;
goto error; goto error;
} }
if (mifare_classic_format_sector (tags[i], *p) < 0) { if (mifare_classic_format_sector(tags[i], *p) < 0) {
nfc_perror (device, "mifare_classic_format_sector"); nfc_perror(device, "mifare_classic_format_sector");
error = 1; error = 1;
goto error; goto error;
} }
p++; p++;
} }
} }
free (sectors); free(sectors);
mifare_application_free (mad, mad_nfcforum_aid); mifare_application_free(mad, mad_nfcforum_aid);
} 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]) == MIFARE_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;
} }
MifareClassicSectorNumber max_s = 0; MifareClassicSectorNumber max_s = 0;
switch (freefare_get_tag_type (tags[i])) { switch (freefare_get_tag_type(tags[i])) {
case MIFARE_CLASSIC_1K: case MIFARE_CLASSIC_1K:
max_s = 15; max_s = 15;
break; break;
@ -360,13 +360,13 @@ main(int argc, char *argv[])
// Mark unusable sectors as so // Mark unusable sectors as so
for (size_t s = max_s; s; s--) { for (size_t s = max_s; s; s--) {
if (s == 0x10) continue; if (s == 0x10) continue;
if (!search_sector_key (tags[i], s, &(card_write_keys[s].key), &(card_write_keys[s].type))) { if (!search_sector_key(tags[i], s, &(card_write_keys[s].key), &(card_write_keys[s].type))) {
mad_set_aid (mad, s, mad_defect_aid); mad_set_aid(mad, s, mad_defect_aid);
} else if ((memcmp (card_write_keys[s].key, transport_key, sizeof (transport_key)) != 0) && } else if ((memcmp(card_write_keys[s].key, transport_key, sizeof(transport_key)) != 0) &&
(card_write_keys[s].type != MFC_KEY_A)) { (card_write_keys[s].type != MFC_KEY_A)) {
// Revert to transport configuration // Revert to transport configuration
if (mifare_classic_format_sector (tags[i], s) < 0) { if (mifare_classic_format_sector(tags[i], s) < 0) {
nfc_perror (device, "mifare_classic_format_sector"); nfc_perror(device, "mifare_classic_format_sector");
error = 1; error = 1;
goto error; goto error;
} }
@ -374,61 +374,61 @@ main(int argc, char *argv[])
} }
} }
MifareClassicSectorNumber *sectors = mifare_application_alloc (mad, mad_nfcforum_aid, encoded_size); MifareClassicSectorNumber *sectors = mifare_application_alloc(mad, mad_nfcforum_aid, encoded_size);
if (!sectors) { if (!sectors) {
nfc_perror (device, "mifare_application_alloc"); nfc_perror(device, "mifare_application_alloc");
error = EXIT_FAILURE; error = EXIT_FAILURE;
goto error; goto error;
} }
if (mad_write (tags[i], mad, card_write_keys[0x00].key, card_write_keys[0x10].key) < 0) { if (mad_write(tags[i], mad, card_write_keys[0x00].key, card_write_keys[0x10].key) < 0) {
nfc_perror (device, "mad_write"); nfc_perror(device, "mad_write");
error = EXIT_FAILURE; error = EXIT_FAILURE;
goto error; goto error;
} }
int s = 0; int s = 0;
while (sectors[s]) { while (sectors[s]) {
MifareClassicBlockNumber block = mifare_classic_sector_last_block (sectors[s]); MifareClassicBlockNumber block = mifare_classic_sector_last_block(sectors[s]);
MifareClassicBlock block_data; MifareClassicBlock block_data;
mifare_classic_trailer_block (&block_data, mifare_classic_nfcforum_public_key_a, 0x0, 0x0, 0x0, 0x6, 0x40, default_keyb); mifare_classic_trailer_block(&block_data, mifare_classic_nfcforum_public_key_a, 0x0, 0x0, 0x0, 0x6, 0x40, default_keyb);
if (mifare_classic_authenticate (tags[i], block, card_write_keys[sectors[s]].key, card_write_keys[sectors[s]].type) < 0) { if (mifare_classic_authenticate(tags[i], block, card_write_keys[sectors[s]].key, card_write_keys[sectors[s]].type) < 0) {
nfc_perror (device, "mifare_classic_authenticate"); nfc_perror(device, "mifare_classic_authenticate");
error = EXIT_FAILURE; error = EXIT_FAILURE;
goto error; goto error;
} }
if (mifare_classic_write (tags[i], block, block_data) < 0) { if (mifare_classic_write(tags[i], block, block_data) < 0) {
nfc_perror (device, "mifare_classic_write"); nfc_perror(device, "mifare_classic_write");
error = EXIT_FAILURE; error = EXIT_FAILURE;
goto error; goto error;
} }
s++; s++;
} }
if ((ssize_t) encoded_size != mifare_application_write (tags[i], mad, mad_nfcforum_aid, tlv_data, encoded_size, default_keyb, MCAB_WRITE_KEYB)) { if ((ssize_t) encoded_size != mifare_application_write(tags[i], mad, mad_nfcforum_aid, tlv_data, encoded_size, default_keyb, MCAB_WRITE_KEYB)) {
nfc_perror (device, "mifare_application_write"); nfc_perror(device, "mifare_application_write");
error = EXIT_FAILURE; error = EXIT_FAILURE;
goto error; goto error;
} }
free (sectors); free(sectors);
free (tlv_data); free(tlv_data);
free (mad); free(mad);
} }
error: error:
free (tag_uid); free(tag_uid);
} }
if (ndef_msg != ndef_default_msg) if (ndef_msg != ndef_default_msg)
free (ndef_msg); free(ndef_msg);
freefare_free_tags (tags); freefare_free_tags(tags);
nfc_close (device); nfc_close(device);
} }
free (card_write_keys); free(card_write_keys);
nfc_exit (context); nfc_exit(context);
exit (error); exit(error);
} }

View file

@ -34,105 +34,105 @@ main(int argc, char *argv[])
FreefareTag *tags = NULL; FreefareTag *tags = NULL;
if (argc > 1) if (argc > 1)
errx (EXIT_FAILURE, "usage: %s", argv[0]); errx(EXIT_FAILURE, "usage: %s", argv[0]);
nfc_connstring devices[8]; nfc_connstring devices[8];
size_t device_count; size_t device_count;
nfc_context *context; nfc_context *context;
nfc_init (&context); nfc_init(&context);
if (context == NULL) if (context == NULL)
errx(EXIT_FAILURE, "Unable to init libnfc (malloc)"); errx(EXIT_FAILURE, "Unable to init libnfc (malloc)");
device_count = nfc_list_devices (context, devices, 8); device_count = nfc_list_devices(context, devices, 8);
if (device_count <= 0) if (device_count <= 0)
errx (EXIT_FAILURE, "No NFC device found."); errx(EXIT_FAILURE, "No NFC device found.");
for (size_t d = 0; d < device_count; d++) { for (size_t d = 0; d < device_count; d++) {
device = nfc_open (context, devices[d]); device = nfc_open(context, devices[d]);
if (!device) { if (!device) {
warnx ("nfc_open() failed."); warnx("nfc_open() failed.");
error = EXIT_FAILURE; error = EXIT_FAILURE;
continue; continue;
} }
tags = freefare_get_tags (device); tags = freefare_get_tags(device);
if (!tags) { if (!tags) {
nfc_close (device); nfc_close(device);
errx (EXIT_FAILURE, "Error listing tags."); errx(EXIT_FAILURE, "Error listing tags.");
} }
for (int i = 0; (!error) && tags[i]; i++) { for (int i = 0; (!error) && tags[i]; i++) {
if (MIFARE_DESFIRE != freefare_get_tag_type (tags[i])) if (MIFARE_DESFIRE != freefare_get_tag_type(tags[i]))
continue; continue;
int res; int res;
char *tag_uid = freefare_get_tag_uid (tags[i]); char *tag_uid = freefare_get_tag_uid(tags[i]);
res = mifare_desfire_connect (tags[i]); res = mifare_desfire_connect(tags[i]);
if (res < 0) { if (res < 0) {
warnx ("Can't connect to Mifare DESFire target."); warnx("Can't connect to Mifare DESFire target.");
error = EXIT_FAILURE; error = EXIT_FAILURE;
break; break;
} }
MifareDESFireKey key = mifare_desfire_des_key_new_with_version (key_data_null); MifareDESFireKey key = mifare_desfire_des_key_new_with_version(key_data_null);
res = mifare_desfire_authenticate (tags[i], 0, key); res = mifare_desfire_authenticate(tags[i], 0, key);
if (res < 0) if (res < 0)
errx (EXIT_FAILURE, "Authentication on master application failed"); errx(EXIT_FAILURE, "Authentication on master application failed");
MadAid mad_aid = { 0x12, 0x34 }; MadAid mad_aid = { 0x12, 0x34 };
MifareDESFireAID aid = mifare_desfire_aid_new_with_mad_aid (mad_aid, 0x5); MifareDESFireAID aid = mifare_desfire_aid_new_with_mad_aid(mad_aid, 0x5);
res = mifare_desfire_create_application (tags[i], aid, 0xFF, 0x1); res = mifare_desfire_create_application(tags[i], aid, 0xFF, 0x1);
if (res < 0) if (res < 0)
errx (EXIT_FAILURE, "Application creation failed"); errx(EXIT_FAILURE, "Application creation failed");
res = mifare_desfire_select_application (tags[i], aid); res = mifare_desfire_select_application(tags[i], aid);
if (res < 0) if (res < 0)
errx (EXIT_FAILURE, "Application selection failed"); errx(EXIT_FAILURE, "Application selection failed");
res = mifare_desfire_authenticate (tags[i], 0, key); res = mifare_desfire_authenticate(tags[i], 0, key);
if (res < 0) if (res < 0)
errx (EXIT_FAILURE, "Authentication on application failed"); errx(EXIT_FAILURE, "Authentication on application failed");
res = mifare_desfire_create_std_data_file (tags[i], 1, MDCM_ENCIPHERED, 0x0000, 20); res = mifare_desfire_create_std_data_file(tags[i], 1, MDCM_ENCIPHERED, 0x0000, 20);
if (res < 0) if (res < 0)
errx (EXIT_FAILURE, "File creation failed"); errx(EXIT_FAILURE, "File creation failed");
const char *s= "Hello World"; const char *s = "Hello World";
res = mifare_desfire_write_data (tags[i], 1, 0, strlen (s), s); res = mifare_desfire_write_data(tags[i], 1, 0, strlen(s), s);
if (res < 0) if (res < 0)
errx (EXIT_FAILURE, "File write failed"); errx(EXIT_FAILURE, "File write failed");
char buffer[20]; char buffer[20];
res = mifare_desfire_read_data (tags[i], 1, 0, 0, buffer); res = mifare_desfire_read_data(tags[i], 1, 0, 0, buffer);
if (res < 0) if (res < 0)
errx (EXIT_FAILURE, "File read failed"); errx(EXIT_FAILURE, "File read failed");
res = mifare_desfire_select_application (tags[i], NULL); res = mifare_desfire_select_application(tags[i], NULL);
if (res < 0) if (res < 0)
errx (EXIT_FAILURE, "Master application selection failed"); errx(EXIT_FAILURE, "Master application selection failed");
res = mifare_desfire_authenticate (tags[i], 0, key); res = mifare_desfire_authenticate(tags[i], 0, key);
if (res < 0) if (res < 0)
errx (EXIT_FAILURE, "Authentication on master application failed"); errx(EXIT_FAILURE, "Authentication on master application failed");
res = mifare_desfire_format_picc (tags[i]); res = mifare_desfire_format_picc(tags[i]);
if (res < 0) if (res < 0)
errx (EXIT_FAILURE, "PICC format failed"); errx(EXIT_FAILURE, "PICC format failed");
mifare_desfire_key_free (key); mifare_desfire_key_free(key);
free (tag_uid); free(tag_uid);
free (aid); free(aid);
mifare_desfire_disconnect (tags[i]); mifare_desfire_disconnect(tags[i]);
} }
freefare_free_tags (tags); freefare_free_tags(tags);
nfc_close (device); nfc_close(device);
} }
nfc_exit (context); nfc_exit(context);
exit (error); exit(error);
} /* main() */ } /* main() */

View file

@ -50,11 +50,11 @@ struct {
static void static void
usage(char *progname) usage(char *progname)
{ {
fprintf (stderr, "This application turns Mifare DESFire targets into NFC Forum Type 4 Tags.\n"); fprintf(stderr, "This application turns Mifare DESFire targets into NFC Forum Type 4 Tags.\n");
fprintf (stderr, "usage: %s [-y] [-K 11223344AABBCCDD]\n", progname); fprintf(stderr, "usage: %s [-y] [-K 11223344AABBCCDD]\n", progname);
fprintf (stderr, "\nOptions:\n"); fprintf(stderr, "\nOptions:\n");
fprintf (stderr, " -y Do not ask for confirmation\n"); fprintf(stderr, " -y Do not ask for confirmation\n");
fprintf (stderr, " -K Provide another PICC key than the default one\n"); fprintf(stderr, " -K Provide another PICC key than the default one\n");
} }
int int
@ -65,31 +65,31 @@ main(int argc, char *argv[])
nfc_device *device = NULL; nfc_device *device = NULL;
FreefareTag *tags = NULL; FreefareTag *tags = NULL;
while ((ch = getopt (argc, argv, "hyK:")) != -1) { while ((ch = getopt(argc, argv, "hyK:")) != -1) {
switch (ch) { switch (ch) {
case 'h': case 'h':
usage(argv[0]); usage(argv[0]);
exit (EXIT_SUCCESS); exit(EXIT_SUCCESS);
break; break;
case 'y': case 'y':
create_options.interactive = false; create_options.interactive = false;
break; break;
case 'K': case 'K':
if (strlen(optarg) != 16) { if (strlen(optarg) != 16) {
usage(argv[0]); usage(argv[0]);
exit (EXIT_FAILURE); exit(EXIT_FAILURE);
} }
uint64_t n = strtoull(optarg, NULL, 16); uint64_t n = strtoull(optarg, NULL, 16);
int i; int i;
for (i=7; i>=0; i--) { for (i = 7; i >= 0; i--) {
key_data_picc[i] = (uint8_t) n; key_data_picc[i] = (uint8_t) n;
n >>= 8; n >>= 8;
} }
break; break;
default: default:
usage(argv[0]); usage(argv[0]);
exit (EXIT_FAILURE); exit(EXIT_FAILURE);
} }
} }
// Remaining args, if any, are in argv[optind .. (argc-1)] // Remaining args, if any, are in argv[optind .. (argc-1)]
@ -97,54 +97,54 @@ main(int argc, char *argv[])
size_t device_count; size_t device_count;
nfc_context *context; nfc_context *context;
nfc_init (&context); nfc_init(&context);
if (context == NULL) if (context == NULL)
errx(EXIT_FAILURE, "Unable to init libnfc (malloc)"); errx(EXIT_FAILURE, "Unable to init libnfc (malloc)");
device_count = nfc_list_devices (context, devices, 8); device_count = nfc_list_devices(context, devices, 8);
if (device_count <= 0) if (device_count <= 0)
errx (EXIT_FAILURE, "No NFC device found."); errx(EXIT_FAILURE, "No NFC device found.");
for (size_t d = 0; d < device_count; d++) { for (size_t d = 0; d < device_count; d++) {
device = nfc_open (context, devices[d]); device = nfc_open(context, devices[d]);
if (!device) { if (!device) {
warnx ("nfc_open() failed."); warnx("nfc_open() failed.");
error = EXIT_FAILURE; error = EXIT_FAILURE;
continue; continue;
} }
tags = freefare_get_tags (device); tags = freefare_get_tags(device);
if (!tags) { if (!tags) {
nfc_close (device); nfc_close(device);
errx (EXIT_FAILURE, "Error listing tags."); errx(EXIT_FAILURE, "Error listing tags.");
} }
for (int i = 0; (!error) && tags[i]; i++) { for (int i = 0; (!error) && tags[i]; i++) {
if (MIFARE_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]);
char buffer[BUFSIZ]; char buffer[BUFSIZ];
int res; int res;
res = mifare_desfire_connect (tags[i]); res = mifare_desfire_connect(tags[i]);
if (res < 0) { if (res < 0) {
warnx ("Can't connect to Mifare DESFire target."); warnx("Can't connect to Mifare DESFire target.");
error = EXIT_FAILURE; error = EXIT_FAILURE;
break; break;
} }
// We've to track DESFire version as NDEF mapping is different // We've to track DESFire version as NDEF mapping is different
struct mifare_desfire_version_info info; struct mifare_desfire_version_info info;
res = mifare_desfire_get_version (tags[i], &info); res = mifare_desfire_get_version(tags[i], &info);
if (res < 0) { if (res < 0) {
freefare_perror (tags[i], "mifare_desfire_get_version"); freefare_perror(tags[i], "mifare_desfire_get_version");
error = 1; error = 1;
break; break;
} }
printf ("Found %s with UID %s and software v%d.%d\n", freefare_get_tag_friendly_name (tags[i]), tag_uid, info.software.version_major, info.software.version_minor); printf("Found %s with UID %s and software v%d.%d\n", freefare_get_tag_friendly_name(tags[i]), tag_uid, info.software.version_major, info.software.version_minor);
bool create_ndef = true; bool create_ndef = true;
int ndef_mapping; int ndef_mapping;
switch (info.software.version_major) { switch (info.software.version_major) {
@ -159,11 +159,11 @@ main(int argc, char *argv[])
ndef_mapping = 2; ndef_mapping = 2;
} }
if (create_options.interactive) { if (create_options.interactive) {
printf ("Create NDEF app v%d [yN] ", ndef_mapping); printf("Create NDEF app v%d [yN] ", ndef_mapping);
fgets (buffer, BUFSIZ, stdin); fgets(buffer, BUFSIZ, stdin);
create_ndef = ((buffer[0] == 'y') || (buffer[0] == 'Y')); create_ndef = ((buffer[0] == 'y') || (buffer[0] == 'Y'));
} else { } else {
printf ("\n"); printf("\n");
} }
if (create_ndef) { if (create_ndef) {
@ -172,24 +172,24 @@ main(int argc, char *argv[])
// Send Mifare DESFire Select Application with AID equal to 000000h to select the PICC level // Send Mifare DESFire Select Application with AID equal to 000000h to select the PICC level
res = mifare_desfire_select_application(tags[i], NULL); res = mifare_desfire_select_application(tags[i], NULL);
if (res < 0) if (res < 0)
errx (EXIT_FAILURE, "Application selection failed"); errx(EXIT_FAILURE, "Application selection failed");
MifareDESFireKey key_picc; MifareDESFireKey key_picc;
MifareDESFireKey key_app; MifareDESFireKey key_app;
key_picc = mifare_desfire_des_key_new_with_version (key_data_picc); key_picc = mifare_desfire_des_key_new_with_version(key_data_picc);
key_app = mifare_desfire_des_key_new_with_version (key_data_app); key_app = mifare_desfire_des_key_new_with_version(key_data_app);
// Authentication with PICC master key MAY be needed to issue ChangeKeySettings command // Authentication with PICC master key MAY be needed to issue ChangeKeySettings command
res = mifare_desfire_authenticate (tags[i], 0, key_picc); res = mifare_desfire_authenticate(tags[i], 0, key_picc);
if (res < 0) if (res < 0)
errx (EXIT_FAILURE, "Authentication with PICC master key failed"); errx(EXIT_FAILURE, "Authentication with PICC master key failed");
MifareDESFireAID aid; MifareDESFireAID aid;
if (ndef_mapping == 1) { if (ndef_mapping == 1) {
uint8_t key_settings; uint8_t key_settings;
uint8_t max_keys; uint8_t max_keys;
mifare_desfire_get_key_settings(tags[i], &key_settings,&max_keys); mifare_desfire_get_key_settings(tags[i], &key_settings, &max_keys);
if ((key_settings & 0x08) == 0x08){ if ((key_settings & 0x08) == 0x08) {
// Send Mifare DESFire ChangeKeySetting to change the PICC master key settings into : // Send Mifare DESFire ChangeKeySetting to change the PICC master key settings into :
// bit7-bit4 equal to 0000b // bit7-bit4 equal to 0000b
@ -197,33 +197,33 @@ main(int argc, char *argv[])
// bit2 equal to 0b, CreateApplication and DeleteApplication commands are allowed with PICC master key authentication // bit2 equal to 0b, CreateApplication and DeleteApplication commands are allowed with PICC master key authentication
// bit1 equal to 0b, GetApplicationIDs, and GetKeySettings are allowed with PICC master key authentication // bit1 equal to 0b, GetApplicationIDs, and GetKeySettings are allowed with PICC master key authentication
// bit0 equal to Xb, PICC masterkey MAY be frozen or changeable // bit0 equal to Xb, PICC masterkey MAY be frozen or changeable
res = mifare_desfire_change_key_settings (tags[i],0x09); res = mifare_desfire_change_key_settings(tags[i], 0x09);
if (res < 0) if (res < 0)
errx (EXIT_FAILURE, "ChangeKeySettings failed"); errx(EXIT_FAILURE, "ChangeKeySettings failed");
} }
// Mifare DESFire Create Application with AID equal to EEEE10h, key settings equal to 0x09, NumOfKeys equal to 01h // Mifare DESFire Create Application with AID equal to EEEE10h, key settings equal to 0x09, NumOfKeys equal to 01h
aid = mifare_desfire_aid_new(0xEEEE10); aid = mifare_desfire_aid_new(0xEEEE10);
res = mifare_desfire_create_application (tags[i], aid, 0x09, 1); res = mifare_desfire_create_application(tags[i], aid, 0x09, 1);
if (res < 0) if (res < 0)
errx (EXIT_FAILURE, "Application creation failed. Try mifare-desfire-format before running %s.", argv[0]); errx(EXIT_FAILURE, "Application creation failed. Try mifare-desfire-format before running %s.", argv[0]);
// Mifare DESFire SelectApplication (Select previously creates application) // Mifare DESFire SelectApplication (Select previously creates application)
res = mifare_desfire_select_application(tags[i], aid); res = mifare_desfire_select_application(tags[i], aid);
if (res < 0) if (res < 0)
errx (EXIT_FAILURE, "Application selection failed"); errx(EXIT_FAILURE, "Application selection failed");
free (aid); free(aid);
// Authentication with NDEF Tag Application master key (Authentication with key 0) // Authentication with NDEF Tag Application master key (Authentication with key 0)
res = mifare_desfire_authenticate (tags[i], 0, key_app); res = mifare_desfire_authenticate(tags[i], 0, key_app);
if (res < 0) if (res < 0)
errx (EXIT_FAILURE, "Authentication with NDEF Tag Application master key failed"); errx(EXIT_FAILURE, "Authentication with NDEF Tag Application master key failed");
// Mifare DESFire ChangeKeySetting with key settings equal to 00001001b // Mifare DESFire ChangeKeySetting with key settings equal to 00001001b
res = mifare_desfire_change_key_settings (tags[i],0x09); res = mifare_desfire_change_key_settings(tags[i], 0x09);
if (res < 0) if (res < 0)
errx (EXIT_FAILURE, "ChangeKeySettings failed"); errx(EXIT_FAILURE, "ChangeKeySettings failed");
// Mifare DESFire CreateStdDataFile with FileNo equal to 03h (CC File DESFire FID), ComSet equal to 00h, // Mifare DESFire CreateStdDataFile with FileNo equal to 03h (CC File DESFire FID), ComSet equal to 00h,
// AccesRights equal to E000h, File Size bigger equal to 00000Fh // AccesRights equal to E000h, File Size bigger equal to 00000Fh
res = mifare_desfire_create_std_data_file(tags[i],0x03,MDCM_PLAIN,0xE000,0x00000F); res = mifare_desfire_create_std_data_file(tags[i], 0x03, MDCM_PLAIN, 0xE000, 0x00000F);
if (res < 0) if (res < 0)
errx (EXIT_FAILURE, "CreateStdDataFile failed"); errx(EXIT_FAILURE, "CreateStdDataFile failed");
// Mifare DESFire WriteData to write the content of the CC File with CClEN equal to 000Fh, // Mifare DESFire WriteData to write the content of the CC File with CClEN equal to 000Fh,
// Mapping Version equal to 10h,MLe equal to 003Bh, MLc equal to 0034h, and NDEF File Control TLV // Mapping Version equal to 10h,MLe equal to 003Bh, MLc equal to 0034h, and NDEF File Control TLV
// equal to T =04h, L=06h, V=E1 04 (NDEF ISO FID=E104h) 0E E0 (NDEF File size =3808 Bytes) 00 (free read access) // equal to T =04h, L=06h, V=E1 04 (NDEF ISO FID=E104h) 0E E0 (NDEF File size =3808 Bytes) 00 (free read access)
@ -239,39 +239,38 @@ main(int argc, char *argv[])
0x00, // free read access 0x00, // free read access
0x00 // free write acces 0x00 // free write acces
}; };
res = mifare_desfire_write_data(tags[i],0x03,0,sizeof(capability_container_file_content),capability_container_file_content); res = mifare_desfire_write_data(tags[i], 0x03, 0, sizeof(capability_container_file_content), capability_container_file_content);
if (res>0){ if (res > 0) {
// Mifare DESFire CreateStdDataFile with FileNo equal to 04h (NDEF FileDESFire FID), CmmSet equal to 00h, AccessRigths // Mifare DESFire CreateStdDataFile with FileNo equal to 04h (NDEF FileDESFire FID), CmmSet equal to 00h, AccessRigths
// equal to EEE0h, FileSize equal to 000EE0h (3808 Bytes) // equal to EEE0h, FileSize equal to 000EE0h (3808 Bytes)
res = mifare_desfire_create_std_data_file(tags[i],0x04,MDCM_PLAIN,0xEEE0,0x000EE0); res = mifare_desfire_create_std_data_file(tags[i], 0x04, MDCM_PLAIN, 0xEEE0, 0x000EE0);
if (res < 0) if (res < 0)
errx (EXIT_FAILURE, "CreateStdDataFile failed"); errx(EXIT_FAILURE, "CreateStdDataFile failed");
} else { } else {
errx (EXIT_FAILURE, "Write CC file content failed"); errx(EXIT_FAILURE, "Write CC file content failed");
} }
} } else if (ndef_mapping == 2) {
else if (ndef_mapping == 2) {
// Mifare DESFire Create Application with AID equal to 000001h, key settings equal to 0x0F, NumOfKeys equal to 01h, // Mifare DESFire Create Application with AID equal to 000001h, key settings equal to 0x0F, NumOfKeys equal to 01h,
// 2 bytes File Identifiers supported, File-ID equal to E110h // 2 bytes File Identifiers supported, File-ID equal to E110h
aid = mifare_desfire_aid_new(0x000001); aid = mifare_desfire_aid_new(0x000001);
uint8_t app[] = {0xd2, 0x76, 0x00, 0x00, 0x85, 0x01, 0x01}; uint8_t app[] = {0xd2, 0x76, 0x00, 0x00, 0x85, 0x01, 0x01};
res = mifare_desfire_create_application_iso (tags[i], aid, 0x0F, 0x21, 0, 0xE110, app, sizeof (app)); res = mifare_desfire_create_application_iso(tags[i], aid, 0x0F, 0x21, 0, 0xE110, app, sizeof(app));
if (res < 0) if (res < 0)
errx (EXIT_FAILURE, "Application creation failed. Try mifare-desfire-format before running %s.", argv[0]); errx(EXIT_FAILURE, "Application creation failed. Try mifare-desfire-format before running %s.", argv[0]);
// Mifare DESFire SelectApplication (Select previously creates application) // Mifare DESFire SelectApplication (Select previously creates application)
res = mifare_desfire_select_application(tags[i], aid); res = mifare_desfire_select_application(tags[i], aid);
if (res < 0) if (res < 0)
errx (EXIT_FAILURE, "Application selection failed"); errx(EXIT_FAILURE, "Application selection failed");
free (aid); free(aid);
// Authentication with NDEF Tag Application master key (Authentication with key 0) // Authentication with NDEF Tag Application master key (Authentication with key 0)
res = mifare_desfire_authenticate (tags[i], 0, key_app); res = mifare_desfire_authenticate(tags[i], 0, key_app);
if (res < 0) if (res < 0)
errx (EXIT_FAILURE, "Authentication with NDEF Tag Application master key failed"); errx(EXIT_FAILURE, "Authentication with NDEF Tag Application master key failed");
// Mifare DESFire CreateStdDataFile with FileNo equal to 01h (DESFire FID), ComSet equal to 00h, // Mifare DESFire CreateStdDataFile with FileNo equal to 01h (DESFire FID), ComSet equal to 00h,
// AccesRights equal to E000h, File Size bigger equal to 00000Fh, ISO File ID equal to E103h // AccesRights equal to E000h, File Size bigger equal to 00000Fh, ISO File ID equal to E103h
res = mifare_desfire_create_std_data_file_iso(tags[i],0x01,MDCM_PLAIN,0xE000,0x00000F,0xE103); res = mifare_desfire_create_std_data_file_iso(tags[i], 0x01, MDCM_PLAIN, 0xE000, 0x00000F, 0xE103);
if (res < 0) if (res < 0)
errx (EXIT_FAILURE, "CreateStdDataFileIso failed"); errx(EXIT_FAILURE, "CreateStdDataFileIso failed");
// Mifare DESFire WriteData to write the content of the CC File with CClEN equal to 000Fh, // Mifare DESFire WriteData to write the content of the CC File with CClEN equal to 000Fh,
// Mapping Version equal to 20h,MLe equal to 003Bh, MLc equal to 0034h, and NDEF File Control TLV // Mapping Version equal to 20h,MLe equal to 003Bh, MLc equal to 0034h, and NDEF File Control TLV
// equal to T =04h, L=06h, V=E1 04 (NDEF ISO FID=E104h) 0xNNNN (NDEF File size = 0x0800/0x1000/0x1E00 bytes) // equal to T =04h, L=06h, V=E1 04 (NDEF ISO FID=E104h) 0xNNNN (NDEF File size = 0x0800/0x1000/0x1E00 bytes)
@ -295,26 +294,26 @@ main(int argc, char *argv[])
ndefmaxsize = 0x1E00; ndefmaxsize = 0x1E00;
capability_container_file_content[11] = ndefmaxsize >> 8; capability_container_file_content[11] = ndefmaxsize >> 8;
capability_container_file_content[12] = ndefmaxsize & 0xFF; capability_container_file_content[12] = ndefmaxsize & 0xFF;
res = mifare_desfire_write_data(tags[i],0x01,0,sizeof(capability_container_file_content),capability_container_file_content); res = mifare_desfire_write_data(tags[i], 0x01, 0, sizeof(capability_container_file_content), capability_container_file_content);
if (res>0){ if (res > 0) {
// Mifare DESFire CreateStdDataFile with FileNo equal to 02h (DESFire FID), CmmSet equal to 00h, AccessRigths // Mifare DESFire CreateStdDataFile with FileNo equal to 02h (DESFire FID), CmmSet equal to 00h, AccessRigths
// equal to EEE0h, FileSize equal to ndefmaxsize (0x000800, 0x001000 or 0x001E00) // equal to EEE0h, FileSize equal to ndefmaxsize (0x000800, 0x001000 or 0x001E00)
res = mifare_desfire_create_std_data_file_iso(tags[i],0x02,MDCM_PLAIN,0xEEE0,ndefmaxsize, 0xE104); res = mifare_desfire_create_std_data_file_iso(tags[i], 0x02, MDCM_PLAIN, 0xEEE0, ndefmaxsize, 0xE104);
if (res < 0) if (res < 0)
errx (EXIT_FAILURE, "CreateStdDataFileIso failed"); errx(EXIT_FAILURE, "CreateStdDataFileIso failed");
} else { } else {
errx (EXIT_FAILURE, "Write CC file content failed"); errx(EXIT_FAILURE, "Write CC file content failed");
} }
} }
mifare_desfire_key_free (key_picc); mifare_desfire_key_free(key_picc);
mifare_desfire_key_free (key_app); mifare_desfire_key_free(key_app);
} }
mifare_desfire_disconnect (tags[i]); mifare_desfire_disconnect(tags[i]);
free (tag_uid); free(tag_uid);
} }
freefare_free_tags (tags); freefare_free_tags(tags);
nfc_close (device); nfc_close(device);
} }
nfc_exit (context); nfc_exit(context);
exit (error); exit(error);
} }

View file

@ -44,10 +44,10 @@ struct {
static void static void
usage(char *progname) usage(char *progname)
{ {
fprintf (stderr, "usage: %s [-y] [-K 11223344AABBCCDD]\n", progname); fprintf(stderr, "usage: %s [-y] [-K 11223344AABBCCDD]\n", progname);
fprintf (stderr, "\nOptions:\n"); fprintf(stderr, "\nOptions:\n");
fprintf (stderr, " -y Do not ask for confirmation (dangerous)\n"); fprintf(stderr, " -y Do not ask for confirmation (dangerous)\n");
fprintf (stderr, " -K Provide another PICC key than the default one\n"); fprintf(stderr, " -K Provide another PICC key than the default one\n");
} }
int int
@ -58,11 +58,11 @@ main(int argc, char *argv[])
nfc_device *device = NULL; nfc_device *device = NULL;
FreefareTag *tags = NULL; FreefareTag *tags = NULL;
while ((ch = getopt (argc, argv, "hyK:")) != -1) { while ((ch = getopt(argc, argv, "hyK:")) != -1) {
switch (ch) { switch (ch) {
case 'h': case 'h':
usage(argv[0]); usage(argv[0]);
exit (EXIT_SUCCESS); exit(EXIT_SUCCESS);
break; break;
case 'y': case 'y':
configure_options.interactive = false; configure_options.interactive = false;
@ -70,18 +70,18 @@ main(int argc, char *argv[])
case 'K': case 'K':
if (strlen(optarg) != 16) { if (strlen(optarg) != 16) {
usage(argv[0]); usage(argv[0]);
exit (EXIT_FAILURE); exit(EXIT_FAILURE);
} }
uint64_t n = strtoull(optarg, NULL, 16); uint64_t n = strtoull(optarg, NULL, 16);
int i; int i;
for (i=7; i>=0; i--) { for (i = 7; i >= 0; i--) {
key_data_picc[i] = (uint8_t) n; key_data_picc[i] = (uint8_t) n;
n >>= 8; n >>= 8;
} }
break; break;
default: default:
usage(argv[0]); usage(argv[0]);
exit (EXIT_FAILURE); exit(EXIT_FAILURE);
} }
} }
// Remaining args, if any, are in argv[optind .. (argc-1)] // Remaining args, if any, are in argv[optind .. (argc-1)]
@ -90,94 +90,94 @@ main(int argc, char *argv[])
size_t device_count; size_t device_count;
nfc_context *context; nfc_context *context;
nfc_init (&context); nfc_init(&context);
if (context == NULL) if (context == NULL)
errx(EXIT_FAILURE, "Unable to init libnfc (malloc)"); errx(EXIT_FAILURE, "Unable to init libnfc (malloc)");
device_count = nfc_list_devices (context, devices, 8); device_count = nfc_list_devices(context, devices, 8);
if (device_count <= 0) if (device_count <= 0)
errx (EXIT_FAILURE, "No NFC device found."); errx(EXIT_FAILURE, "No NFC device found.");
for (size_t d = 0; (!error) && (d < device_count); d++) { for (size_t d = 0; (!error) && (d < device_count); d++) {
device = nfc_open (context, devices[d]); device = nfc_open(context, devices[d]);
if (!device) { if (!device) {
warnx ("nfc_open() failed."); warnx("nfc_open() failed.");
error = EXIT_FAILURE; error = EXIT_FAILURE;
continue; continue;
} }
tags = freefare_get_tags (device); tags = freefare_get_tags(device);
if (!tags) { if (!tags) {
nfc_close (device); nfc_close(device);
errx (EXIT_FAILURE, "Error listing Mifare DESFire tags."); errx(EXIT_FAILURE, "Error listing Mifare DESFire tags.");
} }
for (int i = 0; (!error) && tags[i]; i++) { for (int i = 0; (!error) && tags[i]; i++) {
if (MIFARE_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]);
char buffer[BUFSIZ]; char buffer[BUFSIZ];
int res; int res;
res = mifare_desfire_connect (tags[i]); res = mifare_desfire_connect(tags[i]);
if (res < 0) { if (res < 0) {
warnx ("Can't connect to Mifare DESFire target."); warnx("Can't connect to Mifare DESFire target.");
error = EXIT_FAILURE; error = EXIT_FAILURE;
break; break;
} }
// Make sure we've at least an EV1 version // Make sure we've at least an EV1 version
struct mifare_desfire_version_info info; struct mifare_desfire_version_info info;
res = mifare_desfire_get_version (tags[i], &info); res = mifare_desfire_get_version(tags[i], &info);
if (res < 0) { if (res < 0) {
freefare_perror (tags[i], "mifare_desfire_get_version"); freefare_perror(tags[i], "mifare_desfire_get_version");
error = 1; error = 1;
break; break;
} }
if (info.software.version_major < 1) { if (info.software.version_major < 1) {
warnx ("Found old DESFire, skipping"); warnx("Found old DESFire, skipping");
continue; continue;
} }
printf ("Found %s with UID %s. ", freefare_get_tag_friendly_name (tags[i]), tag_uid); printf("Found %s with UID %s. ", freefare_get_tag_friendly_name(tags[i]), tag_uid);
bool do_it = true; bool do_it = true;
if (configure_options.interactive) { if (configure_options.interactive) {
printf ("Change ATS? [yN] "); printf("Change ATS? [yN] ");
fgets (buffer, BUFSIZ, stdin); fgets(buffer, BUFSIZ, stdin);
do_it = ((buffer[0] == 'y') || (buffer[0] == 'Y')); do_it = ((buffer[0] == 'y') || (buffer[0] == 'Y'));
} else { } else {
printf ("\n"); printf("\n");
} }
if (do_it) { if (do_it) {
MifareDESFireKey key_picc = mifare_desfire_des_key_new_with_version (key_data_picc); MifareDESFireKey key_picc = mifare_desfire_des_key_new_with_version(key_data_picc);
res = mifare_desfire_authenticate (tags[i], 0, key_picc); res = mifare_desfire_authenticate(tags[i], 0, key_picc);
if (res < 0) { if (res < 0) {
freefare_perror (tags[i], "mifare_desfire_authenticate"); freefare_perror(tags[i], "mifare_desfire_authenticate");
error = EXIT_FAILURE; error = EXIT_FAILURE;
break; break;
} }
mifare_desfire_key_free (key_picc); mifare_desfire_key_free(key_picc);
res = mifare_desfire_set_ats (tags[i], new_ats); res = mifare_desfire_set_ats(tags[i], new_ats);
if (res < 0) { if (res < 0) {
freefare_perror (tags[i], "mifare_desfire_set_ats"); freefare_perror(tags[i], "mifare_desfire_set_ats");
error = EXIT_FAILURE; error = EXIT_FAILURE;
break; break;
} }
} }
mifare_desfire_disconnect (tags[i]); mifare_desfire_disconnect(tags[i]);
free (tag_uid); free(tag_uid);
} }
freefare_free_tags (tags); freefare_free_tags(tags);
nfc_close (device); nfc_close(device);
} }
nfc_exit (context); nfc_exit(context);
exit (error); exit(error);
} /* main() */ } /* main() */

View file

@ -43,9 +43,9 @@ struct {
static void static void
usage(char *progname) usage(char *progname)
{ {
fprintf (stderr, "usage: %s [-y]\n", progname); fprintf(stderr, "usage: %s [-y]\n", progname);
fprintf (stderr, "\nOptions:\n"); fprintf(stderr, "\nOptions:\n");
fprintf (stderr, " -y Do not ask for confirmation\n"); fprintf(stderr, " -y Do not ask for confirmation\n");
} }
int int
@ -56,18 +56,18 @@ main(int argc, char *argv[])
nfc_device *device = NULL; nfc_device *device = NULL;
FreefareTag *tags = NULL; FreefareTag *tags = NULL;
while ((ch = getopt (argc, argv, "hy")) != -1) { while ((ch = getopt(argc, argv, "hy")) != -1) {
switch (ch) { switch (ch) {
case 'h': case 'h':
usage(argv[0]); usage(argv[0]);
exit (EXIT_SUCCESS); exit(EXIT_SUCCESS);
break; break;
case 'y': case 'y':
configure_options.interactive = false; configure_options.interactive = false;
break; break;
default: default:
usage(argv[0]); usage(argv[0]);
exit (EXIT_FAILURE); exit(EXIT_FAILURE);
} }
} }
// Remaining args, if any, are in argv[optind .. (argc-1)] // Remaining args, if any, are in argv[optind .. (argc-1)]
@ -76,85 +76,85 @@ main(int argc, char *argv[])
size_t device_count; size_t device_count;
nfc_context *context; nfc_context *context;
nfc_init (&context); nfc_init(&context);
if (context == NULL) if (context == NULL)
errx(EXIT_FAILURE, "Unable to init libnfc (malloc)"); errx(EXIT_FAILURE, "Unable to init libnfc (malloc)");
device_count = nfc_list_devices (context, devices, 8); device_count = nfc_list_devices(context, devices, 8);
if (device_count <= 0) if (device_count <= 0)
errx (EXIT_FAILURE, "No NFC device found."); errx(EXIT_FAILURE, "No NFC device found.");
for (size_t d = 0; (!error) && (d < device_count); d++) { for (size_t d = 0; (!error) && (d < device_count); d++) {
device = nfc_open (context, devices[d]); device = nfc_open(context, devices[d]);
if (!device) { if (!device) {
warnx ("nfc_open() failed."); warnx("nfc_open() failed.");
error = EXIT_FAILURE; error = EXIT_FAILURE;
continue; continue;
} }
tags = freefare_get_tags (device); tags = freefare_get_tags(device);
if (!tags) { if (!tags) {
nfc_close (device); nfc_close(device);
errx (EXIT_FAILURE, "Error listing Mifare DESFire tags."); errx(EXIT_FAILURE, "Error listing Mifare DESFire tags.");
} }
for (int i = 0; (!error) && tags[i]; i++) { for (int i = 0; (!error) && tags[i]; i++) {
if (MIFARE_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]);
char buffer[BUFSIZ]; char buffer[BUFSIZ];
int res; int res;
res = mifare_desfire_connect (tags[i]); res = mifare_desfire_connect(tags[i]);
if (res < 0) { if (res < 0) {
warnx ("Can't connect to Mifare DESFire target."); warnx("Can't connect to Mifare DESFire target.");
error = EXIT_FAILURE; error = EXIT_FAILURE;
break; break;
} }
// Make sure we've at least an EV1 version // Make sure we've at least an EV1 version
struct mifare_desfire_version_info info; struct mifare_desfire_version_info info;
res = mifare_desfire_get_version (tags[i], &info); res = mifare_desfire_get_version(tags[i], &info);
if (res < 0) { if (res < 0) {
freefare_perror (tags[i], "mifare_desfire_get_version"); freefare_perror(tags[i], "mifare_desfire_get_version");
error = 1; error = 1;
break; break;
} }
if (info.software.version_major < 1) { if (info.software.version_major < 1) {
warnx ("Found old DESFire, skipping"); warnx("Found old DESFire, skipping");
continue; continue;
} }
printf ("Found %s with UID %s. ", freefare_get_tag_friendly_name (tags[i]), tag_uid); printf("Found %s with UID %s. ", freefare_get_tag_friendly_name(tags[i]), tag_uid);
bool do_it = true; bool do_it = true;
if (configure_options.interactive) { if (configure_options.interactive) {
printf ("Change default key? [yN] "); printf("Change default key? [yN] ");
fgets (buffer, BUFSIZ, stdin); fgets(buffer, BUFSIZ, stdin);
do_it = ((buffer[0] == 'y') || (buffer[0] == 'Y')); do_it = ((buffer[0] == 'y') || (buffer[0] == 'Y'));
} else { } else {
printf ("\n"); printf("\n");
} }
if (do_it) { if (do_it) {
MifareDESFireKey default_key = mifare_desfire_des_key_new_with_version (null_key_data); MifareDESFireKey default_key = mifare_desfire_des_key_new_with_version(null_key_data);
res = mifare_desfire_authenticate (tags[i], 0, default_key); res = mifare_desfire_authenticate(tags[i], 0, default_key);
if (res < 0) { if (res < 0) {
freefare_perror (tags[i], "mifare_desfire_authenticate"); freefare_perror(tags[i], "mifare_desfire_authenticate");
error = EXIT_FAILURE; error = EXIT_FAILURE;
break; break;
} }
mifare_desfire_key_free (default_key); mifare_desfire_key_free(default_key);
MifareDESFireKey new_key = mifare_desfire_des_key_new (new_key_data); MifareDESFireKey new_key = mifare_desfire_des_key_new(new_key_data);
mifare_desfire_key_set_version (new_key, NEW_KEY_VERSION); mifare_desfire_key_set_version(new_key, NEW_KEY_VERSION);
res = mifare_desfire_set_default_key (tags[i], new_key); res = mifare_desfire_set_default_key(tags[i], new_key);
free (new_key); free(new_key);
if (res < 0) { if (res < 0) {
freefare_perror (tags[i], "mifare_desfire_set_default_key"); freefare_perror(tags[i], "mifare_desfire_set_default_key");
error = EXIT_FAILURE; error = EXIT_FAILURE;
break; break;
} }
@ -164,92 +164,92 @@ main(int argc, char *argv[])
* (it's hard to create a unit-test to do so). * (it's hard to create a unit-test to do so).
*/ */
MifareDESFireAID aid = mifare_desfire_aid_new (0x112233); MifareDESFireAID aid = mifare_desfire_aid_new(0x112233);
res = mifare_desfire_create_application (tags[i], aid, 0xFF, 1); res = mifare_desfire_create_application(tags[i], aid, 0xFF, 1);
if (res < 0) { if (res < 0) {
freefare_perror (tags[i], "mifare_desfire_create_application"); freefare_perror(tags[i], "mifare_desfire_create_application");
error = EXIT_FAILURE; error = EXIT_FAILURE;
break; break;
} }
res = mifare_desfire_select_application (tags[i], aid); res = mifare_desfire_select_application(tags[i], aid);
if (res < 0) { if (res < 0) {
freefare_perror (tags[i], "mifare_desfire_select_application"); freefare_perror(tags[i], "mifare_desfire_select_application");
error = EXIT_FAILURE; error = EXIT_FAILURE;
break; break;
} }
uint8_t version; uint8_t version;
res = mifare_desfire_get_key_version (tags[i], 0, &version); res = mifare_desfire_get_key_version(tags[i], 0, &version);
if (res < 0) { if (res < 0) {
freefare_perror (tags[i], "mifare_desfire_get_key_version"); freefare_perror(tags[i], "mifare_desfire_get_key_version");
error = EXIT_FAILURE; error = EXIT_FAILURE;
break; break;
} }
if (version != NEW_KEY_VERSION) { if (version != NEW_KEY_VERSION) {
fprintf (stderr, "Wrong key version: %02x (expected %02x).\n", version, NEW_KEY_VERSION); fprintf(stderr, "Wrong key version: %02x (expected %02x).\n", version, NEW_KEY_VERSION);
error = EXIT_FAILURE; error = EXIT_FAILURE;
/* continue */ /* continue */
} }
new_key = mifare_desfire_des_key_new (new_key_data); new_key = mifare_desfire_des_key_new(new_key_data);
res = mifare_desfire_authenticate (tags[i], 0, new_key); res = mifare_desfire_authenticate(tags[i], 0, new_key);
free (new_key); free(new_key);
if (res < 0) { if (res < 0) {
freefare_perror (tags[i], "mifare_desfire_authenticate"); freefare_perror(tags[i], "mifare_desfire_authenticate");
error = EXIT_FAILURE; error = EXIT_FAILURE;
break; break;
} }
free (aid); free(aid);
/* Resetdefault settings */ /* Resetdefault settings */
res = mifare_desfire_select_application (tags[i], NULL); res = mifare_desfire_select_application(tags[i], NULL);
if (res < 0) { if (res < 0) {
freefare_perror (tags[i], "mifare_desfire_select_application"); freefare_perror(tags[i], "mifare_desfire_select_application");
error = EXIT_FAILURE; error = EXIT_FAILURE;
break; break;
} }
default_key = mifare_desfire_des_key_new (null_key_data); default_key = mifare_desfire_des_key_new(null_key_data);
res = mifare_desfire_authenticate (tags[i], 0, default_key); res = mifare_desfire_authenticate(tags[i], 0, default_key);
if (res < 0) { if (res < 0) {
freefare_perror (tags[i], "mifare_desfire_authenticate"); freefare_perror(tags[i], "mifare_desfire_authenticate");
error = EXIT_FAILURE; error = EXIT_FAILURE;
break; break;
} }
res = mifare_desfire_set_default_key (tags[i], default_key); res = mifare_desfire_set_default_key(tags[i], default_key);
if (res < 0) { if (res < 0) {
freefare_perror (tags[i], "mifare_desfire_set_default_key"); freefare_perror(tags[i], "mifare_desfire_set_default_key");
error = EXIT_FAILURE; error = EXIT_FAILURE;
break; break;
} }
mifare_desfire_key_free (default_key); mifare_desfire_key_free(default_key);
/* Wipeout the card */ /* Wipeout the card */
res = mifare_desfire_format_picc (tags[i]); res = mifare_desfire_format_picc(tags[i]);
if (res < 0) { if (res < 0) {
freefare_perror (tags[i], "mifare_desfire_format_picc"); freefare_perror(tags[i], "mifare_desfire_format_picc");
error = EXIT_FAILURE; error = EXIT_FAILURE;
break; break;
} }
} }
mifare_desfire_disconnect (tags[i]); mifare_desfire_disconnect(tags[i]);
free (tag_uid); free(tag_uid);
} }
freefare_free_tags (tags); freefare_free_tags(tags);
nfc_close (device); nfc_close(device);
} }
nfc_exit (context); nfc_exit(context);
exit (error); exit(error);
} }

View file

@ -40,10 +40,10 @@ struct {
static void static void
usage(char *progname) usage(char *progname)
{ {
fprintf (stderr, "usage: %s [-y] [-K 11223344AABBCCDD]\n", progname); fprintf(stderr, "usage: %s [-y] [-K 11223344AABBCCDD]\n", progname);
fprintf (stderr, "\nOptions:\n"); fprintf(stderr, "\nOptions:\n");
fprintf (stderr, " -y Do not ask for confirmation (dangerous)\n"); fprintf(stderr, " -y Do not ask for confirmation (dangerous)\n");
fprintf (stderr, " -K Provide another PICC key than the default one\n"); fprintf(stderr, " -K Provide another PICC key than the default one\n");
} }
int int
@ -54,11 +54,11 @@ main(int argc, char *argv[])
nfc_device *device = NULL; nfc_device *device = NULL;
FreefareTag *tags = NULL; FreefareTag *tags = NULL;
while ((ch = getopt (argc, argv, "hyK:")) != -1) { while ((ch = getopt(argc, argv, "hyK:")) != -1) {
switch (ch) { switch (ch) {
case 'h': case 'h':
usage(argv[0]); usage(argv[0]);
exit (EXIT_SUCCESS); exit(EXIT_SUCCESS);
break; break;
case 'y': case 'y':
configure_options.interactive = false; configure_options.interactive = false;
@ -66,18 +66,18 @@ main(int argc, char *argv[])
case 'K': case 'K':
if (strlen(optarg) != 16) { if (strlen(optarg) != 16) {
usage(argv[0]); usage(argv[0]);
exit (EXIT_FAILURE); exit(EXIT_FAILURE);
} }
uint64_t n = strtoull(optarg, NULL, 16); uint64_t n = strtoull(optarg, NULL, 16);
int i; int i;
for (i=7; i>=0; i--) { for (i = 7; i >= 0; i--) {
key_data_picc[i] = (uint8_t) n; key_data_picc[i] = (uint8_t) n;
n >>= 8; n >>= 8;
} }
break; break;
default: default:
usage(argv[0]); usage(argv[0]);
exit (EXIT_FAILURE); exit(EXIT_FAILURE);
} }
} }
// Remaining args, if any, are in argv[optind .. (argc-1)] // Remaining args, if any, are in argv[optind .. (argc-1)]
@ -86,127 +86,127 @@ main(int argc, char *argv[])
size_t device_count; size_t device_count;
nfc_context *context; nfc_context *context;
nfc_init (&context); nfc_init(&context);
if (context == NULL) if (context == NULL)
errx(EXIT_FAILURE, "Unable to init libnfc (malloc)"); errx(EXIT_FAILURE, "Unable to init libnfc (malloc)");
device_count = nfc_list_devices (context, devices, 8); device_count = nfc_list_devices(context, devices, 8);
if (device_count <= 0) if (device_count <= 0)
errx (EXIT_FAILURE, "No NFC device found."); errx(EXIT_FAILURE, "No NFC device found.");
for (size_t d = 0; (!error) && (d < device_count); d++) { for (size_t d = 0; (!error) && (d < device_count); d++) {
device = nfc_open (context, devices[d]); device = nfc_open(context, devices[d]);
if (!device) { if (!device) {
warnx ("nfc_open() failed."); warnx("nfc_open() failed.");
error = EXIT_FAILURE; error = EXIT_FAILURE;
continue; continue;
} }
tags = freefare_get_tags (device); tags = freefare_get_tags(device);
if (!tags) { if (!tags) {
nfc_close (device); nfc_close(device);
errx (EXIT_FAILURE, "Error listing Mifare DESFire tags."); errx(EXIT_FAILURE, "Error listing Mifare DESFire tags.");
} }
for (int i = 0; (!error) && tags[i]; i++) { for (int i = 0; (!error) && tags[i]; i++) {
if (MIFARE_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]);
char buffer[BUFSIZ]; char buffer[BUFSIZ];
int res; int res;
res = mifare_desfire_connect (tags[i]); res = mifare_desfire_connect(tags[i]);
if (res < 0) { if (res < 0) {
warnx ("Can't connect to Mifare DESFire target."); warnx("Can't connect to Mifare DESFire target.");
error = EXIT_FAILURE; error = EXIT_FAILURE;
break; break;
} }
// Make sure we've at least an EV1 version // Make sure we've at least an EV1 version
struct mifare_desfire_version_info info; struct mifare_desfire_version_info info;
res = mifare_desfire_get_version (tags[i], &info); res = mifare_desfire_get_version(tags[i], &info);
if (res < 0) { if (res < 0) {
freefare_perror (tags[i], "mifare_desfire_get_version"); freefare_perror(tags[i], "mifare_desfire_get_version");
error = 1; error = 1;
break; break;
} }
if (info.software.version_major < 1) { if (info.software.version_major < 1) {
warnx ("Found old DESFire, skipping"); warnx("Found old DESFire, skipping");
continue; continue;
} }
printf ("Found %s with UID %s. ", freefare_get_tag_friendly_name (tags[i]), tag_uid); printf("Found %s with UID %s. ", freefare_get_tag_friendly_name(tags[i]), tag_uid);
bool do_it = true; bool do_it = true;
size_t tag_uid_len = strlen (tag_uid) / 2; size_t tag_uid_len = strlen(tag_uid) / 2;
switch (tag_uid_len) { switch (tag_uid_len) {
case 7: // Regular UID case 7: // Regular UID
if (configure_options.interactive) { if (configure_options.interactive) {
printf ("Configure random UID (this cannot be undone) [yN] "); printf("Configure random UID (this cannot be undone) [yN] ");
fgets (buffer, BUFSIZ, stdin); fgets(buffer, BUFSIZ, stdin);
do_it = ((buffer[0] == 'y') || (buffer[0] == 'Y')); do_it = ((buffer[0] == 'y') || (buffer[0] == 'Y'));
} else { } else {
printf ("\n"); printf("\n");
} }
if (do_it) { if (do_it) {
MifareDESFireKey key_picc = mifare_desfire_des_key_new_with_version (key_data_picc); MifareDESFireKey key_picc = mifare_desfire_des_key_new_with_version(key_data_picc);
res = mifare_desfire_authenticate (tags[i], 0, key_picc); res = mifare_desfire_authenticate(tags[i], 0, key_picc);
if (res < 0) { if (res < 0) {
freefare_perror (tags[i], "mifare_desfire_authenticate"); freefare_perror(tags[i], "mifare_desfire_authenticate");
error = EXIT_FAILURE; error = EXIT_FAILURE;
break; break;
} }
mifare_desfire_key_free (key_picc); mifare_desfire_key_free(key_picc);
res = mifare_desfire_set_configuration (tags[i], false, true); res = mifare_desfire_set_configuration(tags[i], false, true);
if (res < 0) { if (res < 0) {
freefare_perror (tags[i], "mifare_desfire_set_configuration"); freefare_perror(tags[i], "mifare_desfire_set_configuration");
error = EXIT_FAILURE; error = EXIT_FAILURE;
break; break;
} }
} }
break; break;
case 4: // Random UID case 4: // Random UID
{} // Compilation fails if label is directly followed by the declaration rather than a statement {} // Compilation fails if label is directly followed by the declaration rather than a statement
MifareDESFireKey key_picc = mifare_desfire_des_key_new_with_version (key_data_picc); MifareDESFireKey key_picc = mifare_desfire_des_key_new_with_version(key_data_picc);
res = mifare_desfire_authenticate (tags[i], 0, key_picc); res = mifare_desfire_authenticate(tags[i], 0, key_picc);
if (res < 0) { if (res < 0) {
freefare_perror (tags[i], "mifare_desfire_authenticate"); freefare_perror(tags[i], "mifare_desfire_authenticate");
error = EXIT_FAILURE; error = EXIT_FAILURE;
break;
}
mifare_desfire_key_free (key_picc);
char *old_tag_uid;
res = mifare_desfire_get_card_uid (tags[i], &old_tag_uid);
if (res < 0) {
freefare_perror (tags[i], "mifare_desfire_get_card_uid");
error = EXIT_FAILURE;
break;
}
printf ("Old card UID: %s\n", old_tag_uid);
free (old_tag_uid);
break; break;
default: // Should not happen }
warnx ("Unsupported UID length %d.", (int) tag_uid_len); mifare_desfire_key_free(key_picc);
char *old_tag_uid;
res = mifare_desfire_get_card_uid(tags[i], &old_tag_uid);
if (res < 0) {
freefare_perror(tags[i], "mifare_desfire_get_card_uid");
error = EXIT_FAILURE; error = EXIT_FAILURE;
break; break;
} }
mifare_desfire_disconnect (tags[i]); printf("Old card UID: %s\n", old_tag_uid);
free (tag_uid); free(old_tag_uid);
break;
default: // Should not happen
warnx("Unsupported UID length %d.", (int) tag_uid_len);
error = EXIT_FAILURE;
break;
}
mifare_desfire_disconnect(tags[i]);
free(tag_uid);
} }
freefare_free_tags (tags); freefare_free_tags(tags);
nfc_close (device); nfc_close(device);
} }
nfc_exit (context); nfc_exit(context);
exit (error); exit(error);
} /* main() */ } /* main() */

View file

@ -40,10 +40,10 @@ struct {
static void static void
usage(char *progname) usage(char *progname)
{ {
fprintf (stderr, "usage: %s [-y] [-K 11223344AABBCCDD]\n", progname); fprintf(stderr, "usage: %s [-y] [-K 11223344AABBCCDD]\n", progname);
fprintf (stderr, "\nOptions:\n"); fprintf(stderr, "\nOptions:\n");
fprintf (stderr, " -y Do not ask for confirmation (dangerous)\n"); fprintf(stderr, " -y Do not ask for confirmation (dangerous)\n");
fprintf (stderr, " -K Provide another PICC key than the default one\n"); fprintf(stderr, " -K Provide another PICC key than the default one\n");
} }
int int
@ -54,30 +54,30 @@ main(int argc, char *argv[])
nfc_device *device = NULL; nfc_device *device = NULL;
FreefareTag *tags = NULL; FreefareTag *tags = NULL;
while ((ch = getopt (argc, argv, "hyK:")) != -1) { while ((ch = getopt(argc, argv, "hyK:")) != -1) {
switch (ch) { switch (ch) {
case 'h': case 'h':
usage(argv[0]);
exit(EXIT_SUCCESS);
break;
case 'y':
format_options.interactive = false;
break;
case 'K':
if (strlen(optarg) != 16) {
usage(argv[0]); usage(argv[0]);
exit (EXIT_SUCCESS); exit(EXIT_FAILURE);
break; }
case 'y': uint64_t n = strtoull(optarg, NULL, 16);
format_options.interactive = false; int i;
break; for (i = 7; i >= 0; i--) {
case 'K': key_data_picc[i] = (uint8_t) n;
if (strlen(optarg) != 16) { n >>= 8;
usage(argv[0]); }
exit (EXIT_FAILURE); break;
} default:
uint64_t n = strtoull(optarg, NULL, 16); usage(argv[0]);
int i; exit(EXIT_FAILURE);
for (i=7; i>=0; i--) {
key_data_picc[i] = (uint8_t) n;
n >>= 8;
}
break;
default:
usage(argv[0]);
exit (EXIT_FAILURE);
} }
} }
// Remaining args, if any, are in argv[optind .. (argc-1)] // Remaining args, if any, are in argv[optind .. (argc-1)]
@ -86,63 +86,63 @@ main(int argc, char *argv[])
size_t device_count; size_t device_count;
nfc_context *context; nfc_context *context;
nfc_init (&context); nfc_init(&context);
if (context == NULL) if (context == NULL)
errx(EXIT_FAILURE, "Unable to init libnfc (malloc)"); errx(EXIT_FAILURE, "Unable to init libnfc (malloc)");
device_count = nfc_list_devices (context, devices, 8); device_count = nfc_list_devices(context, devices, 8);
if (device_count <= 0) if (device_count <= 0)
errx (EXIT_FAILURE, "No NFC device found."); errx(EXIT_FAILURE, "No NFC device found.");
for (size_t d = 0; (!error) && (d < device_count); d++) { for (size_t d = 0; (!error) && (d < device_count); d++) {
device = nfc_open (context, devices[d]); device = nfc_open(context, devices[d]);
if (!device) { if (!device) {
warnx ("nfc_open() failed."); warnx("nfc_open() failed.");
error = EXIT_FAILURE; error = EXIT_FAILURE;
continue; continue;
} }
tags = freefare_get_tags (device); tags = freefare_get_tags(device);
if (!tags) { if (!tags) {
nfc_close (device); nfc_close(device);
errx (EXIT_FAILURE, "Error listing Mifare DESFire tags."); errx(EXIT_FAILURE, "Error listing Mifare DESFire tags.");
} }
for (int i = 0; (!error) && tags[i]; i++) { for (int i = 0; (!error) && tags[i]; i++) {
if (MIFARE_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]);
char buffer[BUFSIZ]; char buffer[BUFSIZ];
printf ("Found %s with UID %s. ", freefare_get_tag_friendly_name (tags[i]), tag_uid); printf("Found %s with UID %s. ", freefare_get_tag_friendly_name(tags[i]), tag_uid);
bool format = true; bool format = true;
if (format_options.interactive) { if (format_options.interactive) {
printf ("Format [yN] "); printf("Format [yN] ");
fgets (buffer, BUFSIZ, stdin); fgets(buffer, BUFSIZ, stdin);
format = ((buffer[0] == 'y') || (buffer[0] == 'Y')); format = ((buffer[0] == 'y') || (buffer[0] == 'Y'));
} else { } else {
printf ("\n"); printf("\n");
} }
if (format) { if (format) {
int res; int res;
res = mifare_desfire_connect (tags[i]); res = mifare_desfire_connect(tags[i]);
if (res < 0) { if (res < 0) {
warnx ("Can't connect to Mifare DESFire target."); warnx("Can't connect to Mifare DESFire target.");
error = EXIT_FAILURE; error = EXIT_FAILURE;
break; break;
} }
MifareDESFireKey key_picc = mifare_desfire_des_key_new_with_version (key_data_picc); MifareDESFireKey key_picc = mifare_desfire_des_key_new_with_version(key_data_picc);
res = mifare_desfire_authenticate (tags[i], 0, key_picc); res = mifare_desfire_authenticate(tags[i], 0, key_picc);
if (res < 0) { if (res < 0) {
warnx ("Can't authenticate on Mifare DESFire target."); warnx("Can't authenticate on Mifare DESFire target.");
error = EXIT_FAILURE; error = EXIT_FAILURE;
break; break;
} }
mifare_desfire_key_free (key_picc); mifare_desfire_key_free(key_picc);
// Send Mifare DESFire ChangeKeySetting to change the PICC master key settings into : // Send Mifare DESFire ChangeKeySetting to change the PICC master key settings into :
// bit7-bit4 equal to 0000b // bit7-bit4 equal to 0000b
@ -150,26 +150,26 @@ main(int argc, char *argv[])
// bit2 equal to 1b, CreateApplication and DeleteApplication commands are allowed without PICC master key authentication // bit2 equal to 1b, CreateApplication and DeleteApplication commands are allowed without PICC master key authentication
// bit1 equal to 1b, GetApplicationIDs, and GetKeySettings are allowed without PICC master key authentication // bit1 equal to 1b, GetApplicationIDs, and GetKeySettings are allowed without PICC master key authentication
// bit0 equal to 1b, PICC masterkey MAY be frozen or changeable // bit0 equal to 1b, PICC masterkey MAY be frozen or changeable
res = mifare_desfire_change_key_settings (tags[i],0x0F); res = mifare_desfire_change_key_settings(tags[i], 0x0F);
if (res < 0) if (res < 0)
errx (EXIT_FAILURE, "ChangeKeySettings failed"); errx(EXIT_FAILURE, "ChangeKeySettings failed");
res = mifare_desfire_format_picc (tags[i]); res = mifare_desfire_format_picc(tags[i]);
if (res < 0) { if (res < 0) {
warn ("Can't format PICC."); warn("Can't format PICC.");
error = EXIT_FAILURE; error = EXIT_FAILURE;
break; break;
} }
mifare_desfire_disconnect (tags[i]); mifare_desfire_disconnect(tags[i]);
} }
free (tag_uid); free(tag_uid);
} }
freefare_free_tags (tags); freefare_free_tags(tags);
nfc_close (device); nfc_close(device);
} }
nfc_exit (context); nfc_exit(context);
exit (error); exit(error);
} /* main() */ } /* main() */

View file

@ -32,117 +32,117 @@ main(int argc, char *argv[])
FreefareTag *tags = NULL; FreefareTag *tags = NULL;
if (argc > 1) if (argc > 1)
errx (EXIT_FAILURE, "usage: %s", argv[0]); errx(EXIT_FAILURE, "usage: %s", argv[0]);
nfc_connstring devices[8]; nfc_connstring devices[8];
size_t device_count; size_t device_count;
nfc_context *context; nfc_context *context;
nfc_init (&context); nfc_init(&context);
if (context == NULL) if (context == NULL)
errx(EXIT_FAILURE, "Unable to init libnfc (malloc)"); errx(EXIT_FAILURE, "Unable to init libnfc (malloc)");
device_count = nfc_list_devices (context, devices, 8); device_count = nfc_list_devices(context, devices, 8);
if (device_count <= 0) if (device_count <= 0)
errx (EXIT_FAILURE, "No NFC device found."); errx(EXIT_FAILURE, "No NFC device found.");
for (size_t d = 0; d < device_count; d++) { for (size_t d = 0; d < device_count; d++) {
device = nfc_open (context, devices[d]); device = nfc_open(context, devices[d]);
if (!device) { if (!device) {
warnx ("nfc_open() failed."); warnx("nfc_open() failed.");
error = EXIT_FAILURE; error = EXIT_FAILURE;
continue; continue;
} }
tags = freefare_get_tags (device); tags = freefare_get_tags(device);
if (!tags) { if (!tags) {
nfc_close (device); nfc_close(device);
errx (EXIT_FAILURE, "Error listing tags."); errx(EXIT_FAILURE, "Error listing tags.");
} }
for (int i = 0; (!error) && tags[i]; i++) { for (int i = 0; (!error) && tags[i]; i++) {
if (MIFARE_DESFIRE != freefare_get_tag_type (tags[i])) if (MIFARE_DESFIRE != freefare_get_tag_type(tags[i]))
continue; continue;
int res; int res;
char *tag_uid = freefare_get_tag_uid (tags[i]); char *tag_uid = freefare_get_tag_uid(tags[i]);
struct mifare_desfire_version_info info; struct mifare_desfire_version_info info;
res = mifare_desfire_connect (tags[i]); res = mifare_desfire_connect(tags[i]);
if (res < 0) { if (res < 0) {
warnx ("Can't connect to Mifare DESFire target."); warnx("Can't connect to Mifare DESFire target.");
error = 1; error = 1;
break; break;
} }
res = mifare_desfire_get_version (tags[i], &info); res = mifare_desfire_get_version(tags[i], &info);
if (res < 0) { if (res < 0) {
freefare_perror (tags[i], "mifare_desfire_get_version"); freefare_perror(tags[i], "mifare_desfire_get_version");
error = 1; error = 1;
break; break;
} }
printf ("===> Version information for tag %s:\n", tag_uid); printf("===> Version information for tag %s:\n", tag_uid);
printf ("UID: 0x%02x%02x%02x%02x%02x%02x%02x\n", info.uid[0], info.uid[1], info.uid[2], info.uid[3], info.uid[4], info.uid[5], info.uid[6]); printf("UID: 0x%02x%02x%02x%02x%02x%02x%02x\n", info.uid[0], info.uid[1], info.uid[2], info.uid[3], info.uid[4], info.uid[5], info.uid[6]);
printf ("Batch number: 0x%02x%02x%02x%02x%02x\n", info.batch_number[0], info.batch_number[1], info.batch_number[2], info.batch_number[3], info.batch_number[4]); printf("Batch number: 0x%02x%02x%02x%02x%02x\n", info.batch_number[0], info.batch_number[1], info.batch_number[2], info.batch_number[3], info.batch_number[4]);
printf ("Production date: week %x, 20%02x\n", info.production_week, info.production_year); printf("Production date: week %x, 20%02x\n", info.production_week, info.production_year);
printf ("Hardware Information:\n"); printf("Hardware Information:\n");
printf (" Vendor ID: 0x%02x\n", info.hardware.vendor_id); printf(" Vendor ID: 0x%02x\n", info.hardware.vendor_id);
printf (" Type: 0x%02x\n", info.hardware.type); printf(" Type: 0x%02x\n", info.hardware.type);
printf (" Subtype: 0x%02x\n", info.hardware.subtype); printf(" Subtype: 0x%02x\n", info.hardware.subtype);
printf (" Version: %d.%d\n", info.hardware.version_major, info.hardware.version_minor); printf(" Version: %d.%d\n", info.hardware.version_major, info.hardware.version_minor);
printf (" Storage size: 0x%02x (%s%d bytes)\n", info.hardware.storage_size, (info.hardware.storage_size & 1) ? ">" : "=", 1 << (info.hardware.storage_size >> 1)); printf(" Storage size: 0x%02x (%s%d bytes)\n", info.hardware.storage_size, (info.hardware.storage_size & 1) ? ">" : "=", 1 << (info.hardware.storage_size >> 1));
printf (" Protocol: 0x%02x\n", info.hardware.protocol); printf(" Protocol: 0x%02x\n", info.hardware.protocol);
printf ("Software Information:\n"); printf("Software Information:\n");
printf (" Vendor ID: 0x%02x\n", info.software.vendor_id); printf(" Vendor ID: 0x%02x\n", info.software.vendor_id);
printf (" Type: 0x%02x\n", info.software.type); printf(" Type: 0x%02x\n", info.software.type);
printf (" Subtype: 0x%02x\n", info.software.subtype); printf(" Subtype: 0x%02x\n", info.software.subtype);
printf (" Version: %d.%d\n", info.software.version_major, info.software.version_minor); printf(" Version: %d.%d\n", info.software.version_major, info.software.version_minor);
printf (" Storage size: 0x%02x (%s%d bytes)\n", info.software.storage_size, (info.software.storage_size & 1) ? ">" : "=", 1 << (info.software.storage_size >> 1)); printf(" Storage size: 0x%02x (%s%d bytes)\n", info.software.storage_size, (info.software.storage_size & 1) ? ">" : "=", 1 << (info.software.storage_size >> 1));
printf (" Protocol: 0x%02x\n", info.software.protocol); printf(" Protocol: 0x%02x\n", info.software.protocol);
uint8_t settings; uint8_t settings;
uint8_t max_keys; uint8_t max_keys;
res = mifare_desfire_get_key_settings (tags[i], &settings, &max_keys); res = mifare_desfire_get_key_settings(tags[i], &settings, &max_keys);
if (res == 0) { if (res == 0) {
printf ("Master Key settings (0x%02x):\n", settings); printf("Master Key settings (0x%02x):\n", settings);
printf (" 0x%02x configuration changeable;\n", settings & 0x08); printf(" 0x%02x configuration changeable;\n", settings & 0x08);
printf (" 0x%02x PICC Master Key not required for create / delete;\n", settings & 0x04); printf(" 0x%02x PICC Master Key not required for create / delete;\n", settings & 0x04);
printf (" 0x%02x Free directory list access without PICC Master Key;\n", settings & 0x02); printf(" 0x%02x Free directory list access without PICC Master Key;\n", settings & 0x02);
printf (" 0x%02x Allow changing the Master Key;\n", settings & 0x01); printf(" 0x%02x Allow changing the Master Key;\n", settings & 0x01);
} else if (AUTHENTICATION_ERROR == mifare_desfire_last_picc_error (tags[i])) { } else if (AUTHENTICATION_ERROR == mifare_desfire_last_picc_error(tags[i])) {
printf ("Master Key settings: LOCKED\n"); printf("Master Key settings: LOCKED\n");
} else { } else {
freefare_perror (tags[i], "mifare_desfire_get_key_settings"); freefare_perror(tags[i], "mifare_desfire_get_key_settings");
error = 1; error = 1;
break; break;
} }
uint8_t version; uint8_t version;
mifare_desfire_get_key_version (tags[i], 0, &version); mifare_desfire_get_key_version(tags[i], 0, &version);
printf ("Master Key version: %d (0x%02x)\n", version, version); printf("Master Key version: %d (0x%02x)\n", version, version);
uint32_t size; uint32_t size;
res = mifare_desfire_free_mem (tags[i], &size); res = mifare_desfire_free_mem(tags[i], &size);
printf ("Free memory: "); printf("Free memory: ");
if (0 == res) { if (0 == res) {
printf ("%d bytes\n", size); printf("%d bytes\n", size);
} else { } else {
printf ("unknown\n"); printf("unknown\n");
} }
printf ("Use random UID: %s\n", (strlen (tag_uid) / 2 == 4) ? "yes" : "no"); printf("Use random UID: %s\n", (strlen(tag_uid) / 2 == 4) ? "yes" : "no");
free (tag_uid); free(tag_uid);
mifare_desfire_disconnect (tags[i]); mifare_desfire_disconnect(tags[i]);
} }
freefare_free_tags (tags); freefare_free_tags(tags);
nfc_close (device); nfc_close(device);
} }
nfc_exit (context); nfc_exit(context);
exit (error); exit(error);
} /* main() */ } /* main() */

View file

@ -54,12 +54,12 @@ struct {
static void static void
usage(char *progname) usage(char *progname)
{ {
fprintf (stderr, "This application reads a NDEF payload from a Mifare DESFire formatted as NFC Forum Type 4 Tag.\n"); fprintf(stderr, "This application reads a NDEF payload from a Mifare DESFire formatted as NFC Forum Type 4 Tag.\n");
fprintf (stderr, "usage: %s [-y] -o FILE [-k 11223344AABBCCDD]\n", progname); fprintf(stderr, "usage: %s [-y] -o FILE [-k 11223344AABBCCDD]\n", progname);
fprintf (stderr, "\nOptions:\n"); fprintf(stderr, "\nOptions:\n");
fprintf (stderr, " -y Do not ask for confirmation\n"); fprintf(stderr, " -y Do not ask for confirmation\n");
fprintf (stderr, " -o Extract NDEF message if available in FILE\n"); fprintf(stderr, " -o Extract NDEF message if available in FILE\n");
fprintf (stderr, " -k Provide another NDEF Tag Application key than the default one\n"); fprintf(stderr, " -k Provide another NDEF Tag Application key than the default one\n");
} }
int int
@ -71,53 +71,53 @@ main(int argc, char *argv[])
FreefareTag *tags = NULL; FreefareTag *tags = NULL;
char *ndef_output = NULL; char *ndef_output = NULL;
while ((ch = getopt (argc, argv, "hyo:k:")) != -1) { while ((ch = getopt(argc, argv, "hyo:k:")) != -1) {
switch (ch) { switch (ch) {
case 'h': case 'h':
usage(argv[0]); usage(argv[0]);
exit (EXIT_SUCCESS); exit(EXIT_SUCCESS);
break; break;
case 'y': case 'y':
read_options.interactive = false; read_options.interactive = false;
break; break;
case 'o': case 'o':
ndef_output = optarg; ndef_output = optarg;
break; break;
case 'k': case 'k':
if (strlen(optarg) != 16) { if (strlen(optarg) != 16) {
usage(argv[0]); usage(argv[0]);
exit (EXIT_FAILURE); exit(EXIT_FAILURE);
} }
uint64_t n = strtoull(optarg, NULL, 16); uint64_t n = strtoull(optarg, NULL, 16);
int i; int i;
for (i=7; i>=0; i--) { for (i = 7; i >= 0; i--) {
key_data_app[i] = (uint8_t) n; key_data_app[i] = (uint8_t) n;
n >>= 8; n >>= 8;
} }
break; break;
default: default:
usage(argv[0]); usage(argv[0]);
exit (EXIT_FAILURE); exit(EXIT_FAILURE);
} }
} }
// Remaining args, if any, are in argv[optind .. (argc-1)] // Remaining args, if any, are in argv[optind .. (argc-1)]
if (ndef_output == NULL) { if (ndef_output == NULL) {
usage (argv[0]); usage(argv[0]);
exit (EXIT_FAILURE); exit(EXIT_FAILURE);
} }
FILE* message_stream = NULL; FILE *message_stream = NULL;
FILE* ndef_stream = NULL; FILE *ndef_stream = NULL;
if ((strlen (ndef_output) == 1) && (ndef_output[0] == '-')) { if ((strlen(ndef_output) == 1) && (ndef_output[0] == '-')) {
message_stream = stderr; message_stream = stderr;
ndef_stream = stdout; ndef_stream = stdout;
} else { } else {
message_stream = stdout; message_stream = stdout;
ndef_stream = fopen(ndef_output, "wb"); ndef_stream = fopen(ndef_output, "wb");
if (!ndef_stream) { if (!ndef_stream) {
fprintf (stderr, "Could not open file %s.\n", ndef_output); fprintf(stderr, "Could not open file %s.\n", ndef_output);
exit (EXIT_FAILURE); exit(EXIT_FAILURE);
} }
} }
@ -125,72 +125,72 @@ main(int argc, char *argv[])
size_t device_count; size_t device_count;
nfc_context *context; nfc_context *context;
nfc_init (&context); nfc_init(&context);
if (context == NULL) if (context == NULL)
errx(EXIT_FAILURE, "Unable to init libnfc (malloc)"); errx(EXIT_FAILURE, "Unable to init libnfc (malloc)");
device_count = nfc_list_devices (context, devices, 8); device_count = nfc_list_devices(context, devices, 8);
if (device_count <= 0) if (device_count <= 0)
errx (EXIT_FAILURE, "No NFC device found."); errx(EXIT_FAILURE, "No NFC device found.");
for (size_t d = 0; d < device_count; d++) { for (size_t d = 0; d < device_count; d++) {
device = nfc_open (context, devices[d]); device = nfc_open(context, devices[d]);
if (!device) { if (!device) {
warnx ("nfc_open() failed."); warnx("nfc_open() failed.");
error = EXIT_FAILURE; error = EXIT_FAILURE;
continue; continue;
} }
tags = freefare_get_tags (device); tags = freefare_get_tags(device);
if (!tags) { if (!tags) {
nfc_close (device); nfc_close(device);
errx (EXIT_FAILURE, "Error listing tags."); errx(EXIT_FAILURE, "Error listing tags.");
} }
for (int i = 0; (!error) && tags[i]; i++) { for (int i = 0; (!error) && tags[i]; i++) {
if (MIFARE_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]);
char buffer[BUFSIZ]; char buffer[BUFSIZ];
fprintf (message_stream, "Found %s with UID %s. ", freefare_get_tag_friendly_name (tags[i]), tag_uid); fprintf(message_stream, "Found %s with UID %s. ", freefare_get_tag_friendly_name(tags[i]), tag_uid);
bool read_ndef = true; bool read_ndef = true;
if (read_options.interactive) { if (read_options.interactive) {
fprintf (message_stream, "Read NDEF [yN] "); fprintf(message_stream, "Read NDEF [yN] ");
fgets (buffer, BUFSIZ, stdin); fgets(buffer, BUFSIZ, stdin);
read_ndef = ((buffer[0] == 'y') || (buffer[0] == 'Y')); read_ndef = ((buffer[0] == 'y') || (buffer[0] == 'Y'));
} else { } else {
fprintf (message_stream, "\n"); fprintf(message_stream, "\n");
} }
if (read_ndef) { if (read_ndef) {
int res; int res;
res = mifare_desfire_connect (tags[i]); res = mifare_desfire_connect(tags[i]);
if (res < 0) { if (res < 0) {
warnx ("Can't connect to Mifare DESFire target."); warnx("Can't connect to Mifare DESFire target.");
error = EXIT_FAILURE; error = EXIT_FAILURE;
break; break;
} }
// We've to track DESFire version as NDEF mapping is different // We've to track DESFire version as NDEF mapping is different
struct mifare_desfire_version_info info; struct mifare_desfire_version_info info;
res = mifare_desfire_get_version (tags[i], &info); res = mifare_desfire_get_version(tags[i], &info);
if (res < 0) { if (res < 0) {
freefare_perror (tags[i], "mifare_desfire_get_version"); freefare_perror(tags[i], "mifare_desfire_get_version");
error = 1; error = 1;
break; break;
} }
MifareDESFireKey key_app; MifareDESFireKey key_app;
key_app = mifare_desfire_des_key_new_with_version (key_data_app); key_app = mifare_desfire_des_key_new_with_version(key_data_app);
// Mifare DESFire SelectApplication (Select application) // Mifare DESFire SelectApplication (Select application)
MifareDESFireAID aid; MifareDESFireAID aid;
if (info.software.version_major==0) if (info.software.version_major == 0)
aid = mifare_desfire_aid_new(0xEEEE10); aid = mifare_desfire_aid_new(0xEEEE10);
else else
// There is no more relationship between DESFire AID and ISO AID... // There is no more relationship between DESFire AID and ISO AID...
@ -198,80 +198,80 @@ main(int argc, char *argv[])
aid = mifare_desfire_aid_new(0x000001); aid = mifare_desfire_aid_new(0x000001);
res = mifare_desfire_select_application(tags[i], aid); res = mifare_desfire_select_application(tags[i], aid);
if (res < 0) if (res < 0)
errx (EXIT_FAILURE, "Application selection failed. Try mifare-desfire-create-ndef before running %s.", argv[0]); errx(EXIT_FAILURE, "Application selection failed. Try mifare-desfire-create-ndef before running %s.", argv[0]);
free (aid); free(aid);
// Authentication with NDEF Tag Application master key (Authentication with key 0) // Authentication with NDEF Tag Application master key (Authentication with key 0)
res = mifare_desfire_authenticate (tags[i], 0, key_app); res = mifare_desfire_authenticate(tags[i], 0, key_app);
if (res < 0) if (res < 0)
errx (EXIT_FAILURE, "Authentication with NDEF Tag Application master key failed"); errx(EXIT_FAILURE, "Authentication with NDEF Tag Application master key failed");
// Read Capability Container file E103 // Read Capability Container file E103
uint8_t lendata[20]; // cf FIXME in mifare_desfire.c read_data() uint8_t lendata[20]; // cf FIXME in mifare_desfire.c read_data()
if (info.software.version_major==0) if (info.software.version_major == 0)
res = mifare_desfire_read_data (tags[i], 0x03, 0, 2, lendata); res = mifare_desfire_read_data(tags[i], 0x03, 0, 2, lendata);
else else
// There is no more relationship between DESFire FID and ISO FileID... // There is no more relationship between DESFire FID and ISO FileID...
// Let's assume it's in FID 01h as proposed in the spec // Let's assume it's in FID 01h as proposed in the spec
res = mifare_desfire_read_data (tags[i], 0x01, 0, 2, lendata); res = mifare_desfire_read_data(tags[i], 0x01, 0, 2, lendata);
if (res < 0) if (res < 0)
errx (EXIT_FAILURE, "Read CC len failed"); errx(EXIT_FAILURE, "Read CC len failed");
uint16_t cclen = (((uint16_t) lendata[0]) << 8) + ((uint16_t) lendata[1]); uint16_t cclen = (((uint16_t) lendata[0]) << 8) + ((uint16_t) lendata[1]);
if (cclen < 15) if (cclen < 15)
errx (EXIT_FAILURE, "CC too short IMHO"); errx(EXIT_FAILURE, "CC too short IMHO");
if (!(cc_data = malloc(cclen+20))) // cf FIXME in mifare_desfire.c read_data() if (!(cc_data = malloc(cclen + 20))) // cf FIXME in mifare_desfire.c read_data()
errx (EXIT_FAILURE, "malloc"); errx(EXIT_FAILURE, "malloc");
if (info.software.version_major==0) if (info.software.version_major == 0)
res = mifare_desfire_read_data (tags[i], 0x03, 0, cclen, cc_data); res = mifare_desfire_read_data(tags[i], 0x03, 0, cclen, cc_data);
else else
res = mifare_desfire_read_data (tags[i], 0x01, 0, cclen, cc_data); res = mifare_desfire_read_data(tags[i], 0x01, 0, cclen, cc_data);
if (res < 0) if (res < 0)
errx (EXIT_FAILURE, "Read CC data failed"); errx(EXIT_FAILURE, "Read CC data failed");
// Search NDEF File Control TLV // Search NDEF File Control TLV
uint8_t off = 7; uint8_t off = 7;
while (((off+7) < cclen) && (cc_data[off] != 0x04)) { while (((off + 7) < cclen) && (cc_data[off] != 0x04)) {
// Skip TLV // Skip TLV
off += cc_data[off+1] + 2; off += cc_data[off + 1] + 2;
} }
if (off+7 >= cclen) if (off + 7 >= cclen)
errx (EXIT_FAILURE, "CC does not contain expected NDEF File Control TLV"); errx(EXIT_FAILURE, "CC does not contain expected NDEF File Control TLV");
if (cc_data[off+2] != 0xE1) if (cc_data[off + 2] != 0xE1)
errx (EXIT_FAILURE, "Unknown NDEF File reference in CC"); errx(EXIT_FAILURE, "Unknown NDEF File reference in CC");
uint8_t file_no; uint8_t file_no;
if (info.software.version_major==0) if (info.software.version_major == 0)
file_no = cc_data[off+3]; file_no = cc_data[off + 3];
else else
// There is no more relationship between DESFire FID and ISO FileID... // There is no more relationship between DESFire FID and ISO FileID...
// Let's assume it's in FID 02h as proposed in the spec // Let's assume it's in FID 02h as proposed in the spec
file_no = 2; file_no = 2;
uint16_t ndefmaxlen = (((uint16_t) cc_data[off+4]) << 8) + ((uint16_t) cc_data[off+5]); uint16_t ndefmaxlen = (((uint16_t) cc_data[off + 4]) << 8) + ((uint16_t) cc_data[off + 5]);
fprintf (message_stream, "Max NDEF size: %i bytes\n", ndefmaxlen); fprintf(message_stream, "Max NDEF size: %i bytes\n", ndefmaxlen);
if (!(ndef_msg = malloc(ndefmaxlen+20))) // cf FIXME in mifare_desfire.c read_data() if (!(ndef_msg = malloc(ndefmaxlen + 20))) // cf FIXME in mifare_desfire.c read_data()
errx (EXIT_FAILURE, "malloc"); errx(EXIT_FAILURE, "malloc");
res = mifare_desfire_read_data (tags[i], file_no, 0, 2, lendata); res = mifare_desfire_read_data(tags[i], file_no, 0, 2, lendata);
if (res < 0) if (res < 0)
errx (EXIT_FAILURE, "Read NDEF len failed"); errx(EXIT_FAILURE, "Read NDEF len failed");
ndef_msg_len = (((uint16_t) lendata[0]) << 8) + ((uint16_t) lendata[1]); ndef_msg_len = (((uint16_t) lendata[0]) << 8) + ((uint16_t) lendata[1]);
fprintf (message_stream, "NDEF size: %i bytes\n", ndef_msg_len); fprintf(message_stream, "NDEF size: %i bytes\n", ndef_msg_len);
if (ndef_msg_len + 2 > ndefmaxlen) if (ndef_msg_len + 2 > ndefmaxlen)
errx (EXIT_FAILURE, "Declared NDEF size larger than max NDEF size"); errx(EXIT_FAILURE, "Declared NDEF size larger than max NDEF size");
res = mifare_desfire_read_data (tags[i], file_no, 2, ndef_msg_len, ndef_msg); res = mifare_desfire_read_data(tags[i], file_no, 2, ndef_msg_len, ndef_msg);
if (res < 0) if (res < 0)
errx (EXIT_FAILURE, "Read data failed"); errx(EXIT_FAILURE, "Read data failed");
if (fwrite (ndef_msg, 1, ndef_msg_len, ndef_stream) != ndef_msg_len) if (fwrite(ndef_msg, 1, ndef_msg_len, ndef_stream) != ndef_msg_len)
errx (EXIT_FAILURE, "Write to file failed"); errx(EXIT_FAILURE, "Write to file failed");
free (cc_data); free(cc_data);
free (ndef_msg); free(ndef_msg);
mifare_desfire_key_free (key_app); mifare_desfire_key_free(key_app);
mifare_desfire_disconnect (tags[i]); mifare_desfire_disconnect(tags[i]);
} }
free (tag_uid); free(tag_uid);
} }
freefare_free_tags (tags); freefare_free_tags(tags);
nfc_close (device); nfc_close(device);
} }
nfc_exit (context); nfc_exit(context);
exit (error); exit(error);
} }

View file

@ -62,12 +62,12 @@ struct {
static void static void
usage(char *progname) usage(char *progname)
{ {
fprintf (stderr, "This application writes a NDEF payload into a Mifare DESFire formatted as NFC Forum Type 4 Tag.\n"); fprintf(stderr, "This application writes a NDEF payload into a Mifare DESFire formatted as NFC Forum Type 4 Tag.\n");
fprintf (stderr, "usage: %s [-y] -i FILE [-k 11223344AABBCCDD]\n", progname); fprintf(stderr, "usage: %s [-y] -i FILE [-k 11223344AABBCCDD]\n", progname);
fprintf (stderr, "\nOptions:\n"); fprintf(stderr, "\nOptions:\n");
fprintf (stderr, " -y Do not ask for confirmation\n"); fprintf(stderr, " -y Do not ask for confirmation\n");
fprintf (stderr, " -i Use FILE as NDEF message to write on card (\"-\" = stdin)\n"); fprintf(stderr, " -i Use FILE as NDEF message to write on card (\"-\" = stdin)\n");
fprintf (stderr, " -k Provide another NDEF Tag Application key than the default one\n"); fprintf(stderr, " -k Provide another NDEF Tag Application key than the default one\n");
} }
int int
@ -79,146 +79,146 @@ main(int argc, char *argv[])
FreefareTag *tags = NULL; FreefareTag *tags = NULL;
char *ndef_input = NULL; char *ndef_input = NULL;
while ((ch = getopt (argc, argv, "hyi:k:")) != -1) { while ((ch = getopt(argc, argv, "hyi:k:")) != -1) {
switch (ch) { switch (ch) {
case 'h': case 'h':
usage(argv[0]); usage(argv[0]);
exit (EXIT_SUCCESS); exit(EXIT_SUCCESS);
break; break;
case 'y': case 'y':
write_options.interactive = false; write_options.interactive = false;
break; break;
case 'i': case 'i':
ndef_input = optarg; ndef_input = optarg;
break; break;
case 'k': case 'k':
if (strlen(optarg) != 16) { if (strlen(optarg) != 16) {
usage(argv[0]); usage(argv[0]);
exit (EXIT_FAILURE); exit(EXIT_FAILURE);
} }
uint64_t n = strtoull(optarg, NULL, 16); uint64_t n = strtoull(optarg, NULL, 16);
int i; int i;
for (i=7; i>=0; i--) { for (i = 7; i >= 0; i--) {
key_data_app[i] = (uint8_t) n; key_data_app[i] = (uint8_t) n;
n >>= 8; n >>= 8;
} }
break; break;
default: default:
usage(argv[0]); usage(argv[0]);
exit (EXIT_FAILURE); exit(EXIT_FAILURE);
} }
} }
// Remaining args, if any, are in argv[optind .. (argc-1)] // Remaining args, if any, are in argv[optind .. (argc-1)]
if (ndef_input == NULL) { if (ndef_input == NULL) {
ndef_msg_len = sizeof(ndef_default_msg) + 2; ndef_msg_len = sizeof(ndef_default_msg) + 2;
if (!(ndef_msg = malloc (ndef_msg_len))) { if (!(ndef_msg = malloc(ndef_msg_len))) {
err (EXIT_FAILURE, "malloc"); err(EXIT_FAILURE, "malloc");
} }
ndef_msg[0] = (uint8_t) ((ndef_msg_len - 2) >> 8); ndef_msg[0] = (uint8_t)((ndef_msg_len - 2) >> 8);
ndef_msg[1] = (uint8_t) (ndef_msg_len - 2); ndef_msg[1] = (uint8_t)(ndef_msg_len - 2);
memcpy(ndef_msg + 2, ndef_default_msg, ndef_msg_len - 2); memcpy(ndef_msg + 2, ndef_default_msg, ndef_msg_len - 2);
} else { } else {
FILE* ndef_stream = NULL; FILE *ndef_stream = NULL;
if ((strlen (ndef_input) == 1) && (ndef_input[0] == '-')) { if ((strlen(ndef_input) == 1) && (ndef_input[0] == '-')) {
// FIXME stdin as input have to be readed and buffered in ndef_msg // FIXME stdin as input have to be readed and buffered in ndef_msg
ndef_stream = stdin; ndef_stream = stdin;
fprintf (stderr, "stdin as NDEF is not implemented"); fprintf(stderr, "stdin as NDEF is not implemented");
exit (EXIT_FAILURE); exit(EXIT_FAILURE);
} else { } else {
ndef_stream = fopen(ndef_input, "rb"); ndef_stream = fopen(ndef_input, "rb");
if (!ndef_stream) { if (!ndef_stream) {
fprintf (stderr, "Could not open file %s.\n", ndef_input); fprintf(stderr, "Could not open file %s.\n", ndef_input);
exit (EXIT_FAILURE); exit(EXIT_FAILURE);
} }
fseek(ndef_stream, 0L, SEEK_END); fseek(ndef_stream, 0L, SEEK_END);
ndef_msg_len = ftell(ndef_stream) + 2; ndef_msg_len = ftell(ndef_stream) + 2;
fseek(ndef_stream, 0L, SEEK_SET); fseek(ndef_stream, 0L, SEEK_SET);
if (!(ndef_msg = malloc (ndef_msg_len))) { if (!(ndef_msg = malloc(ndef_msg_len))) {
err (EXIT_FAILURE, "malloc"); err(EXIT_FAILURE, "malloc");
} }
ndef_msg[0] = (uint8_t) ((ndef_msg_len - 2) >> 8); ndef_msg[0] = (uint8_t)((ndef_msg_len - 2) >> 8);
ndef_msg[1] = (uint8_t) (ndef_msg_len - 2); ndef_msg[1] = (uint8_t)(ndef_msg_len - 2);
if (fread (ndef_msg + 2, 1, ndef_msg_len - 2, ndef_stream) != ndef_msg_len - 2) { if (fread(ndef_msg + 2, 1, ndef_msg_len - 2, ndef_stream) != ndef_msg_len - 2) {
fprintf (stderr, "Could not read NDEF from file: %s\n", ndef_input); fprintf(stderr, "Could not read NDEF from file: %s\n", ndef_input);
fclose (ndef_stream); fclose(ndef_stream);
exit (EXIT_FAILURE); exit(EXIT_FAILURE);
} }
fclose (ndef_stream); fclose(ndef_stream);
} }
} }
printf ("NDEF file is %zu bytes long.\n", ndef_msg_len); printf("NDEF file is %zu bytes long.\n", ndef_msg_len);
nfc_connstring devices[8]; nfc_connstring devices[8];
size_t device_count; size_t device_count;
nfc_context *context; nfc_context *context;
nfc_init (&context); nfc_init(&context);
if (context == NULL) if (context == NULL)
errx(EXIT_FAILURE, "Unable to init libnfc (malloc)"); errx(EXIT_FAILURE, "Unable to init libnfc (malloc)");
device_count = nfc_list_devices (context, devices, 8); device_count = nfc_list_devices(context, devices, 8);
if (device_count <= 0) if (device_count <= 0)
errx (EXIT_FAILURE, "No NFC device found."); errx(EXIT_FAILURE, "No NFC device found.");
for (size_t d = 0; d < device_count; d++) { for (size_t d = 0; d < device_count; d++) {
device = nfc_open (context, devices[d]); device = nfc_open(context, devices[d]);
if (!device) { if (!device) {
warnx ("nfc_open() failed."); warnx("nfc_open() failed.");
error = EXIT_FAILURE; error = EXIT_FAILURE;
continue; continue;
} }
tags = freefare_get_tags (device); tags = freefare_get_tags(device);
if (!tags) { if (!tags) {
nfc_close (device); nfc_close(device);
errx (EXIT_FAILURE, "Error listing tags."); errx(EXIT_FAILURE, "Error listing tags.");
} }
for (int i = 0; (!error) && tags[i]; i++) { for (int i = 0; (!error) && tags[i]; i++) {
if (MIFARE_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]);
char buffer[BUFSIZ]; char buffer[BUFSIZ];
printf ("Found %s with UID %s. ", freefare_get_tag_friendly_name (tags[i]), tag_uid); printf("Found %s with UID %s. ", freefare_get_tag_friendly_name(tags[i]), tag_uid);
bool write_ndef = true; bool write_ndef = true;
if (write_options.interactive) { if (write_options.interactive) {
printf ("Write NDEF [yN] "); printf("Write NDEF [yN] ");
fgets (buffer, BUFSIZ, stdin); fgets(buffer, BUFSIZ, stdin);
write_ndef = ((buffer[0] == 'y') || (buffer[0] == 'Y')); write_ndef = ((buffer[0] == 'y') || (buffer[0] == 'Y'));
} else { } else {
printf ("\n"); printf("\n");
} }
if (write_ndef) { if (write_ndef) {
int res; int res;
res = mifare_desfire_connect (tags[i]); res = mifare_desfire_connect(tags[i]);
if (res < 0) { if (res < 0) {
warnx ("Can't connect to Mifare DESFire target."); warnx("Can't connect to Mifare DESFire target.");
error = EXIT_FAILURE; error = EXIT_FAILURE;
break; break;
} }
// We've to track DESFire version as NDEF mapping is different // We've to track DESFire version as NDEF mapping is different
struct mifare_desfire_version_info info; struct mifare_desfire_version_info info;
res = mifare_desfire_get_version (tags[i], &info); res = mifare_desfire_get_version(tags[i], &info);
if (res < 0) { if (res < 0) {
freefare_perror (tags[i], "mifare_desfire_get_version"); freefare_perror(tags[i], "mifare_desfire_get_version");
error = 1; error = 1;
break; break;
} }
MifareDESFireKey key_app; MifareDESFireKey key_app;
key_app = mifare_desfire_des_key_new_with_version (key_data_app); key_app = mifare_desfire_des_key_new_with_version(key_data_app);
// Mifare DESFire SelectApplication (Select application) // Mifare DESFire SelectApplication (Select application)
MifareDESFireAID aid; MifareDESFireAID aid;
if (info.software.version_major==0) if (info.software.version_major == 0)
aid = mifare_desfire_aid_new(0xEEEE10); aid = mifare_desfire_aid_new(0xEEEE10);
else else
// There is no more relationship between DESFire AID and ISO AID... // There is no more relationship between DESFire AID and ISO AID...
@ -227,74 +227,74 @@ main(int argc, char *argv[])
res = mifare_desfire_select_application(tags[i], aid); res = mifare_desfire_select_application(tags[i], aid);
if (res < 0) if (res < 0)
errx (EXIT_FAILURE, "Application selection failed. Try mifare-desfire-create-ndef before running %s.", argv[0]); errx(EXIT_FAILURE, "Application selection failed. Try mifare-desfire-create-ndef before running %s.", argv[0]);
free (aid); free(aid);
// Authentication with NDEF Tag Application master key (Authentication with key 0) // Authentication with NDEF Tag Application master key (Authentication with key 0)
res = mifare_desfire_authenticate (tags[i], 0, key_app); res = mifare_desfire_authenticate(tags[i], 0, key_app);
if (res < 0) if (res < 0)
errx (EXIT_FAILURE, "Authentication with NDEF Tag Application master key failed"); errx(EXIT_FAILURE, "Authentication with NDEF Tag Application master key failed");
// Read Capability Container file E103 // Read Capability Container file E103
uint8_t lendata[20]; // cf FIXME in mifare_desfire.c read_data() uint8_t lendata[20]; // cf FIXME in mifare_desfire.c read_data()
if (info.software.version_major==0) if (info.software.version_major == 0)
res = mifare_desfire_read_data (tags[i], 0x03, 0, 2, lendata); res = mifare_desfire_read_data(tags[i], 0x03, 0, 2, lendata);
else else
// There is no more relationship between DESFire FID and ISO FileID... // There is no more relationship between DESFire FID and ISO FileID...
// Let's assume it's in FID 01h as proposed in the spec // Let's assume it's in FID 01h as proposed in the spec
res = mifare_desfire_read_data (tags[i], 0x01, 0, 2, lendata); res = mifare_desfire_read_data(tags[i], 0x01, 0, 2, lendata);
if (res < 0) if (res < 0)
errx (EXIT_FAILURE, "Read CC len failed"); errx(EXIT_FAILURE, "Read CC len failed");
uint16_t cclen = (((uint16_t) lendata[0]) << 8) + ((uint16_t) lendata[1]); uint16_t cclen = (((uint16_t) lendata[0]) << 8) + ((uint16_t) lendata[1]);
if (cclen < 15) if (cclen < 15)
errx (EXIT_FAILURE, "CC too short IMHO"); errx(EXIT_FAILURE, "CC too short IMHO");
if (!(cc_data = malloc(cclen + 20))) // cf FIXME in mifare_desfire.c read_data() if (!(cc_data = malloc(cclen + 20))) // cf FIXME in mifare_desfire.c read_data()
errx (EXIT_FAILURE, "malloc"); errx(EXIT_FAILURE, "malloc");
if (info.software.version_major==0) if (info.software.version_major == 0)
res = mifare_desfire_read_data (tags[i], 0x03, 0, cclen, cc_data); res = mifare_desfire_read_data(tags[i], 0x03, 0, cclen, cc_data);
else else
res = mifare_desfire_read_data (tags[i], 0x01, 0, cclen, cc_data); res = mifare_desfire_read_data(tags[i], 0x01, 0, cclen, cc_data);
if (res < 0) if (res < 0)
errx (EXIT_FAILURE, "Read CC data failed"); errx(EXIT_FAILURE, "Read CC data failed");
// Search NDEF File Control TLV // Search NDEF File Control TLV
uint8_t off = 7; uint8_t off = 7;
while (((off+7) < cclen) && (cc_data[off] != 0x04)) { while (((off + 7) < cclen) && (cc_data[off] != 0x04)) {
// Skip TLV // Skip TLV
off += cc_data[off+1] + 2; off += cc_data[off + 1] + 2;
} }
if (off+7 >= cclen) if (off + 7 >= cclen)
errx (EXIT_FAILURE, "CC does not contain expected NDEF File Control TLV"); errx(EXIT_FAILURE, "CC does not contain expected NDEF File Control TLV");
if (cc_data[off+2] != 0xE1) if (cc_data[off + 2] != 0xE1)
errx (EXIT_FAILURE, "Unknown NDEF File reference in CC"); errx(EXIT_FAILURE, "Unknown NDEF File reference in CC");
uint8_t file_no; uint8_t file_no;
if (info.software.version_major==0) if (info.software.version_major == 0)
file_no = cc_data[off+3]; file_no = cc_data[off + 3];
else else
// There is no more relationship between DESFire FID and ISO FileID... // There is no more relationship between DESFire FID and ISO FileID...
// Let's assume it's in FID 02h as proposed in the spec // Let's assume it's in FID 02h as proposed in the spec
file_no = 2; file_no = 2;
uint16_t ndefmaxlen = (((uint16_t) cc_data[off+4]) << 8) + ((uint16_t) cc_data[off+5]); uint16_t ndefmaxlen = (((uint16_t) cc_data[off + 4]) << 8) + ((uint16_t) cc_data[off + 5]);
fprintf (stdout, "Max NDEF size: %i bytes\n", ndefmaxlen); fprintf(stdout, "Max NDEF size: %i bytes\n", ndefmaxlen);
if (ndef_msg_len > ndefmaxlen) if (ndef_msg_len > ndefmaxlen)
errx (EXIT_FAILURE, "Supplied NDEF larger than max NDEF size"); errx(EXIT_FAILURE, "Supplied NDEF larger than max NDEF size");
//Mifare DESFire WriteData to write the content of the NDEF File with NLEN equal to NDEF Message length and NDEF Message //Mifare DESFire WriteData to write the content of the NDEF File with NLEN equal to NDEF Message length and NDEF Message
res = mifare_desfire_write_data(tags[i], file_no, 0, ndef_msg_len, (uint8_t *) ndef_msg); res = mifare_desfire_write_data(tags[i], file_no, 0, ndef_msg_len, (uint8_t *) ndef_msg);
if (res < 0) if (res < 0)
errx (EXIT_FAILURE, " Write data failed"); errx(EXIT_FAILURE, " Write data failed");
free(cc_data); free(cc_data);
mifare_desfire_key_free (key_app); mifare_desfire_key_free(key_app);
mifare_desfire_disconnect (tags[i]); mifare_desfire_disconnect(tags[i]);
} }
free (tag_uid); free(tag_uid);
} }
free (ndef_msg); free(ndef_msg);
freefare_free_tags (tags); freefare_free_tags(tags);
nfc_close (device); nfc_close(device);
} }
nfc_exit (context); nfc_exit(context);
exit (error); exit(error);
} }

View file

@ -22,41 +22,41 @@
#include <freefare.h> #include <freefare.h>
int int
main (int argc, char *argv[]) main(int argc, char *argv[])
{ {
int error = EXIT_SUCCESS; int error = EXIT_SUCCESS;
nfc_device *device = NULL; nfc_device *device = NULL;
FreefareTag *tags = NULL; FreefareTag *tags = NULL;
if (argc > 1) if (argc > 1)
errx (EXIT_FAILURE, "usage: %s", argv[0]); errx(EXIT_FAILURE, "usage: %s", argv[0]);
nfc_connstring devices[8]; nfc_connstring devices[8];
size_t device_count; size_t device_count;
nfc_context *context; nfc_context *context;
nfc_init (&context); nfc_init(&context);
if (context == NULL) if (context == NULL)
errx(EXIT_FAILURE, "Unable to init libnfc (malloc)"); errx(EXIT_FAILURE, "Unable to init libnfc (malloc)");
device_count = nfc_list_devices (context, devices, sizeof (devices) / sizeof (*devices)); device_count = nfc_list_devices(context, devices, sizeof(devices) / sizeof(*devices));
if (device_count <= 0) if (device_count <= 0)
errx (EXIT_FAILURE, "No NFC device found"); errx(EXIT_FAILURE, "No NFC device found");
for (size_t d = 0; d < device_count; d++) { for (size_t d = 0; d < device_count; d++) {
if (!(device = nfc_open (context, devices[d]))) { if (!(device = nfc_open(context, devices[d]))) {
warnx ("nfc_open() failed."); warnx("nfc_open() failed.");
error = EXIT_FAILURE; error = EXIT_FAILURE;
continue; continue;
} }
if (!(tags = freefare_get_tags (device))) { if (!(tags = freefare_get_tags(device))) {
nfc_close (device); nfc_close(device);
errx (EXIT_FAILURE, "Error listing tags."); errx(EXIT_FAILURE, "Error listing tags.");
} }
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 MIFARE_ULTRALIGHT: case MIFARE_ULTRALIGHT:
case MIFARE_ULTRALIGHT_C: case MIFARE_ULTRALIGHT_C:
break; break;
@ -64,28 +64,28 @@ main (int argc, char *argv[])
continue; continue;
} }
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]) == MIFARE_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;
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);
if (mifare_ultralight_connect (tag) < 0) if (mifare_ultralight_connect(tag) < 0)
errx (EXIT_FAILURE, "Error connecting to tag."); errx(EXIT_FAILURE, "Error connecting to tag.");
res = mifare_ultralightc_authenticate (tag, key); res = mifare_ultralightc_authenticate(tag, key);
printf ("Authentication with default key: %s\n", res ? "fail" : "success"); printf("Authentication with default key: %s\n", res ? "fail" : "success");
mifare_desfire_key_free (key); mifare_desfire_key_free(key);
mifare_ultralight_disconnect (tag); mifare_ultralight_disconnect(tag);
} }
free (tag_uid); free(tag_uid);
} }
freefare_free_tags (tags); freefare_free_tags(tags);
nfc_close (device); nfc_close(device);
} }
nfc_exit (context); nfc_exit(context);
exit(error); exit(error);
} }

View file

@ -39,7 +39,7 @@ main(int argc, char *argv[])
if (context == NULL) if (context == NULL)
errx(EXIT_FAILURE, "Unable to init libnfc (malloc)"); errx(EXIT_FAILURE, "Unable to init libnfc (malloc)");
device_count = nfc_list_devices (context, devices, sizeof (devices) / sizeof (*devices)); device_count = nfc_list_devices(context, devices, sizeof(devices) / sizeof(*devices));
if (device_count <= 0) if (device_count <= 0)
errx(EXIT_FAILURE, "No NFC device found"); errx(EXIT_FAILURE, "No NFC device found");

View file

@ -40,7 +40,7 @@ main(int argc, char *argv[])
if (context == NULL) if (context == NULL)
errx(EXIT_FAILURE, "Unable to init libnfc (malloc)"); errx(EXIT_FAILURE, "Unable to init libnfc (malloc)");
device_count = nfc_list_devices(context, devices, sizeof (devices) / sizeof (*devices)); device_count = nfc_list_devices(context, devices, sizeof(devices) / sizeof(*devices));
if (device_count <= 0) if (device_count <= 0)
errx(EXIT_FAILURE, "No NFC device found"); errx(EXIT_FAILURE, "No NFC device found");
@ -71,14 +71,14 @@ main(int argc, char *argv[])
if (ntag21x_connect(tag) < 0) if (ntag21x_connect(tag) < 0)
errx(EXIT_FAILURE, "Error connecting to tag."); errx(EXIT_FAILURE, "Error connecting to tag.");
uint8_t pwd[4] = {0xff,0xff,0xff,0xff}; uint8_t pwd[4] = {0xff, 0xff, 0xff, 0xff};
uint8_t pack[2] = {0xaa,0xaa}; uint8_t pack[2] = {0xaa, 0xaa};
uint8_t pack_old[2] = {0x00,0x00}; uint8_t pack_old[2] = {0x00, 0x00};
NTAG21xKey key; NTAG21xKey key;
NTAG21xKey key_old; NTAG21xKey key_old;
key = ntag21x_key_new(pwd,pack); // Creating key key = ntag21x_key_new(pwd, pack); // Creating key
key_old = ntag21x_key_new(pwd,pack_old); // Creating key key_old = ntag21x_key_new(pwd, pack_old); // Creating key
uint8_t auth0 = 0x00; // Buffer for auth0 byte uint8_t auth0 = 0x00; // Buffer for auth0 byte
@ -89,48 +89,48 @@ main(int argc, char *argv[])
MUST do, because here we are recognizing tag subtype (NTAG213,NTAG215,NTAG216), and gathering all parameters MUST do, because here we are recognizing tag subtype (NTAG213,NTAG215,NTAG216), and gathering all parameters
*/ */
res = ntag21x_get_info(tag); res = ntag21x_get_info(tag);
if(res < 0) { if (res < 0) {
printf("Error getting info from tag\n"); printf("Error getting info from tag\n");
break; break;
} }
// Authenticate with tag // Authenticate with tag
res = ntag21x_authenticate(tag,key); res = ntag21x_authenticate(tag, key);
if(res < 0) { if (res < 0) {
printf("Error getting info from tag\n"); printf("Error getting info from tag\n");
break; break;
} }
// Get auth byte from tag // Get auth byte from tag
res = ntag21x_get_auth(tag,&auth0); res = ntag21x_get_auth(tag, &auth0);
if(res < 0) { if (res < 0) {
printf("Error getting auth0 byte from tag\n"); printf("Error getting auth0 byte from tag\n");
break; break;
} }
printf("Old auth0: %#02x\n",auth0); printf("Old auth0: %#02x\n", auth0);
// Set old key // Set old key
res = ntag21x_set_key(tag,key_old); res = ntag21x_set_key(tag, key_old);
if(res < 0) { if (res < 0) {
printf("Error setting key tag\n"); printf("Error setting key tag\n");
break; break;
} }
// Disable password protection (when auth0 byte > last page) // Disable password protection (when auth0 byte > last page)
res = ntag21x_set_auth(tag,0xff); res = ntag21x_set_auth(tag, 0xff);
if(res<0) { if (res < 0) {
printf("Error setting auth0 byte \n"); printf("Error setting auth0 byte \n");
break; break;
} }
// Disable read & write pwd protection -> (default: write only protection) // Disable read & write pwd protection -> (default: write only protection)
res = ntag21x_access_disable(tag,NTAG_PROT); res = ntag21x_access_disable(tag, NTAG_PROT);
if(res < 0) { if (res < 0) {
printf("Error setting access byte \n"); printf("Error setting access byte \n");
break; break;
} }
// Get auth byte from tag // Get auth byte from tag
res = ntag21x_get_auth(tag,&auth0); res = ntag21x_get_auth(tag, &auth0);
if(res < 0) { if (res < 0) {
printf("Error getting auth0 byte from tag\n"); printf("Error getting auth0 byte from tag\n");
break; break;
} }
printf("New auth0: %#02x\n",auth0); printf("New auth0: %#02x\n", auth0);
} }
ntag21x_disconnect(tag); ntag21x_disconnect(tag);

View file

@ -36,22 +36,22 @@ main(int argc, char *argv[])
size_t device_count; size_t device_count;
nfc_context *context; nfc_context *context;
nfc_init (&context); nfc_init(&context);
if (context == NULL) if (context == NULL)
errx(EXIT_FAILURE, "Unable to init libnfc (malloc)"); errx(EXIT_FAILURE, "Unable to init libnfc (malloc)");
device_count = nfc_list_devices (context, devices, sizeof (devices) / sizeof (*devices)); device_count = nfc_list_devices(context, devices, sizeof(devices) / sizeof(*devices));
if (device_count <= 0) if (device_count <= 0)
errx(EXIT_FAILURE, "No NFC device found"); errx(EXIT_FAILURE, "No NFC device found");
for (size_t d = 0; d < device_count; d++) { for (size_t d = 0; d < device_count; d++) {
if (!(device = nfc_open (context, devices[d]))) { if (!(device = nfc_open(context, devices[d]))) {
warnx("nfc_open() failed."); warnx("nfc_open() failed.");
error = EXIT_FAILURE; error = EXIT_FAILURE;
continue; continue;
} }
if (!(tags = freefare_get_tags (device))) { if (!(tags = freefare_get_tags(device))) {
nfc_close(device); nfc_close(device);
errx(EXIT_FAILURE, "Error listing tags."); errx(EXIT_FAILURE, "Error listing tags.");
} }
@ -68,14 +68,14 @@ main(int argc, char *argv[])
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]));
FreefareTag tag = tags[i]; FreefareTag tag = tags[i];
int res; int res;
if (ntag21x_connect (tag) < 0) if (ntag21x_connect(tag) < 0)
errx(EXIT_FAILURE, "Error connecting to tag."); errx(EXIT_FAILURE, "Error connecting to tag.");
uint8_t pwd[4] = {0xff,0xff,0xff,0xff}; uint8_t pwd[4] = {0xff, 0xff, 0xff, 0xff};
uint8_t pack[2] = {0xaa,0xaa}; uint8_t pack[2] = {0xaa, 0xaa};
NTAG21xKey key; NTAG21xKey key;
key = ntag21x_key_new(pwd,pack); // Creating key key = ntag21x_key_new(pwd, pack); // Creating key
uint8_t auth0 = 0x00; // Buffer for auth0 byte uint8_t auth0 = 0x00; // Buffer for auth0 byte
uint8_t authlim = 0x00; uint8_t authlim = 0x00;
@ -86,57 +86,57 @@ main(int argc, char *argv[])
MUST do, because here we are recognizing tag subtype (NTAG213,NTAG215,NTAG216), and gathering all parameters MUST do, because here we are recognizing tag subtype (NTAG213,NTAG215,NTAG216), and gathering all parameters
*/ */
res = ntag21x_get_info(tag); res = ntag21x_get_info(tag);
if(res < 0) { if (res < 0) {
printf("Error getting info from tag\n"); printf("Error getting info from tag\n");
break; break;
} }
// Get auth byte from tag // Get auth byte from tag
res = ntag21x_get_auth(tag,&auth0); res = ntag21x_get_auth(tag, &auth0);
if(res < 0) { if (res < 0) {
printf("Error getting auth0 byte from tag\n"); printf("Error getting auth0 byte from tag\n");
break; break;
} }
printf("Old auth0: %#02x\n",auth0); printf("Old auth0: %#02x\n", auth0);
res = ntag21x_get_authentication_limit(tag,&authlim); res = ntag21x_get_authentication_limit(tag, &authlim);
if(res < 0) { if (res < 0) {
printf("Error getting auth0 byte from tag\n"); printf("Error getting auth0 byte from tag\n");
break; break;
} }
printf("Authlim: %#02x\n",authlim); printf("Authlim: %#02x\n", authlim);
// Check if auth is required to set pwd and pack // Check if auth is required to set pwd and pack
if(auth0 < ntag21x_get_last_page(tag) - 2) { // Check if last 2 pages are protected if (auth0 < ntag21x_get_last_page(tag) - 2) { // Check if last 2 pages are protected
printf("Error: pwd and PACK sections are protected with unknown password\n"); printf("Error: pwd and PACK sections are protected with unknown password\n");
break; break;
} }
// Set key // Set key
res = ntag21x_set_key(tag,key); res = ntag21x_set_key(tag, key);
if(res < 0) { if (res < 0) {
printf("Error setting key tag\n"); printf("Error setting key tag\n");
break; break;
} }
// Protect last 6 pages !! It can be hacked if you don't protect last 4 pages where auth0 byte is located // Protect last 6 pages !! It can be hacked if you don't protect last 4 pages where auth0 byte is located
res = ntag21x_set_auth(tag,ntag21x_get_last_page(tag)-5); res = ntag21x_set_auth(tag, ntag21x_get_last_page(tag) - 5);
if(res < 0) { if (res < 0) {
printf("Error setting auth0 byte \n"); printf("Error setting auth0 byte \n");
break; break;
} }
// Enable read & write pwd protection (default: write only protection) // Enable read & write pwd protection (default: write only protection)
res = ntag21x_access_enable(tag,NTAG_PROT); res = ntag21x_access_enable(tag, NTAG_PROT);
if(res < 0) { if (res < 0) {
printf("Error setting access byte \n"); printf("Error setting access byte \n");
break; break;
} }
// Get auth byte from tag // Get auth byte from tag
res = ntag21x_get_auth(tag,&auth0); res = ntag21x_get_auth(tag, &auth0);
if(res < 0) { if (res < 0) {
printf("Error getting auth0 byte from tag\n"); printf("Error getting auth0 byte from tag\n");
break; break;
} }
printf("New auth0: %#02x\n",auth0); printf("New auth0: %#02x\n", auth0);
} }
ntag21x_disconnect (tag); ntag21x_disconnect(tag);
ntag21x_key_free(key); // Delete key ntag21x_key_free(key); // Delete key
free (tag_uid); free(tag_uid);
} }
freefare_free_tags(tags); freefare_free_tags(tags);
nfc_close(device); nfc_close(device);

View file

@ -40,7 +40,7 @@ main(int argc, char *argv[])
if (context == NULL) if (context == NULL)
errx(EXIT_FAILURE, "Unable to init libnfc (malloc)"); errx(EXIT_FAILURE, "Unable to init libnfc (malloc)");
device_count = nfc_list_devices(context, devices, sizeof (devices) / sizeof (*devices)); device_count = nfc_list_devices(context, devices, sizeof(devices) / sizeof(*devices));
if (device_count <= 0) if (device_count <= 0)
errx(EXIT_FAILURE, "No NFC device found"); errx(EXIT_FAILURE, "No NFC device found");
@ -65,13 +65,13 @@ 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]));
FreefareTag tag = tags[i]; FreefareTag tag = tags[i];
int res; int res;
if (ntag21x_connect(tag) < 0) if (ntag21x_connect(tag) < 0)
errx(EXIT_FAILURE, "Error connecting to tag."); errx(EXIT_FAILURE, "Error connecting to tag.");
uint8_t data [4] = {0xfa,0xca,0xac,0xad}; // Data to write on tag uint8_t data [4] = {0xfa, 0xca, 0xac, 0xad}; // Data to write on tag
uint8_t read[4]; // Buffer for reading data from tag uint8_t read[4]; // Buffer for reading data from tag
bool flag_match = true; bool flag_match = true;
@ -82,28 +82,28 @@ main(int argc, char *argv[])
MUST do, because here we are recognizing tag subtype (NTAG213,NTAG215,NTAG216), and gathering all parameters MUST do, because here we are recognizing tag subtype (NTAG213,NTAG215,NTAG216), and gathering all parameters
*/ */
res = ntag21x_get_info(tag); res = ntag21x_get_info(tag);
if(res < 0) { if (res < 0) {
printf("Error getting info from tag\n"); printf("Error getting info from tag\n");
break; break;
} }
// writing to tag 4 bytes on page 0x27 (check specs for NTAG21x before changing page number !!!) // writing to tag 4 bytes on page 0x27 (check specs for NTAG21x before changing page number !!!)
res = ntag21x_write(tag,0x27,data); res = ntag21x_write(tag, 0x27, data);
if(res < 0) { if (res < 0) {
printf("Error writing to tag\n"); printf("Error writing to tag\n");
break; break;
} }
res = ntag21x_fast_read4(tag,0x27,read); // Reading page from tag (4 bytes), you can also use ntag21x_read4 or ntag21x_read (16 bytes) or ntag21x_fast_read (start_page to end_page) res = ntag21x_fast_read4(tag, 0x27, read); // Reading page from tag (4 bytes), you can also use ntag21x_read4 or ntag21x_read (16 bytes) or ntag21x_fast_read (start_page to end_page)
if(res < 0) { if (res < 0) {
printf("Error reading tag\n"); printf("Error reading tag\n");
break; break;
} }
for(int i=0;i < 4;i++) // Checking if we can read what we have written earlyer for (int i = 0; i < 4; i++) // Checking if we can read what we have written earlyer
if(data[i] != read[i]) { if (data[i] != read[i]) {
flag_match = false; flag_match = false;
break; break;
} }
if(!flag_match) if (!flag_match)
printf("Data don't match\n"); printf("Data don't match\n");
else else
printf("Data match\n"); printf("Data match\n");

View file

@ -44,27 +44,27 @@
#define MAX_BLOCK_COUNT 8 #define MAX_BLOCK_COUNT 8
inline static inline static
ssize_t felica_transceive (FreefareTag tag, uint8_t *data_in, uint8_t *data_out, size_t data_out_length) ssize_t felica_transceive(FreefareTag tag, uint8_t *data_in, uint8_t *data_out, size_t data_out_length)
{ {
DEBUG_XFER (data_in, data_in[0], "===> "); DEBUG_XFER(data_in, data_in[0], "===> ");
ssize_t res = nfc_initiator_transceive_bytes (tag->device, data_in, data_in[0], data_out, data_out_length, 0); ssize_t res = nfc_initiator_transceive_bytes(tag->device, data_in, data_in[0], data_out, data_out_length, 0);
DEBUG_XFER (data_out, res, "<=== "); DEBUG_XFER(data_out, res, "<=== ");
return res; return res;
} }
bool bool
felica_taste (nfc_device *device, nfc_target target) felica_taste(nfc_device *device, nfc_target target)
{ {
(void) device; (void) device;
return target.nm.nmt == NMT_FELICA; return target.nm.nmt == NMT_FELICA;
} }
FreefareTag FreefareTag
felica_tag_new (nfc_device *device, nfc_target target) felica_tag_new(nfc_device *device, nfc_target target)
{ {
FreefareTag tag; FreefareTag tag;
if ((tag = malloc (sizeof (struct felica_tag)))) { if ((tag = malloc(sizeof(struct felica_tag)))) {
tag->type = FELICA; tag->type = FELICA;
tag->free_tag = felica_tag_free; tag->free_tag = felica_tag_free;
tag->device = device; tag->device = device;
@ -76,18 +76,18 @@ felica_tag_new (nfc_device *device, nfc_target target)
} }
void void
felica_tag_free (FreefareTag tag) felica_tag_free(FreefareTag tag)
{ {
free (tag); free(tag);
} }
ssize_t ssize_t
felica_read_ex (FreefareTag tag, uint16_t service, uint8_t block_count, uint8_t blocks[], uint8_t *data, size_t length) felica_read_ex(FreefareTag tag, uint16_t service, uint8_t block_count, uint8_t blocks[], uint8_t *data, size_t length)
{ {
assert (block_count <= MAX_BLOCK_COUNT); assert(block_count <= MAX_BLOCK_COUNT);
assert (length == 16 * block_count); assert(length == 16 * block_count);
DEBUG_FUNCTION(); DEBUG_FUNCTION();
@ -104,43 +104,43 @@ felica_read_ex (FreefareTag tag, uint16_t service, uint8_t block_count, uint8_t
uint8_t res[100]; uint8_t res[100];
cmd[0] = 14 + 2 * block_count; cmd[0] = 14 + 2 * block_count;
memcpy (cmd + 2, tag->info.nti.nfi.abtId, 8); memcpy(cmd + 2, tag->info.nti.nfi.abtId, 8);
cmd[11] = service; cmd[11] = service;
cmd[12] = service >> 8; cmd[12] = service >> 8;
cmd[13] = block_count; cmd[13] = block_count;
for (int i = 0; i < block_count; i++) { for (int i = 0; i < block_count; i++) {
cmd[14 + 2*i] = 0x80; cmd[14 + 2 * i] = 0x80;
cmd[14 + 2*i + 1] = blocks[i]; cmd[14 + 2 * i + 1] = blocks[i];
} }
int cnt = felica_transceive (tag, cmd, res, sizeof (res)); int cnt = felica_transceive(tag, cmd, res, sizeof(res));
if (cnt != 1 + 1 + 8 + 1 + 1 + 1 + 16 * block_count) { if (cnt != 1 + 1 + 8 + 1 + 1 + 1 + 16 * block_count) {
return -1; return -1;
} }
size_t len = MIN(res[12] * 16, length); size_t len = MIN(res[12] * 16, length);
memcpy (data, res + 13, len); memcpy(data, res + 13, len);
return len; return len;
} }
ssize_t ssize_t
felica_read (FreefareTag tag, uint16_t service, uint8_t block, uint8_t *data, size_t length) felica_read(FreefareTag tag, uint16_t service, uint8_t block, uint8_t *data, size_t length)
{ {
uint8_t blocks[] = { uint8_t blocks[] = {
block block
}; };
return felica_read_ex (tag, service, 1, blocks, data, length); return felica_read_ex(tag, service, 1, blocks, data, length);
} }
ssize_t ssize_t
felica_write_ex (FreefareTag tag, uint16_t service, uint8_t block_count, uint8_t blocks[], uint8_t *data, size_t length) felica_write_ex(FreefareTag tag, uint16_t service, uint8_t block_count, uint8_t blocks[], uint8_t *data, size_t length)
{ {
DEBUG_FUNCTION(); DEBUG_FUNCTION();
assert (block_count <= MAX_BLOCK_COUNT); assert(block_count <= MAX_BLOCK_COUNT);
assert (length == 16 * block_count); assert(length == 16 * block_count);
uint8_t cmd[1 + 1 + 8 + 1 + 2 + 1 + 2 + 16 * MAX_BLOCK_COUNT] = { uint8_t cmd[1 + 1 + 8 + 1 + 2 + 1 + 2 + 16 * MAX_BLOCK_COUNT] = {
0x00, /* Length */ 0x00, /* Length */
@ -156,32 +156,32 @@ felica_write_ex (FreefareTag tag, uint16_t service, uint8_t block_count, uint8_t
uint8_t res[12]; uint8_t res[12];
cmd[0] = 1 + 1 + 8 + 1 + 2 * 1 + 1 + 2 * 1 + 16 * block_count; cmd[0] = 1 + 1 + 8 + 1 + 2 * 1 + 1 + 2 * 1 + 16 * block_count;
memcpy (cmd + 2, tag->info.nti.nfi.abtId, 8); memcpy(cmd + 2, tag->info.nti.nfi.abtId, 8);
cmd[11] = service; cmd[11] = service;
cmd[12] = service >> 8; cmd[12] = service >> 8;
cmd[13] = block_count; cmd[13] = block_count;
for (int i = 0; i < block_count; i++) { for (int i = 0; i < block_count; i++) {
cmd[14 + 2*i] = 0x80; cmd[14 + 2 * i] = 0x80;
cmd[14 + 2*i + 1] = blocks[i]; cmd[14 + 2 * i + 1] = blocks[i];
} }
memcpy (cmd + 14 + 2 * block_count, data, length); memcpy(cmd + 14 + 2 * block_count, data, length);
ssize_t cnt = felica_transceive (tag, cmd, res, sizeof (res)); ssize_t cnt = felica_transceive(tag, cmd, res, sizeof(res));
if (cnt != sizeof (res)) if (cnt != sizeof(res))
return -1; return -1;
return res[10] == 0 ? 0 : -1; return res[10] == 0 ? 0 : -1;
} }
ssize_t ssize_t
felica_write (FreefareTag tag, uint16_t service, uint8_t block, uint8_t *data, size_t length) felica_write(FreefareTag tag, uint16_t service, uint8_t block, uint8_t *data, size_t length)
{ {
uint8_t blocks[] = { uint8_t blocks[] = {
block block
}; };
return felica_write_ex (tag, service, 1, blocks, data, length); return felica_write_ex(tag, service, 1, blocks, data, length);
} }

View file

@ -34,26 +34,26 @@
* Automagically allocate a FreefareTag given a device and target info. * Automagically allocate a FreefareTag given a device and target info.
*/ */
FreefareTag FreefareTag
freefare_tag_new (nfc_device *device, nfc_target target) freefare_tag_new(nfc_device *device, nfc_target target)
{ {
FreefareTag tag = NULL; FreefareTag tag = NULL;
if (felica_taste (device, target)) { if (felica_taste(device, target)) {
tag = felica_tag_new (device, target); tag = felica_tag_new(device, target);
} else if (mifare_mini_taste (device, target)) { } else if (mifare_mini_taste(device, target)) {
tag = mifare_mini_tag_new (device, target); tag = mifare_mini_tag_new(device, target);
} else if (mifare_classic1k_taste (device, target)) { } else if (mifare_classic1k_taste(device, target)) {
tag = mifare_classic1k_tag_new (device, target); tag = mifare_classic1k_tag_new(device, target);
} else if (mifare_classic4k_taste (device, target)) { } else if (mifare_classic4k_taste(device, target)) {
tag = mifare_classic4k_tag_new (device, target); tag = mifare_classic4k_tag_new(device, target);
} else if (mifare_desfire_taste (device, target)) { } else if (mifare_desfire_taste(device, target)) {
tag = mifare_desfire_tag_new (device, target); tag = mifare_desfire_tag_new(device, target);
} else if (ntag21x_taste (device, target)) { } else if (ntag21x_taste(device, target)) {
tag = ntag21x_tag_new (device, target); tag = ntag21x_tag_new(device, target);
} else if (mifare_ultralightc_taste (device, target)) { } else if (mifare_ultralightc_taste(device, target)) {
tag = mifare_ultralightc_tag_new (device, target); tag = mifare_ultralightc_tag_new(device, target);
} else if (mifare_ultralight_taste (device, target)) { } else if (mifare_ultralight_taste(device, target)) {
tag = mifare_ultralight_tag_new (device, target); tag = mifare_ultralight_tag_new(device, target);
} }
return tag; return tag;
@ -74,7 +74,7 @@ freefare_tag_new (nfc_device *device, nfc_target target)
* The list has to be freed using the freefare_free_tags() function. * The list has to be freed using the freefare_free_tags() function.
*/ */
FreefareTag * FreefareTag *
freefare_get_tags (nfc_device *device) freefare_get_tags(nfc_device *device)
{ {
FreefareTag *tags = NULL; FreefareTag *tags = NULL;
int tag_count = 0; int tag_count = 0;
@ -82,15 +82,15 @@ freefare_get_tags (nfc_device *device)
nfc_initiator_init(device); nfc_initiator_init(device);
// Drop the field for a while // Drop the field for a while
nfc_device_set_property_bool(device,NP_ACTIVATE_FIELD,false); nfc_device_set_property_bool(device, NP_ACTIVATE_FIELD, false);
// Configure the CRC and Parity settings // Configure the CRC and Parity settings
nfc_device_set_property_bool(device,NP_HANDLE_CRC,true); nfc_device_set_property_bool(device, NP_HANDLE_CRC, true);
nfc_device_set_property_bool(device,NP_HANDLE_PARITY,true); nfc_device_set_property_bool(device, NP_HANDLE_PARITY, true);
nfc_device_set_property_bool(device,NP_AUTO_ISO14443_4,true); nfc_device_set_property_bool(device, NP_AUTO_ISO14443_4, true);
// Enable field so more power consuming cards can power themselves up // Enable field so more power consuming cards can power themselves up
nfc_device_set_property_bool(device,NP_ACTIVATE_FIELD,true); nfc_device_set_property_bool(device, NP_ACTIVATE_FIELD, true);
// Poll for a ISO14443A (MIFARE) tag // Poll for a ISO14443A (MIFARE) tag
nfc_target candidates[MAX_CANDIDATES]; nfc_target candidates[MAX_CANDIDATES];
@ -102,15 +102,15 @@ freefare_get_tags (nfc_device *device)
if ((candidates_count = nfc_initiator_list_passive_targets(device, modulation, candidates, MAX_CANDIDATES)) < 0) if ((candidates_count = nfc_initiator_list_passive_targets(device, modulation, candidates, MAX_CANDIDATES)) < 0)
return NULL; return NULL;
tags = malloc(sizeof (void *)); tags = malloc(sizeof(void *));
if(!tags) return NULL; if (!tags) return NULL;
tags[0] = NULL; tags[0] = NULL;
for (int c = 0; c < candidates_count; c++) { for (int c = 0; c < candidates_count; c++) {
FreefareTag t; FreefareTag t;
if ((t = freefare_tag_new(device, candidates[c]))) { if ((t = freefare_tag_new(device, candidates[c]))) {
/* (Re)Allocate memory for the found MIFARE targets array */ /* (Re)Allocate memory for the found MIFARE targets array */
FreefareTag *p = realloc (tags, (tag_count + 2) * sizeof (FreefareTag)); FreefareTag *p = realloc(tags, (tag_count + 2) * sizeof(FreefareTag));
if (p) if (p)
tags = p; tags = p;
else else
@ -130,7 +130,7 @@ freefare_get_tags (nfc_device *device)
FreefareTag t; FreefareTag t;
if ((t = freefare_tag_new(device, candidates[c]))) { if ((t = freefare_tag_new(device, candidates[c]))) {
/* (Re)Allocate memory for the found FELICA targets array */ /* (Re)Allocate memory for the found FELICA targets array */
FreefareTag *p = realloc (tags, (tag_count + 2) * sizeof (FreefareTag)); FreefareTag *p = realloc(tags, (tag_count + 2) * sizeof(FreefareTag));
if (p) if (p)
tags = p; tags = p;
else else
@ -147,8 +147,7 @@ freefare_get_tags (nfc_device *device)
* Returns the type of the provided tag. * Returns the type of the provided tag.
*/ */
enum freefare_tag_type enum freefare_tag_type
freefare_get_tag_type (FreefareTag tag) freefare_get_tag_type(FreefareTag tag) {
{
return tag->type; return tag->type;
} }
@ -156,13 +155,13 @@ freefare_get_tag_type (FreefareTag tag)
* Returns the friendly name of the provided tag. * Returns the friendly name of the provided tag.
*/ */
const char * const char *
freefare_get_tag_friendly_name (FreefareTag tag) freefare_get_tag_friendly_name(FreefareTag tag)
{ {
switch (tag->type) { switch (tag->type) {
case FELICA: case FELICA:
return "FeliCA"; return "FeliCA";
case MIFARE_MINI: case MIFARE_MINI:
return "Mifare Mini 0.3k"; return "Mifare Mini 0.3k";
case MIFARE_CLASSIC_1K: case MIFARE_CLASSIC_1K:
return "Mifare Classic 1k"; return "Mifare Classic 1k";
case MIFARE_CLASSIC_4K: case MIFARE_CLASSIC_4K:
@ -184,20 +183,20 @@ freefare_get_tag_friendly_name (FreefareTag tag)
* Returns the UID of the provided tag. * Returns the UID of the provided tag.
*/ */
char * char *
freefare_get_tag_uid (FreefareTag tag) freefare_get_tag_uid(FreefareTag tag)
{ {
char *res = NULL; char *res = NULL;
switch (tag->info.nm.nmt) { switch (tag->info.nm.nmt) {
case NMT_FELICA: case NMT_FELICA:
if ((res = malloc (17))) { if ((res = malloc(17))) {
for (size_t i = 0; i < 8; i++) for (size_t i = 0; i < 8; i++)
snprintf (res + 2*i, 3, "%02x", tag->info.nti.nfi.abtId[i]); snprintf(res + 2 * i, 3, "%02x", tag->info.nti.nfi.abtId[i]);
} }
break; break;
case NMT_ISO14443A: case NMT_ISO14443A:
if ((res = malloc (2 * tag->info.nti.nai.szUidLen + 1))) { if ((res = malloc(2 * tag->info.nti.nai.szUidLen + 1))) {
for (size_t i = 0; i < tag->info.nti.nai.szUidLen; i++) for (size_t i = 0; i < tag->info.nti.nai.szUidLen; i++)
snprintf (res + 2*i, 3, "%02x", tag->info.nti.nai.abtUid[i]); snprintf(res + 2 * i, 3, "%02x", tag->info.nti.nai.abtUid[i]);
} }
break; break;
case NMT_DEP: case NMT_DEP:
@ -206,7 +205,7 @@ freefare_get_tag_uid (FreefareTag tag)
case NMT_ISO14443B: case NMT_ISO14443B:
case NMT_ISO14443BI: case NMT_ISO14443BI:
case NMT_JEWEL: case NMT_JEWEL:
res = strdup ("UNKNOWN"); res = strdup("UNKNOWN");
} }
return res; return res;
} }
@ -223,54 +222,54 @@ bool freefare_selected_tag_is_present(nfc_device *device)
* Free the provided tag. * Free the provided tag.
*/ */
void void
freefare_free_tag (FreefareTag tag) freefare_free_tag(FreefareTag tag)
{ {
if (tag) { if (tag) {
tag->free_tag (tag); tag->free_tag(tag);
} }
} }
const char * const char *
freefare_strerror (FreefareTag tag) freefare_strerror(FreefareTag tag)
{ {
const char *p = "Unknown error"; const char *p = "Unknown error";
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->type == MIFARE_DESFIRE) { if (tag->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) {
p = mifare_desfire_error_lookup (MIFARE_DESFIRE (tag)->last_picc_error); p = mifare_desfire_error_lookup(MIFARE_DESFIRE(tag)->last_picc_error);
} }
} }
} }
return p; return p;
} }
int int
freefare_strerror_r (FreefareTag tag, char *buffer, size_t len) freefare_strerror_r(FreefareTag tag, char *buffer, size_t len)
{ {
return (snprintf (buffer, len, "%s", freefare_strerror (tag)) < 0) ? -1 : 0; return (snprintf(buffer, len, "%s", freefare_strerror(tag)) < 0) ? -1 : 0;
} }
void void
freefare_perror (FreefareTag tag, const char *string) freefare_perror(FreefareTag tag, const char *string)
{ {
fprintf (stderr, "%s: %s\n", string, freefare_strerror (tag)); fprintf(stderr, "%s: %s\n", string, freefare_strerror(tag));
} }
/* /*
* Free the provided tag list. * Free the provided tag list.
*/ */
void void
freefare_free_tags (FreefareTag *tags) freefare_free_tags(FreefareTag *tags)
{ {
if (tags) { if (tags) {
for (int i=0; tags[i]; i++) { for (int i = 0; tags[i]; i++) {
freefare_free_tag(tags[i]); freefare_free_tag(tags[i]);
} }
free (tags); free(tags);
} }
} }
@ -280,11 +279,11 @@ freefare_free_tags (FreefareTag *tags)
*/ */
void * void *
memdup (const void *p, const size_t n) memdup(const void *p, const size_t n)
{ {
void *res; void *res;
if ((res = malloc (n))) { if ((res = malloc(n))) {
memcpy (res, p, n); memcpy(res, p, n);
} }
return res; return res;
} }

View file

@ -25,7 +25,7 @@
#include <nfc/nfc.h> #include <nfc/nfc.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif // __cplusplus #endif // __cplusplus
enum freefare_tag_type { enum freefare_tag_type {
@ -47,7 +47,7 @@ struct freefare_tag;
typedef struct freefare_tag *FreefareTag; typedef struct freefare_tag *FreefareTag;
/* Replace any MifareTag by the generic FreefareTag. */ /* Replace any MifareTag by the generic FreefareTag. */
typedef struct freefare_tag *MifareTag __attribute__ ((deprecated)); typedef struct freefare_tag *MifareTag __attribute__((deprecated));
struct mifare_desfire_key; struct mifare_desfire_key;
typedef struct mifare_desfire_key *MifareDESFireKey; typedef struct mifare_desfire_key *MifareDESFireKey;
@ -58,57 +58,57 @@ typedef struct ntag21x_key *NTAG21xKey;
typedef uint8_t MifareUltralightPageNumber; typedef uint8_t MifareUltralightPageNumber;
typedef unsigned char MifareUltralightPage[4]; typedef unsigned char MifareUltralightPage[4];
FreefareTag *freefare_get_tags (nfc_device *device); FreefareTag *freefare_get_tags(nfc_device *device);
FreefareTag freefare_tag_new (nfc_device *device, nfc_target target); FreefareTag freefare_tag_new(nfc_device *device, nfc_target target);
enum freefare_tag_type freefare_get_tag_type (FreefareTag tag); enum freefare_tag_type freefare_get_tag_type(FreefareTag tag);
const char *freefare_get_tag_friendly_name (FreefareTag tag); const char *freefare_get_tag_friendly_name(FreefareTag tag);
char *freefare_get_tag_uid (FreefareTag tag); char *freefare_get_tag_uid(FreefareTag tag);
void freefare_free_tag (FreefareTag tag); void freefare_free_tag(FreefareTag tag);
void freefare_free_tags (FreefareTag *tags); void freefare_free_tags(FreefareTag *tags);
bool freefare_selected_tag_is_present(nfc_device *device); bool freefare_selected_tag_is_present(nfc_device *device);
const char *freefare_strerror (FreefareTag tag); const char *freefare_strerror(FreefareTag tag);
int freefare_strerror_r (FreefareTag tag, char *buffer, size_t len); int freefare_strerror_r(FreefareTag tag, char *buffer, size_t len);
void freefare_perror (FreefareTag tag, const char *string); void freefare_perror(FreefareTag tag, const char *string);
bool felica_taste (nfc_device *device, nfc_target target); bool felica_taste(nfc_device *device, nfc_target target);
#define FELICA_SC_RW 0x0009 #define FELICA_SC_RW 0x0009
#define FELICA_SC_RO 0x000b #define FELICA_SC_RO 0x000b
FreefareTag felica_tag_new (nfc_device *device, nfc_target target); FreefareTag felica_tag_new(nfc_device *device, nfc_target target);
void felica_tag_free (FreefareTag tag); void felica_tag_free(FreefareTag tag);
ssize_t felica_read (FreefareTag tag, uint16_t service, uint8_t block, uint8_t *data, size_t length); ssize_t felica_read(FreefareTag tag, uint16_t service, uint8_t block, uint8_t *data, size_t length);
ssize_t felica_read_ex (FreefareTag tag, uint16_t service, uint8_t block_count, uint8_t blocks[], uint8_t *data, size_t length); ssize_t felica_read_ex(FreefareTag tag, uint16_t service, uint8_t block_count, uint8_t blocks[], uint8_t *data, size_t length);
ssize_t felica_write (FreefareTag tag, uint16_t service, uint8_t block, uint8_t *data, size_t length); ssize_t felica_write(FreefareTag tag, uint16_t service, uint8_t block, uint8_t *data, size_t length);
ssize_t felica_write_ex (FreefareTag tag, uint16_t service, uint8_t block_count, uint8_t blocks[], uint8_t *data, size_t length); ssize_t felica_write_ex(FreefareTag tag, uint16_t service, uint8_t block_count, uint8_t blocks[], uint8_t *data, size_t length);
bool mifare_ultralight_taste (nfc_device *device, nfc_target target); bool mifare_ultralight_taste(nfc_device *device, nfc_target target);
bool mifare_ultralightc_taste (nfc_device *device, nfc_target target); bool mifare_ultralightc_taste(nfc_device *device, nfc_target target);
FreefareTag mifare_ultralight_tag_new (nfc_device *device, nfc_target target); FreefareTag mifare_ultralight_tag_new(nfc_device *device, nfc_target target);
FreefareTag mifare_ultralightc_tag_new (nfc_device *device, nfc_target target); FreefareTag mifare_ultralightc_tag_new(nfc_device *device, nfc_target target);
void mifare_ultralight_tag_free (FreefareTag tag); void mifare_ultralight_tag_free(FreefareTag tag);
void mifare_ultralightc_tag_free (FreefareTag tag); void mifare_ultralightc_tag_free(FreefareTag tag);
int mifare_ultralight_connect (FreefareTag tag); int mifare_ultralight_connect(FreefareTag tag);
int mifare_ultralight_disconnect (FreefareTag tag); int mifare_ultralight_disconnect(FreefareTag tag);
int mifare_ultralight_read (FreefareTag tag, const MifareUltralightPageNumber page, MifareUltralightPage *data); int mifare_ultralight_read(FreefareTag tag, const MifareUltralightPageNumber page, MifareUltralightPage *data);
int mifare_ultralight_write (FreefareTag tag, const MifareUltralightPageNumber page, const MifareUltralightPage data); int mifare_ultralight_write(FreefareTag tag, const MifareUltralightPageNumber page, const MifareUltralightPage data);
int mifare_ultralightc_authenticate (FreefareTag tag, const MifareDESFireKey key); int mifare_ultralightc_authenticate(FreefareTag tag, const MifareDESFireKey key);
bool is_mifare_ultralight (FreefareTag tag); bool is_mifare_ultralight(FreefareTag tag);
bool is_mifare_ultralightc (FreefareTag tag); bool is_mifare_ultralightc(FreefareTag tag);
bool is_mifare_ultralightc_on_reader (nfc_device *device, nfc_iso14443a_info nai); bool is_mifare_ultralightc_on_reader(nfc_device *device, nfc_iso14443a_info nai);
bool ntag21x_taste (nfc_device *device, nfc_target target); bool ntag21x_taste(nfc_device *device, nfc_target target);
/* NTAG21x access features */ /* NTAG21x access features */
#define NTAG_PROT 0x80 #define NTAG_PROT 0x80
@ -123,48 +123,48 @@ enum ntag_tag_subtype {
NTAG_216 NTAG_216
}; };
FreefareTag ntag21x_tag_new (nfc_device *device, nfc_target target); FreefareTag ntag21x_tag_new(nfc_device *device, nfc_target target);
FreefareTag ntag21x_tag_reuse (FreefareTag tag); /* Copy data from Ultralight tag to new NTAG21x, don't forget to free your old tag */ FreefareTag ntag21x_tag_reuse(FreefareTag tag); /* Copy data from Ultralight tag to new NTAG21x, don't forget to free your old tag */
NTAG21xKey ntag21x_key_new (const uint8_t data[4],const uint8_t pack[2]); /* Create new key */ NTAG21xKey ntag21x_key_new(const uint8_t data[4], const uint8_t pack[2]); /* Create new key */
void ntag21x_key_free (NTAG21xKey key); /* Clear key from memory */ void ntag21x_key_free(NTAG21xKey key); /* Clear key from memory */
void ntag21x_tag_free (FreefareTag tag); void ntag21x_tag_free(FreefareTag tag);
int ntag21x_connect (FreefareTag tag); int ntag21x_connect(FreefareTag tag);
int ntag21x_disconnect (FreefareTag tag); int ntag21x_disconnect(FreefareTag tag);
int ntag21x_get_info (FreefareTag tag); /* Get all information about tag (size,vendor ...) */ int ntag21x_get_info(FreefareTag tag); /* Get all information about tag (size,vendor ...) */
enum ntag_tag_subtype ntag21x_get_subtype (FreefareTag tag); /* Get subtype of tag */ enum ntag_tag_subtype ntag21x_get_subtype(FreefareTag tag); /* Get subtype of tag */
uint8_t ntag21x_get_last_page (FreefareTag tag); /* Get last page address based on gathered info from function above */ uint8_t ntag21x_get_last_page(FreefareTag tag); /* Get last page address based on gathered info from function above */
int ntag21x_read_signature (FreefareTag tag,uint8_t *data); /* Get tag signature */ int ntag21x_read_signature(FreefareTag tag, uint8_t *data); /* Get tag signature */
int ntag21x_set_pwd (FreefareTag tag, uint8_t data[4]); /* Set password */ int ntag21x_set_pwd(FreefareTag tag, uint8_t data[4]); /* Set password */
int ntag21x_set_pack (FreefareTag tag, uint8_t data[2]); /* Set pack */ int ntag21x_set_pack(FreefareTag tag, uint8_t data[2]); /* Set pack */
int ntag21x_set_key (FreefareTag tag,const NTAG21xKey key); /* Set key */ int ntag21x_set_key(FreefareTag tag, const NTAG21xKey key); /* Set key */
int ntag21x_set_auth (FreefareTag tag,uint8_t byte); /* Set AUTH0 byte (from which page starts password protection) */ int ntag21x_set_auth(FreefareTag tag, uint8_t byte); /* Set AUTH0 byte (from which page starts password protection) */
int ntag21x_get_auth (FreefareTag tag,uint8_t *byte); /* Get AUTH0 byte */ int ntag21x_get_auth(FreefareTag tag, uint8_t *byte); /* Get AUTH0 byte */
int ntag21x_access_enable (FreefareTag tag,uint8_t byte); /* Enable access feature in ACCESS byte */ int ntag21x_access_enable(FreefareTag tag, uint8_t byte); /* Enable access feature in ACCESS byte */
int ntag21x_access_disable (FreefareTag tag,uint8_t byte); /* Disable access feature in ACCESS byte */ int ntag21x_access_disable(FreefareTag tag, uint8_t byte); /* Disable access feature in ACCESS byte */
int ntag21x_get_access (FreefareTag tag,uint8_t *byte); /* Get ACCESS byte */ int ntag21x_get_access(FreefareTag tag, uint8_t *byte); /* Get ACCESS byte */
int ntag21x_check_access (FreefareTag tag,uint8_t byte,bool *result); /* Check if access feature is enabled */ int ntag21x_check_access(FreefareTag tag, uint8_t byte, bool *result); /* Check if access feature is enabled */
int ntag21x_get_authentication_limit (FreefareTag tag,uint8_t *byte); /* Get authentication limit */ int ntag21x_get_authentication_limit(FreefareTag tag, uint8_t *byte); /* Get authentication limit */
int ntag21x_set_authentication_limit (FreefareTag tag,uint8_t byte); /* Set authentication limit (0x00 = disabled, [0x01,0x07] = valid range, > 0x07 invalid range) */ int ntag21x_set_authentication_limit(FreefareTag tag, uint8_t byte); /* Set authentication limit (0x00 = disabled, [0x01,0x07] = valid range, > 0x07 invalid range) */
int ntag21x_read (FreefareTag tag, uint8_t page,uint8_t *data); /* Read 16 bytes starting from page */ int ntag21x_read(FreefareTag tag, uint8_t page, uint8_t *data); /* Read 16 bytes starting from page */
int ntag21x_read4 (FreefareTag tag,uint8_t page,uint8_t *data); /* Read 4 bytes on page */ int ntag21x_read4(FreefareTag tag, uint8_t page, uint8_t *data); /* Read 4 bytes on page */
int ntag21x_fast_read (FreefareTag tag, uint8_t start_page,uint8_t end_page, uint8_t *data); /* Read n*4 bytes from range [start_page,end_page] */ int ntag21x_fast_read(FreefareTag tag, uint8_t start_page, uint8_t end_page, uint8_t *data); /* Read n*4 bytes from range [start_page,end_page] */
int ntag21x_fast_read4 (FreefareTag tag,uint8_t page,uint8_t *data); /* Fast read certain page */ int ntag21x_fast_read4(FreefareTag tag, uint8_t page, uint8_t *data); /* Fast read certain page */
int ntag21x_read_cnt (FreefareTag tag, uint8_t *data); /* Read 3-byte NFC counter if enabled else it returns error */ int ntag21x_read_cnt(FreefareTag tag, uint8_t *data); /* Read 3-byte NFC counter if enabled else it returns error */
int ntag21x_write (FreefareTag tag, uint8_t page, uint8_t data[4]); /* Write 4 bytes to page */ int ntag21x_write(FreefareTag tag, uint8_t page, uint8_t data[4]); /* Write 4 bytes to page */
int ntag21x_compatibility_write (FreefareTag tag, uint8_t page, uint8_t data[4]); /* Writes 4 bytes to page with mifare classic write */ int ntag21x_compatibility_write(FreefareTag tag, uint8_t page, uint8_t data[4]); /* Writes 4 bytes to page with mifare classic write */
int ntag21x_authenticate (FreefareTag tag, const NTAG21xKey key); /* Authenticate with tag */ int ntag21x_authenticate(FreefareTag tag, const NTAG21xKey key); /* Authenticate with tag */
bool is_ntag21x (FreefareTag tag); /* Check if tag type is NTAG21x */ bool is_ntag21x(FreefareTag tag); /* Check if tag type is NTAG21x */
bool ntag21x_is_auth_supported (nfc_device *device, nfc_iso14443a_info nai); /* Check if tag supports 21x commands */ bool ntag21x_is_auth_supported(nfc_device *device, nfc_iso14443a_info nai); /* Check if tag supports 21x commands */
bool mifare_mini_taste (nfc_device *device, nfc_target target); bool mifare_mini_taste(nfc_device *device, nfc_target target);
bool mifare_classic1k_taste (nfc_device *device, nfc_target target); bool mifare_classic1k_taste(nfc_device *device, nfc_target target);
bool mifare_classic4k_taste (nfc_device *device, nfc_target target); bool mifare_classic4k_taste(nfc_device *device, nfc_target target);
FreefareTag mifare_mini_tag_new (nfc_device *device, nfc_target target); FreefareTag mifare_mini_tag_new(nfc_device *device, nfc_target target);
FreefareTag mifare_classic1k_tag_new (nfc_device *device, nfc_target target); FreefareTag mifare_classic1k_tag_new(nfc_device *device, nfc_target target);
FreefareTag mifare_classic4k_tag_new (nfc_device *device, nfc_target target); FreefareTag mifare_classic4k_tag_new(nfc_device *device, nfc_target target);
void mifare_classic_tag_free (FreefareTag tag); void mifare_classic_tag_free(FreefareTag tag);
typedef unsigned char MifareClassicBlock[16]; typedef unsigned char MifareClassicBlock[16];
@ -177,31 +177,31 @@ typedef unsigned char MifareClassicKey[6];
/* NFC Forum public key */ /* NFC Forum public key */
extern const MifareClassicKey mifare_classic_nfcforum_public_key_a; extern const MifareClassicKey mifare_classic_nfcforum_public_key_a;
int mifare_classic_connect (FreefareTag tag); int mifare_classic_connect(FreefareTag tag);
int mifare_classic_disconnect (FreefareTag tag); int mifare_classic_disconnect(FreefareTag tag);
int mifare_classic_authenticate (FreefareTag tag, const MifareClassicBlockNumber block, const MifareClassicKey key, const MifareClassicKeyType key_type); int mifare_classic_authenticate(FreefareTag tag, const MifareClassicBlockNumber block, const MifareClassicKey key, const MifareClassicKeyType key_type);
int mifare_classic_read (FreefareTag tag, const MifareClassicBlockNumber block, MifareClassicBlock *data); int mifare_classic_read(FreefareTag tag, const MifareClassicBlockNumber block, MifareClassicBlock *data);
int mifare_classic_init_value (FreefareTag tag, const MifareClassicBlockNumber block, const int32_t value, const MifareClassicBlockNumber adr); int mifare_classic_init_value(FreefareTag tag, const MifareClassicBlockNumber block, const int32_t value, const MifareClassicBlockNumber adr);
int mifare_classic_read_value (FreefareTag tag, const MifareClassicBlockNumber block, int32_t *value, MifareClassicBlockNumber *adr); int mifare_classic_read_value(FreefareTag tag, const MifareClassicBlockNumber block, int32_t *value, MifareClassicBlockNumber *adr);
int mifare_classic_write (FreefareTag tag, const MifareClassicBlockNumber block, const MifareClassicBlock data); int mifare_classic_write(FreefareTag tag, const MifareClassicBlockNumber block, const MifareClassicBlock data);
int mifare_classic_increment (FreefareTag tag, const MifareClassicBlockNumber block, const uint32_t amount); int mifare_classic_increment(FreefareTag tag, const MifareClassicBlockNumber block, const uint32_t amount);
int mifare_classic_decrement (FreefareTag tag, const MifareClassicBlockNumber block, const uint32_t amount); int mifare_classic_decrement(FreefareTag tag, const MifareClassicBlockNumber block, const uint32_t amount);
int mifare_classic_restore (FreefareTag tag, const MifareClassicBlockNumber block); int mifare_classic_restore(FreefareTag tag, const MifareClassicBlockNumber block);
int mifare_classic_transfer (FreefareTag tag, const MifareClassicBlockNumber block); int mifare_classic_transfer(FreefareTag tag, const MifareClassicBlockNumber block);
int mifare_classic_get_trailer_block_permission (FreefareTag tag, const MifareClassicBlockNumber block, const uint16_t permission, const MifareClassicKeyType key_type); int mifare_classic_get_trailer_block_permission(FreefareTag tag, const MifareClassicBlockNumber block, const uint16_t permission, const MifareClassicKeyType key_type);
int mifare_classic_get_data_block_permission (FreefareTag tag, const MifareClassicBlockNumber block, const unsigned char permission, const MifareClassicKeyType key_type); int mifare_classic_get_data_block_permission(FreefareTag tag, const MifareClassicBlockNumber block, const unsigned char permission, const MifareClassicKeyType key_type);
int mifare_classic_format_sector (FreefareTag tag, const MifareClassicSectorNumber sector); int mifare_classic_format_sector(FreefareTag tag, const MifareClassicSectorNumber sector);
void mifare_classic_trailer_block (MifareClassicBlock *block, const MifareClassicKey key_a, uint8_t ab_0, uint8_t ab_1, uint8_t ab_2, uint8_t ab_tb, const uint8_t gpb, const MifareClassicKey key_b); void mifare_classic_trailer_block(MifareClassicBlock *block, const MifareClassicKey key_a, uint8_t ab_0, uint8_t ab_1, uint8_t ab_2, uint8_t ab_tb, const uint8_t gpb, const MifareClassicKey key_b);
MifareClassicSectorNumber mifare_classic_block_sector (MifareClassicBlockNumber block); MifareClassicSectorNumber mifare_classic_block_sector(MifareClassicBlockNumber block);
MifareClassicBlockNumber mifare_classic_sector_first_block (MifareClassicSectorNumber sector); MifareClassicBlockNumber mifare_classic_sector_first_block(MifareClassicSectorNumber sector);
size_t mifare_classic_sector_block_count (MifareClassicSectorNumber sector); size_t mifare_classic_sector_block_count(MifareClassicSectorNumber sector);
MifareClassicBlockNumber mifare_classic_sector_last_block (MifareClassicSectorNumber sector); MifareClassicBlockNumber mifare_classic_sector_last_block(MifareClassicSectorNumber sector);
#define C_000 0 #define C_000 0
#define C_001 1 #define C_001 1
@ -248,28 +248,28 @@ extern const MadAid mad_not_applicable_aid;
/* NFC Forum AID */ /* NFC Forum AID */
extern const MadAid mad_nfcforum_aid; extern const MadAid mad_nfcforum_aid;
Mad mad_new (const uint8_t version); Mad mad_new(const uint8_t version);
Mad mad_read (FreefareTag tag); Mad mad_read(FreefareTag tag);
int mad_write (FreefareTag tag, Mad mad, const MifareClassicKey key_b_sector_00, const MifareClassicKey key_b_sector_10); int mad_write(FreefareTag tag, Mad mad, const MifareClassicKey key_b_sector_00, const MifareClassicKey key_b_sector_10);
int mad_get_version (Mad mad); int mad_get_version(Mad mad);
void mad_set_version (Mad mad, const uint8_t version); void mad_set_version(Mad mad, const uint8_t version);
MifareClassicSectorNumber mad_get_card_publisher_sector (Mad mad); MifareClassicSectorNumber mad_get_card_publisher_sector(Mad mad);
int mad_set_card_publisher_sector (Mad mad, const MifareClassicSectorNumber cps); int mad_set_card_publisher_sector(Mad mad, const MifareClassicSectorNumber cps);
int mad_get_aid (Mad mad, const MifareClassicSectorNumber sector, MadAid *aid); int mad_get_aid(Mad mad, const MifareClassicSectorNumber sector, MadAid *aid);
int mad_set_aid (Mad mad, const MifareClassicSectorNumber sector, MadAid aid); int mad_set_aid(Mad mad, const MifareClassicSectorNumber sector, MadAid aid);
bool mad_sector_reserved (const MifareClassicSectorNumber sector); bool mad_sector_reserved(const MifareClassicSectorNumber sector);
void mad_free (Mad mad); void mad_free(Mad mad);
MifareClassicSectorNumber *mifare_application_alloc (Mad mad, const MadAid aid, const size_t size); MifareClassicSectorNumber *mifare_application_alloc(Mad mad, const MadAid aid, const size_t size);
ssize_t mifare_application_read (FreefareTag tag, Mad mad, const MadAid aid, void *buf, size_t nbytes, const MifareClassicKey key, const MifareClassicKeyType key_type); ssize_t mifare_application_read(FreefareTag tag, Mad mad, const MadAid aid, void *buf, size_t nbytes, const MifareClassicKey key, const MifareClassicKeyType key_type);
ssize_t mifare_application_write (FreefareTag tag, Mad mad, const MadAid aid, const void *buf, size_t nbytes, const MifareClassicKey key, const MifareClassicKeyType key_type); ssize_t mifare_application_write(FreefareTag tag, Mad mad, const MadAid aid, const void *buf, size_t nbytes, const MifareClassicKey key, const MifareClassicKeyType key_type);
int mifare_application_free (Mad mad, const MadAid aid); int mifare_application_free(Mad mad, const MadAid aid);
MifareClassicSectorNumber *mifare_application_find (Mad mad, const MadAid aid); MifareClassicSectorNumber *mifare_application_find(Mad mad, const MadAid aid);
bool mifare_desfire_taste (nfc_device *device, nfc_target target); bool mifare_desfire_taste(nfc_device *device, nfc_target target);
/* File types */ /* File types */
@ -302,21 +302,21 @@ enum mifare_desfire_file_types {
*/ */
#define MDAPP_SETTINGS(key_no_for_key_changing,config_changeable,free_create_delete_files,free_listing_contents,app_master_key_changeable) ( \ #define MDAPP_SETTINGS(key_no_for_key_changing,config_changeable,free_create_delete_files,free_listing_contents,app_master_key_changeable) ( \
(key_no_for_key_changing << 4) | \ (key_no_for_key_changing << 4) | \
(config_changeable << 3) | \ (config_changeable << 3) | \
(free_listing_contents << 1) | \ (free_listing_contents << 1) | \
(app_master_key_changeable) \ (app_master_key_changeable) \
) )
/* Access right */ /* Access right */
#define MDAR(read,write,read_write,change_access_rights) ( \ #define MDAR(read,write,read_write,change_access_rights) ( \
(read << 12) | \ (read << 12) | \
(write << 8) | \ (write << 8) | \
(read_write << 4) | \ (read_write << 4) | \
(change_access_rights) \ (change_access_rights) \
) )
#define MDAR_READ(ar) (((ar) >> 12) & 0x0f) #define MDAR_READ(ar) (((ar) >> 12) & 0x0f)
#define MDAR_WRITE(ar) (((ar) >> 8) & 0x0f) #define MDAR_WRITE(ar) (((ar) >> 8) & 0x0f)
#define MDAR_READ_WRITE(ar) (((ar) >> 4) & 0x0f) #define MDAR_READ_WRITE(ar) (((ar) >> 4) & 0x0f)
@ -379,12 +379,12 @@ struct mifare_desfire_df {
}; };
typedef struct mifare_desfire_df MifareDESFireDF; typedef struct mifare_desfire_df MifareDESFireDF;
MifareDESFireAID mifare_desfire_aid_new (uint32_t aid); MifareDESFireAID mifare_desfire_aid_new(uint32_t aid);
MifareDESFireAID mifare_desfire_aid_new_with_mad_aid (MadAid mad_aid, uint8_t n); MifareDESFireAID mifare_desfire_aid_new_with_mad_aid(MadAid mad_aid, uint8_t n);
uint32_t mifare_desfire_aid_get_aid (MifareDESFireAID aid); uint32_t mifare_desfire_aid_get_aid(MifareDESFireAID aid);
uint8_t mifare_desfire_last_pcd_error (FreefareTag tag); uint8_t mifare_desfire_last_pcd_error(FreefareTag tag);
uint8_t mifare_desfire_last_picc_error (FreefareTag tag); uint8_t mifare_desfire_last_picc_error(FreefareTag tag);
#pragma pack (push) #pragma pack (push)
#pragma pack (1) #pragma pack (1)
@ -436,93 +436,93 @@ struct mifare_desfire_file_settings {
} settings; } settings;
}; };
FreefareTag mifare_desfire_tag_new (nfc_device *device, nfc_target target); FreefareTag mifare_desfire_tag_new(nfc_device *device, nfc_target target);
void mifare_desfire_tag_free (FreefareTag tags); void mifare_desfire_tag_free(FreefareTag tags);
int mifare_desfire_connect (FreefareTag tag); int mifare_desfire_connect(FreefareTag tag);
int mifare_desfire_disconnect (FreefareTag tag); int mifare_desfire_disconnect(FreefareTag tag);
int mifare_desfire_authenticate (FreefareTag tag, uint8_t key_no, MifareDESFireKey key); int mifare_desfire_authenticate(FreefareTag tag, uint8_t key_no, MifareDESFireKey key);
int mifare_desfire_authenticate_iso (FreefareTag tag, uint8_t key_no, MifareDESFireKey key); int mifare_desfire_authenticate_iso(FreefareTag tag, uint8_t key_no, MifareDESFireKey key);
int mifare_desfire_authenticate_aes (FreefareTag tag, uint8_t key_no, MifareDESFireKey key); int mifare_desfire_authenticate_aes(FreefareTag tag, uint8_t key_no, MifareDESFireKey key);
int mifare_desfire_change_key_settings (FreefareTag tag, uint8_t settings); int mifare_desfire_change_key_settings(FreefareTag tag, uint8_t settings);
int mifare_desfire_get_key_settings (FreefareTag tag, uint8_t *settings, uint8_t *max_keys); int mifare_desfire_get_key_settings(FreefareTag tag, uint8_t *settings, uint8_t *max_keys);
int mifare_desfire_change_key (FreefareTag tag, uint8_t key_no, MifareDESFireKey new_key, MifareDESFireKey old_key); int mifare_desfire_change_key(FreefareTag tag, uint8_t key_no, MifareDESFireKey new_key, MifareDESFireKey old_key);
int mifare_desfire_get_key_version (FreefareTag tag, uint8_t key_no, uint8_t *version); int mifare_desfire_get_key_version(FreefareTag tag, uint8_t key_no, uint8_t *version);
int mifare_desfire_create_application (FreefareTag tag, MifareDESFireAID aid, uint8_t settings, uint8_t key_no); int mifare_desfire_create_application(FreefareTag tag, MifareDESFireAID aid, uint8_t settings, uint8_t key_no);
int mifare_desfire_create_application_3k3des (FreefareTag tag, MifareDESFireAID aid, uint8_t settings, uint8_t key_no); int mifare_desfire_create_application_3k3des(FreefareTag tag, MifareDESFireAID aid, uint8_t settings, uint8_t key_no);
int mifare_desfire_create_application_aes (FreefareTag tag, MifareDESFireAID aid, uint8_t settings, uint8_t key_no); int mifare_desfire_create_application_aes(FreefareTag tag, MifareDESFireAID aid, uint8_t settings, uint8_t key_no);
int mifare_desfire_create_application_iso (FreefareTag tag, MifareDESFireAID aid, uint8_t settings, uint8_t key_no, int want_iso_file_identifiers, uint16_t iso_file_id, uint8_t *iso_file_name, size_t iso_file_name_len); int mifare_desfire_create_application_iso(FreefareTag tag, MifareDESFireAID aid, uint8_t settings, uint8_t key_no, int want_iso_file_identifiers, uint16_t iso_file_id, uint8_t *iso_file_name, size_t iso_file_name_len);
int mifare_desfire_create_application_3k3des_iso (FreefareTag tag, MifareDESFireAID aid, uint8_t settings, uint8_t key_no, int want_iso_file_identifiers, uint16_t iso_file_id, uint8_t *iso_file_name, size_t iso_file_name_len); int mifare_desfire_create_application_3k3des_iso(FreefareTag tag, MifareDESFireAID aid, uint8_t settings, uint8_t key_no, int want_iso_file_identifiers, uint16_t iso_file_id, uint8_t *iso_file_name, size_t iso_file_name_len);
int mifare_desfire_create_application_aes_iso (FreefareTag tag, MifareDESFireAID aid, uint8_t settings, uint8_t key_no, int want_iso_file_identifiers, uint16_t iso_file_id, uint8_t *iso_file_name, size_t iso_file_name_len); int mifare_desfire_create_application_aes_iso(FreefareTag tag, MifareDESFireAID aid, uint8_t settings, uint8_t key_no, int want_iso_file_identifiers, uint16_t iso_file_id, uint8_t *iso_file_name, size_t iso_file_name_len);
int mifare_desfire_delete_application (FreefareTag tag, MifareDESFireAID aid); int mifare_desfire_delete_application(FreefareTag tag, MifareDESFireAID aid);
int mifare_desfire_get_application_ids (FreefareTag tag, MifareDESFireAID *aids[], size_t *count); int mifare_desfire_get_application_ids(FreefareTag tag, MifareDESFireAID *aids[], size_t *count);
int mifare_desfire_get_df_names (FreefareTag tag, MifareDESFireDF *dfs[], size_t *count); int mifare_desfire_get_df_names(FreefareTag tag, MifareDESFireDF *dfs[], size_t *count);
void mifare_desfire_free_application_ids (MifareDESFireAID aids[]); void mifare_desfire_free_application_ids(MifareDESFireAID aids[]);
int mifare_desfire_select_application (FreefareTag tag, MifareDESFireAID aid); int mifare_desfire_select_application(FreefareTag tag, MifareDESFireAID aid);
int mifare_desfire_format_picc (FreefareTag tag); int mifare_desfire_format_picc(FreefareTag tag);
int mifare_desfire_get_version (FreefareTag tag, struct mifare_desfire_version_info *version_info); int mifare_desfire_get_version(FreefareTag tag, struct mifare_desfire_version_info *version_info);
int mifare_desfire_free_mem (FreefareTag tag, uint32_t *size); int mifare_desfire_free_mem(FreefareTag tag, uint32_t *size);
int mifare_desfire_set_configuration (FreefareTag tag, bool disable_format, bool enable_random_uid); int mifare_desfire_set_configuration(FreefareTag tag, bool disable_format, bool enable_random_uid);
int mifare_desfire_set_default_key (FreefareTag tag, MifareDESFireKey key); int mifare_desfire_set_default_key(FreefareTag tag, MifareDESFireKey key);
int mifare_desfire_set_ats (FreefareTag tag, uint8_t *ats); int mifare_desfire_set_ats(FreefareTag tag, uint8_t *ats);
int mifare_desfire_get_card_uid (FreefareTag tag, char **uid); int mifare_desfire_get_card_uid(FreefareTag tag, char **uid);
int mifare_desfire_get_file_ids (FreefareTag tag, uint8_t **files, size_t *count); int mifare_desfire_get_file_ids(FreefareTag tag, uint8_t **files, size_t *count);
int mifare_desfire_get_iso_file_ids (FreefareTag tag, uint16_t **files, size_t *count); int mifare_desfire_get_iso_file_ids(FreefareTag tag, uint16_t **files, size_t *count);
int mifare_desfire_get_file_settings (FreefareTag tag, uint8_t file_no, struct mifare_desfire_file_settings *settings); int mifare_desfire_get_file_settings(FreefareTag tag, uint8_t file_no, struct mifare_desfire_file_settings *settings);
int mifare_desfire_change_file_settings (FreefareTag tag, uint8_t file_no, uint8_t communication_settings, uint16_t access_rights); int mifare_desfire_change_file_settings(FreefareTag tag, uint8_t file_no, uint8_t communication_settings, uint16_t access_rights);
int mifare_desfire_create_std_data_file (FreefareTag tag, uint8_t file_no, uint8_t communication_settings, uint16_t access_rights, uint32_t file_size); int mifare_desfire_create_std_data_file(FreefareTag tag, uint8_t file_no, uint8_t communication_settings, uint16_t access_rights, uint32_t file_size);
int mifare_desfire_create_std_data_file_iso (FreefareTag tag, uint8_t file_no, uint8_t communication_settings, uint16_t access_rights, uint32_t file_size, uint16_t iso_file_id); int mifare_desfire_create_std_data_file_iso(FreefareTag tag, uint8_t file_no, uint8_t communication_settings, uint16_t access_rights, uint32_t file_size, uint16_t iso_file_id);
int mifare_desfire_create_backup_data_file (FreefareTag tag, uint8_t file_no, uint8_t communication_settings, uint16_t access_rights, uint32_t file_size); int mifare_desfire_create_backup_data_file(FreefareTag tag, uint8_t file_no, uint8_t communication_settings, uint16_t access_rights, uint32_t file_size);
int mifare_desfire_create_backup_data_file_iso (FreefareTag tag, uint8_t file_no, uint8_t communication_settings, uint16_t access_rights, uint32_t file_size, uint16_t iso_file_id); int mifare_desfire_create_backup_data_file_iso(FreefareTag tag, uint8_t file_no, uint8_t communication_settings, uint16_t access_rights, uint32_t file_size, uint16_t iso_file_id);
int mifare_desfire_create_value_file (FreefareTag tag, uint8_t file_no, uint8_t communication_settings, uint16_t access_rights, int32_t lower_limit, int32_t upper_limit, int32_t value, uint8_t limited_credit_enable); int mifare_desfire_create_value_file(FreefareTag tag, uint8_t file_no, uint8_t communication_settings, uint16_t access_rights, int32_t lower_limit, int32_t upper_limit, int32_t value, uint8_t limited_credit_enable);
int mifare_desfire_create_linear_record_file (FreefareTag tag, uint8_t file_no, uint8_t communication_settings, uint16_t access_rights, uint32_t record_size, uint32_t max_number_of_records); int mifare_desfire_create_linear_record_file(FreefareTag tag, uint8_t file_no, uint8_t communication_settings, uint16_t access_rights, uint32_t record_size, uint32_t max_number_of_records);
int mifare_desfire_create_linear_record_file_iso (FreefareTag tag, uint8_t file_no, uint8_t communication_settings, uint16_t access_rights, uint32_t record_size, uint32_t max_number_of_records, uint16_t iso_file_id); int mifare_desfire_create_linear_record_file_iso(FreefareTag tag, uint8_t file_no, uint8_t communication_settings, uint16_t access_rights, uint32_t record_size, uint32_t max_number_of_records, uint16_t iso_file_id);
int mifare_desfire_create_cyclic_record_file (FreefareTag tag, uint8_t file_no, uint8_t communication_settings, uint16_t access_rights, uint32_t record_size, uint32_t max_number_of_records); int mifare_desfire_create_cyclic_record_file(FreefareTag tag, uint8_t file_no, uint8_t communication_settings, uint16_t access_rights, uint32_t record_size, uint32_t max_number_of_records);
int mifare_desfire_create_cyclic_record_file_iso (FreefareTag tag, uint8_t file_no, uint8_t communication_settings, uint16_t access_rights, uint32_t record_size, uint32_t max_number_of_records, uint16_t iso_file_id); int mifare_desfire_create_cyclic_record_file_iso(FreefareTag tag, uint8_t file_no, uint8_t communication_settings, uint16_t access_rights, uint32_t record_size, uint32_t max_number_of_records, uint16_t iso_file_id);
int mifare_desfire_delete_file (FreefareTag tag, uint8_t file_no); int mifare_desfire_delete_file(FreefareTag tag, uint8_t file_no);
ssize_t mifare_desfire_read_data (FreefareTag tag, uint8_t file_no, off_t offset, size_t length, void *data); ssize_t mifare_desfire_read_data(FreefareTag tag, uint8_t file_no, off_t offset, size_t length, void *data);
ssize_t mifare_desfire_read_data_ex (FreefareTag tag, uint8_t file_no, off_t offset, size_t length, void *data, int cs); ssize_t mifare_desfire_read_data_ex(FreefareTag tag, uint8_t file_no, off_t offset, size_t length, void *data, int cs);
ssize_t mifare_desfire_write_data (FreefareTag tag, uint8_t file_no, off_t offset, size_t length, const void *data); ssize_t mifare_desfire_write_data(FreefareTag tag, uint8_t file_no, off_t offset, size_t length, const void *data);
ssize_t mifare_desfire_write_data_ex (FreefareTag tag, uint8_t file_no, off_t offset, size_t length, const void *data, int cs); ssize_t mifare_desfire_write_data_ex(FreefareTag tag, uint8_t file_no, off_t offset, size_t length, const void *data, int cs);
int mifare_desfire_get_value (FreefareTag tag, uint8_t file_no, int32_t *value); int mifare_desfire_get_value(FreefareTag tag, uint8_t file_no, int32_t *value);
int mifare_desfire_get_value_ex (FreefareTag tag, uint8_t file_no, int32_t *value, int cs); int mifare_desfire_get_value_ex(FreefareTag tag, uint8_t file_no, int32_t *value, int cs);
int mifare_desfire_credit (FreefareTag tag, uint8_t file_no, int32_t amount); int mifare_desfire_credit(FreefareTag tag, uint8_t file_no, int32_t amount);
int mifare_desfire_credit_ex (FreefareTag tag, uint8_t file_no, int32_t amount, int cs); int mifare_desfire_credit_ex(FreefareTag tag, uint8_t file_no, int32_t amount, int cs);
int mifare_desfire_debit (FreefareTag tag, uint8_t file_no, int32_t amount); int mifare_desfire_debit(FreefareTag tag, uint8_t file_no, int32_t amount);
int mifare_desfire_debit_ex (FreefareTag tag, uint8_t file_no, int32_t amount, int cs); int mifare_desfire_debit_ex(FreefareTag tag, uint8_t file_no, int32_t amount, int cs);
int mifare_desfire_limited_credit (FreefareTag tag, uint8_t file_no, int32_t amount); int mifare_desfire_limited_credit(FreefareTag tag, uint8_t file_no, int32_t amount);
int mifare_desfire_limited_credit_ex (FreefareTag tag, uint8_t file_no, int32_t amount, int cs); int mifare_desfire_limited_credit_ex(FreefareTag tag, uint8_t file_no, int32_t amount, int cs);
ssize_t mifare_desfire_write_record (FreefareTag tag, uint8_t file_no, off_t offset, size_t length, void *data); ssize_t mifare_desfire_write_record(FreefareTag tag, uint8_t file_no, off_t offset, size_t length, void *data);
ssize_t mifare_desfire_write_record_ex (FreefareTag tag, uint8_t file_no, off_t offset, size_t length, void *data, int cs); ssize_t mifare_desfire_write_record_ex(FreefareTag tag, uint8_t file_no, off_t offset, size_t length, void *data, int cs);
ssize_t mifare_desfire_read_records (FreefareTag tag, uint8_t file_no, off_t offset, size_t length, void *data); ssize_t mifare_desfire_read_records(FreefareTag tag, uint8_t file_no, off_t offset, size_t length, void *data);
ssize_t mifare_desfire_read_records_ex (FreefareTag tag, uint8_t file_no, off_t offset, size_t length, void *data, int cs); ssize_t mifare_desfire_read_records_ex(FreefareTag tag, uint8_t file_no, off_t offset, size_t length, void *data, int cs);
int mifare_desfire_clear_record_file (FreefareTag tag, uint8_t file_no); int mifare_desfire_clear_record_file(FreefareTag tag, uint8_t file_no);
int mifare_desfire_commit_transaction (FreefareTag tag); int mifare_desfire_commit_transaction(FreefareTag tag);
int mifare_desfire_abort_transaction (FreefareTag tag); int mifare_desfire_abort_transaction(FreefareTag tag);
MifareDESFireKey mifare_desfire_des_key_new (const uint8_t value[8]); MifareDESFireKey mifare_desfire_des_key_new(const uint8_t value[8]);
MifareDESFireKey mifare_desfire_3des_key_new (const uint8_t value[16]); MifareDESFireKey mifare_desfire_3des_key_new(const uint8_t value[16]);
MifareDESFireKey mifare_desfire_des_key_new_with_version (const uint8_t value[8]); MifareDESFireKey mifare_desfire_des_key_new_with_version(const uint8_t value[8]);
MifareDESFireKey mifare_desfire_3des_key_new_with_version (const uint8_t value[16]); MifareDESFireKey mifare_desfire_3des_key_new_with_version(const uint8_t value[16]);
MifareDESFireKey mifare_desfire_3k3des_key_new (const uint8_t value[24]); MifareDESFireKey mifare_desfire_3k3des_key_new(const uint8_t value[24]);
MifareDESFireKey mifare_desfire_3k3des_key_new_with_version (const uint8_t value[24]); MifareDESFireKey mifare_desfire_3k3des_key_new_with_version(const uint8_t value[24]);
MifareDESFireKey mifare_desfire_aes_key_new (const uint8_t value[16]); MifareDESFireKey mifare_desfire_aes_key_new(const uint8_t value[16]);
MifareDESFireKey mifare_desfire_aes_key_new_with_version (const uint8_t value[16], uint8_t version); MifareDESFireKey mifare_desfire_aes_key_new_with_version(const uint8_t value[16], uint8_t version);
uint8_t mifare_desfire_key_get_version (MifareDESFireKey key); uint8_t mifare_desfire_key_get_version(MifareDESFireKey key);
void mifare_desfire_key_set_version (MifareDESFireKey key, uint8_t version); void mifare_desfire_key_set_version(MifareDESFireKey key, uint8_t version);
void mifare_desfire_key_free (MifareDESFireKey key); void mifare_desfire_key_free(MifareDESFireKey key);
uint8_t *tlv_encode (const uint8_t type, const uint8_t *istream, uint16_t isize, size_t *osize); uint8_t *tlv_encode(const uint8_t type, const uint8_t *istream, uint16_t isize, size_t *osize);
uint8_t *tlv_decode (const uint8_t *istream, uint8_t *type, uint16_t *size); uint8_t *tlv_decode(const uint8_t *istream, uint8_t *type, uint16_t *size);
size_t tlv_record_length (const uint8_t *istream, size_t *field_length_size, size_t *field_value_size); size_t tlv_record_length(const uint8_t *istream, size_t *field_length_size, size_t *field_value_size);
uint8_t *tlv_append (uint8_t *a, uint8_t *b); uint8_t *tlv_append(uint8_t *a, uint8_t *b);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif // __cplusplus #endif // __cplusplus
#endif /* !__FREEFARE_H__ */ #endif /* !__FREEFARE_H__ */

View file

@ -98,14 +98,14 @@
#define MAX_CRYPTO_BLOCK_SIZE 16 #define MAX_CRYPTO_BLOCK_SIZE 16
void *memdup (const void *p, const size_t n); void *memdup(const void *p, const size_t n);
struct mad_sector_0x00; struct mad_sector_0x00;
struct mad_sector_0x10; struct mad_sector_0x10;
void nxp_crc (uint8_t *crc, const uint8_t value); void nxp_crc(uint8_t *crc, const uint8_t value);
uint8_t sector_0x00_crc8 (Mad mad); uint8_t sector_0x00_crc8(Mad mad);
uint8_t sector_0x10_crc8 (Mad mad); uint8_t sector_0x10_crc8(Mad mad);
typedef enum { typedef enum {
MCD_SEND, MCD_SEND,
@ -137,21 +137,21 @@ typedef enum {
#define MAC_MASK 0x0F0 #define MAC_MASK 0x0F0
#define CMAC_MACK 0xF00 #define CMAC_MACK 0xF00
void *mifare_cryto_preprocess_data (FreefareTag tag, void *data, size_t *nbytes, off_t offset, int communication_settings); void *mifare_cryto_preprocess_data(FreefareTag tag, void *data, size_t *nbytes, off_t offset, int communication_settings);
void *mifare_cryto_postprocess_data (FreefareTag tag, void *data, ssize_t *nbytes, int communication_settings); void *mifare_cryto_postprocess_data(FreefareTag tag, void *data, ssize_t *nbytes, int communication_settings);
void mifare_cypher_single_block (MifareDESFireKey key, uint8_t *data, uint8_t *ivect, MifareCryptoDirection direction, MifareCryptoOperation operation, size_t block_size); void mifare_cypher_single_block(MifareDESFireKey key, uint8_t *data, uint8_t *ivect, MifareCryptoDirection direction, MifareCryptoOperation operation, size_t block_size);
void mifare_cypher_blocks_chained (FreefareTag tag, MifareDESFireKey key, uint8_t *ivect, uint8_t *data, size_t data_size, MifareCryptoDirection direction, MifareCryptoOperation operation); void mifare_cypher_blocks_chained(FreefareTag tag, MifareDESFireKey key, uint8_t *ivect, uint8_t *data, size_t data_size, MifareCryptoDirection direction, MifareCryptoOperation operation);
void rol (uint8_t *data, const size_t len); void rol(uint8_t *data, const size_t len);
void desfire_crc32 (const uint8_t *data, const size_t len, uint8_t *crc); void desfire_crc32(const uint8_t *data, const size_t len, uint8_t *crc);
void desfire_crc32_append (uint8_t *data, const size_t len); void desfire_crc32_append(uint8_t *data, const size_t len);
size_t key_block_size (const MifareDESFireKey key); size_t key_block_size(const MifareDESFireKey key);
size_t padded_data_length (const size_t nbytes, const size_t block_size); size_t padded_data_length(const size_t nbytes, const size_t block_size);
size_t maced_data_length (const MifareDESFireKey key, const size_t nbytes); size_t maced_data_length(const MifareDESFireKey key, const size_t nbytes);
size_t enciphered_data_length (const FreefareTag tag, const size_t nbytes, int communication_settings); size_t enciphered_data_length(const FreefareTag tag, const size_t nbytes, int communication_settings);
void cmac_generate_subkeys (MifareDESFireKey key); void cmac_generate_subkeys(MifareDESFireKey key);
void cmac (const MifareDESFireKey key, uint8_t *ivect, const uint8_t *data, size_t len, uint8_t *cmac); void cmac(const MifareDESFireKey key, uint8_t *ivect, const uint8_t *data, size_t len, uint8_t *cmac);
void *assert_crypto_buffer_size (FreefareTag tag, size_t nbytes); void *assert_crypto_buffer_size(FreefareTag tag, size_t nbytes);
#define MIFARE_ULTRALIGHT_PAGE_COUNT 0x10 #define MIFARE_ULTRALIGHT_PAGE_COUNT 0x10
#define MIFARE_ULTRALIGHT_C_PAGE_COUNT 0x30 #define MIFARE_ULTRALIGHT_C_PAGE_COUNT 0x30
@ -172,7 +172,7 @@ struct freefare_tag {
nfc_target info; nfc_target info;
int type; int type;
int active; int active;
void (*free_tag) (FreefareTag tag); void (*free_tag)(FreefareTag tag);
}; };
struct felica_tag { struct felica_tag {
@ -189,10 +189,10 @@ struct mifare_classic_tag {
* address and avoid false cache hit with inconsistent data. * address and avoid false cache hit with inconsistent data.
*/ */
struct { struct {
int16_t sector_trailer_block_number; int16_t sector_trailer_block_number;
uint16_t sector_access_bits; uint16_t sector_access_bits;
int16_t block_number; int16_t block_number;
uint8_t block_access_bits; uint8_t block_access_bits;
} cached_access_bits; } cached_access_bits;
}; };
@ -232,8 +232,8 @@ struct mifare_desfire_tag {
uint32_t selected_application; uint32_t selected_application;
}; };
MifareDESFireKey mifare_desfire_session_key_new (const uint8_t rnda[], const uint8_t rndb[], MifareDESFireKey authentication_key); MifareDESFireKey mifare_desfire_session_key_new(const uint8_t rnda[], const uint8_t rndb[], MifareDESFireKey authentication_key);
const char *mifare_desfire_error_lookup (uint8_t error); const char *mifare_desfire_error_lookup(uint8_t error);
struct mifare_ultralight_tag { struct mifare_ultralight_tag {
struct freefare_tag __tag; struct freefare_tag __tag;
@ -345,7 +345,7 @@ struct ntag21x_key {
*/ */
#define BUFFER_APPEND(buffer_name, data) \ #define BUFFER_APPEND(buffer_name, data) \
do { \ do { \
buffer_name[__##buffer_name##_n++] = data; \ buffer_name[__##buffer_name##_n++] = data; \
} while (0) } while (0)
/* /*
@ -353,10 +353,10 @@ struct ntag21x_key {
*/ */
#define BUFFER_APPEND_BYTES(buffer_name, data, size) \ #define BUFFER_APPEND_BYTES(buffer_name, data, size) \
do { \ do { \
size_t __n = 0; \ size_t __n = 0; \
while (__n < size) { \ while (__n < size) { \
buffer_name[__##buffer_name##_n++] = ((uint8_t *)data)[__n++]; \ buffer_name[__##buffer_name##_n++] = ((uint8_t *)data)[__n++]; \
} \ } \
} while (0) } while (0)
/* /*
@ -371,17 +371,17 @@ struct ntag21x_key {
#if defined(_BYTE_ORDER) && (_BYTE_ORDER != _LITTLE_ENDIAN) #if defined(_BYTE_ORDER) && (_BYTE_ORDER != _LITTLE_ENDIAN)
#define BUFFER_APPEND_LE(buffer, data, data_size, field_size) \ #define BUFFER_APPEND_LE(buffer, data, data_size, field_size) \
do { \ do { \
size_t __data_size = data_size; \ size_t __data_size = data_size; \
size_t __field_size = field_size; \ size_t __field_size = field_size; \
while (__field_size--, __data_size--) { \ while (__field_size--, __data_size--) { \
buffer[__##buffer##_n++] = ((uint8_t *)&data)[__field_size]; \ buffer[__##buffer##_n++] = ((uint8_t *)&data)[__field_size]; \
} \ } \
} while (0) } while (0)
#else #else
#define BUFFER_APPEND_LE(buffer, data, data_size, field_size) \ #define BUFFER_APPEND_LE(buffer, data, data_size, field_size) \
do { \ do { \
memcpy (buffer + __##buffer##_n, &data, data_size); \ memcpy (buffer + __##buffer##_n, &data, data_size); \
__##buffer##_n += data_size; \ __##buffer##_n += data_size; \
} while (0) } while (0)
#endif #endif

View file

@ -110,16 +110,16 @@ const MadAid mad_nfcforum_aid = {
* Allocate an empty new MAD. * Allocate an empty new MAD.
*/ */
Mad Mad
mad_new (uint8_t version) mad_new(uint8_t version)
{ {
Mad mad = malloc (sizeof (*mad)); Mad mad = malloc(sizeof(*mad));
if (!mad) if (!mad)
return NULL; return NULL;
mad->version = version; mad->version = version;
memset (&(mad->sector_0x00), 0, sizeof (mad->sector_0x00)); memset(&(mad->sector_0x00), 0, sizeof(mad->sector_0x00));
memset (&(mad->sector_0x10), 0, sizeof (mad->sector_0x10)); memset(&(mad->sector_0x10), 0, sizeof(mad->sector_0x10));
return mad; return mad;
} }
@ -128,7 +128,7 @@ mad_new (uint8_t version)
* Compute CRC. * Compute CRC.
*/ */
void void
nxp_crc (uint8_t *crc, const uint8_t value) nxp_crc(uint8_t *crc, const uint8_t value)
{ {
/* x^8 + x^4 + x^3 + x^2 + 1 => 0x11d */ /* x^8 + x^4 + x^3 + x^2 + 1 => 0x11d */
const uint8_t poly = 0x1d; const uint8_t poly = 0x1d;
@ -144,30 +144,30 @@ nxp_crc (uint8_t *crc, const uint8_t value)
} }
uint8_t uint8_t
sector_0x00_crc8 (Mad mad) sector_0x00_crc8(Mad mad)
{ {
uint8_t crc = CRC_PRESET; uint8_t crc = CRC_PRESET;
nxp_crc (&crc, mad->sector_0x00.info); nxp_crc(&crc, mad->sector_0x00.info);
for (int n = 0; n < SECTOR_0X00_AIDS; n++) { for (int n = 0; n < SECTOR_0X00_AIDS; n++) {
nxp_crc (&crc, mad->sector_0x00.aids[n].application_code); nxp_crc(&crc, mad->sector_0x00.aids[n].application_code);
nxp_crc (&crc, mad->sector_0x00.aids[n].function_cluster_code); nxp_crc(&crc, mad->sector_0x00.aids[n].function_cluster_code);
} }
return crc; return crc;
} }
uint8_t uint8_t
sector_0x10_crc8 (Mad mad) sector_0x10_crc8(Mad mad)
{ {
uint8_t crc = CRC_PRESET; uint8_t crc = CRC_PRESET;
nxp_crc (&crc, mad->sector_0x10.info); nxp_crc(&crc, mad->sector_0x10.info);
for (int n = 0; n < SECTOR_0X10_AIDS; n++) { for (int n = 0; n < SECTOR_0X10_AIDS; n++) {
nxp_crc (&crc, mad->sector_0x10.aids[n].application_code); nxp_crc(&crc, mad->sector_0x10.aids[n].application_code);
nxp_crc (&crc, mad->sector_0x10.aids[n].function_cluster_code); nxp_crc(&crc, mad->sector_0x10.aids[n].function_cluster_code);
} }
return crc; return crc;
@ -177,21 +177,21 @@ sector_0x10_crc8 (Mad mad)
* Read a MAD from the provided MIFARE tag. * Read a MAD from the provided MIFARE tag.
*/ */
Mad Mad
mad_read (FreefareTag tag) mad_read(FreefareTag tag)
{ {
Mad mad = malloc (sizeof (*mad)); Mad mad = malloc(sizeof(*mad));
if (!mad) if (!mad)
goto error; goto error;
/* Authenticate using MAD key A */ /* Authenticate using MAD key A */
if (mifare_classic_authenticate (tag, 0x03, mad_public_key_a, MFC_KEY_A) < 0) { if (mifare_classic_authenticate(tag, 0x03, mad_public_key_a, MFC_KEY_A) < 0) {
goto error; goto error;
} }
/* Read first sector trailer block */ /* Read first sector trailer block */
MifareClassicBlock data; MifareClassicBlock data;
if (mifare_classic_read (tag, 0x03, &data) < 0) { if (mifare_classic_read(tag, 0x03, &data) < 0) {
goto error; goto error;
} }
uint8_t gpb = data[9]; uint8_t gpb = data[9];
@ -216,20 +216,20 @@ mad_read (FreefareTag tag)
} }
/* Read MAD data at 0x00 (MAD1, MAD2) */ /* Read MAD data at 0x00 (MAD1, MAD2) */
if (mifare_classic_read (tag, 0x01, &data) < 0) if (mifare_classic_read(tag, 0x01, &data) < 0)
goto error; goto error;
uint8_t *p = (uint8_t *) &(mad->sector_0x00); uint8_t *p = (uint8_t *) & (mad->sector_0x00);
memcpy (p, data, sizeof (data)); memcpy(p, data, sizeof(data));
p+= sizeof (data); p += sizeof(data);
if (mifare_classic_read (tag, 0x02, &data) < 0) if (mifare_classic_read(tag, 0x02, &data) < 0)
goto error; goto error;
memcpy (p, data, sizeof (data)); memcpy(p, data, sizeof(data));
uint8_t crc = mad->sector_0x00.crc; uint8_t crc = mad->sector_0x00.crc;
uint8_t computed_crc = sector_0x00_crc8 (mad); uint8_t computed_crc = sector_0x00_crc8(mad);
if (crc != computed_crc) if (crc != computed_crc)
goto error; goto error;
@ -237,30 +237,30 @@ mad_read (FreefareTag tag)
if (mad->version == 2) { if (mad->version == 2) {
/* Authenticate using MAD key A */ /* Authenticate using MAD key A */
if (mifare_classic_authenticate (tag, 0x43, mad_public_key_a, MFC_KEY_A) < 0) { if (mifare_classic_authenticate(tag, 0x43, mad_public_key_a, MFC_KEY_A) < 0) {
goto error; goto error;
} }
p = (uint8_t *) &(mad->sector_0x10); p = (uint8_t *) & (mad->sector_0x10);
if (mifare_classic_read (tag, 0x40, &data) < 0) if (mifare_classic_read(tag, 0x40, &data) < 0)
goto error; goto error;
memcpy (p, data, sizeof (data)); memcpy(p, data, sizeof(data));
p += sizeof (data); p += sizeof(data);
if (mifare_classic_read (tag, 0x41, &data) < 0) if (mifare_classic_read(tag, 0x41, &data) < 0)
goto error; goto error;
memcpy (p, data, sizeof (data)); memcpy(p, data, sizeof(data));
p += sizeof (data); p += sizeof(data);
if (mifare_classic_read (tag, 0x42, &data) < 0) if (mifare_classic_read(tag, 0x42, &data) < 0)
goto error; goto error;
memcpy (p, data, sizeof (data)); memcpy(p, data, sizeof(data));
crc = mad->sector_0x10.crc; crc = mad->sector_0x10.crc;
computed_crc = sector_0x10_crc8 (mad); computed_crc = sector_0x10_crc8(mad);
if (crc != computed_crc) if (crc != computed_crc)
goto error; goto error;
} }
@ -268,7 +268,7 @@ mad_read (FreefareTag tag)
return mad; return mad;
error: error:
free (mad); free(mad);
return NULL; return NULL;
} }
@ -276,17 +276,17 @@ error:
* Write the mad to the provided MIFARE tad using the provided Key-B keys. * Write the mad to the provided MIFARE tad using the provided Key-B keys.
*/ */
int int
mad_write (FreefareTag tag, Mad mad, const MifareClassicKey key_b_sector_00, const MifareClassicKey key_b_sector_10) mad_write(FreefareTag tag, Mad mad, const MifareClassicKey key_b_sector_00, const MifareClassicKey key_b_sector_10)
{ {
MifareClassicBlock data; MifareClassicBlock data;
if (mifare_classic_authenticate (tag, 0x00, key_b_sector_00, MFC_KEY_B) < 0) if (mifare_classic_authenticate(tag, 0x00, key_b_sector_00, MFC_KEY_B) < 0)
return -1; return -1;
if ((1 != mifare_classic_get_data_block_permission (tag, 0x01, MCAB_W, MFC_KEY_B)) || if ((1 != mifare_classic_get_data_block_permission(tag, 0x01, MCAB_W, MFC_KEY_B)) ||
(1 != mifare_classic_get_data_block_permission (tag, 0x02, MCAB_W, MFC_KEY_B)) || (1 != mifare_classic_get_data_block_permission(tag, 0x02, MCAB_W, MFC_KEY_B)) ||
(1 != mifare_classic_get_trailer_block_permission (tag, 0x03, MCAB_WRITE_KEYA, MFC_KEY_B)) || (1 != mifare_classic_get_trailer_block_permission(tag, 0x03, MCAB_WRITE_KEYA, MFC_KEY_B)) ||
(1 != mifare_classic_get_trailer_block_permission (tag, 0x03, MCAB_WRITE_ACCESS_BITS, MFC_KEY_B))) { (1 != mifare_classic_get_trailer_block_permission(tag, 0x03, MCAB_WRITE_ACCESS_BITS, MFC_KEY_B))) {
errno = EPERM; errno = EPERM;
return -1; return -1;
} }
@ -309,42 +309,42 @@ mad_write (FreefareTag tag, Mad mad, const MifareClassicKey key_b_sector_00, con
} }
if (2 == mad->version) { if (2 == mad->version) {
if (mifare_classic_authenticate (tag, 0x40, key_b_sector_10, MFC_KEY_B) < 0) if (mifare_classic_authenticate(tag, 0x40, key_b_sector_10, MFC_KEY_B) < 0)
return -1; return -1;
if ((1 != mifare_classic_get_data_block_permission (tag, 0x40, MCAB_W, MFC_KEY_B)) || if ((1 != mifare_classic_get_data_block_permission(tag, 0x40, MCAB_W, MFC_KEY_B)) ||
(1 != mifare_classic_get_data_block_permission (tag, 0x41, MCAB_W, MFC_KEY_B)) || (1 != mifare_classic_get_data_block_permission(tag, 0x41, MCAB_W, MFC_KEY_B)) ||
(1 != mifare_classic_get_data_block_permission (tag, 0x42, MCAB_W, MFC_KEY_B)) || (1 != mifare_classic_get_data_block_permission(tag, 0x42, MCAB_W, MFC_KEY_B)) ||
(1 != mifare_classic_get_trailer_block_permission (tag, 0x43, MCAB_WRITE_KEYA, MFC_KEY_B)) || (1 != mifare_classic_get_trailer_block_permission(tag, 0x43, MCAB_WRITE_KEYA, MFC_KEY_B)) ||
(1 != mifare_classic_get_trailer_block_permission (tag, 0x43, MCAB_WRITE_ACCESS_BITS, MFC_KEY_B))) { (1 != mifare_classic_get_trailer_block_permission(tag, 0x43, MCAB_WRITE_ACCESS_BITS, MFC_KEY_B))) {
errno = EPERM; errno = EPERM;
return -1; return -1;
} }
mad->sector_0x10.crc = sector_0x10_crc8 (mad); mad->sector_0x10.crc = sector_0x10_crc8(mad);
memcpy (data, (uint8_t *)&(mad->sector_0x10), sizeof (data)); memcpy(data, (uint8_t *) & (mad->sector_0x10), sizeof(data));
if (mifare_classic_write (tag, 0x40, data) < 0) return -1; if (mifare_classic_write(tag, 0x40, data) < 0) return -1;
memcpy (data, (uint8_t *)&(mad->sector_0x10) + sizeof (data), sizeof (data)); memcpy(data, (uint8_t *) & (mad->sector_0x10) + sizeof(data), sizeof(data));
if (mifare_classic_write (tag, 0x41, data) < 0) return -1; if (mifare_classic_write(tag, 0x41, data) < 0) return -1;
memcpy (data, (uint8_t *)&(mad->sector_0x10) + sizeof (data) * 2, sizeof (data)); memcpy(data, (uint8_t *) & (mad->sector_0x10) + sizeof(data) * 2, sizeof(data));
if (mifare_classic_write (tag, 0x42, data) < 0) return -1; if (mifare_classic_write(tag, 0x42, data) < 0) return -1;
mifare_classic_trailer_block (&data, mad_public_key_a, 0x0, 0x1, 0x1, 0x6, 0x00, key_b_sector_10); mifare_classic_trailer_block(&data, mad_public_key_a, 0x0, 0x1, 0x1, 0x6, 0x00, key_b_sector_10);
if (mifare_classic_write (tag, 0x43, data) < 0) return -1; if (mifare_classic_write(tag, 0x43, data) < 0) return -1;
} }
mad->sector_0x00.crc = sector_0x00_crc8 (mad); mad->sector_0x00.crc = sector_0x00_crc8(mad);
if (mifare_classic_authenticate (tag, 0x00, key_b_sector_00, MFC_KEY_B) < 0) return -1; if (mifare_classic_authenticate(tag, 0x00, key_b_sector_00, MFC_KEY_B) < 0) return -1;
memcpy (data, (uint8_t *)&(mad->sector_0x00), sizeof (data)); memcpy(data, (uint8_t *) & (mad->sector_0x00), sizeof(data));
if (mifare_classic_write (tag, 0x01, data) < 0) return -1; if (mifare_classic_write(tag, 0x01, data) < 0) return -1;
memcpy (data, (uint8_t *)&(mad->sector_0x00) + sizeof (data), sizeof (data)); memcpy(data, (uint8_t *) & (mad->sector_0x00) + sizeof(data), sizeof(data));
if (mifare_classic_write (tag, 0x02, data) < 0) return -1; if (mifare_classic_write(tag, 0x02, data) < 0) return -1;
mifare_classic_trailer_block (&data, mad_public_key_a, 0x0, 0x1, 0x1, 0x6, gpb, key_b_sector_00); mifare_classic_trailer_block(&data, mad_public_key_a, 0x0, 0x1, 0x1, 0x6, gpb, key_b_sector_00);
if (mifare_classic_write (tag, 0x03, data) < 0) return -1; if (mifare_classic_write(tag, 0x03, data) < 0) return -1;
return 0; return 0;
} }
@ -353,7 +353,7 @@ mad_write (FreefareTag tag, Mad mad, const MifareClassicKey key_b_sector_00, con
* Return a MAD version. * Return a MAD version.
*/ */
int int
mad_get_version (Mad mad) mad_get_version(Mad mad)
{ {
return mad->version; return mad->version;
} }
@ -362,11 +362,11 @@ mad_get_version (Mad mad)
* Set a MAD version. * Set a MAD version.
*/ */
void void
mad_set_version (Mad mad, const uint8_t version) mad_set_version(Mad mad, const uint8_t version)
{ {
if ((version == 2) && (mad->version == 1)) { if ((version == 2) && (mad->version == 1)) {
/* We use a larger MAD so initialise the new blocks */ /* We use a larger MAD so initialise the new blocks */
memset (&(mad->sector_0x10), 0, sizeof (mad->sector_0x10)); memset(&(mad->sector_0x10), 0, sizeof(mad->sector_0x10));
} }
mad->version = version; mad->version = version;
} }
@ -449,7 +449,7 @@ mad_set_aid(Mad mad, const MifareClassicSectorNumber sector, MadAid aid)
} }
bool bool
mad_sector_reserved (const MifareClassicSectorNumber sector) mad_sector_reserved(const MifareClassicSectorNumber sector)
{ {
return ((0x00 == sector) || (0x10 == sector)); return ((0x00 == sector) || (0x10 == sector));
} }
@ -458,7 +458,7 @@ mad_sector_reserved (const MifareClassicSectorNumber sector)
* Free memory allocated by mad_new() and mad_read(). * Free memory allocated by mad_new() and mad_read().
*/ */
void void
mad_free (Mad mad) mad_free(Mad mad)
{ {
free (mad); free(mad);
} }

View file

@ -35,24 +35,24 @@
#define FIRST_SECTOR 1 #define FIRST_SECTOR 1
int aidcmp (const MadAid left, const MadAid right); int aidcmp(const MadAid left, const MadAid right);
size_t count_aids (const Mad mad, const MadAid aid); size_t count_aids(const Mad mad, const MadAid aid);
/* /*
* Get the number of sectors allocated in the MAD for the provided application. * Get the number of sectors allocated in the MAD for the provided application.
*/ */
size_t size_t
count_aids (const Mad mad, const MadAid aid) count_aids(const Mad mad, const MadAid aid)
{ {
size_t result = 0; size_t result = 0;
MifareClassicSectorNumber s_max = (mad_get_version (mad) == 1) ? 0x0f : 0x27; MifareClassicSectorNumber s_max = (mad_get_version(mad) == 1) ? 0x0f : 0x27;
/* Count application sectors */ /* Count application sectors */
MadAid c_aid; MadAid c_aid;
for (MifareClassicSectorNumber s = FIRST_SECTOR; s <= s_max; s++) { for (MifareClassicSectorNumber s = FIRST_SECTOR; s <= s_max; s++) {
mad_get_aid (mad, s, &c_aid); mad_get_aid(mad, s, &c_aid);
if (0 == aidcmp (aid, c_aid)) { if (0 == aidcmp(aid, c_aid)) {
result++; result++;
} }
} }
@ -64,7 +64,7 @@ count_aids (const Mad mad, const MadAid aid)
* Compare two application identifiers. * Compare two application identifiers.
*/ */
inline int inline int
aidcmp (const MadAid left, const MadAid right) aidcmp(const MadAid left, const MadAid right)
{ {
return ((left.function_cluster_code - right.function_cluster_code) << 8) | (left.application_code - right.application_code); return ((left.function_cluster_code - right.function_cluster_code) << 8) | (left.application_code - right.application_code);
} }
@ -78,7 +78,7 @@ aidcmp (const MadAid left, const MadAid right)
* Allocates a new application into a MAD. * Allocates a new application into a MAD.
*/ */
MifareClassicSectorNumber * MifareClassicSectorNumber *
mifare_application_alloc (Mad mad, MadAid aid, size_t size) mifare_application_alloc(Mad mad, MadAid aid, size_t size)
{ {
uint8_t sector_map[40]; uint8_t sector_map[40];
MifareClassicSectorNumber sector; MifareClassicSectorNumber sector;
@ -90,12 +90,12 @@ mifare_application_alloc (Mad mad, MadAid aid, size_t size)
* Ensure the card does not already have the application registered. * Ensure the card does not already have the application registered.
*/ */
MifareClassicSectorNumber *found; MifareClassicSectorNumber *found;
if ((found = mifare_application_find (mad, aid))) { if ((found = mifare_application_find(mad, aid))) {
free (found); free(found);
return NULL; return NULL;
} }
for (size_t i = 0; i < sizeof (sector_map); i++) for (size_t i = 0; i < sizeof(sector_map); i++)
sector_map[i] = 0; sector_map[i] = 0;
/* /*
@ -103,27 +103,27 @@ mifare_application_alloc (Mad mad, MadAid aid, size_t size)
* when the target is a Mifare Classic 4k. * when the target is a Mifare Classic 4k.
*/ */
MadAid free_aid = { 0x00, 0x00 }; MadAid free_aid = { 0x00, 0x00 };
if (mad_get_version (mad) == 2) { if (mad_get_version(mad) == 2) {
sector = 32; sector = 32;
while ((s >= 12*16) && sector < 40) { while ((s >= 12 * 16) && sector < 40) {
mad_get_aid (mad, sector, &sector_aid); mad_get_aid(mad, sector, &sector_aid);
if (0 == aidcmp (sector_aid, free_aid)) { if (0 == aidcmp(sector_aid, free_aid)) {
sector_map[sector] = 1; sector_map[sector] = 1;
s -= 15*16; s -= 15 * 16;
} }
sector++; sector++;
} }
} }
sector = FIRST_SECTOR; sector = FIRST_SECTOR;
MifareClassicSectorNumber s_max = (mad_get_version (mad) == 1) ? 15 : 31; MifareClassicSectorNumber s_max = (mad_get_version(mad) == 1) ? 15 : 31;
while ((s > 0) && (sector <= s_max)) { while ((s > 0) && (sector <= s_max)) {
if (mad_sector_reserved (sector)) if (mad_sector_reserved(sector))
continue; continue;
mad_get_aid (mad, sector, &sector_aid); mad_get_aid(mad, sector, &sector_aid);
if (0 == aidcmp (sector_aid, free_aid)) { if (0 == aidcmp(sector_aid, free_aid)) {
sector_map[sector] = 1; sector_map[sector] = 1;
s -= 3*16; s -= 3 * 16;
} }
sector++; sector++;
} }
@ -135,18 +135,18 @@ mifare_application_alloc (Mad mad, MadAid aid, size_t size)
return NULL; return NULL;
int n = 0; int n = 0;
for (size_t i = FIRST_SECTOR; i < sizeof (sector_map); i++) for (size_t i = FIRST_SECTOR; i < sizeof(sector_map); i++)
if (sector_map[i]) if (sector_map[i])
n++; n++;
if (!(res = malloc (sizeof (*res) * (n+1)))) if (!(res = malloc(sizeof(*res) * (n + 1))))
return NULL; return NULL;
n = 0; n = 0;
for (size_t i = FIRST_SECTOR; i < sizeof (sector_map); i++) for (size_t i = FIRST_SECTOR; i < sizeof(sector_map); i++)
if (sector_map[i]) { if (sector_map[i]) {
res[n] = i; res[n] = i;
mad_set_aid (mad, i, aid); mad_set_aid(mad, i, aid);
n++; n++;
} }
@ -160,21 +160,21 @@ mifare_application_alloc (Mad mad, MadAid aid, size_t size)
* Remove an application from a MAD. * Remove an application from a MAD.
*/ */
int int
mifare_application_free (Mad mad, MadAid aid) mifare_application_free(Mad mad, MadAid aid)
{ {
MifareClassicSectorNumber *sectors = mifare_application_find (mad, aid); MifareClassicSectorNumber *sectors = mifare_application_find(mad, aid);
MifareClassicSectorNumber *p = sectors; MifareClassicSectorNumber *p = sectors;
MadAid free_aid = { 0x00, 0x00 }; MadAid free_aid = { 0x00, 0x00 };
/* figure out if malloc() in mifare_application_find() failed */ /* figure out if malloc() in mifare_application_find() failed */
if (sectors == NULL) return count_aids (mad, aid) ? -1 : 0; if (sectors == NULL) return count_aids(mad, aid) ? -1 : 0;
while (*p) { while (*p) {
mad_set_aid (mad, *p, free_aid); mad_set_aid(mad, *p, free_aid);
p++; p++;
} }
free (sectors); free(sectors);
return 0; return 0;
} }
@ -188,21 +188,21 @@ mifare_application_free (Mad mad, MadAid aid)
* Get all sector numbers of an application from the provided MAD. * Get all sector numbers of an application from the provided MAD.
*/ */
MifareClassicSectorNumber * MifareClassicSectorNumber *
mifare_application_find (Mad mad, MadAid aid) mifare_application_find(Mad mad, MadAid aid)
{ {
MifareClassicSectorNumber *res = NULL; MifareClassicSectorNumber *res = NULL;
size_t res_count = count_aids (mad, aid); size_t res_count = count_aids(mad, aid);
if (res_count) if (res_count)
res = malloc (sizeof (*res) * (res_count + 1)); res = malloc(sizeof(*res) * (res_count + 1));
size_t r = FIRST_SECTOR, w = 0; size_t r = FIRST_SECTOR, w = 0;
if (res) { if (res) {
/* Fill in the result */ /* Fill in the result */
MadAid c_aid; MadAid c_aid;
while (w < res_count) { while (w < res_count) {
mad_get_aid (mad, r, &c_aid); mad_get_aid(mad, r, &c_aid);
if (0 == aidcmp (c_aid, aid)) { if (0 == aidcmp(c_aid, aid)) {
res[w++] = r; res[w++] = r;
} }
r++; r++;
@ -214,36 +214,36 @@ mifare_application_find (Mad mad, MadAid aid)
} }
ssize_t ssize_t
mifare_application_read (FreefareTag tag, Mad mad, const MadAid aid, void *buf, size_t nbytes, const MifareClassicKey key, const MifareClassicKeyType key_type) mifare_application_read(FreefareTag tag, Mad mad, const MadAid aid, void *buf, size_t nbytes, const MifareClassicKey key, const MifareClassicKeyType key_type)
{ {
ssize_t res = 0; ssize_t res = 0;
MifareClassicSectorNumber *sectors = mifare_application_find (mad, aid); MifareClassicSectorNumber *sectors = mifare_application_find(mad, aid);
MifareClassicSectorNumber *s = sectors; MifareClassicSectorNumber *s = sectors;
if (!sectors) if (!sectors)
return errno = EBADF, -1; return errno = EBADF, -1;
while (*s && nbytes && (res >= 0)) { while (*s && nbytes && (res >= 0)) {
MifareClassicBlockNumber first_block = mifare_classic_sector_first_block (*s); MifareClassicBlockNumber first_block = mifare_classic_sector_first_block(*s);
MifareClassicBlockNumber last_block = mifare_classic_sector_last_block (*s); MifareClassicBlockNumber last_block = mifare_classic_sector_last_block(*s);
MifareClassicBlockNumber b = first_block; MifareClassicBlockNumber b = first_block;
MifareClassicBlock block; MifareClassicBlock block;
if (mifare_classic_authenticate (tag, first_block, key, key_type) < 0) { if (mifare_classic_authenticate(tag, first_block, key, key_type) < 0) {
res = -1; res = -1;
break; break;
} }
while ((b < last_block) && nbytes) { while ((b < last_block) && nbytes) {
size_t n = MIN (nbytes, 16); size_t n = MIN(nbytes, 16);
if (mifare_classic_read (tag, b, &block) < 0) { if (mifare_classic_read(tag, b, &block) < 0) {
res = -1; res = -1;
break; break;
} }
memcpy ((uint8_t *)buf + res, &block, n); memcpy((uint8_t *)buf + res, &block, n);
nbytes -= n; nbytes -= n;
res += n; res += n;
@ -254,16 +254,16 @@ mifare_application_read (FreefareTag tag, Mad mad, const MadAid aid, void *buf,
s++; s++;
} }
free (sectors); free(sectors);
return res; return res;
} }
ssize_t ssize_t
mifare_application_write (FreefareTag tag, Mad mad, const MadAid aid, const void *buf, size_t nbytes, const MifareClassicKey key, const MifareClassicKeyType key_type) mifare_application_write(FreefareTag tag, Mad mad, const MadAid aid, const void *buf, size_t nbytes, const MifareClassicKey key, const MifareClassicKeyType key_type)
{ {
ssize_t res = 0; ssize_t res = 0;
MifareClassicSectorNumber *sectors = mifare_application_find (mad, aid); MifareClassicSectorNumber *sectors = mifare_application_find(mad, aid);
MifareClassicSectorNumber *s = sectors; MifareClassicSectorNumber *s = sectors;
if (!sectors) { if (!sectors) {
@ -273,29 +273,29 @@ mifare_application_write (FreefareTag tag, Mad mad, const MadAid aid, const void
} }
while (*s && nbytes && (res >= 0)) { while (*s && nbytes && (res >= 0)) {
MifareClassicBlockNumber first_block = mifare_classic_sector_first_block (*s); MifareClassicBlockNumber first_block = mifare_classic_sector_first_block(*s);
MifareClassicBlockNumber last_block = mifare_classic_sector_last_block (*s); MifareClassicBlockNumber last_block = mifare_classic_sector_last_block(*s);
MifareClassicBlockNumber b = first_block; MifareClassicBlockNumber b = first_block;
MifareClassicBlock block; MifareClassicBlock block;
if (mifare_classic_authenticate (tag, first_block, key, key_type) < 0) { if (mifare_classic_authenticate(tag, first_block, key, key_type) < 0) {
res = -1; res = -1;
break; break;
} }
while ((b < last_block) && nbytes) { while ((b < last_block) && nbytes) {
size_t n = MIN (nbytes, 16); size_t n = MIN(nbytes, 16);
// Avoid overwriting existing data with uninitialized memory. // Avoid overwriting existing data with uninitialized memory.
if (n < 16) { if (n < 16) {
if (mifare_classic_read (tag, b, &block) < 0) { if (mifare_classic_read(tag, b, &block) < 0) {
res = -1; res = -1;
break; break;
} }
} }
memcpy (&block, (uint8_t *)buf + res, n); memcpy(&block, (uint8_t *)buf + res, n);
if (mifare_classic_write (tag, b, block) < 0) { if (mifare_classic_write(tag, b, block) < 0) {
res = -1; res = -1;
break; break;
} }
@ -309,7 +309,7 @@ mifare_application_write (FreefareTag tag, Mad mad, const MadAid aid, const void
s++; s++;
} }
free (sectors); free(sectors);
return res; return res;
} }

View file

@ -87,19 +87,19 @@
#define CLASSIC_TRANSCEIVE_EX(tag, msg, res, disconnect) \ #define CLASSIC_TRANSCEIVE_EX(tag, msg, res, disconnect) \
do { \ do { \
errno = 0; \ errno = 0; \
DEBUG_XFER (msg, __##msg##_n, "===> "); \ DEBUG_XFER (msg, __##msg##_n, "===> "); \
int _res; \ int _res; \
if ((_res = nfc_initiator_transceive_bytes (tag->device, msg, __##msg##_n, res, __##res##_size, 0)) < 0) { \ if ((_res = nfc_initiator_transceive_bytes (tag->device, msg, __##msg##_n, res, __##res##_size, 0)) < 0) { \
if (disconnect) { \ if (disconnect) { \
tag->active = false; \ tag->active = false; \
} \ } \
if (_res == NFC_EMFCAUTHFAIL) \ if (_res == NFC_EMFCAUTHFAIL) \
return errno = EACCES, -1; \ return errno = EACCES, -1; \
return errno = EIO, -1; \ return errno = EIO, -1; \
} \ } \
__##res##_n = _res; \ __##res##_n = _res; \
DEBUG_XFER (res, __##res##_n, "<=== "); \ DEBUG_XFER (res, __##res##_n, "<=== "); \
} while (0) } while (0)
@ -187,8 +187,8 @@ uint16_t mifare_trailer_access_permissions[] = {
* Private functions * Private functions
*/ */
int get_block_access_bits_shift (MifareClassicBlockNumber block, MifareClassicBlockNumber trailer); int get_block_access_bits_shift(MifareClassicBlockNumber block, MifareClassicBlockNumber trailer);
int get_block_access_bits (FreefareTag tag, const MifareClassicBlockNumber block, MifareClassicAccessBits *block_access_bits); int get_block_access_bits(FreefareTag tag, const MifareClassicBlockNumber block, MifareClassicAccessBits *block_access_bits);
/* /*
@ -196,37 +196,37 @@ int get_block_access_bits (FreefareTag tag, const MifareClassicBlockNumber blo
*/ */
bool bool
mifare_mini_taste (nfc_device *device, nfc_target target) mifare_mini_taste(nfc_device *device, nfc_target target)
{ {
(void) device; (void) device;
return target.nm.nmt == NMT_ISO14443A && return target.nm.nmt == NMT_ISO14443A &&
( (
target.nti.nai.btSak == 0x09 target.nti.nai.btSak == 0x09
); );
} }
bool bool
mifare_classic1k_taste (nfc_device *device, nfc_target target) mifare_classic1k_taste(nfc_device *device, nfc_target target)
{ {
(void) device; (void) device;
return target.nm.nmt == NMT_ISO14443A && return target.nm.nmt == NMT_ISO14443A &&
( (
target.nti.nai.btSak == 0x08 || target.nti.nai.btSak == 0x08 ||
target.nti.nai.btSak == 0x28 || target.nti.nai.btSak == 0x28 ||
target.nti.nai.btSak == 0x68 || target.nti.nai.btSak == 0x68 ||
target.nti.nai.btSak == 0x88 target.nti.nai.btSak == 0x88
); );
} }
bool bool
mifare_classic4k_taste (nfc_device *device, nfc_target target) mifare_classic4k_taste(nfc_device *device, nfc_target target)
{ {
(void) device; (void) device;
return target.nm.nmt == NMT_ISO14443A && return target.nm.nmt == NMT_ISO14443A &&
( (
target.nti.nai.btSak == 0x18 || target.nti.nai.btSak == 0x18 ||
target.nti.nai.btSak == 0x38 target.nti.nai.btSak == 0x38
); );
} }
/* /*
@ -234,11 +234,11 @@ mifare_classic4k_taste (nfc_device *device, nfc_target target)
*/ */
static FreefareTag static FreefareTag
_mifare_classic_tag_new (nfc_device *device, nfc_target target, int tag_type) _mifare_classic_tag_new(nfc_device *device, nfc_target target, int tag_type)
{ {
FreefareTag tag; FreefareTag tag;
if ((tag = malloc (sizeof (struct mifare_classic_tag)))) { if ((tag = malloc(sizeof(struct mifare_classic_tag)))) {
tag->type = tag_type; tag->type = tag_type;
tag->free_tag = mifare_classic_tag_free; tag->free_tag = mifare_classic_tag_free;
tag->device = device; tag->device = device;
@ -251,30 +251,30 @@ _mifare_classic_tag_new (nfc_device *device, nfc_target target, int tag_type)
FreefareTag FreefareTag
mifare_mini_tag_new (nfc_device *device, nfc_target target) mifare_mini_tag_new(nfc_device *device, nfc_target target)
{ {
return _mifare_classic_tag_new (device, target, MIFARE_MINI); return _mifare_classic_tag_new(device, target, MIFARE_MINI);
} }
FreefareTag FreefareTag
mifare_classic1k_tag_new (nfc_device *device, nfc_target target) mifare_classic1k_tag_new(nfc_device *device, nfc_target target)
{ {
return _mifare_classic_tag_new (device, target, MIFARE_CLASSIC_1K); return _mifare_classic_tag_new(device, target, MIFARE_CLASSIC_1K);
} }
FreefareTag FreefareTag
mifare_classic4k_tag_new (nfc_device *device, nfc_target target) mifare_classic4k_tag_new(nfc_device *device, nfc_target target)
{ {
return _mifare_classic_tag_new (device, target, MIFARE_CLASSIC_4K); return _mifare_classic_tag_new(device, target, MIFARE_CLASSIC_4K);
} }
/* /*
* Free the provided tag. * Free the provided tag.
*/ */
void void
mifare_classic_tag_free (FreefareTag tag) mifare_classic_tag_free(FreefareTag tag)
{ {
free (tag); free(tag);
} }
@ -290,16 +290,16 @@ mifare_classic_tag_free (FreefareTag tag)
* Establish connection to the provided tag. * Establish connection to the provided tag.
*/ */
int int
mifare_classic_connect (FreefareTag tag) mifare_classic_connect(FreefareTag tag)
{ {
ASSERT_INACTIVE (tag); ASSERT_INACTIVE(tag);
nfc_target pnti; nfc_target pnti;
nfc_modulation modulation = { nfc_modulation modulation = {
.nmt = NMT_ISO14443A, .nmt = NMT_ISO14443A,
.nbr = NBR_106 .nbr = NBR_106
}; };
if (nfc_initiator_select_passive_target (tag->device, modulation, tag->info.nti.nai.abtUid, tag->info.nti.nai.szUidLen, &pnti) >= 0) { if (nfc_initiator_select_passive_target(tag->device, modulation, tag->info.nti.nai.abtUid, tag->info.nti.nai.szUidLen, &pnti) >= 0) {
tag->active = 1; tag->active = 1;
} else { } else {
errno = EIO; errno = EIO;
@ -312,11 +312,11 @@ mifare_classic_connect (FreefareTag tag)
* Terminate connection with the provided tag. * Terminate connection with the provided tag.
*/ */
int int
mifare_classic_disconnect (FreefareTag tag) mifare_classic_disconnect(FreefareTag tag)
{ {
ASSERT_ACTIVE (tag); ASSERT_ACTIVE(tag);
if (nfc_initiator_deselect_target (tag->device) >= 0) { if (nfc_initiator_deselect_target(tag->device) >= 0) {
tag->active = 0; tag->active = 0;
} else { } else {
errno = EIO; errno = EIO;
@ -337,57 +337,57 @@ mifare_classic_disconnect (FreefareTag tag)
* Send an authentification command to the provided MIFARE target. * Send an authentification command to the provided MIFARE target.
*/ */
int int
mifare_classic_authenticate (FreefareTag tag, const MifareClassicBlockNumber block, const MifareClassicKey key, const MifareClassicKeyType key_type) mifare_classic_authenticate(FreefareTag tag, const MifareClassicBlockNumber block, const MifareClassicKey key, const MifareClassicKeyType key_type)
{ {
ASSERT_ACTIVE (tag); ASSERT_ACTIVE(tag);
BUFFER_INIT (cmd, 12); BUFFER_INIT(cmd, 12);
BUFFER_INIT (res, 1); BUFFER_INIT(res, 1);
if (key_type == MFC_KEY_A) if (key_type == MFC_KEY_A)
BUFFER_APPEND (cmd, MC_AUTH_A); BUFFER_APPEND(cmd, MC_AUTH_A);
else else
BUFFER_APPEND (cmd, MC_AUTH_B); BUFFER_APPEND(cmd, MC_AUTH_B);
BUFFER_APPEND(cmd, block); BUFFER_APPEND(cmd, block);
BUFFER_APPEND_BYTES (cmd, key, 6); BUFFER_APPEND_BYTES(cmd, key, 6);
// To support both 4-byte & 7-byte UID cards: // To support both 4-byte & 7-byte UID cards:
BUFFER_APPEND_BYTES (cmd, tag->info.nti.nai.abtUid + tag->info.nti.nai.szUidLen - 4, 4); BUFFER_APPEND_BYTES(cmd, tag->info.nti.nai.abtUid + tag->info.nti.nai.szUidLen - 4, 4);
CLASSIC_TRANSCEIVE_EX (tag, cmd, res, 1); CLASSIC_TRANSCEIVE_EX(tag, cmd, res, 1);
MIFARE_CLASSIC(tag)->cached_access_bits.sector_trailer_block_number = -1; MIFARE_CLASSIC(tag)->cached_access_bits.sector_trailer_block_number = -1;
MIFARE_CLASSIC(tag)->cached_access_bits.sector_access_bits = 0x00; MIFARE_CLASSIC(tag)->cached_access_bits.sector_access_bits = 0x00;
MIFARE_CLASSIC(tag)->last_authentication_key_type = key_type; MIFARE_CLASSIC(tag)->last_authentication_key_type = key_type;
return (BUFFER_SIZE (res) == 0) ? 0 : res[0]; return (BUFFER_SIZE(res) == 0) ? 0 : res[0];
} }
/* /*
* Read data from the provided MIFARE target. * Read data from the provided MIFARE target.
*/ */
int int
mifare_classic_read (FreefareTag tag, const MifareClassicBlockNumber block, MifareClassicBlock *data) mifare_classic_read(FreefareTag tag, const MifareClassicBlockNumber block, MifareClassicBlock *data)
{ {
ASSERT_ACTIVE (tag); ASSERT_ACTIVE(tag);
BUFFER_INIT (cmd, 2); BUFFER_INIT(cmd, 2);
BUFFER_ALIAS (res, data, sizeof(MifareClassicBlock)); BUFFER_ALIAS(res, data, sizeof(MifareClassicBlock));
BUFFER_APPEND (cmd, MC_READ); BUFFER_APPEND(cmd, MC_READ);
BUFFER_APPEND (cmd, block); BUFFER_APPEND(cmd, block);
CLASSIC_TRANSCEIVE (tag, cmd, res); CLASSIC_TRANSCEIVE(tag, cmd, res);
return 0; return 0;
} }
int int
mifare_classic_init_value (FreefareTag tag, const MifareClassicBlockNumber block, const int32_t value, const MifareClassicBlockNumber adr) mifare_classic_init_value(FreefareTag tag, const MifareClassicBlockNumber block, const int32_t value, const MifareClassicBlockNumber adr)
{ {
union mifare_classic_block b; union mifare_classic_block b;
uint32_t le_value = htole32 ((uint32_t)value); uint32_t le_value = htole32((uint32_t)value);
b.value.value = le_value; b.value.value = le_value;
b.value.value_ = ~le_value; b.value.value_ = ~le_value;
@ -398,18 +398,18 @@ mifare_classic_init_value (FreefareTag tag, const MifareClassicBlockNumber block
b.value.address__ = adr; b.value.address__ = adr;
b.value.address___ = ~adr; b.value.address___ = ~adr;
if (mifare_classic_write (tag, block, b.data) < 0) if (mifare_classic_write(tag, block, b.data) < 0)
return -1; return -1;
return 0; return 0;
} }
int int
mifare_classic_read_value (FreefareTag tag, const MifareClassicBlockNumber block, int32_t *value, MifareClassicBlockNumber *adr) mifare_classic_read_value(FreefareTag tag, const MifareClassicBlockNumber block, int32_t *value, MifareClassicBlockNumber *adr)
{ {
union mifare_classic_block b; union mifare_classic_block b;
if (mifare_classic_read (tag, block, &b.data) < 0) if (mifare_classic_read(tag, block, &b.data) < 0)
return -1; return -1;
if ((b.value.value ^ (uint32_t)~b.value.value_) || (b.value.value != b.value.value__)) { if ((b.value.value ^ (uint32_t)~b.value.value_) || (b.value.value != b.value.value__)) {
@ -423,7 +423,7 @@ mifare_classic_read_value (FreefareTag tag, const MifareClassicBlockNumber block
} }
if (value) if (value)
*value = le32toh (b.value.value); *value = le32toh(b.value.value);
if (adr) if (adr)
*adr = b.value.address; *adr = b.value.address;
@ -435,20 +435,20 @@ mifare_classic_read_value (FreefareTag tag, const MifareClassicBlockNumber block
* Write data to the provided MIFARE target. * Write data to the provided MIFARE target.
*/ */
int int
mifare_classic_write (FreefareTag tag, const MifareClassicBlockNumber block, const MifareClassicBlock data) mifare_classic_write(FreefareTag tag, const MifareClassicBlockNumber block, const MifareClassicBlock data)
{ {
ASSERT_ACTIVE (tag); ASSERT_ACTIVE(tag);
BUFFER_INIT (cmd, 2 + sizeof (MifareClassicBlock)); BUFFER_INIT(cmd, 2 + sizeof(MifareClassicBlock));
BUFFER_INIT (res, 1); BUFFER_INIT(res, 1);
BUFFER_APPEND (cmd, MC_WRITE); BUFFER_APPEND(cmd, MC_WRITE);
BUFFER_APPEND (cmd, block); BUFFER_APPEND(cmd, block);
BUFFER_APPEND_BYTES (cmd, data, sizeof (MifareClassicBlock)); BUFFER_APPEND_BYTES(cmd, data, sizeof(MifareClassicBlock));
CLASSIC_TRANSCEIVE (tag, cmd, res); CLASSIC_TRANSCEIVE(tag, cmd, res);
return (BUFFER_SIZE (res) == 0) ? 0 : res[0]; return (BUFFER_SIZE(res) == 0) ? 0 : res[0];
} }
/* /*
@ -456,20 +456,20 @@ mifare_classic_write (FreefareTag tag, const MifareClassicBlockNumber block, con
* data register. * data register.
*/ */
int int
mifare_classic_increment (FreefareTag tag, const MifareClassicBlockNumber block, const uint32_t amount) mifare_classic_increment(FreefareTag tag, const MifareClassicBlockNumber block, const uint32_t amount)
{ {
ASSERT_ACTIVE (tag); ASSERT_ACTIVE(tag);
BUFFER_INIT (cmd, 6); BUFFER_INIT(cmd, 6);
BUFFER_INIT (res, 1); BUFFER_INIT(res, 1);
BUFFER_APPEND (cmd, MC_INCREMENT); BUFFER_APPEND(cmd, MC_INCREMENT);
BUFFER_APPEND (cmd, block); BUFFER_APPEND(cmd, block);
BUFFER_APPEND_LE (cmd, amount, 4, sizeof (amount)); BUFFER_APPEND_LE(cmd, amount, 4, sizeof(amount));
CLASSIC_TRANSCEIVE (tag, cmd, res); CLASSIC_TRANSCEIVE(tag, cmd, res);
return (BUFFER_SIZE (res) == 0) ? 0 : res[0]; return (BUFFER_SIZE(res) == 0) ? 0 : res[0];
} }
/* /*
@ -477,65 +477,65 @@ mifare_classic_increment (FreefareTag tag, const MifareClassicBlockNumber block,
* data register. * data register.
*/ */
int int
mifare_classic_decrement (FreefareTag tag, const MifareClassicBlockNumber block, const uint32_t amount) mifare_classic_decrement(FreefareTag tag, const MifareClassicBlockNumber block, const uint32_t amount)
{ {
ASSERT_ACTIVE (tag); ASSERT_ACTIVE(tag);
BUFFER_INIT (cmd, 6); BUFFER_INIT(cmd, 6);
BUFFER_INIT (res, 1); BUFFER_INIT(res, 1);
BUFFER_APPEND (cmd, MC_DECREMENT); BUFFER_APPEND(cmd, MC_DECREMENT);
BUFFER_APPEND (cmd, block); BUFFER_APPEND(cmd, block);
BUFFER_APPEND_LE (cmd, amount, 4, sizeof (amount)); BUFFER_APPEND_LE(cmd, amount, 4, sizeof(amount));
CLASSIC_TRANSCEIVE (tag, cmd, res); CLASSIC_TRANSCEIVE(tag, cmd, res);
return (BUFFER_SIZE (res) == 0) ? 0 : res[0]; return (BUFFER_SIZE(res) == 0) ? 0 : res[0];
} }
/* /*
* Store the provided block to the internal data register. * Store the provided block to the internal data register.
*/ */
int int
mifare_classic_restore (FreefareTag tag, const MifareClassicBlockNumber block) mifare_classic_restore(FreefareTag tag, const MifareClassicBlockNumber block)
{ {
ASSERT_ACTIVE (tag); ASSERT_ACTIVE(tag);
/* /*
* Same length as the increment and decrement commands but only the first * Same length as the increment and decrement commands but only the first
* two bytes are actually used. The 4 bytes after the block number are * two bytes are actually used. The 4 bytes after the block number are
* meaningless but required (NULL-filled). * meaningless but required (NULL-filled).
*/ */
BUFFER_INIT (cmd, 6); BUFFER_INIT(cmd, 6);
BUFFER_INIT (res, 1); BUFFER_INIT(res, 1);
BUFFER_APPEND (cmd, MC_RESTORE); BUFFER_APPEND(cmd, MC_RESTORE);
BUFFER_APPEND (cmd, block); BUFFER_APPEND(cmd, block);
BUFFER_APPEND (cmd, 0x00); BUFFER_APPEND(cmd, 0x00);
BUFFER_APPEND (cmd, 0x00); BUFFER_APPEND(cmd, 0x00);
BUFFER_APPEND (cmd, 0x00); BUFFER_APPEND(cmd, 0x00);
BUFFER_APPEND (cmd, 0x00); BUFFER_APPEND(cmd, 0x00);
CLASSIC_TRANSCEIVE (tag, cmd, res); CLASSIC_TRANSCEIVE(tag, cmd, res);
return (BUFFER_SIZE (res) == 0) ? 0 : res[0]; return (BUFFER_SIZE(res) == 0) ? 0 : res[0];
} }
/* /*
* Store the internal data register to the provided block. * Store the internal data register to the provided block.
*/ */
int int
mifare_classic_transfer (FreefareTag tag, const MifareClassicBlockNumber block) mifare_classic_transfer(FreefareTag tag, const MifareClassicBlockNumber block)
{ {
ASSERT_ACTIVE (tag); ASSERT_ACTIVE(tag);
BUFFER_INIT (cmd, 2); BUFFER_INIT(cmd, 2);
BUFFER_INIT (res, 1); BUFFER_INIT(res, 1);
BUFFER_APPEND (cmd, MC_TRANSFER); BUFFER_APPEND(cmd, MC_TRANSFER);
BUFFER_APPEND (cmd, block); BUFFER_APPEND(cmd, block);
CLASSIC_TRANSCEIVE (tag, cmd, res); CLASSIC_TRANSCEIVE(tag, cmd, res);
/* /*
* Depending on the device we are using, on success, the TRANSFER command * Depending on the device we are using, on success, the TRANSFER command
@ -543,7 +543,7 @@ mifare_classic_transfer (FreefareTag tag, const MifareClassicBlockNumber block)
* meaning that the action was performed correctly (e.g. Snapper Feeder, * meaning that the action was performed correctly (e.g. Snapper Feeder,
* SCL 3711). * SCL 3711).
*/ */
if (!BUFFER_SIZE (res) || ((BUFFER_SIZE (res) == 1) && (res[0] = MC_OK))) if (!BUFFER_SIZE(res) || ((BUFFER_SIZE(res) == 1) && (res[0] = MC_OK)))
return 0; return 0;
else else
return res[0]; return res[0];
@ -576,7 +576,7 @@ mifare_classic_transfer (FreefareTag tag, const MifareClassicBlockNumber block)
* *
*/ */
int int
get_block_access_bits_shift (MifareClassicBlockNumber block, MifareClassicBlockNumber trailer) get_block_access_bits_shift(MifareClassicBlockNumber block, MifareClassicBlockNumber trailer)
{ {
if (block == trailer) { if (block == trailer) {
return 3; return 3;
@ -593,7 +593,7 @@ get_block_access_bits_shift (MifareClassicBlockNumber block, MifareClassicBlockN
* block. * block.
*/ */
int int
get_block_access_bits (FreefareTag tag, const MifareClassicBlockNumber block, MifareClassicAccessBits *block_access_bits) get_block_access_bits(FreefareTag tag, const MifareClassicBlockNumber block, MifareClassicAccessBits *block_access_bits)
{ {
/* /*
* The first block which holds the manufacturer block seems to have * The first block which holds the manufacturer block seems to have
@ -606,7 +606,7 @@ get_block_access_bits (FreefareTag tag, const MifareClassicBlockNumber block, Mi
uint16_t sector_access_bits, sector_access_bits_; uint16_t sector_access_bits, sector_access_bits_;
MifareClassicBlockNumber trailer = mifare_classic_sector_last_block (mifare_classic_block_sector (block)); MifareClassicBlockNumber trailer = mifare_classic_sector_last_block(mifare_classic_block_sector(block));
/* /*
* The trailer block contains access bits for the whole sector in a 3 bytes * The trailer block contains access bits for the whole sector in a 3 bytes
@ -623,7 +623,7 @@ get_block_access_bits (FreefareTag tag, const MifareClassicBlockNumber block, Mi
} else { } else {
MifareClassicBlock trailer_data; MifareClassicBlock trailer_data;
if (mifare_classic_read (tag, trailer, &trailer_data) < 0) { if (mifare_classic_read(tag, trailer, &trailer_data) < 0) {
return -1; return -1;
} }
@ -653,7 +653,7 @@ get_block_access_bits (FreefareTag tag, const MifareClassicBlockNumber block, Mi
* |,------C2 * |,------C2
* ||,---- C1 * ||,---- C1
* ||| */ * ||| */
uint16_t block_access_bits_mask = 0x0111 << get_block_access_bits_shift (block, trailer); uint16_t block_access_bits_mask = 0x0111 << get_block_access_bits_shift(block, trailer);
/* ||| /* |||
* ||`---------------. * ||`---------------.
* |`---------------.| * |`---------------.|
@ -674,10 +674,10 @@ get_block_access_bits (FreefareTag tag, const MifareClassicBlockNumber block, Mi
* Get information about the trailer block. * Get information about the trailer block.
*/ */
int int
mifare_classic_get_trailer_block_permission (FreefareTag tag, const MifareClassicBlockNumber block, const uint16_t permission, const MifareClassicKeyType key_type) mifare_classic_get_trailer_block_permission(FreefareTag tag, const MifareClassicBlockNumber block, const uint16_t permission, const MifareClassicKeyType key_type)
{ {
MifareClassicAccessBits access_bits; MifareClassicAccessBits access_bits;
if (get_block_access_bits (tag, block, &access_bits) < 0) { if (get_block_access_bits(tag, block, &access_bits) < 0) {
return -1; return -1;
} }
@ -693,15 +693,15 @@ mifare_classic_get_trailer_block_permission (FreefareTag tag, const MifareClassi
* Get information about data blocks. * Get information about data blocks.
*/ */
int int
mifare_classic_get_data_block_permission (FreefareTag tag, const MifareClassicBlockNumber block, const unsigned char permission, const MifareClassicKeyType key_type) mifare_classic_get_data_block_permission(FreefareTag tag, const MifareClassicBlockNumber block, const unsigned char permission, const MifareClassicKeyType key_type)
{ {
MifareClassicAccessBits access_bits; MifareClassicAccessBits access_bits;
if (get_block_access_bits (tag, block, &access_bits) < 0) { if (get_block_access_bits(tag, block, &access_bits) < 0) {
return -1; return -1;
} }
if (MIFARE_CLASSIC(tag)->cached_access_bits.sector_trailer_block_number != block) { if (MIFARE_CLASSIC(tag)->cached_access_bits.sector_trailer_block_number != block) {
return ((mifare_data_access_permissions[access_bits] & (permission << ( (key_type == MFC_KEY_A) ? 4 : 0 ))) ? 1 : 0); return ((mifare_data_access_permissions[access_bits] & (permission << ((key_type == MFC_KEY_A) ? 4 : 0))) ? 1 : 0);
} else { } else {
errno = EINVAL; errno = EINVAL;
return -1; return -1;
@ -717,10 +717,10 @@ mifare_classic_get_data_block_permission (FreefareTag tag, const MifareClassicBl
* Reset a MIFARE target sector to factory default. * Reset a MIFARE target sector to factory default.
*/ */
int int
mifare_classic_format_sector (FreefareTag tag, const MifareClassicSectorNumber sector) mifare_classic_format_sector(FreefareTag tag, const MifareClassicSectorNumber sector)
{ {
MifareClassicBlockNumber first_sector_block = mifare_classic_sector_first_block (sector); MifareClassicBlockNumber first_sector_block = mifare_classic_sector_first_block(sector);
MifareClassicBlockNumber last_sector_block = mifare_classic_sector_last_block (sector); MifareClassicBlockNumber last_sector_block = mifare_classic_sector_last_block(sector);
/* /*
* Check that the current key allow us to rewrite data and trailer blocks. * Check that the current key allow us to rewrite data and trailer blocks.
@ -743,7 +743,7 @@ mifare_classic_format_sector (FreefareTag tag, const MifareClassicSectorNumber s
} }
MifareClassicBlock empty_data_block; MifareClassicBlock empty_data_block;
memset (empty_data_block, 0, sizeof (empty_data_block)); memset(empty_data_block, 0, sizeof(empty_data_block));
MifareClassicBlock default_trailer_block = { MifareClassicBlock default_trailer_block = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* Key A */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* Key A */
@ -753,11 +753,11 @@ mifare_classic_format_sector (FreefareTag tag, const MifareClassicSectorNumber s
}; };
for (int n = first_sector_block; n < last_sector_block; n++) { for (int n = first_sector_block; n < last_sector_block; n++) {
if (mifare_classic_write (tag, n, empty_data_block) < 0) { if (mifare_classic_write(tag, n, empty_data_block) < 0) {
return errno = EIO, -1; return errno = EIO, -1;
} }
} }
if (mifare_classic_write (tag, last_sector_block, default_trailer_block) < 0) { if (mifare_classic_write(tag, last_sector_block, default_trailer_block) < 0) {
return errno = EIO, -1; return errno = EIO, -1;
} }
@ -765,14 +765,14 @@ mifare_classic_format_sector (FreefareTag tag, const MifareClassicSectorNumber s
} }
MifareClassicSectorNumber MifareClassicSectorNumber
mifare_classic_block_sector (MifareClassicBlockNumber block) mifare_classic_block_sector(MifareClassicBlockNumber block)
{ {
MifareClassicSectorNumber res; MifareClassicSectorNumber res;
if (block < 32 * 4) if (block < 32 * 4)
res = block / 4; res = block / 4;
else else
res = 32 + ( (block - (32 * 4)) / 16 ); res = 32 + ((block - (32 * 4)) / 16);
return res; return res;
} }
@ -781,7 +781,7 @@ mifare_classic_block_sector (MifareClassicBlockNumber block)
* Get the sector's first block number * Get the sector's first block number
*/ */
MifareClassicBlockNumber MifareClassicBlockNumber
mifare_classic_sector_first_block (MifareClassicSectorNumber sector) mifare_classic_sector_first_block(MifareClassicSectorNumber sector)
{ {
int res; int res;
if (sector < 32) { if (sector < 32) {
@ -794,7 +794,7 @@ mifare_classic_sector_first_block (MifareClassicSectorNumber sector)
} }
size_t size_t
mifare_classic_sector_block_count (MifareClassicSectorNumber sector) mifare_classic_sector_block_count(MifareClassicSectorNumber sector)
{ {
return (sector < 32) ? 4 : 16 ; return (sector < 32) ? 4 : 16 ;
} }
@ -803,17 +803,17 @@ mifare_classic_sector_block_count (MifareClassicSectorNumber sector)
* Get the sector's last block number (aka trailer block) * Get the sector's last block number (aka trailer block)
*/ */
MifareClassicBlockNumber MifareClassicBlockNumber
mifare_classic_sector_last_block (MifareClassicSectorNumber sector) mifare_classic_sector_last_block(MifareClassicSectorNumber sector)
{ {
return mifare_classic_sector_first_block (sector) + return mifare_classic_sector_first_block(sector) +
mifare_classic_sector_block_count (sector) - 1; mifare_classic_sector_block_count(sector) - 1;
} }
/* /*
* Generates a MIFARE trailer block. * Generates a MIFARE trailer block.
*/ */
void void
mifare_classic_trailer_block (MifareClassicBlock *block, const MifareClassicKey key_a, uint8_t ab_0, uint8_t ab_1, uint8_t ab_2, uint8_t ab_tb, const uint8_t gpb, const MifareClassicKey key_b) mifare_classic_trailer_block(MifareClassicBlock *block, const MifareClassicKey key_a, uint8_t ab_0, uint8_t ab_1, uint8_t ab_2, uint8_t ab_tb, const uint8_t gpb, const MifareClassicKey key_b)
{ {
union mifare_classic_block *b = (union mifare_classic_block *)block; // *((union mifare_classic_block *)(&block)); union mifare_classic_block *b = (union mifare_classic_block *)block; // *((union mifare_classic_block *)(&block));
@ -822,9 +822,9 @@ mifare_classic_trailer_block (MifareClassicBlock *block, const MifareClassicKey
ab_2 = DB_AB(ab_2); ab_2 = DB_AB(ab_2);
ab_tb = TB_AB(ab_tb); ab_tb = TB_AB(ab_tb);
memcpy (b->trailer.key_a, key_a, sizeof (MifareClassicKey)); memcpy(b->trailer.key_a, key_a, sizeof(MifareClassicKey));
uint32_t access_bits = ((((( ab_0 & 0x4) >> 2) << 8) | (((ab_0 & 0x2) >> 1) << 4) | (ab_0 & 0x1)) | uint32_t access_bits = (((((ab_0 & 0x4) >> 2) << 8) | (((ab_0 & 0x2) >> 1) << 4) | (ab_0 & 0x1)) |
(((((ab_1 & 0x4) >> 2) << 8) | (((ab_1 & 0x2) >> 1) << 4) | (ab_1 & 0x1)) << 1) | (((((ab_1 & 0x4) >> 2) << 8) | (((ab_1 & 0x2) >> 1) << 4) | (ab_1 & 0x1)) << 1) |
(((((ab_2 & 0x4) >> 2) << 8) | (((ab_2 & 0x2) >> 1) << 4) | (ab_2 & 0x1)) << 2) | (((((ab_2 & 0x4) >> 2) << 8) | (((ab_2 & 0x2) >> 1) << 4) | (ab_2 & 0x1)) << 2) |
(((((ab_tb & 0x4) >> 2) << 8) | (((ab_tb & 0x2) >> 1) << 4) | (ab_tb & 0x1)) << 3)); (((((ab_tb & 0x4) >> 2) << 8) | (((ab_tb & 0x2) >> 1) << 4) | (ab_tb & 0x1)) << 3));
@ -832,8 +832,8 @@ mifare_classic_trailer_block (MifareClassicBlock *block, const MifareClassicKey
uint32_t access_bits_ = ((~access_bits) & 0x00000fff); uint32_t access_bits_ = ((~access_bits) & 0x00000fff);
uint32_t ab = htole32(((access_bits << 12) | access_bits_)); uint32_t ab = htole32(((access_bits << 12) | access_bits_));
memcpy (&(b->trailer.access_bits), &ab, 3); memcpy(&(b->trailer.access_bits), &ab, 3);
b->trailer.gpb = gpb; b->trailer.gpb = gpb;
memcpy (b->trailer.key_b, key_b, sizeof (MifareClassicKey)); memcpy(b->trailer.key_b, key_b, sizeof(MifareClassicKey));
} }

File diff suppressed because it is too large Load diff

View file

@ -57,16 +57,16 @@
// Theorically, it should be an uint24_t ... // Theorically, it should be an uint24_t ...
MifareDESFireAID MifareDESFireAID
mifare_desfire_aid_new (uint32_t aid) mifare_desfire_aid_new(uint32_t aid)
{ {
if (aid > 0x00ffffff) if (aid > 0x00ffffff)
return errno = EINVAL, NULL; return errno = EINVAL, NULL;
MifareDESFireAID res; MifareDESFireAID res;
uint32_t aid_le = htole32 (aid); uint32_t aid_le = htole32(aid);
if ((res = malloc (sizeof (*res)))) { if ((res = malloc(sizeof(*res)))) {
memcpy(res->data, ((uint8_t*)&aid_le), 3); memcpy(res->data, ((uint8_t *)&aid_le), 3);
} }
return res; return res;
@ -74,16 +74,16 @@ mifare_desfire_aid_new (uint32_t aid)
// This function ease the MifareDESFireAID creation using a Mifare Classic AID (see MIFARE Application Directory document - section 3.10 MAD and MIFARE DESFire) // This function ease the MifareDESFireAID creation using a Mifare Classic AID (see MIFARE Application Directory document - section 3.10 MAD and MIFARE DESFire)
MifareDESFireAID MifareDESFireAID
mifare_desfire_aid_new_with_mad_aid (MadAid mad_aid, uint8_t n) mifare_desfire_aid_new_with_mad_aid(MadAid mad_aid, uint8_t n)
{ {
if (n > 0x0f) if (n > 0x0f)
return errno = EINVAL, NULL; return errno = EINVAL, NULL;
return mifare_desfire_aid_new (0xf00000 | (mad_aid.function_cluster_code << 12) | (mad_aid.application_code << 4) | n); return mifare_desfire_aid_new(0xf00000 | (mad_aid.function_cluster_code << 12) | (mad_aid.application_code << 4) | n);
} }
uint32_t uint32_t
mifare_desfire_aid_get_aid (MifareDESFireAID aid) mifare_desfire_aid_get_aid(MifareDESFireAID aid)
{ {
return aid->data[0] | (aid->data[1] << 8) | (aid->data[2] << 16); return aid->data[0] | (aid->data[1] << 8) | (aid->data[2] << 16);
} }

View file

@ -71,12 +71,12 @@
#define MAC_LENGTH 4 #define MAC_LENGTH 4
#define CMAC_LENGTH 8 #define CMAC_LENGTH 8
static void xor (const uint8_t *ivect, uint8_t *data, const size_t len); static void xor(const uint8_t *ivect, uint8_t *data, const size_t len);
static void desfire_crc32_byte (uint32_t *crc, const uint8_t value); static void desfire_crc32_byte(uint32_t *crc, const uint8_t value);
static size_t key_macing_length (MifareDESFireKey key); static size_t key_macing_length(MifareDESFireKey key);
static void static void
xor (const uint8_t *ivect, uint8_t *data, const size_t len) xor(const uint8_t *ivect, uint8_t *data, const size_t len)
{ {
for (size_t i = 0; i < len; i++) { for (size_t i = 0; i < len; i++) {
data[i] ^= ivect[i]; data[i] ^= ivect[i];
@ -84,87 +84,87 @@ xor (const uint8_t *ivect, uint8_t *data, const size_t len)
} }
void void
rol (uint8_t *data, const size_t len) rol(uint8_t *data, const size_t len)
{ {
uint8_t first = data[0]; uint8_t first = data[0];
for (size_t i = 0; i < len-1; i++) { for (size_t i = 0; i < len - 1; i++) {
data[i] = data[i+1]; data[i] = data[i + 1];
} }
data[len-1] = first; data[len - 1] = first;
} }
void void
lsl (uint8_t *data, size_t len) lsl(uint8_t *data, size_t len)
{ {
for (size_t n = 0; n < len - 1; n++) { for (size_t n = 0; n < len - 1; n++) {
data[n] = (data[n] << 1) | (data[n+1] >> 7); data[n] = (data[n] << 1) | (data[n + 1] >> 7);
} }
data[len - 1] <<= 1; data[len - 1] <<= 1;
} }
void void
cmac_generate_subkeys (MifareDESFireKey key) cmac_generate_subkeys(MifareDESFireKey key)
{ {
int kbs = key_block_size (key); int kbs = key_block_size(key);
const uint8_t R = (kbs == 8) ? 0x1B : 0x87; const uint8_t R = (kbs == 8) ? 0x1B : 0x87;
uint8_t l[kbs]; uint8_t l[kbs];
memset (l, 0, kbs); memset(l, 0, kbs);
uint8_t ivect[kbs]; uint8_t ivect[kbs];
memset (ivect, 0, kbs); memset(ivect, 0, kbs);
mifare_cypher_blocks_chained (NULL, key, ivect, l, kbs, MCD_RECEIVE, MCO_ENCYPHER); mifare_cypher_blocks_chained(NULL, key, ivect, l, kbs, MCD_RECEIVE, MCO_ENCYPHER);
bool xor = false; bool xor = false;
// Used to compute CMAC on complete blocks // Used to compute CMAC on complete blocks
memcpy (key->cmac_sk1, l, kbs); memcpy(key->cmac_sk1, l, kbs);
xor = l[0] & 0x80; xor = l[0] & 0x80;
lsl (key->cmac_sk1, kbs); lsl(key->cmac_sk1, kbs);
if (xor) if (xor)
key->cmac_sk1[kbs-1] ^= R; key->cmac_sk1[kbs - 1] ^= R;
// Used to compute CMAC on the last block if non-complete // Used to compute CMAC on the last block if non-complete
memcpy (key->cmac_sk2, key->cmac_sk1, kbs); memcpy(key->cmac_sk2, key->cmac_sk1, kbs);
xor = key->cmac_sk1[0] & 0x80; xor = key->cmac_sk1[0] & 0x80;
lsl (key->cmac_sk2, kbs); lsl(key->cmac_sk2, kbs);
if (xor) if (xor)
key->cmac_sk2[kbs-1] ^= R; key->cmac_sk2[kbs - 1] ^= R;
} }
void void
cmac (const MifareDESFireKey key, uint8_t *ivect, const uint8_t *data, size_t len, uint8_t *cmac) cmac(const MifareDESFireKey key, uint8_t *ivect, const uint8_t *data, size_t len, uint8_t *cmac)
{ {
int kbs = key_block_size (key); int kbs = key_block_size(key);
uint8_t *buffer = malloc (padded_data_length (len, kbs)); uint8_t *buffer = malloc(padded_data_length(len, kbs));
if (!buffer) if (!buffer)
abort(); abort();
memcpy (buffer, data, len); memcpy(buffer, data, len);
if ((!len) || (len % kbs)) { if ((!len) || (len % kbs)) {
buffer[len++] = 0x80; buffer[len++] = 0x80;
while (len % kbs) { while (len % kbs) {
buffer[len++] = 0x00; buffer[len++] = 0x00;
} }
xor (key->cmac_sk2, buffer + len - kbs, kbs); xor(key->cmac_sk2, buffer + len - kbs, kbs);
} else { } else {
xor (key->cmac_sk1, buffer + len - kbs, kbs); xor(key->cmac_sk1, buffer + len - kbs, kbs);
} }
mifare_cypher_blocks_chained (NULL, key, ivect, buffer, len, MCD_SEND, MCO_ENCYPHER); mifare_cypher_blocks_chained(NULL, key, ivect, buffer, len, MCD_SEND, MCO_ENCYPHER);
memcpy (cmac, ivect, kbs); memcpy(cmac, ivect, kbs);
free (buffer); free(buffer);
} }
#define CRC32_PRESET 0xFFFFFFFF #define CRC32_PRESET 0xFFFFFFFF
static void static void
desfire_crc32_byte (uint32_t *crc, const uint8_t value) desfire_crc32_byte(uint32_t *crc, const uint8_t value)
{ {
/* x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 1 */ /* x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 1 */
const uint32_t poly = 0xEDB88320; const uint32_t poly = 0xEDB88320;
@ -179,24 +179,24 @@ desfire_crc32_byte (uint32_t *crc, const uint8_t value)
} }
void void
desfire_crc32 (const uint8_t *data, const size_t len, uint8_t *crc) desfire_crc32(const uint8_t *data, const size_t len, uint8_t *crc)
{ {
uint32_t desfire_crc = CRC32_PRESET; uint32_t desfire_crc = CRC32_PRESET;
for (size_t i = 0; i < len; i++) { for (size_t i = 0; i < len; i++) {
desfire_crc32_byte (&desfire_crc, data[i]); desfire_crc32_byte(&desfire_crc, data[i]);
} }
*((uint32_t *)(crc)) = htole32 (desfire_crc); *((uint32_t *)(crc)) = htole32(desfire_crc);
} }
void void
desfire_crc32_append (uint8_t *data, const size_t len) desfire_crc32_append(uint8_t *data, const size_t len)
{ {
desfire_crc32 (data, len, data + len); desfire_crc32(data, len, data + len);
} }
size_t size_t
key_block_size (const MifareDESFireKey key) key_block_size(const MifareDESFireKey key)
{ {
size_t block_size; size_t block_size;
@ -218,7 +218,7 @@ key_block_size (const MifareDESFireKey key)
* Size of MACing produced with the key. * Size of MACing produced with the key.
*/ */
static size_t static size_t
key_macing_length (const MifareDESFireKey key) key_macing_length(const MifareDESFireKey key)
{ {
size_t mac_length; size_t mac_length;
@ -240,7 +240,7 @@ key_macing_length (const MifareDESFireKey key)
* Size required to store nbytes of data in a buffer of size n*block_size. * Size required to store nbytes of data in a buffer of size n*block_size.
*/ */
size_t size_t
padded_data_length (const size_t nbytes, const size_t block_size) padded_data_length(const size_t nbytes, const size_t block_size)
{ {
if ((!nbytes) || (nbytes % block_size)) if ((!nbytes) || (nbytes % block_size))
return ((nbytes / block_size) + 1) * block_size; return ((nbytes / block_size) + 1) * block_size;
@ -252,19 +252,19 @@ padded_data_length (const size_t nbytes, const size_t block_size)
* Buffer size required to MAC nbytes of data * Buffer size required to MAC nbytes of data
*/ */
size_t size_t
maced_data_length (const MifareDESFireKey key, const size_t nbytes) maced_data_length(const MifareDESFireKey key, const size_t nbytes)
{ {
return nbytes + key_macing_length (key); return nbytes + key_macing_length(key);
} }
/* /*
* Buffer size required to encipher nbytes of data and a two bytes CRC. * Buffer size required to encipher nbytes of data and a two bytes CRC.
*/ */
size_t size_t
enciphered_data_length (const FreefareTag tag, const size_t nbytes, int communication_settings) enciphered_data_length(const FreefareTag tag, const size_t nbytes, int communication_settings)
{ {
size_t crc_length = 0; size_t crc_length = 0;
if (!(communication_settings & NO_CRC)) { if (!(communication_settings & NO_CRC)) {
switch (MIFARE_DESFIRE (tag)->authentication_scheme) { switch (MIFARE_DESFIRE(tag)->authentication_scheme) {
case AS_LEGACY: case AS_LEGACY:
crc_length = 2; crc_length = 2;
break; break;
@ -274,9 +274,9 @@ enciphered_data_length (const FreefareTag tag, const size_t nbytes, int communic
} }
} }
size_t block_size = MIFARE_DESFIRE(tag)->session_key ? key_block_size (MIFARE_DESFIRE (tag)->session_key) : 1; size_t block_size = MIFARE_DESFIRE(tag)->session_key ? key_block_size(MIFARE_DESFIRE(tag)->session_key) : 1;
return padded_data_length (nbytes + crc_length, block_size); return padded_data_length(nbytes + crc_length, block_size);
} }
@ -284,33 +284,33 @@ enciphered_data_length (const FreefareTag tag, const size_t nbytes, int communic
* Ensure that tag's crypto buffer is large enough to store nbytes of data. * Ensure that tag's crypto buffer is large enough to store nbytes of data.
*/ */
void * void *
assert_crypto_buffer_size (FreefareTag tag, size_t nbytes) assert_crypto_buffer_size(FreefareTag tag, size_t nbytes)
{ {
void *res = MIFARE_DESFIRE (tag)->crypto_buffer; void *res = MIFARE_DESFIRE(tag)->crypto_buffer;
if (MIFARE_DESFIRE (tag)->crypto_buffer_size < nbytes) { if (MIFARE_DESFIRE(tag)->crypto_buffer_size < nbytes) {
if ((res = realloc (MIFARE_DESFIRE (tag)->crypto_buffer, nbytes))) { if ((res = realloc(MIFARE_DESFIRE(tag)->crypto_buffer, nbytes))) {
MIFARE_DESFIRE (tag)->crypto_buffer = res; MIFARE_DESFIRE(tag)->crypto_buffer = res;
MIFARE_DESFIRE (tag)->crypto_buffer_size = nbytes; MIFARE_DESFIRE(tag)->crypto_buffer_size = nbytes;
} }
} }
return res; return res;
} }
void * void *
mifare_cryto_preprocess_data (FreefareTag tag, void *data, size_t *nbytes, off_t offset, int communication_settings) mifare_cryto_preprocess_data(FreefareTag tag, void *data, size_t *nbytes, off_t offset, int communication_settings)
{ {
uint8_t *res = data; uint8_t *res = data;
uint8_t mac[4]; uint8_t mac[4];
size_t edl, mdl; size_t edl, mdl;
bool append_mac = true; bool append_mac = true;
MifareDESFireKey key = MIFARE_DESFIRE (tag)->session_key; MifareDESFireKey key = MIFARE_DESFIRE(tag)->session_key;
if (!key) if (!key)
return data; return data;
switch (communication_settings & MDCM_MASK) { switch (communication_settings & MDCM_MASK) {
case MDCM_PLAIN: case MDCM_PLAIN:
if (AS_LEGACY == MIFARE_DESFIRE (tag)->authentication_scheme) if (AS_LEGACY == MIFARE_DESFIRE(tag)->authentication_scheme)
break; break;
/* /*
@ -325,53 +325,53 @@ mifare_cryto_preprocess_data (FreefareTag tag, void *data, size_t *nbytes, off_t
append_mac = false; append_mac = false;
/* pass through */ /* pass through */
case MDCM_MACED: case MDCM_MACED:
switch (MIFARE_DESFIRE (tag)->authentication_scheme) { switch (MIFARE_DESFIRE(tag)->authentication_scheme) {
case AS_LEGACY: case AS_LEGACY:
if (!(communication_settings & MAC_COMMAND)) if (!(communication_settings & MAC_COMMAND))
break; break;
/* pass through */ /* pass through */
edl = padded_data_length (*nbytes - offset, key_block_size (MIFARE_DESFIRE (tag)->session_key)) + offset; edl = padded_data_length(*nbytes - offset, key_block_size(MIFARE_DESFIRE(tag)->session_key)) + offset;
if (!(res = assert_crypto_buffer_size (tag, edl))) if (!(res = assert_crypto_buffer_size(tag, edl)))
abort(); abort();
// Fill in the crypto buffer with data ... // Fill in the crypto buffer with data ...
memcpy (res, data, *nbytes); memcpy(res, data, *nbytes);
// ... and 0 padding // ... and 0 padding
memset (res + *nbytes, 0, edl - *nbytes); memset(res + *nbytes, 0, edl - *nbytes);
mifare_cypher_blocks_chained (tag, NULL, NULL, res + offset, edl - offset, MCD_SEND, MCO_ENCYPHER); mifare_cypher_blocks_chained(tag, NULL, NULL, res + offset, edl - offset, MCD_SEND, MCO_ENCYPHER);
memcpy (mac, res + edl - 8, 4); memcpy(mac, res + edl - 8, 4);
// Copy again provided data (was overwritten by mifare_cypher_blocks_chained) // Copy again provided data (was overwritten by mifare_cypher_blocks_chained)
memcpy (res, data, *nbytes); memcpy(res, data, *nbytes);
if (!(communication_settings & MAC_COMMAND)) if (!(communication_settings & MAC_COMMAND))
break; break;
// Append MAC // Append MAC
mdl = maced_data_length (MIFARE_DESFIRE (tag)->session_key, *nbytes - offset) + offset; mdl = maced_data_length(MIFARE_DESFIRE(tag)->session_key, *nbytes - offset) + offset;
if (!(res = assert_crypto_buffer_size (tag, mdl))) if (!(res = assert_crypto_buffer_size(tag, mdl)))
abort(); abort();
memcpy (res + *nbytes, mac, 4); memcpy(res + *nbytes, mac, 4);
*nbytes += 4; *nbytes += 4;
break; break;
case AS_NEW: case AS_NEW:
if (!(communication_settings & CMAC_COMMAND)) if (!(communication_settings & CMAC_COMMAND))
break; break;
cmac (key, MIFARE_DESFIRE (tag)->ivect, res, *nbytes, MIFARE_DESFIRE (tag)->cmac); cmac(key, MIFARE_DESFIRE(tag)->ivect, res, *nbytes, MIFARE_DESFIRE(tag)->cmac);
if (append_mac) { if (append_mac) {
mdl = maced_data_length (key, *nbytes); mdl = maced_data_length(key, *nbytes);
if (!(res = assert_crypto_buffer_size (tag, mdl))) if (!(res = assert_crypto_buffer_size(tag, mdl)))
abort(); abort();
memcpy (res, data, *nbytes); memcpy(res, data, *nbytes);
memcpy (res + *nbytes, MIFARE_DESFIRE (tag)->cmac, CMAC_LENGTH); memcpy(res + *nbytes, MIFARE_DESFIRE(tag)->cmac, CMAC_LENGTH);
*nbytes += CMAC_LENGTH; *nbytes += CMAC_LENGTH;
} }
break; break;
@ -394,41 +394,41 @@ mifare_cryto_preprocess_data (FreefareTag tag, void *data, size_t *nbytes, off_t
* encypher()/decypher() * encypher()/decypher()
*/ */
if (!(communication_settings & ENC_COMMAND)) if (!(communication_settings & ENC_COMMAND))
break;
edl = enciphered_data_length(tag, *nbytes - offset, communication_settings) + offset;
if (!(res = assert_crypto_buffer_size(tag, edl)))
abort();
// Fill in the crypto buffer with data ...
memcpy(res, data, *nbytes);
if (!(communication_settings & NO_CRC)) {
// ... CRC ...
switch (MIFARE_DESFIRE(tag)->authentication_scheme) {
case AS_LEGACY:
iso14443a_crc_append(res + offset, *nbytes - offset);
*nbytes += 2;
break;
case AS_NEW:
desfire_crc32_append(res, *nbytes);
*nbytes += 4;
break; break;
edl = enciphered_data_length (tag, *nbytes - offset, communication_settings) + offset;
if (!(res = assert_crypto_buffer_size (tag, edl)))
abort();
// Fill in the crypto buffer with data ...
memcpy (res, data, *nbytes);
if (!(communication_settings & NO_CRC)) {
// ... CRC ...
switch (MIFARE_DESFIRE (tag)->authentication_scheme) {
case AS_LEGACY:
iso14443a_crc_append (res + offset, *nbytes - offset);
*nbytes += 2;
break;
case AS_NEW:
desfire_crc32_append (res, *nbytes);
*nbytes += 4;
break;
}
} }
// ... and padding }
memset (res + *nbytes, 0, edl - *nbytes); // ... and padding
memset(res + *nbytes, 0, edl - *nbytes);
*nbytes = edl; *nbytes = edl;
mifare_cypher_blocks_chained (tag, NULL, NULL, res + offset, *nbytes - offset, MCD_SEND, (AS_NEW == MIFARE_DESFIRE (tag)->authentication_scheme) ? MCO_ENCYPHER : MCO_DECYPHER); mifare_cypher_blocks_chained(tag, NULL, NULL, res + offset, *nbytes - offset, MCD_SEND, (AS_NEW == MIFARE_DESFIRE(tag)->authentication_scheme) ? MCO_ENCYPHER : MCO_DECYPHER);
break; break;
default: default:
MIFARE_DESFIRE (tag)->last_pcd_error = CRYPTO_ERROR; MIFARE_DESFIRE(tag)->last_pcd_error = CRYPTO_ERROR;
*nbytes = -1; *nbytes = -1;
res = NULL; res = NULL;
#ifdef WITH_DEBUG #ifdef WITH_DEBUG
warnx ("Unknown communication settings"); warnx("Unknown communication settings");
abort (); abort();
#endif #endif
break; break;
} }
@ -437,14 +437,14 @@ mifare_cryto_preprocess_data (FreefareTag tag, void *data, size_t *nbytes, off_t
} }
void * void *
mifare_cryto_postprocess_data (FreefareTag tag, void *data, ssize_t *nbytes, int communication_settings) mifare_cryto_postprocess_data(FreefareTag tag, void *data, ssize_t *nbytes, int communication_settings)
{ {
void *res = data; void *res = data;
size_t edl; size_t edl;
void *edata = NULL; void *edata = NULL;
uint8_t first_cmac_byte; uint8_t first_cmac_byte;
MifareDESFireKey key = MIFARE_DESFIRE (tag)->session_key; MifareDESFireKey key = MIFARE_DESFIRE(tag)->session_key;
if (!key) if (!key)
return data; return data;
@ -456,42 +456,42 @@ mifare_cryto_postprocess_data (FreefareTag tag, void *data, ssize_t *nbytes, int
switch (communication_settings & MDCM_MASK) { switch (communication_settings & MDCM_MASK) {
case MDCM_PLAIN: case MDCM_PLAIN:
if (AS_LEGACY == MIFARE_DESFIRE (tag)->authentication_scheme) if (AS_LEGACY == MIFARE_DESFIRE(tag)->authentication_scheme)
break; break;
/* pass through */ /* pass through */
case MDCM_MACED: case MDCM_MACED:
switch (MIFARE_DESFIRE (tag)->authentication_scheme) { switch (MIFARE_DESFIRE(tag)->authentication_scheme) {
case AS_LEGACY: case AS_LEGACY:
if (communication_settings & MAC_VERIFY) { if (communication_settings & MAC_VERIFY) {
*nbytes -= key_macing_length (key); *nbytes -= key_macing_length(key);
if (*nbytes <= 0) { if (*nbytes <= 0) {
MIFARE_DESFIRE (tag)->last_pcd_error = CRYPTO_ERROR; MIFARE_DESFIRE(tag)->last_pcd_error = CRYPTO_ERROR;
*nbytes = -1; *nbytes = -1;
res = NULL; res = NULL;
#ifdef WITH_DEBUG #ifdef WITH_DEBUG
warnx ("No room for MAC!"); warnx("No room for MAC!");
abort (); abort();
#endif #endif
break; break;
} }
edl = enciphered_data_length (tag, *nbytes - 1, communication_settings); edl = enciphered_data_length(tag, *nbytes - 1, communication_settings);
if (!(edata = malloc (edl))) if (!(edata = malloc(edl)))
abort (); abort();
memcpy (edata, data, *nbytes - 1); memcpy(edata, data, *nbytes - 1);
memset ((uint8_t *)edata + *nbytes - 1, 0, edl - *nbytes + 1); memset((uint8_t *)edata + *nbytes - 1, 0, edl - *nbytes + 1);
mifare_cypher_blocks_chained (tag, NULL, NULL, edata, edl, MCD_SEND, MCO_ENCYPHER); mifare_cypher_blocks_chained(tag, NULL, NULL, edata, edl, MCD_SEND, MCO_ENCYPHER);
if (0 != memcmp ((uint8_t *)data + *nbytes - 1, (uint8_t *)edata + edl - 8, 4)) { if (0 != memcmp((uint8_t *)data + *nbytes - 1, (uint8_t *)edata + edl - 8, 4)) {
#ifdef WITH_DEBUG #ifdef WITH_DEBUG
warnx ("MACing not verified"); warnx("MACing not verified");
hexdump ((uint8_t *)data + *nbytes - 1, key_macing_length (key), "Expect ", 0); hexdump((uint8_t *)data + *nbytes - 1, key_macing_length(key), "Expect ", 0);
hexdump ((uint8_t *)edata + edl - 8, key_macing_length (key), "Actual ", 0); hexdump((uint8_t *)edata + edl - 8, key_macing_length(key), "Actual ", 0);
#endif #endif
MIFARE_DESFIRE (tag)->last_pcd_error = CRYPTO_ERROR; MIFARE_DESFIRE(tag)->last_pcd_error = CRYPTO_ERROR;
*nbytes = -1; *nbytes = -1;
res = NULL; res = NULL;
} }
@ -502,31 +502,31 @@ mifare_cryto_postprocess_data (FreefareTag tag, void *data, ssize_t *nbytes, int
break; break;
if (communication_settings & CMAC_VERIFY) { if (communication_settings & CMAC_VERIFY) {
if (*nbytes < 9) { if (*nbytes < 9) {
MIFARE_DESFIRE (tag)->last_pcd_error = CRYPTO_ERROR; MIFARE_DESFIRE(tag)->last_pcd_error = CRYPTO_ERROR;
*nbytes = -1; *nbytes = -1;
res = NULL; res = NULL;
#ifdef WITH_DEBUG #ifdef WITH_DEBUG
warnx ("No room for CMAC!"); warnx("No room for CMAC!");
abort (); abort();
#endif #endif
break; break;
} }
first_cmac_byte = ((uint8_t *)data)[*nbytes - 9]; first_cmac_byte = ((uint8_t *)data)[*nbytes - 9];
((uint8_t *)data)[*nbytes - 9] = ((uint8_t *)data)[*nbytes-1]; ((uint8_t *)data)[*nbytes - 9] = ((uint8_t *)data)[*nbytes - 1];
} }
int n = (communication_settings & CMAC_VERIFY) ? 8 : 0; int n = (communication_settings & CMAC_VERIFY) ? 8 : 0;
cmac (key, MIFARE_DESFIRE (tag)->ivect, ((uint8_t *)data), *nbytes - n, MIFARE_DESFIRE (tag)->cmac); cmac(key, MIFARE_DESFIRE(tag)->ivect, ((uint8_t *)data), *nbytes - n, MIFARE_DESFIRE(tag)->cmac);
if (communication_settings & CMAC_VERIFY) { if (communication_settings & CMAC_VERIFY) {
((uint8_t *)data)[*nbytes - 9] = first_cmac_byte; ((uint8_t *)data)[*nbytes - 9] = first_cmac_byte;
if (0 != memcmp (MIFARE_DESFIRE (tag)->cmac, (uint8_t *)data + *nbytes - 9, 8)) { if (0 != memcmp(MIFARE_DESFIRE(tag)->cmac, (uint8_t *)data + *nbytes - 9, 8)) {
#ifdef WITH_DEBUG #ifdef WITH_DEBUG
warnx ("CMAC NOT verified :-("); warnx("CMAC NOT verified :-(");
hexdump ((uint8_t *)data + *nbytes - 9, 8, "Expect ", 0); hexdump((uint8_t *)data + *nbytes - 9, 8, "Expect ", 0);
hexdump (MIFARE_DESFIRE (tag)->cmac, 8, "Actual ", 0); hexdump(MIFARE_DESFIRE(tag)->cmac, 8, "Actual ", 0);
#endif #endif
MIFARE_DESFIRE (tag)->last_pcd_error = CRYPTO_ERROR; MIFARE_DESFIRE(tag)->last_pcd_error = CRYPTO_ERROR;
*nbytes = -1; *nbytes = -1;
res = NULL; res = NULL;
} else { } else {
@ -536,7 +536,7 @@ mifare_cryto_postprocess_data (FreefareTag tag, void *data, ssize_t *nbytes, int
break; break;
} }
free (edata); free(edata);
break; break;
case MDCM_ENCIPHERED: case MDCM_ENCIPHERED:
@ -568,14 +568,14 @@ mifare_cryto_postprocess_data (FreefareTag tag, void *data, ssize_t *nbytes, int
* `------------------' * `------------------'
*/ */
mifare_cypher_blocks_chained (tag, NULL, NULL, res, *nbytes, MCD_RECEIVE, MCO_DECYPHER); mifare_cypher_blocks_chained(tag, NULL, NULL, res, *nbytes, MCD_RECEIVE, MCO_DECYPHER);
/* /*
* Look for the CRC and ensure it is followed by NULL padding. We * Look for the CRC and ensure it is followed by NULL padding. We
* can't start by the end because the CRC is supposed to be 0 when * can't start by the end because the CRC is supposed to be 0 when
* verified, and accumulating 0's in it should not change it. * verified, and accumulating 0's in it should not change it.
*/ */
switch (MIFARE_DESFIRE (tag)->authentication_scheme) { switch (MIFARE_DESFIRE(tag)->authentication_scheme) {
case AS_LEGACY: case AS_LEGACY:
crc_pos = *nbytes - 8 - 1; // The CRC can be over two blocks crc_pos = *nbytes - 8 - 1; // The CRC can be over two blocks
if (crc_pos < 0) { if (crc_pos < 0) {
@ -585,15 +585,15 @@ mifare_cryto_postprocess_data (FreefareTag tag, void *data, ssize_t *nbytes, int
break; break;
case AS_NEW: case AS_NEW:
/* Move status between payload and CRC */ /* Move status between payload and CRC */
res = assert_crypto_buffer_size (tag, (*nbytes) + 1); res = assert_crypto_buffer_size(tag, (*nbytes) + 1);
memcpy (res, data, *nbytes); memcpy(res, data, *nbytes);
crc_pos = (*nbytes) - 16 - 3; crc_pos = (*nbytes) - 16 - 3;
if (crc_pos < 0) { if (crc_pos < 0) {
/* Single block */ /* Single block */
crc_pos = 0; crc_pos = 0;
} }
memmove ((uint8_t *)res + crc_pos + 1, (uint8_t *)res + crc_pos, *nbytes - crc_pos); memmove((uint8_t *)res + crc_pos + 1, (uint8_t *)res + crc_pos, *nbytes - crc_pos);
((uint8_t *)res)[crc_pos] = 0x00; ((uint8_t *)res)[crc_pos] = 0x00;
crc_pos++; crc_pos++;
*nbytes += 1; *nbytes += 1;
@ -603,28 +603,28 @@ mifare_cryto_postprocess_data (FreefareTag tag, void *data, ssize_t *nbytes, int
do { do {
uint16_t crc16; uint16_t crc16;
uint32_t crc; uint32_t crc;
switch (MIFARE_DESFIRE (tag)->authentication_scheme) { switch (MIFARE_DESFIRE(tag)->authentication_scheme) {
case AS_LEGACY: case AS_LEGACY:
end_crc_pos = crc_pos + 2; end_crc_pos = crc_pos + 2;
iso14443a_crc (res, end_crc_pos, (uint8_t *)&crc16); iso14443a_crc(res, end_crc_pos, (uint8_t *)&crc16);
crc = crc16; crc = crc16;
break; break;
case AS_NEW: case AS_NEW:
end_crc_pos = crc_pos + 4; end_crc_pos = crc_pos + 4;
desfire_crc32 (res, end_crc_pos, (uint8_t *)&crc); desfire_crc32(res, end_crc_pos, (uint8_t *)&crc);
break; break;
} }
if (!crc) { if (!crc) {
verified = true; verified = true;
for (int n = end_crc_pos; n < *nbytes - 1; n++) { for (int n = end_crc_pos; n < *nbytes - 1; n++) {
uint8_t byte = ((uint8_t *)res)[n]; uint8_t byte = ((uint8_t *)res)[n];
if (!( (0x00 == byte) || ((0x80 == byte) && (n == end_crc_pos)) )) if (!((0x00 == byte) || ((0x80 == byte) && (n == end_crc_pos))))
verified = false; verified = false;
} }
} }
if (verified) { if (verified) {
*nbytes = crc_pos; *nbytes = crc_pos;
switch (MIFARE_DESFIRE (tag)->authentication_scheme) { switch (MIFARE_DESFIRE(tag)->authentication_scheme) {
case AS_LEGACY: case AS_LEGACY:
((uint8_t *)data)[(*nbytes)++] = 0x00; ((uint8_t *)data)[(*nbytes)++] = 0x00;
break; break;
@ -633,7 +633,7 @@ mifare_cryto_postprocess_data (FreefareTag tag, void *data, ssize_t *nbytes, int
break; break;
} }
} else { } else {
switch (MIFARE_DESFIRE (tag)->authentication_scheme) { switch (MIFARE_DESFIRE(tag)->authentication_scheme) {
case AS_LEGACY: case AS_LEGACY:
break; break;
case AS_NEW: case AS_NEW:
@ -649,21 +649,21 @@ mifare_cryto_postprocess_data (FreefareTag tag, void *data, ssize_t *nbytes, int
if (!verified) { if (!verified) {
#ifdef WITH_DEBUG #ifdef WITH_DEBUG
/* FIXME In some configurations, the file is transmitted PLAIN */ /* FIXME In some configurations, the file is transmitted PLAIN */
warnx ("CRC not verified in decyphered stream"); warnx("CRC not verified in decyphered stream");
#endif #endif
MIFARE_DESFIRE (tag)->last_pcd_error = CRYPTO_ERROR; MIFARE_DESFIRE(tag)->last_pcd_error = CRYPTO_ERROR;
*nbytes = -1; *nbytes = -1;
res = NULL; res = NULL;
} }
break; break;
default: default:
MIFARE_DESFIRE (tag)->last_pcd_error = CRYPTO_ERROR; MIFARE_DESFIRE(tag)->last_pcd_error = CRYPTO_ERROR;
*nbytes = -1; *nbytes = -1;
res = NULL; res = NULL;
#ifdef WITH_DEBUG #ifdef WITH_DEBUG
warnx ("Unknown communication settings"); warnx("Unknown communication settings");
abort (); abort();
#endif #endif
break; break;
@ -672,15 +672,15 @@ mifare_cryto_postprocess_data (FreefareTag tag, void *data, ssize_t *nbytes, int
} }
void void
mifare_cypher_single_block (MifareDESFireKey key, uint8_t *data, uint8_t *ivect, MifareCryptoDirection direction, MifareCryptoOperation operation, size_t block_size) mifare_cypher_single_block(MifareDESFireKey key, uint8_t *data, uint8_t *ivect, MifareCryptoDirection direction, MifareCryptoOperation operation, size_t block_size)
{ {
AES_KEY k; AES_KEY k;
uint8_t ovect[MAX_CRYPTO_BLOCK_SIZE]; uint8_t ovect[MAX_CRYPTO_BLOCK_SIZE];
if (direction == MCD_SEND) { if (direction == MCD_SEND) {
xor (ivect, data, block_size); xor(ivect, data, block_size);
} else { } else {
memcpy (ovect, data, block_size); memcpy(ovect, data, block_size);
} }
uint8_t edata[MAX_CRYPTO_BLOCK_SIZE]; uint8_t edata[MAX_CRYPTO_BLOCK_SIZE];
@ -689,62 +689,62 @@ mifare_cypher_single_block (MifareDESFireKey key, uint8_t *data, uint8_t *ivect,
case T_DES: case T_DES:
switch (operation) { switch (operation) {
case MCO_ENCYPHER: case MCO_ENCYPHER:
DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_ENCRYPT); DES_ecb_encrypt((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_ENCRYPT);
break; break;
case MCO_DECYPHER: case MCO_DECYPHER:
DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_DECRYPT); DES_ecb_encrypt((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_DECRYPT);
break; break;
} }
break; break;
case T_3DES: case T_3DES:
switch (operation) { switch (operation) {
case MCO_ENCYPHER: case MCO_ENCYPHER:
DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_ENCRYPT); DES_ecb_encrypt((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_ENCRYPT);
DES_ecb_encrypt ((DES_cblock *) edata, (DES_cblock *) data, &(key->ks2), DES_DECRYPT); DES_ecb_encrypt((DES_cblock *) edata, (DES_cblock *) data, &(key->ks2), DES_DECRYPT);
DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_ENCRYPT); DES_ecb_encrypt((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_ENCRYPT);
break; break;
case MCO_DECYPHER: case MCO_DECYPHER:
DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_DECRYPT); DES_ecb_encrypt((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_DECRYPT);
DES_ecb_encrypt ((DES_cblock *) edata, (DES_cblock *) data, &(key->ks2), DES_ENCRYPT); DES_ecb_encrypt((DES_cblock *) edata, (DES_cblock *) data, &(key->ks2), DES_ENCRYPT);
DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_DECRYPT); DES_ecb_encrypt((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_DECRYPT);
break; break;
} }
break; break;
case T_3K3DES: case T_3K3DES:
switch (operation) { switch (operation) {
case MCO_ENCYPHER: case MCO_ENCYPHER:
DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_ENCRYPT); DES_ecb_encrypt((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_ENCRYPT);
DES_ecb_encrypt ((DES_cblock *) edata, (DES_cblock *) data, &(key->ks2), DES_DECRYPT); DES_ecb_encrypt((DES_cblock *) edata, (DES_cblock *) data, &(key->ks2), DES_DECRYPT);
DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks3), DES_ENCRYPT); DES_ecb_encrypt((DES_cblock *) data, (DES_cblock *) edata, &(key->ks3), DES_ENCRYPT);
break; break;
case MCO_DECYPHER: case MCO_DECYPHER:
DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks3), DES_DECRYPT); DES_ecb_encrypt((DES_cblock *) data, (DES_cblock *) edata, &(key->ks3), DES_DECRYPT);
DES_ecb_encrypt ((DES_cblock *) edata, (DES_cblock *) data, &(key->ks2), DES_ENCRYPT); DES_ecb_encrypt((DES_cblock *) edata, (DES_cblock *) data, &(key->ks2), DES_ENCRYPT);
DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_DECRYPT); DES_ecb_encrypt((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_DECRYPT);
break; break;
} }
break; break;
case T_AES: case T_AES:
switch (operation) { switch (operation) {
case MCO_ENCYPHER: case MCO_ENCYPHER:
AES_set_encrypt_key (key->data, 8*16, &k); AES_set_encrypt_key(key->data, 8 * 16, &k);
AES_encrypt (data, edata, &k); AES_encrypt(data, edata, &k);
break; break;
case MCO_DECYPHER: case MCO_DECYPHER:
AES_set_decrypt_key (key->data, 8*16, &k); AES_set_decrypt_key(key->data, 8 * 16, &k);
AES_decrypt (data, edata, &k); AES_decrypt(data, edata, &k);
break; break;
} }
break; break;
} }
memcpy (data, edata, block_size); memcpy(data, edata, block_size);
if (direction == MCD_SEND) { if (direction == MCD_SEND) {
memcpy (ivect, data, block_size); memcpy(ivect, data, block_size);
} else { } else {
xor (ivect, data, block_size); xor(ivect, data, block_size);
memcpy (ivect, ovect, block_size); memcpy(ivect, ovect, block_size);
} }
} }
@ -759,19 +759,19 @@ mifare_cypher_single_block (MifareDESFireKey key, uint8_t *data, uint8_t *ivect,
* function with tag, key and ivect defined. * function with tag, key and ivect defined.
*/ */
void void
mifare_cypher_blocks_chained (FreefareTag tag, MifareDESFireKey key, uint8_t *ivect, uint8_t *data, size_t data_size, MifareCryptoDirection direction, MifareCryptoOperation operation) mifare_cypher_blocks_chained(FreefareTag tag, MifareDESFireKey key, uint8_t *ivect, uint8_t *data, size_t data_size, MifareCryptoDirection direction, MifareCryptoOperation operation)
{ {
size_t block_size; size_t block_size;
if (tag) { if (tag) {
if (!key) if (!key)
key = MIFARE_DESFIRE (tag)->session_key; key = MIFARE_DESFIRE(tag)->session_key;
if (!ivect) if (!ivect)
ivect = MIFARE_DESFIRE (tag)->ivect; ivect = MIFARE_DESFIRE(tag)->ivect;
switch (MIFARE_DESFIRE (tag)->authentication_scheme) { switch (MIFARE_DESFIRE(tag)->authentication_scheme) {
case AS_LEGACY: case AS_LEGACY:
memset (ivect, 0, MAX_CRYPTO_BLOCK_SIZE); memset(ivect, 0, MAX_CRYPTO_BLOCK_SIZE);
break; break;
case AS_NEW: case AS_NEW:
break; break;
@ -781,11 +781,11 @@ mifare_cypher_blocks_chained (FreefareTag tag, MifareDESFireKey key, uint8_t *iv
if (!key || !ivect) if (!key || !ivect)
abort(); abort();
block_size = key_block_size (key); block_size = key_block_size(key);
size_t offset = 0; size_t offset = 0;
while (offset < data_size) { while (offset < data_size) {
mifare_cypher_single_block (key, data + offset, ivect, direction, operation, block_size); mifare_cypher_single_block(key, data + offset, ivect, direction, operation, block_size);
offset += block_size; offset += block_size;
} }
} }

View file

@ -57,7 +57,7 @@ static struct error_message {
}; };
const char * const char *
mifare_desfire_error_lookup (uint8_t code) mifare_desfire_error_lookup(uint8_t code)
{ {
struct error_message *e = error_messages; struct error_message *e = error_messages;
while (e->message) { while (e->message) {
@ -70,19 +70,19 @@ 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->type != MIFARE_DESFIRE) if (tag->type != MIFARE_DESFIRE)
return 0; return 0;
return MIFARE_DESFIRE (tag)->last_pcd_error; return MIFARE_DESFIRE(tag)->last_pcd_error;
} }
uint8_t uint8_t
mifare_desfire_last_picc_error (FreefareTag tag) mifare_desfire_last_picc_error(FreefareTag tag)
{ {
if (tag->type != MIFARE_DESFIRE) if (tag->type != MIFARE_DESFIRE)
return 0; return 0;
return MIFARE_DESFIRE (tag)->last_picc_error; return MIFARE_DESFIRE(tag)->last_picc_error;
} }

View file

@ -23,103 +23,103 @@
#include <freefare.h> #include <freefare.h>
#include "freefare_internal.h" #include "freefare_internal.h"
static inline void update_key_schedules (MifareDESFireKey key); static inline void update_key_schedules(MifareDESFireKey key);
static inline void static inline void
update_key_schedules (MifareDESFireKey key) update_key_schedules(MifareDESFireKey key)
{ {
DES_set_key ((DES_cblock *)key->data, &(key->ks1)); DES_set_key((DES_cblock *)key->data, &(key->ks1));
DES_set_key ((DES_cblock *)(key->data + 8), &(key->ks2)); DES_set_key((DES_cblock *)(key->data + 8), &(key->ks2));
if (T_3K3DES == key->type) { if (T_3K3DES == key->type) {
DES_set_key ((DES_cblock *)(key->data + 16), &(key->ks3)); DES_set_key((DES_cblock *)(key->data + 16), &(key->ks3));
} }
} }
MifareDESFireKey MifareDESFireKey
mifare_desfire_des_key_new (const uint8_t value[8]) mifare_desfire_des_key_new(const uint8_t value[8])
{ {
uint8_t data[8]; uint8_t data[8];
memcpy (data, value, 8); memcpy(data, value, 8);
for (int n=0; n < 8; n++) for (int n = 0; n < 8; n++)
data[n] &= 0xfe; data[n] &= 0xfe;
return mifare_desfire_des_key_new_with_version (data); return mifare_desfire_des_key_new_with_version(data);
} }
MifareDESFireKey MifareDESFireKey
mifare_desfire_des_key_new_with_version (const uint8_t value[8]) mifare_desfire_des_key_new_with_version(const uint8_t value[8])
{ {
MifareDESFireKey key; MifareDESFireKey key;
if ((key = malloc (sizeof (struct mifare_desfire_key)))) { if ((key = malloc(sizeof(struct mifare_desfire_key)))) {
key->type = T_DES; key->type = T_DES;
memcpy (key->data, value, 8); memcpy(key->data, value, 8);
memcpy (key->data+8, value, 8); memcpy(key->data + 8, value, 8);
update_key_schedules (key); update_key_schedules(key);
} }
return key; return key;
} }
MifareDESFireKey MifareDESFireKey
mifare_desfire_3des_key_new (const uint8_t value[16]) mifare_desfire_3des_key_new(const uint8_t value[16])
{ {
uint8_t data[16]; uint8_t data[16];
memcpy (data, value, 16); memcpy(data, value, 16);
for (int n=0; n < 8; n++) for (int n = 0; n < 8; n++)
data[n] &= 0xfe; data[n] &= 0xfe;
for (int n=8; n < 16; n++) for (int n = 8; n < 16; n++)
data[n] |= 0x01; data[n] |= 0x01;
return mifare_desfire_3des_key_new_with_version (data); return mifare_desfire_3des_key_new_with_version(data);
} }
MifareDESFireKey MifareDESFireKey
mifare_desfire_3des_key_new_with_version (const uint8_t value[16]) mifare_desfire_3des_key_new_with_version(const uint8_t value[16])
{ {
MifareDESFireKey key; MifareDESFireKey key;
if ((key = malloc (sizeof (struct mifare_desfire_key)))) { if ((key = malloc(sizeof(struct mifare_desfire_key)))) {
key->type = T_3DES; key->type = T_3DES;
memcpy (key->data, value, 16); memcpy(key->data, value, 16);
update_key_schedules (key); update_key_schedules(key);
} }
return key; return key;
} }
MifareDESFireKey MifareDESFireKey
mifare_desfire_3k3des_key_new (const uint8_t value[24]) mifare_desfire_3k3des_key_new(const uint8_t value[24])
{ {
uint8_t data[24]; uint8_t data[24];
memcpy (data, value, 24); memcpy(data, value, 24);
for (int n=0; n < 8; n++) for (int n = 0; n < 8; n++)
data[n] &= 0xfe; data[n] &= 0xfe;
return mifare_desfire_3k3des_key_new_with_version (data); return mifare_desfire_3k3des_key_new_with_version(data);
} }
MifareDESFireKey MifareDESFireKey
mifare_desfire_3k3des_key_new_with_version (const uint8_t value[24]) mifare_desfire_3k3des_key_new_with_version(const uint8_t value[24])
{ {
MifareDESFireKey key; MifareDESFireKey key;
if ((key = malloc (sizeof (struct mifare_desfire_key)))) { if ((key = malloc(sizeof(struct mifare_desfire_key)))) {
key->type = T_3K3DES; key->type = T_3K3DES;
memcpy (key->data, value, 24); memcpy(key->data, value, 24);
update_key_schedules (key); update_key_schedules(key);
} }
return key; return key;
} }
MifareDESFireKey MifareDESFireKey
mifare_desfire_aes_key_new (const uint8_t value[16]) mifare_desfire_aes_key_new(const uint8_t value[16])
{ {
return mifare_desfire_aes_key_new_with_version (value, 0); return mifare_desfire_aes_key_new_with_version(value, 0);
} }
MifareDESFireKey MifareDESFireKey
mifare_desfire_aes_key_new_with_version (const uint8_t value[16], uint8_t version) mifare_desfire_aes_key_new_with_version(const uint8_t value[16], uint8_t version)
{ {
MifareDESFireKey key; MifareDESFireKey key;
if ((key = malloc (sizeof (struct mifare_desfire_key)))) { if ((key = malloc(sizeof(struct mifare_desfire_key)))) {
memcpy (key->data, value, 16); memcpy(key->data, value, 16);
key->type = T_AES; key->type = T_AES;
key->aes_version = version; key->aes_version = version;
} }
@ -127,7 +127,7 @@ mifare_desfire_aes_key_new_with_version (const uint8_t value[16], uint8_t versio
} }
uint8_t uint8_t
mifare_desfire_key_get_version (MifareDESFireKey key) mifare_desfire_key_get_version(MifareDESFireKey key)
{ {
uint8_t version = 0; uint8_t version = 0;
@ -139,24 +139,24 @@ mifare_desfire_key_get_version (MifareDESFireKey key)
} }
void void
mifare_desfire_key_set_version (MifareDESFireKey key, uint8_t version) mifare_desfire_key_set_version(MifareDESFireKey key, uint8_t version)
{ {
for (int n = 0; n < 8; n++) { for (int n = 0; n < 8; n++) {
uint8_t version_bit = ((version & (1 << (7-n))) >> (7-n)); uint8_t version_bit = ((version & (1 << (7 - n))) >> (7 - n));
key->data[n] &= 0xfe; key->data[n] &= 0xfe;
key->data[n] |= version_bit; key->data[n] |= version_bit;
if (key->type == T_DES) { if (key->type == T_DES) {
key->data[n+8] = key->data[n]; key->data[n + 8] = key->data[n];
} else { } else {
// Write ~version to avoid turning a 3DES key into a DES key // Write ~version to avoid turning a 3DES key into a DES key
key->data[n+8] &= 0xfe; key->data[n + 8] &= 0xfe;
key->data[n+8] |= ~version_bit; key->data[n + 8] |= ~version_bit;
} }
} }
} }
MifareDESFireKey MifareDESFireKey
mifare_desfire_session_key_new (const uint8_t rnda[], const uint8_t rndb[], MifareDESFireKey authentication_key) mifare_desfire_session_key_new(const uint8_t rnda[], const uint8_t rndb[], MifareDESFireKey authentication_key)
{ {
MifareDESFireKey key = NULL; MifareDESFireKey key = NULL;
@ -164,32 +164,32 @@ mifare_desfire_session_key_new (const uint8_t rnda[], const uint8_t rndb[], Mifa
switch (authentication_key->type) { switch (authentication_key->type) {
case T_DES: case T_DES:
memcpy (buffer, rnda, 4); memcpy(buffer, rnda, 4);
memcpy (buffer+4, rndb, 4); memcpy(buffer + 4, rndb, 4);
key = mifare_desfire_des_key_new_with_version (buffer); key = mifare_desfire_des_key_new_with_version(buffer);
break; break;
case T_3DES: case T_3DES:
memcpy (buffer, rnda, 4); memcpy(buffer, rnda, 4);
memcpy (buffer+4, rndb, 4); memcpy(buffer + 4, rndb, 4);
memcpy (buffer+8, rnda+4, 4); memcpy(buffer + 8, rnda + 4, 4);
memcpy (buffer+12, rndb+4, 4); memcpy(buffer + 12, rndb + 4, 4);
key = mifare_desfire_3des_key_new_with_version (buffer); key = mifare_desfire_3des_key_new_with_version(buffer);
break; break;
case T_3K3DES: case T_3K3DES:
memcpy (buffer, rnda, 4); memcpy(buffer, rnda, 4);
memcpy (buffer+4, rndb, 4); memcpy(buffer + 4, rndb, 4);
memcpy (buffer+8, rnda+6, 4); memcpy(buffer + 8, rnda + 6, 4);
memcpy (buffer+12, rndb+6, 4); memcpy(buffer + 12, rndb + 6, 4);
memcpy (buffer+16, rnda+12, 4); memcpy(buffer + 16, rnda + 12, 4);
memcpy (buffer+20, rndb+12, 4); memcpy(buffer + 20, rndb + 12, 4);
key = mifare_desfire_3k3des_key_new (buffer); key = mifare_desfire_3k3des_key_new(buffer);
break; break;
case T_AES: case T_AES:
memcpy (buffer, rnda, 4); memcpy(buffer, rnda, 4);
memcpy (buffer+4, rndb, 4); memcpy(buffer + 4, rndb, 4);
memcpy (buffer+8, rnda+12, 4); memcpy(buffer + 8, rnda + 12, 4);
memcpy (buffer+12, rndb+12, 4); memcpy(buffer + 12, rndb + 12, 4);
key = mifare_desfire_aes_key_new (buffer); key = mifare_desfire_aes_key_new(buffer);
break; break;
} }
@ -197,7 +197,7 @@ mifare_desfire_session_key_new (const uint8_t rnda[], const uint8_t rndb[], Mifa
} }
void void
mifare_desfire_key_free (MifareDESFireKey key) mifare_desfire_key_free(MifareDESFireKey key)
{ {
free (key); free(key);
} }

View file

@ -47,66 +47,66 @@
#define ASSERT_VALID_PAGE(tag, page, mode_write) \ #define ASSERT_VALID_PAGE(tag, page, mode_write) \
do { \ do { \
if (is_mifare_ultralightc (tag)) { \ if (is_mifare_ultralightc (tag)) { \
if (mode_write) { \ if (mode_write) { \
if (page >= MIFARE_ULTRALIGHT_C_PAGE_COUNT) return errno = EINVAL, -1; \ if (page >= MIFARE_ULTRALIGHT_C_PAGE_COUNT) return errno = EINVAL, -1; \
} else { \ } else { \
if (page >= MIFARE_ULTRALIGHT_C_PAGE_COUNT_READ) return errno = EINVAL, -1; \ if (page >= MIFARE_ULTRALIGHT_C_PAGE_COUNT_READ) return errno = EINVAL, -1; \
} \ } \
} else { \ } else { \
if (page >= MIFARE_ULTRALIGHT_PAGE_COUNT) return errno = EINVAL, -1; \ if (page >= MIFARE_ULTRALIGHT_PAGE_COUNT) return errno = EINVAL, -1; \
} \ } \
} while (0) } while (0)
#define ULTRALIGHT_TRANSCEIVE(tag, msg, res) \ #define ULTRALIGHT_TRANSCEIVE(tag, msg, res) \
do { \ do { \
errno = 0; \ errno = 0; \
DEBUG_XFER (msg, __##msg##_n, "===> "); \ DEBUG_XFER (msg, __##msg##_n, "===> "); \
int _res; \ int _res; \
if ((_res = nfc_initiator_transceive_bytes (tag->device, msg, __##msg##_n, res, __##res##_size, 0)) < 0) { \ if ((_res = nfc_initiator_transceive_bytes (tag->device, msg, __##msg##_n, res, __##res##_size, 0)) < 0) { \
return errno = EIO, -1; \ return errno = EIO, -1; \
} \ } \
__##res##_n = _res; \ __##res##_n = _res; \
DEBUG_XFER (res, __##res##_n, "<=== "); \ DEBUG_XFER (res, __##res##_n, "<=== "); \
} while (0) } while (0)
#define ULTRALIGHT_TRANSCEIVE_RAW(tag, msg, res) \ #define ULTRALIGHT_TRANSCEIVE_RAW(tag, msg, res) \
do { \ do { \
errno = 0; \ errno = 0; \
if (nfc_device_set_property_bool (tag->device, NP_EASY_FRAMING, false) < 0) { \ if (nfc_device_set_property_bool (tag->device, NP_EASY_FRAMING, false) < 0) { \
errno = EIO; \ errno = EIO; \
return -1; \ return -1; \
} \ } \
DEBUG_XFER (msg, __##msg##_n, "===> "); \ DEBUG_XFER (msg, __##msg##_n, "===> "); \
int _res; \ int _res; \
if ((_res = nfc_initiator_transceive_bytes (tag->device, msg, __##msg##_n, res, __##res##_size, 0)) < 0) { \ if ((_res = nfc_initiator_transceive_bytes (tag->device, msg, __##msg##_n, res, __##res##_size, 0)) < 0) { \
nfc_device_set_property_bool (tag->device, NP_EASY_FRAMING, true); \ nfc_device_set_property_bool (tag->device, NP_EASY_FRAMING, true); \
return errno = EIO, -1; \ return errno = EIO, -1; \
} \ } \
__##res##_n = _res; \ __##res##_n = _res; \
DEBUG_XFER (res, __##res##_n, "<=== "); \ DEBUG_XFER (res, __##res##_n, "<=== "); \
if (nfc_device_set_property_bool (tag->device, NP_EASY_FRAMING, true) < 0) { \ if (nfc_device_set_property_bool (tag->device, NP_EASY_FRAMING, true) < 0) { \
errno = EIO; \ errno = EIO; \
return -1; \ return -1; \
} \ } \
} while (0) } while (0)
static bool static bool
taste (nfc_target target) taste(nfc_target target)
{ {
return target.nm.nmt == NMT_ISO14443A && target.nti.nai.btSak == 0x00; return target.nm.nmt == NMT_ISO14443A && target.nti.nai.btSak == 0x00;
} }
bool bool
mifare_ultralight_taste (nfc_device *device, nfc_target target) mifare_ultralight_taste(nfc_device *device, nfc_target target)
{ {
return taste (target) && !is_mifare_ultralightc_on_reader (device, target.nti.nai); return taste(target) && !is_mifare_ultralightc_on_reader(device, target.nti.nai);
} }
bool bool
mifare_ultralightc_taste (nfc_device *device, nfc_target target) mifare_ultralightc_taste(nfc_device *device, nfc_target target)
{ {
return taste (target) && is_mifare_ultralightc_on_reader (device, target.nti.nai); return taste(target) && is_mifare_ultralightc_on_reader(device, target.nti.nai);
} }
@ -118,11 +118,11 @@ mifare_ultralightc_taste (nfc_device *device, nfc_target target)
* Allocates and initialize a MIFARE UltraLight tag. * Allocates and initialize a MIFARE UltraLight tag.
*/ */
static FreefareTag static FreefareTag
_mifare_ultralightc_tag_new (nfc_device *device, nfc_target target, bool is_ultralightc) _mifare_ultralightc_tag_new(nfc_device *device, nfc_target target, bool is_ultralightc)
{ {
FreefareTag tag; FreefareTag tag;
if ((tag = malloc (sizeof (struct mifare_ultralight_tag)))) { if ((tag = malloc(sizeof(struct mifare_ultralight_tag)))) {
tag->type = (is_ultralightc) ? MIFARE_ULTRALIGHT_C : MIFARE_ULTRALIGHT; tag->type = (is_ultralightc) ? MIFARE_ULTRALIGHT_C : MIFARE_ULTRALIGHT;
tag->free_tag = mifare_ultralightc_tag_free; tag->free_tag = mifare_ultralightc_tag_free;
tag->device = device; tag->device = device;
@ -134,30 +134,30 @@ _mifare_ultralightc_tag_new (nfc_device *device, nfc_target target, bool is_ultr
} }
FreefareTag FreefareTag
mifare_ultralight_tag_new (nfc_device *device, nfc_target target) mifare_ultralight_tag_new(nfc_device *device, nfc_target target)
{ {
return _mifare_ultralightc_tag_new (device, target, false); return _mifare_ultralightc_tag_new(device, target, false);
} }
FreefareTag FreefareTag
mifare_ultralightc_tag_new (nfc_device *device, nfc_target target) mifare_ultralightc_tag_new(nfc_device *device, nfc_target target)
{ {
return _mifare_ultralightc_tag_new (device, target, true); return _mifare_ultralightc_tag_new(device, target, true);
} }
/* /*
* Free the provided tag. * Free the provided tag.
*/ */
void void
mifare_ultralight_tag_free (FreefareTag tag) mifare_ultralight_tag_free(FreefareTag tag)
{ {
free (tag); free(tag);
} }
void void
mifare_ultralightc_tag_free (FreefareTag tag) mifare_ultralightc_tag_free(FreefareTag tag)
{ {
mifare_ultralight_tag_free (tag); mifare_ultralight_tag_free(tag);
} }
@ -174,16 +174,16 @@ mifare_ultralightc_tag_free (FreefareTag tag)
* Establish connection to the provided tag. * Establish connection to the provided tag.
*/ */
int int
mifare_ultralight_connect (FreefareTag tag) mifare_ultralight_connect(FreefareTag tag)
{ {
ASSERT_INACTIVE (tag); ASSERT_INACTIVE(tag);
nfc_target pnti; nfc_target pnti;
nfc_modulation modulation = { nfc_modulation modulation = {
.nmt = NMT_ISO14443A, .nmt = NMT_ISO14443A,
.nbr = NBR_106 .nbr = NBR_106
}; };
if (nfc_initiator_select_passive_target (tag->device, modulation, tag->info.nti.nai.abtUid, tag->info.nti.nai.szUidLen, &pnti) >= 0) { if (nfc_initiator_select_passive_target(tag->device, modulation, tag->info.nti.nai.abtUid, tag->info.nti.nai.szUidLen, &pnti) >= 0) {
tag->active = 1; tag->active = 1;
for (int i = 0; i < MIFARE_ULTRALIGHT_MAX_PAGE_COUNT; i++) for (int i = 0; i < MIFARE_ULTRALIGHT_MAX_PAGE_COUNT; i++)
MIFARE_ULTRALIGHT(tag)->cached_pages[i] = 0; MIFARE_ULTRALIGHT(tag)->cached_pages[i] = 0;
@ -198,11 +198,11 @@ mifare_ultralight_connect (FreefareTag tag)
* Terminate connection with the provided tag. * Terminate connection with the provided tag.
*/ */
int int
mifare_ultralight_disconnect (FreefareTag tag) mifare_ultralight_disconnect(FreefareTag tag)
{ {
ASSERT_ACTIVE (tag); ASSERT_ACTIVE(tag);
if (nfc_initiator_deselect_target (tag->device) >= 0) { if (nfc_initiator_deselect_target(tag->device) >= 0) {
tag->active = 0; tag->active = 0;
} else { } else {
errno = EIO; errno = EIO;
@ -223,29 +223,29 @@ mifare_ultralight_disconnect (FreefareTag tag)
* Read data from the provided MIFARE tag. * Read data from the provided MIFARE tag.
*/ */
int int
mifare_ultralight_read (FreefareTag tag, MifareUltralightPageNumber page, MifareUltralightPage *data) mifare_ultralight_read(FreefareTag tag, MifareUltralightPageNumber page, MifareUltralightPage *data)
{ {
ASSERT_ACTIVE (tag); ASSERT_ACTIVE(tag);
ASSERT_VALID_PAGE (tag, page, false); ASSERT_VALID_PAGE(tag, page, false);
if (!MIFARE_ULTRALIGHT(tag)->cached_pages[page]) { if (!MIFARE_ULTRALIGHT(tag)->cached_pages[page]) {
BUFFER_INIT (cmd, 2); BUFFER_INIT(cmd, 2);
BUFFER_ALIAS (res, MIFARE_ULTRALIGHT(tag)->cache[page], sizeof(MifareUltralightPage) * 4); BUFFER_ALIAS(res, MIFARE_ULTRALIGHT(tag)->cache[page], sizeof(MifareUltralightPage) * 4);
BUFFER_APPEND (cmd, 0x30); BUFFER_APPEND(cmd, 0x30);
BUFFER_APPEND (cmd, page); BUFFER_APPEND(cmd, page);
ULTRALIGHT_TRANSCEIVE (tag, cmd, res); ULTRALIGHT_TRANSCEIVE(tag, cmd, res);
/* Handle wrapped pages */ /* Handle wrapped pages */
int iPageCount; int iPageCount;
if (is_mifare_ultralightc (tag)) { if (is_mifare_ultralightc(tag)) {
iPageCount = MIFARE_ULTRALIGHT_C_PAGE_COUNT_READ; iPageCount = MIFARE_ULTRALIGHT_C_PAGE_COUNT_READ;
} else { } else {
iPageCount = MIFARE_ULTRALIGHT_PAGE_COUNT; iPageCount = MIFARE_ULTRALIGHT_PAGE_COUNT;
} }
for (int i = iPageCount; i <= page + 3; i++) { for (int i = iPageCount; i <= page + 3; i++) {
memcpy (MIFARE_ULTRALIGHT(tag)->cache[i % iPageCount], MIFARE_ULTRALIGHT(tag)->cache[i], sizeof (MifareUltralightPage)); memcpy(MIFARE_ULTRALIGHT(tag)->cache[i % iPageCount], MIFARE_ULTRALIGHT(tag)->cache[i], sizeof(MifareUltralightPage));
} }
/* Mark pages as cached */ /* Mark pages as cached */
@ -254,7 +254,7 @@ mifare_ultralight_read (FreefareTag tag, MifareUltralightPageNumber page, Mifare
} }
} }
memcpy (data, MIFARE_ULTRALIGHT(tag)->cache[page], sizeof (*data)); memcpy(data, MIFARE_ULTRALIGHT(tag)->cache[page], sizeof(*data));
return 0; return 0;
} }
@ -262,19 +262,19 @@ mifare_ultralight_read (FreefareTag tag, MifareUltralightPageNumber page, Mifare
* Read data to the provided MIFARE tag. * Read data to the provided MIFARE tag.
*/ */
int int
mifare_ultralight_write (FreefareTag tag, const MifareUltralightPageNumber page, const MifareUltralightPage data) mifare_ultralight_write(FreefareTag tag, const MifareUltralightPageNumber page, const MifareUltralightPage data)
{ {
ASSERT_ACTIVE (tag); ASSERT_ACTIVE(tag);
ASSERT_VALID_PAGE (tag, page, true); ASSERT_VALID_PAGE(tag, page, true);
BUFFER_INIT (cmd, 6); BUFFER_INIT(cmd, 6);
BUFFER_INIT (res, 1); BUFFER_INIT(res, 1);
BUFFER_APPEND (cmd, 0xA2); BUFFER_APPEND(cmd, 0xA2);
BUFFER_APPEND (cmd, page); BUFFER_APPEND(cmd, page);
BUFFER_APPEND_BYTES (cmd, data, sizeof (MifareUltralightPage)); BUFFER_APPEND_BYTES(cmd, data, sizeof(MifareUltralightPage));
ULTRALIGHT_TRANSCEIVE (tag, cmd, res); ULTRALIGHT_TRANSCEIVE(tag, cmd, res);
/* Invalidate page in cache */ /* Invalidate page in cache */
MIFARE_ULTRALIGHT(tag)->cached_pages[page] = 0; MIFARE_ULTRALIGHT(tag)->cached_pages[page] = 0;
@ -286,62 +286,62 @@ mifare_ultralight_write (FreefareTag tag, const MifareUltralightPageNumber page,
* Authenticate to the provided MIFARE tag. * Authenticate to the provided MIFARE tag.
*/ */
int int
mifare_ultralightc_authenticate (FreefareTag tag, const MifareDESFireKey key) mifare_ultralightc_authenticate(FreefareTag tag, const MifareDESFireKey key)
{ {
ASSERT_ACTIVE (tag); ASSERT_ACTIVE(tag);
BUFFER_INIT (cmd1, 2); BUFFER_INIT(cmd1, 2);
BUFFER_INIT (res, 9); BUFFER_INIT(res, 9);
BUFFER_APPEND (cmd1, 0x1A); BUFFER_APPEND(cmd1, 0x1A);
BUFFER_APPEND (cmd1, 0x00); BUFFER_APPEND(cmd1, 0x00);
ULTRALIGHT_TRANSCEIVE_RAW(tag, cmd1, res); ULTRALIGHT_TRANSCEIVE_RAW(tag, cmd1, res);
uint8_t PICC_E_RndB[8]; uint8_t PICC_E_RndB[8];
memcpy (PICC_E_RndB, res+1, 8); memcpy(PICC_E_RndB, res + 1, 8);
uint8_t PICC_RndB[8]; uint8_t PICC_RndB[8];
memcpy (PICC_RndB, PICC_E_RndB, 8); memcpy(PICC_RndB, PICC_E_RndB, 8);
uint8_t ivect[8]; uint8_t ivect[8];
memset (ivect, '\0', sizeof (ivect)); memset(ivect, '\0', sizeof(ivect));
mifare_cypher_single_block (key, PICC_RndB, ivect, MCD_RECEIVE, MCO_DECYPHER, 8); mifare_cypher_single_block(key, PICC_RndB, ivect, MCD_RECEIVE, MCO_DECYPHER, 8);
uint8_t PCD_RndA[8]; uint8_t PCD_RndA[8];
DES_random_key ((DES_cblock*)&PCD_RndA); DES_random_key((DES_cblock *)&PCD_RndA);
uint8_t PCD_r_RndB[8]; uint8_t PCD_r_RndB[8];
memcpy (PCD_r_RndB, PICC_RndB, 8); memcpy(PCD_r_RndB, PICC_RndB, 8);
rol (PCD_r_RndB, 8); rol(PCD_r_RndB, 8);
uint8_t token[16]; uint8_t token[16];
memcpy (token, PCD_RndA, 8); memcpy(token, PCD_RndA, 8);
memcpy (token+8, PCD_r_RndB, 8); memcpy(token + 8, PCD_r_RndB, 8);
size_t offset = 0; size_t offset = 0;
while (offset < 16) { while (offset < 16) {
mifare_cypher_single_block (key, token + offset, ivect, MCD_SEND, MCO_ENCYPHER, 8); mifare_cypher_single_block(key, token + offset, ivect, MCD_SEND, MCO_ENCYPHER, 8);
offset += 8; offset += 8;
} }
BUFFER_INIT (cmd2, 17); BUFFER_INIT(cmd2, 17);
BUFFER_APPEND (cmd2, 0xAF); BUFFER_APPEND(cmd2, 0xAF);
BUFFER_APPEND_BYTES (cmd2, token, 16); BUFFER_APPEND_BYTES(cmd2, token, 16);
ULTRALIGHT_TRANSCEIVE_RAW(tag, cmd2, res); ULTRALIGHT_TRANSCEIVE_RAW(tag, cmd2, res);
uint8_t PICC_E_RndA_s[8]; uint8_t PICC_E_RndA_s[8];
memcpy (PICC_E_RndA_s, res+1, 8); memcpy(PICC_E_RndA_s, res + 1, 8);
uint8_t PICC_RndA_s[8]; uint8_t PICC_RndA_s[8];
memcpy (PICC_RndA_s, PICC_E_RndA_s, 8); memcpy(PICC_RndA_s, PICC_E_RndA_s, 8);
mifare_cypher_single_block (key, PICC_RndA_s, ivect, MCD_RECEIVE, MCO_DECYPHER, 8); mifare_cypher_single_block(key, PICC_RndA_s, ivect, MCD_RECEIVE, MCO_DECYPHER, 8);
uint8_t PCD_RndA_s[8]; uint8_t PCD_RndA_s[8];
memcpy (PCD_RndA_s, PCD_RndA, 8); memcpy(PCD_RndA_s, PCD_RndA, 8);
rol (PCD_RndA_s, 8); rol(PCD_RndA_s, 8);
if (0 != memcmp (PCD_RndA_s, PICC_RndA_s, 8)) { if (0 != memcmp(PCD_RndA_s, PICC_RndA_s, 8)) {
errno = EACCES; errno = EACCES;
return -1; return -1;
} }
@ -350,13 +350,13 @@ mifare_ultralightc_authenticate (FreefareTag tag, const MifareDESFireKey key)
} }
bool bool
is_mifare_ultralight (FreefareTag tag) is_mifare_ultralight(FreefareTag tag)
{ {
return tag->type == MIFARE_ULTRALIGHT; return tag->type == MIFARE_ULTRALIGHT;
} }
bool bool
is_mifare_ultralightc (FreefareTag tag) is_mifare_ultralightc(FreefareTag tag)
{ {
return tag->type == MIFARE_ULTRALIGHT_C; return tag->type == MIFARE_ULTRALIGHT_C;
} }
@ -365,7 +365,7 @@ is_mifare_ultralightc (FreefareTag tag)
* Callback for freefare_tag_new to test presence of a MIFARE UltralightC on the reader. * Callback for freefare_tag_new to test presence of a MIFARE UltralightC on the reader.
*/ */
bool bool
is_mifare_ultralightc_on_reader (nfc_device *device, nfc_iso14443a_info nai) is_mifare_ultralightc_on_reader(nfc_device *device, nfc_iso14443a_info nai)
{ {
int ret; int ret;
uint8_t cmd_step1[2]; uint8_t cmd_step1[2];
@ -378,10 +378,10 @@ is_mifare_ultralightc_on_reader (nfc_device *device, nfc_iso14443a_info nai)
.nmt = NMT_ISO14443A, .nmt = NMT_ISO14443A,
.nbr = NBR_106 .nbr = NBR_106
}; };
nfc_initiator_select_passive_target (device, modulation, nai.abtUid, nai.szUidLen, &pnti); nfc_initiator_select_passive_target(device, modulation, nai.abtUid, nai.szUidLen, &pnti);
nfc_device_set_property_bool (device, NP_EASY_FRAMING, false); nfc_device_set_property_bool(device, NP_EASY_FRAMING, false);
ret = nfc_initiator_transceive_bytes (device, cmd_step1, sizeof (cmd_step1), res_step1, sizeof(res_step1), 0); ret = nfc_initiator_transceive_bytes(device, cmd_step1, sizeof(cmd_step1), res_step1, sizeof(res_step1), 0);
nfc_device_set_property_bool (device, NP_EASY_FRAMING, true); nfc_device_set_property_bool(device, NP_EASY_FRAMING, true);
nfc_initiator_deselect_target (device); nfc_initiator_deselect_target(device);
return ret >= 0; return ret >= 0;
} }

View file

@ -50,63 +50,63 @@
#define NTAG_ASSERT_VALID_PAGE(tag, page, mode_write) \ #define NTAG_ASSERT_VALID_PAGE(tag, page, mode_write) \
do { \ do { \
if (mode_write) { \ if (mode_write) { \
if (page<=0x02) \ if (page<=0x02) \
{return errno = EINVAL, -1;} \ {return errno = EINVAL, -1;} \
else if(NTAG_21x(tag)->subtype == NTAG_213&&page>0x2C) \ else if(NTAG_21x(tag)->subtype == NTAG_213&&page>0x2C) \
{return errno = EINVAL, -1;} \ {return errno = EINVAL, -1;} \
else if(NTAG_21x(tag)->subtype == NTAG_215&&page>0x86) \ else if(NTAG_21x(tag)->subtype == NTAG_215&&page>0x86) \
{return errno = EINVAL, -1;} \ {return errno = EINVAL, -1;} \
else if(NTAG_21x(tag)->subtype == NTAG_216&&page>0xE6) \ else if(NTAG_21x(tag)->subtype == NTAG_216&&page>0xE6) \
{return errno = EINVAL, -1;} \ {return errno = EINVAL, -1;} \
} else { \ } else { \
if(NTAG_21x(tag)->subtype == NTAG_213&&page>0x2C) \ if(NTAG_21x(tag)->subtype == NTAG_213&&page>0x2C) \
{return errno = EINVAL, -1;} \ {return errno = EINVAL, -1;} \
else if(NTAG_21x(tag)->subtype == NTAG_215&&page>0x86) \ else if(NTAG_21x(tag)->subtype == NTAG_215&&page>0x86) \
{return errno = EINVAL, -1;} \ {return errno = EINVAL, -1;} \
else if(NTAG_21x(tag)->subtype == NTAG_216&&page>0xE6) \ else if(NTAG_21x(tag)->subtype == NTAG_216&&page>0xE6) \
{return errno = EINVAL, -1;} \ {return errno = EINVAL, -1;} \
} \ } \
} while (0) } while (0)
#define NTAG_TRANSCEIVE(tag, msg, res) \ #define NTAG_TRANSCEIVE(tag, msg, res) \
do { \ do { \
errno = 0; \ errno = 0; \
DEBUG_XFER (msg, __##msg##_n, "===> "); \ DEBUG_XFER (msg, __##msg##_n, "===> "); \
int _res; \ int _res; \
if ((_res = nfc_initiator_transceive_bytes (tag->device, msg, __##msg##_n, res, __##res##_size, 0)) < 0) { \ if ((_res = nfc_initiator_transceive_bytes (tag->device, msg, __##msg##_n, res, __##res##_size, 0)) < 0) { \
return errno = EIO, -1; \ return errno = EIO, -1; \
} \ } \
__##res##_n = _res; \ __##res##_n = _res; \
DEBUG_XFER (res, __##res##_n, "<=== "); \ DEBUG_XFER (res, __##res##_n, "<=== "); \
} while (0) } while (0)
#define NTAG_TRANSCEIVE_RAW(tag, msg, res) \ #define NTAG_TRANSCEIVE_RAW(tag, msg, res) \
do { \ do { \
errno = 0; \ errno = 0; \
if (nfc_device_set_property_bool (tag->device, NP_EASY_FRAMING, false) < 0) { \ if (nfc_device_set_property_bool (tag->device, NP_EASY_FRAMING, false) < 0) { \
errno = EIO; \ errno = EIO; \
return -1; \ return -1; \
} \ } \
DEBUG_XFER (msg, __##msg##_n, "===> "); \ DEBUG_XFER (msg, __##msg##_n, "===> "); \
int _res; \ int _res; \
if ((_res = nfc_initiator_transceive_bytes (tag->device, msg, __##msg##_n, res, __##res##_size, 0)) < 0) { \ if ((_res = nfc_initiator_transceive_bytes (tag->device, msg, __##msg##_n, res, __##res##_size, 0)) < 0) { \
nfc_device_set_property_bool (tag->device, NP_EASY_FRAMING, true); \ nfc_device_set_property_bool (tag->device, NP_EASY_FRAMING, true); \
return errno = EIO, -1; \ return errno = EIO, -1; \
} \ } \
__##res##_n = _res; \ __##res##_n = _res; \
DEBUG_XFER (res, __##res##_n, "<=== "); \ DEBUG_XFER (res, __##res##_n, "<=== "); \
if (nfc_device_set_property_bool (tag->device, NP_EASY_FRAMING, true) < 0) { \ if (nfc_device_set_property_bool (tag->device, NP_EASY_FRAMING, true) < 0) { \
errno = EIO; \ errno = EIO; \
return -1; \ return -1; \
} \ } \
} while (0) } while (0)
bool bool
ntag21x_taste(nfc_device *device, nfc_target target) ntag21x_taste(nfc_device *device, nfc_target target)
{ {
return target.nm.nmt == NMT_ISO14443A && target.nti.nai.btSak == 0x00 && ntag21x_is_auth_supported (device, target.nti.nai); return target.nm.nmt == NMT_ISO14443A && target.nti.nai.btSak == 0x00 && ntag21x_is_auth_supported(device, target.nti.nai);
} }
@ -122,7 +122,7 @@ _ntag21x_tag_new(nfc_device *device, nfc_target target)
{ {
FreefareTag tag; FreefareTag tag;
if ((tag = malloc (sizeof (struct ntag21x_tag)))) { if ((tag = malloc(sizeof(struct ntag21x_tag)))) {
tag->type = NTAG_21x ; tag->type = NTAG_21x ;
tag->free_tag = ntag21x_tag_free; tag->free_tag = ntag21x_tag_free;
tag->device = device; tag->device = device;
@ -146,7 +146,7 @@ _ntag21x_tag_reuse(FreefareTag old_tag)
{ {
FreefareTag tag; FreefareTag tag;
if ((tag = malloc (sizeof (struct ntag21x_tag)))) { if ((tag = malloc(sizeof(struct ntag21x_tag)))) {
tag->type = NTAG_21x ; tag->type = NTAG_21x ;
tag->free_tag = ntag21x_tag_free; tag->free_tag = ntag21x_tag_free;
tag->device = old_tag->device; tag->device = old_tag->device;
@ -168,25 +168,25 @@ _ntag21x_tag_reuse(FreefareTag old_tag)
FreefareTag FreefareTag
ntag21x_tag_new(nfc_device *device, nfc_target target) ntag21x_tag_new(nfc_device *device, nfc_target target)
{ {
return _ntag21x_tag_new (device, target); return _ntag21x_tag_new(device, target);
} }
FreefareTag FreefareTag
ntag21x_tag_reuse(FreefareTag tag) ntag21x_tag_reuse(FreefareTag tag)
{ {
return _ntag21x_tag_reuse (tag); return _ntag21x_tag_reuse(tag);
} }
/* /*
* Create new key for NTAG * Create new key for NTAG
*/ */
NTAG21xKey NTAG21xKey
ntag21x_key_new(const uint8_t data[4],const uint8_t pack[2]) ntag21x_key_new(const uint8_t data[4], const uint8_t pack[2])
{ {
NTAG21xKey key; NTAG21xKey key;
if ((key = malloc (sizeof (struct ntag21x_key)))) { if ((key = malloc(sizeof(struct ntag21x_key)))) {
memcpy(key->data,data,4); memcpy(key->data, data, 4);
memcpy(key->pack,pack,2); memcpy(key->pack, pack, 2);
} }
return key; return key;
} }
@ -206,7 +206,7 @@ ntag21x_key_free(NTAG21xKey key)
void void
ntag21x_tag_free(FreefareTag tag) ntag21x_tag_free(FreefareTag tag)
{ {
free (tag); free(tag);
} }
@ -226,14 +226,14 @@ ntag21x_tag_free(FreefareTag tag)
int int
ntag21x_connect(FreefareTag tag) ntag21x_connect(FreefareTag tag)
{ {
ASSERT_INACTIVE (tag); ASSERT_INACTIVE(tag);
nfc_target pnti; nfc_target pnti;
nfc_modulation modulation = { nfc_modulation modulation = {
.nmt = NMT_ISO14443A, .nmt = NMT_ISO14443A,
.nbr = NBR_106 .nbr = NBR_106
}; };
if (nfc_initiator_select_passive_target (tag->device, modulation, tag->info.nti.nai.abtUid, tag->info.nti.nai.szUidLen, &pnti) >= 0) { if (nfc_initiator_select_passive_target(tag->device, modulation, tag->info.nti.nai.abtUid, tag->info.nti.nai.szUidLen, &pnti) >= 0) {
tag->active = 1; tag->active = 1;
} else { } else {
@ -249,9 +249,9 @@ ntag21x_connect(FreefareTag tag)
int int
ntag21x_disconnect(FreefareTag tag) ntag21x_disconnect(FreefareTag tag)
{ {
ASSERT_ACTIVE (tag); ASSERT_ACTIVE(tag);
if (nfc_initiator_deselect_target (tag->device) >= 0) { if (nfc_initiator_deselect_target(tag->device) >= 0) {
tag->active = 0; tag->active = 0;
} else { } else {
errno = EIO; errno = EIO;
@ -266,16 +266,16 @@ ntag21x_disconnect(FreefareTag tag)
int int
ntag21x_get_info(FreefareTag tag) ntag21x_get_info(FreefareTag tag)
{ {
ASSERT_ACTIVE (tag); ASSERT_ACTIVE(tag);
// Init buffers // Init buffers
BUFFER_INIT (cmd, 1); BUFFER_INIT(cmd, 1);
BUFFER_INIT (res,8); BUFFER_INIT(res, 8);
// Append get version command to buffer // Append get version command to buffer
BUFFER_APPEND (cmd, 0x60); BUFFER_APPEND(cmd, 0x60);
NTAG_TRANSCEIVE_RAW (tag, cmd, res); // Send & receive to & from tag NTAG_TRANSCEIVE_RAW(tag, cmd, res); // Send & receive to & from tag
NTAG_21x(tag)->vendor_id = res[1]; NTAG_21x(tag)->vendor_id = res[1];
NTAG_21x(tag)->product_type = res[2]; NTAG_21x(tag)->product_type = res[2];
@ -286,7 +286,7 @@ ntag21x_get_info(FreefareTag tag)
NTAG_21x(tag)->protocol_type = res[7]; NTAG_21x(tag)->protocol_type = res[7];
// Set ntag subtype based on storage size // Set ntag subtype based on storage size
switch(NTAG_21x(tag)->storage_size) { switch (NTAG_21x(tag)->storage_size) {
case 0x0f: case 0x0f:
NTAG_21x(tag)->subtype = NTAG_213; NTAG_21x(tag)->subtype = NTAG_213;
break; break;
@ -306,8 +306,7 @@ ntag21x_get_info(FreefareTag tag)
* Get subtype of tag * Get subtype of tag
*/ */
enum ntag_tag_subtype enum ntag_tag_subtype
ntag21x_get_subtype(FreefareTag tag) ntag21x_get_subtype(FreefareTag tag) {
{
return NTAG_21x(tag)->subtype; return NTAG_21x(tag)->subtype;
} }
@ -333,21 +332,21 @@ ntag21x_get_last_page(FreefareTag tag)
* Read signature * Read signature
*/ */
int int
ntag21x_read_signature(FreefareTag tag,uint8_t *data) ntag21x_read_signature(FreefareTag tag, uint8_t *data)
{ {
ASSERT_ACTIVE (tag); ASSERT_ACTIVE(tag);
// Init buffers // Init buffers
BUFFER_INIT (cmd, 2); BUFFER_INIT(cmd, 2);
BUFFER_INIT (res,32); BUFFER_INIT(res, 32);
// Append get version command to buffer // Append get version command to buffer
BUFFER_APPEND (cmd, 0x3C); BUFFER_APPEND(cmd, 0x3C);
BUFFER_APPEND (cmd, 0x00); BUFFER_APPEND(cmd, 0x00);
NTAG_TRANSCEIVE_RAW (tag, cmd, res); // Send & receive to & from tag NTAG_TRANSCEIVE_RAW(tag, cmd, res); // Send & receive to & from tag
memcpy(data,res,32); // Copy response to data output memcpy(data, res, 32); // Copy response to data output
return 0; return 0;
} }
@ -365,147 +364,147 @@ int
ntag21x_set_pwd(FreefareTag tag, uint8_t data[4]) // Set password ntag21x_set_pwd(FreefareTag tag, uint8_t data[4]) // Set password
{ {
uint8_t page = ntag21x_get_last_page(tag) - 1; // PWD page is located 1 before last page uint8_t page = ntag21x_get_last_page(tag) - 1; // PWD page is located 1 before last page
int res = ntag21x_write(tag,page,data); int res = ntag21x_write(tag, page, data);
return res; return res;
} }
int int
ntag21x_set_pack(FreefareTag tag, uint8_t data[2]) // Set pack ntag21x_set_pack(FreefareTag tag, uint8_t data[2]) // Set pack
{ {
BUFFER_INIT(buff,4); BUFFER_INIT(buff, 4);
BUFFER_APPEND_BYTES(buff,data,2); BUFFER_APPEND_BYTES(buff, data, 2);
BUFFER_APPEND(buff,0x00); BUFFER_APPEND(buff, 0x00);
BUFFER_APPEND(buff,0x00); BUFFER_APPEND(buff, 0x00);
uint8_t page = ntag21x_get_last_page(tag); // PACK page is located on last page uint8_t page = ntag21x_get_last_page(tag); // PACK page is located on last page
int res = ntag21x_write(tag,page,buff); int res = ntag21x_write(tag, page, buff);
return res; return res;
} }
int int
ntag21x_set_key(FreefareTag tag,const NTAG21xKey key) // Set key ntag21x_set_key(FreefareTag tag, const NTAG21xKey key) // Set key
{ {
int res; int res;
// Set password // Set password
res = ntag21x_set_pwd(tag,key->data); res = ntag21x_set_pwd(tag, key->data);
if(res < 0) if (res < 0)
return res; return res;
// Set pack // Set pack
res = ntag21x_set_pack(tag,key->pack); res = ntag21x_set_pack(tag, key->pack);
return res; return res;
} }
int int
ntag21x_set_auth(FreefareTag tag,uint8_t byte) // Set AUTH0 byte (from which page starts password protection) ntag21x_set_auth(FreefareTag tag, uint8_t byte) // Set AUTH0 byte (from which page starts password protection)
{ {
BUFFER_INIT(cdata,4); BUFFER_INIT(cdata, 4);
int page = ntag21x_get_last_page(tag) - 3; // AUTH0 byte is on 4th page from back int page = ntag21x_get_last_page(tag) - 3; // AUTH0 byte is on 4th page from back
int res; int res;
res = ntag21x_read4(tag,page,cdata); // Read current configuration from tag res = ntag21x_read4(tag, page, cdata); // Read current configuration from tag
if(res < 0) if (res < 0)
return res; return res;
cdata[3] = byte; // Set AUTH0 byte in buffer cdata[3] = byte; // Set AUTH0 byte in buffer
res = ntag21x_write(tag,page,cdata); // Write new configuration to tag res = ntag21x_write(tag, page, cdata); // Write new configuration to tag
return res; return res;
} }
int int
ntag21x_get_auth(FreefareTag tag,uint8_t *byte) // Get AUTH0 byte ntag21x_get_auth(FreefareTag tag, uint8_t *byte) // Get AUTH0 byte
{ {
BUFFER_INIT(cdata,4); BUFFER_INIT(cdata, 4);
int page = ntag21x_get_last_page(tag) - 3; // AUTH0 byte is on 4th page from back int page = ntag21x_get_last_page(tag) - 3; // AUTH0 byte is on 4th page from back
int res; int res;
res = ntag21x_read4(tag,page,cdata); // Read current configuration from tag res = ntag21x_read4(tag, page, cdata); // Read current configuration from tag
if(res < 0) if (res < 0)
return res; return res;
*byte = cdata[3]; // Get AUTH0 byte in buffer *byte = cdata[3]; // Get AUTH0 byte in buffer
return res; return res;
} }
int int
ntag21x_access_enable(FreefareTag tag,uint8_t byte) // Enable access feature in ACCESS byte ntag21x_access_enable(FreefareTag tag, uint8_t byte) // Enable access feature in ACCESS byte
{ {
BUFFER_INIT(cdata,4); BUFFER_INIT(cdata, 4);
int page = ntag21x_get_last_page(tag) - 2; // ACCESS byte is on 3th page from back int page = ntag21x_get_last_page(tag) - 2; // ACCESS byte is on 3th page from back
int res; int res;
res = ntag21x_read4(tag,page,cdata); // Read current configuration from tag res = ntag21x_read4(tag, page, cdata); // Read current configuration from tag
if(res < 0) if (res < 0)
return res; return res;
cdata[0] |= byte; // Set bit to 1 in ACCESS byte cdata[0] |= byte; // Set bit to 1 in ACCESS byte
res = ntag21x_write(tag,page,cdata); // Write new configuration to tag res = ntag21x_write(tag, page, cdata); // Write new configuration to tag
return res; return res;
} }
int int
ntag21x_access_disable(FreefareTag tag,uint8_t byte) // Disable access feature in ACCESS byte ntag21x_access_disable(FreefareTag tag, uint8_t byte) // Disable access feature in ACCESS byte
{ {
BUFFER_INIT(cdata,4); BUFFER_INIT(cdata, 4);
int page = ntag21x_get_last_page(tag) - 2; // ACCESS byte is on 3th page from back int page = ntag21x_get_last_page(tag) - 2; // ACCESS byte is on 3th page from back
int res; int res;
res = ntag21x_read4(tag,page,cdata); // Read current configuration from tag res = ntag21x_read4(tag, page, cdata); // Read current configuration from tag
if(res < 0) if (res < 0)
return res; return res;
cdata[0] &= ~byte; // Set bit to 0 in ACCESS byte cdata[0] &= ~byte; // Set bit to 0 in ACCESS byte
res = ntag21x_write(tag,page,cdata); // Write new configuration to tag res = ntag21x_write(tag, page, cdata); // Write new configuration to tag
return res; return res;
} }
int int
ntag21x_get_access(FreefareTag tag,uint8_t *byte) // Get ACCESS byte ntag21x_get_access(FreefareTag tag, uint8_t *byte) // Get ACCESS byte
{ {
BUFFER_INIT(cdata,4); BUFFER_INIT(cdata, 4);
uint8_t page = ntag21x_get_last_page(tag) - 2; // ACCESS byte is on 3th page from back uint8_t page = ntag21x_get_last_page(tag) - 2; // ACCESS byte is on 3th page from back
int res; int res;
res = ntag21x_read4(tag,page,cdata); // Read current configuration from tag res = ntag21x_read4(tag, page, cdata); // Read current configuration from tag
if(res < 0) if (res < 0)
return res; return res;
memcpy(byte,cdata,1); // Return 1 byte of page memcpy(byte, cdata, 1); // Return 1 byte of page
return res; return res;
} }
int int
ntag21x_check_access(FreefareTag tag,uint8_t byte,bool *result) // Check if access feature is enabled ntag21x_check_access(FreefareTag tag, uint8_t byte, bool *result) // Check if access feature is enabled
{ {
BUFFER_INIT(buff,1); BUFFER_INIT(buff, 1);
int res; int res;
res = ntag21x_get_access(tag,buff); res = ntag21x_get_access(tag, buff);
if(res<0) if (res < 0)
return res; // Return error if can't get access byte return res; // Return error if can't get access byte
*result = (buff[0]&byte)>0; // Set result, check if bit is 1 in access byte *result = (buff[0] & byte) > 0; // Set result, check if bit is 1 in access byte
return res; return res;
} }
int int
ntag21x_get_authentication_limit(FreefareTag tag,uint8_t *byte) // Get authentication limit ntag21x_get_authentication_limit(FreefareTag tag, uint8_t *byte) // Get authentication limit
{ {
BUFFER_INIT(cdata,4); BUFFER_INIT(cdata, 4);
uint8_t page = ntag21x_get_last_page(tag) - 2; // ACCESS byte is on 3th page from back uint8_t page = ntag21x_get_last_page(tag) - 2; // ACCESS byte is on 3th page from back
int res; int res;
res = ntag21x_read4(tag,page,cdata); // Read current configuration from tag res = ntag21x_read4(tag, page, cdata); // Read current configuration from tag
if(res < 0) if (res < 0)
return res; return res;
cdata[0]&=0x07; // Extract last 3 bits from access byte cdata[0] &= 0x07; // Extract last 3 bits from access byte
memcpy(byte,cdata,1); // Return 1 byte of page memcpy(byte, cdata, 1); // Return 1 byte of page
return res; return res;
} }
int int
ntag21x_set_authentication_limit(FreefareTag tag,uint8_t byte) // Set authentication limit (0x00 = disabled, [0x01,0x07] = valid range, > 0x07 invalid range) ntag21x_set_authentication_limit(FreefareTag tag, uint8_t byte) // Set authentication limit (0x00 = disabled, [0x01,0x07] = valid range, > 0x07 invalid range)
{ {
if(byte > 7) // Check for invalid range of auth limit if (byte > 7) // Check for invalid range of auth limit
return -1; return -1;
BUFFER_INIT(cdata,4); BUFFER_INIT(cdata, 4);
int page = ntag21x_get_last_page(tag) - 2; // ACCESS byte is on 3th page from back int page = ntag21x_get_last_page(tag) - 2; // ACCESS byte is on 3th page from back
int res; int res;
res = ntag21x_read4(tag,page,cdata); // Read current configuration from tag res = ntag21x_read4(tag, page, cdata); // Read current configuration from tag
if(res < 0) if (res < 0)
return res; return res;
cdata[0] &= 0xf8; // Reset auth limit bits cdata[0] &= 0xf8; // Reset auth limit bits
cdata[0] |= byte; // Set aut limit cdata[0] |= byte; // Set aut limit
res = ntag21x_write(tag,page,cdata); // Write new configuration to tag res = ntag21x_write(tag, page, cdata); // Write new configuration to tag
return res; return res;
} }
@ -513,21 +512,21 @@ ntag21x_set_authentication_limit(FreefareTag tag,uint8_t byte) // Set authentica
* Read 16 bytes from NTAG. * Read 16 bytes from NTAG.
*/ */
int int
ntag21x_read(FreefareTag tag, uint8_t page,uint8_t *data) ntag21x_read(FreefareTag tag, uint8_t page, uint8_t *data)
{ {
ASSERT_ACTIVE (tag); ASSERT_ACTIVE(tag);
NTAG_ASSERT_VALID_PAGE (tag, page, false); NTAG_ASSERT_VALID_PAGE(tag, page, false);
// Init buffers // Init buffers
BUFFER_INIT (cmd, 2); BUFFER_INIT(cmd, 2);
BUFFER_INIT (res,16); BUFFER_INIT(res, 16);
// Append read 16B command to buffer // Append read 16B command to buffer
BUFFER_APPEND (cmd, 0x30); BUFFER_APPEND(cmd, 0x30);
BUFFER_APPEND (cmd, page); BUFFER_APPEND(cmd, page);
NTAG_TRANSCEIVE (tag, cmd, res); // Send & receive to & from tag NTAG_TRANSCEIVE(tag, cmd, res); // Send & receive to & from tag
memcpy (data, res, 16); // Copy first 4 bytes (selected page) to data output memcpy(data, res, 16); // Copy first 4 bytes (selected page) to data output
return 0; return 0;
} }
@ -535,11 +534,11 @@ ntag21x_read(FreefareTag tag, uint8_t page,uint8_t *data)
* Read 4 bytes from NTAG * Read 4 bytes from NTAG
*/ */
int int
ntag21x_read4(FreefareTag tag,uint8_t page,uint8_t *data) ntag21x_read4(FreefareTag tag, uint8_t page, uint8_t *data)
{ {
BUFFER_INIT (res,16); BUFFER_INIT(res, 16);
int re = ntag21x_read(tag,page,res); int re = ntag21x_read(tag, page, res);
memcpy(data,res,4); memcpy(data, res, 4);
return re; return re;
} }
@ -547,33 +546,33 @@ ntag21x_read4(FreefareTag tag,uint8_t page,uint8_t *data)
* Read pages from [start,end] from NTAG * Read pages from [start,end] from NTAG
*/ */
int int
ntag21x_fast_read(FreefareTag tag, uint8_t start_page,uint8_t end_page, uint8_t *data) ntag21x_fast_read(FreefareTag tag, uint8_t start_page, uint8_t end_page, uint8_t *data)
{ {
ASSERT_ACTIVE (tag); ASSERT_ACTIVE(tag);
NTAG_ASSERT_VALID_PAGE (tag, start_page, false); NTAG_ASSERT_VALID_PAGE(tag, start_page, false);
NTAG_ASSERT_VALID_PAGE (tag, end_page, false); NTAG_ASSERT_VALID_PAGE(tag, end_page, false);
// Init buffers // Init buffers
BUFFER_INIT (cmd, 3); BUFFER_INIT(cmd, 3);
BUFFER_INIT (res,4*(end_page - start_page + 1)); BUFFER_INIT(res, 4 * (end_page - start_page + 1));
// Append read 16B command to buffer // Append read 16B command to buffer
BUFFER_APPEND (cmd, 0x3A); BUFFER_APPEND(cmd, 0x3A);
BUFFER_APPEND (cmd, start_page); BUFFER_APPEND(cmd, start_page);
BUFFER_APPEND (cmd, end_page); BUFFER_APPEND(cmd, end_page);
NTAG_TRANSCEIVE_RAW (tag, cmd, res); // Send & receive to & from tag NTAG_TRANSCEIVE_RAW(tag, cmd, res); // Send & receive to & from tag
memcpy (data, res, 4*(end_page - start_page + 1)); // Copy first 4 bytes (selected page) to data output memcpy(data, res, 4 * (end_page - start_page + 1)); // Copy first 4 bytes (selected page) to data output
return 0; return 0;
} }
int int
ntag21x_fast_read4(FreefareTag tag,uint8_t page,uint8_t *data) ntag21x_fast_read4(FreefareTag tag, uint8_t page, uint8_t *data)
{ {
BUFFER_INIT (res,4); BUFFER_INIT(res, 4);
int re = ntag21x_fast_read(tag,page,page,res); int re = ntag21x_fast_read(tag, page, page, res);
memcpy(data,res,4); memcpy(data, res, 4);
return re; return re;
} }
@ -583,19 +582,19 @@ ntag21x_fast_read4(FreefareTag tag,uint8_t page,uint8_t *data)
int int
ntag21x_read_cnt(FreefareTag tag, uint8_t *data) ntag21x_read_cnt(FreefareTag tag, uint8_t *data)
{ {
ASSERT_ACTIVE (tag); ASSERT_ACTIVE(tag);
// Init buffers // Init buffers
BUFFER_INIT (cmd, 2); BUFFER_INIT(cmd, 2);
BUFFER_INIT (res,3); BUFFER_INIT(res, 3);
// Append read cnt command to buffer // Append read cnt command to buffer
BUFFER_APPEND (cmd, 0x39); BUFFER_APPEND(cmd, 0x39);
BUFFER_APPEND (cmd, 0x02); BUFFER_APPEND(cmd, 0x02);
NTAG_TRANSCEIVE_RAW (tag, cmd, res); // Send & receive to & from tag NTAG_TRANSCEIVE_RAW(tag, cmd, res); // Send & receive to & from tag
memcpy (data, res, 3); // Copy first 3 bytes (selected page) to data output memcpy(data, res, 3); // Copy first 3 bytes (selected page) to data output
return 0; return 0;
} }
@ -605,19 +604,19 @@ ntag21x_read_cnt(FreefareTag tag, uint8_t *data)
int int
ntag21x_write(FreefareTag tag, uint8_t page, uint8_t data[4]) ntag21x_write(FreefareTag tag, uint8_t page, uint8_t data[4])
{ {
ASSERT_ACTIVE (tag); ASSERT_ACTIVE(tag);
NTAG_ASSERT_VALID_PAGE (tag, page, true); NTAG_ASSERT_VALID_PAGE(tag, page, true);
// Init buffera // Init buffera
BUFFER_INIT (cmd, 6); BUFFER_INIT(cmd, 6);
BUFFER_INIT (res, 1); BUFFER_INIT(res, 1);
// Append write 4B command to buffer // Append write 4B command to buffer
BUFFER_APPEND (cmd, 0xA2); BUFFER_APPEND(cmd, 0xA2);
BUFFER_APPEND (cmd, page); BUFFER_APPEND(cmd, page);
BUFFER_APPEND_BYTES (cmd, data, 4); // Copy data to last 4 bytes of buffer BUFFER_APPEND_BYTES(cmd, data, 4); // Copy data to last 4 bytes of buffer
NTAG_TRANSCEIVE (tag, cmd, res); NTAG_TRANSCEIVE(tag, cmd, res);
return 0; return 0;
} }
@ -625,22 +624,22 @@ ntag21x_write(FreefareTag tag, uint8_t page, uint8_t data[4])
int int
ntag21x_compatibility_write(FreefareTag tag, uint8_t page, uint8_t data[4]) ntag21x_compatibility_write(FreefareTag tag, uint8_t page, uint8_t data[4])
{ {
ASSERT_ACTIVE (tag); ASSERT_ACTIVE(tag);
NTAG_ASSERT_VALID_PAGE (tag, page, true); NTAG_ASSERT_VALID_PAGE(tag, page, true);
// Init buffera // Init buffera
BUFFER_INIT (cmd, 18); BUFFER_INIT(cmd, 18);
BUFFER_INIT (res, 1); BUFFER_INIT(res, 1);
// Append write 4B command to buffer // Append write 4B command to buffer
BUFFER_APPEND (cmd, 0xA0); BUFFER_APPEND(cmd, 0xA0);
BUFFER_APPEND (cmd, page); BUFFER_APPEND(cmd, page);
BUFFER_APPEND_BYTES (cmd, data, 4); // Copy data to last 4 bytes of buffer BUFFER_APPEND_BYTES(cmd, data, 4); // Copy data to last 4 bytes of buffer
for (int i=0;i<12;i++) { for (int i = 0; i < 12; i++) {
BUFFER_APPEND(cmd,0x00); BUFFER_APPEND(cmd, 0x00);
} }
NTAG_TRANSCEIVE (tag, cmd, res); NTAG_TRANSCEIVE(tag, cmd, res);
return 0; return 0;
} }
@ -650,22 +649,22 @@ ntag21x_compatibility_write(FreefareTag tag, uint8_t page, uint8_t data[4])
int int
ntag21x_authenticate(FreefareTag tag, const NTAG21xKey key) ntag21x_authenticate(FreefareTag tag, const NTAG21xKey key)
{ {
ASSERT_ACTIVE (tag); ASSERT_ACTIVE(tag);
BUFFER_INIT (cmd1, 5); BUFFER_INIT(cmd1, 5);
BUFFER_INIT (res, 2); BUFFER_INIT(res, 2);
BUFFER_APPEND (cmd1, 0x1B); BUFFER_APPEND(cmd1, 0x1B);
BUFFER_APPEND_BYTES (cmd1, key->data,4); // Append key to command BUFFER_APPEND_BYTES(cmd1, key->data, 4); // Append key to command
NTAG_TRANSCEIVE_RAW(tag, cmd1, res); NTAG_TRANSCEIVE_RAW(tag, cmd1, res);
//Check if authenticated (PACK must be as expected) //Check if authenticated (PACK must be as expected)
bool flag_auth = true; bool flag_auth = true;
for(int i=0;i<2;i++) for (int i = 0; i < 2; i++)
if (res[i] != key->pack[i]) { if (res[i] != key->pack[i]) {
flag_auth = false; flag_auth = false;
break; break;
} }
if(!flag_auth) if (!flag_auth)
return -1; return -1;
// XXX Should we store the state "authenticated" in the tag struct?? // XXX Should we store the state "authenticated" in the tag struct??
return 0; return 0;
@ -696,7 +695,7 @@ ntag21x_is_auth_supported(nfc_device *device, nfc_iso14443a_info nai)
}; };
nfc_initiator_select_passive_target(device, modulation, nai.abtUid, nai.szUidLen, &pnti); nfc_initiator_select_passive_target(device, modulation, nai.abtUid, nai.szUidLen, &pnti);
nfc_device_set_property_bool(device, NP_EASY_FRAMING, false); nfc_device_set_property_bool(device, NP_EASY_FRAMING, false);
ret = nfc_initiator_transceive_bytes(device, cmd_step1, sizeof (cmd_step1), res_step1, sizeof(res_step1), 0); ret = nfc_initiator_transceive_bytes(device, cmd_step1, sizeof(cmd_step1), res_step1, sizeof(res_step1), 0);
nfc_device_set_property_bool(device, NP_EASY_FRAMING, true); nfc_device_set_property_bool(device, NP_EASY_FRAMING, true);
nfc_initiator_deselect_target(device); nfc_initiator_deselect_target(device);
return ret >= 0; return ret >= 0;

View file

@ -57,9 +57,9 @@
#define TLV_TERMINATOR 0xFE #define TLV_TERMINATOR 0xFE
size_t tlv_record_length (const uint8_t *stream, size_t *field_length_size, size_t *field_value_size); size_t tlv_record_length(const uint8_t *stream, size_t *field_length_size, size_t *field_value_size);
uint8_t *tlv_next (uint8_t *stream); uint8_t *tlv_next(uint8_t *stream);
size_t tlv_sequence_length (uint8_t *stream); size_t tlv_sequence_length(uint8_t *stream);
/* /*
* TLV (Type Length Value) Manipulation Functions. * TLV (Type Length Value) Manipulation Functions.
@ -69,7 +69,7 @@ size_t tlv_sequence_length (uint8_t *stream);
* Encode data stream into TLV. * Encode data stream into TLV.
*/ */
uint8_t * uint8_t *
tlv_encode (const uint8_t type, const uint8_t *istream, uint16_t isize, size_t *osize) tlv_encode(const uint8_t type, const uint8_t *istream, uint16_t isize, size_t *osize)
{ {
uint8_t *res; uint8_t *res;
off_t n = 0; off_t n = 0;
@ -80,20 +80,20 @@ tlv_encode (const uint8_t type, const uint8_t *istream, uint16_t isize, size_t *
if (isize == 0xffff) /* RFU */ if (isize == 0xffff) /* RFU */
return NULL; return NULL;
if ((res = malloc (1 + ((isize > 254) ? 3 : 1) + isize + 1))) { if ((res = malloc(1 + ((isize > 254) ? 3 : 1) + isize + 1))) {
/* type + size + payload + terminator */ /* type + size + payload + terminator */
res[n++] = type; res[n++] = type;
if (isize > 254) { if (isize > 254) {
res[n++] = 0xff; res[n++] = 0xff;
uint16_t size_be = htobe16 (isize); uint16_t size_be = htobe16(isize);
memcpy (res + n, &size_be, sizeof (uint16_t)); memcpy(res + n, &size_be, sizeof(uint16_t));
n += 2; n += 2;
} else { } else {
res[n++] = (uint8_t)isize; res[n++] = (uint8_t)isize;
} }
memcpy (res + n, istream, isize); memcpy(res + n, istream, isize);
n += isize; n += isize;
res[n++] = TLV_TERMINATOR; res[n++] = TLV_TERMINATOR;
@ -108,7 +108,7 @@ tlv_encode (const uint8_t type, const uint8_t *istream, uint16_t isize, size_t *
* Decode TLV from data stream. * Decode TLV from data stream.
*/ */
uint8_t * uint8_t *
tlv_decode (const uint8_t *istream, uint8_t *type, uint16_t *size) tlv_decode(const uint8_t *istream, uint8_t *type, uint16_t *size)
{ {
size_t fls = 0; size_t fls = 0;
size_t fvs = 0; size_t fvs = 0;
@ -117,14 +117,14 @@ tlv_decode (const uint8_t *istream, uint8_t *type, uint16_t *size)
if (type) if (type)
*type = istream[0]; *type = istream[0];
tlv_record_length (istream, &fls, &fvs); tlv_record_length(istream, &fls, &fvs);
if (size) { if (size) {
*size = fvs; *size = fvs;
} }
if ((res = malloc (fvs))) { if ((res = malloc(fvs))) {
memcpy (res, istream + 1 + fls, fvs); memcpy(res, istream + 1 + fls, fvs);
} }
return res; return res;
} }
@ -133,7 +133,7 @@ tlv_decode (const uint8_t *istream, uint8_t *type, uint16_t *size)
* Length of a TLV field * Length of a TLV field
*/ */
size_t size_t
tlv_record_length (const uint8_t *stream, size_t *field_length_size, size_t *field_value_size) tlv_record_length(const uint8_t *stream, size_t *field_length_size, size_t *field_value_size)
{ {
size_t fls = 0; size_t fls = 0;
size_t fvs = 0; size_t fvs = 0;
@ -148,7 +148,7 @@ tlv_record_length (const uint8_t *stream, size_t *field_length_size, size_t *fie
default: // FIXME Not supported. default: // FIXME Not supported.
if (stream[1] == 0xff) { if (stream[1] == 0xff) {
uint16_t be_size; uint16_t be_size;
memcpy (&be_size, stream + 2, sizeof (uint16_t)); memcpy(&be_size, stream + 2, sizeof(uint16_t));
fls = 3; fls = 3;
fvs = be16toh(be_size); fvs = be16toh(be_size);
} else { } else {
@ -176,11 +176,11 @@ tlv_record_length (const uint8_t *stream, size_t *field_length_size, size_t *fie
* Fourth call NULL * Fourth call NULL
*/ */
uint8_t * uint8_t *
tlv_next (uint8_t *stream) tlv_next(uint8_t *stream)
{ {
uint8_t *res = NULL; uint8_t *res = NULL;
if (stream[0] != TLV_TERMINATOR) if (stream[0] != TLV_TERMINATOR)
res = stream + tlv_record_length (stream, NULL, NULL); res = stream + tlv_record_length(stream, NULL, NULL);
return res; return res;
} }
@ -189,13 +189,13 @@ tlv_next (uint8_t *stream)
* Full-length of all TLV fields. * Full-length of all TLV fields.
*/ */
size_t size_t
tlv_sequence_length (uint8_t *stream) tlv_sequence_length(uint8_t *stream)
{ {
size_t res = 0; size_t res = 0;
do { do {
res += tlv_record_length (stream, NULL, NULL); res += tlv_record_length(stream, NULL, NULL);
} while ((stream = tlv_next (stream))); } while ((stream = tlv_next(stream)));
return res; return res;
} }
@ -205,14 +205,14 @@ tlv_sequence_length (uint8_t *stream)
* Append two TLV. Acts like realloc(3). * Append two TLV. Acts like realloc(3).
*/ */
uint8_t * uint8_t *
tlv_append (uint8_t *a, uint8_t *b) tlv_append(uint8_t *a, uint8_t *b)
{ {
size_t a_size = tlv_sequence_length (a); size_t a_size = tlv_sequence_length(a);
size_t b_size = tlv_sequence_length (b); size_t b_size = tlv_sequence_length(b);
size_t new_size = a_size + b_size - 1; size_t new_size = a_size + b_size - 1;
if ((a = realloc (a, new_size))) { if ((a = realloc(a, new_size))) {
memcpy (a + a_size - 1, b, b_size); memcpy(a + a_size - 1, b, b_size);
} }
return a; return a;

View file

@ -26,57 +26,58 @@ uint8_t key_data_des[8] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H' };
uint8_t key_data_3des[16] = { 'C', 'a', 'r', 'd', ' ', 'M', 'a', 's', 't', 'e', 'r', ' ', 'K', 'e', 'y', '!' }; uint8_t key_data_3des[16] = { 'C', 'a', 'r', 'd', ' ', 'M', 'a', 's', 't', 'e', 'r', ' ', 'K', 'e', 'y', '!' };
uint8_t key_data_aes[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; uint8_t key_data_aes[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
uint8_t key_data_3k3des[24] = { 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, uint8_t key_data_3k3des[24] = { 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
const uint8_t key_data_aes_version = 0x42; const uint8_t key_data_aes_version = 0x42;
void void
mifare_desfire_auto_authenticate (FreefareTag tag, uint8_t key_no) mifare_desfire_auto_authenticate(FreefareTag tag, uint8_t key_no)
{ {
/* Determine which key is currently the master one */ /* Determine which key is currently the master one */
uint8_t key_version; uint8_t key_version;
int res = mifare_desfire_get_key_version (tag, key_no, &key_version); int res = mifare_desfire_get_key_version(tag, key_no, &key_version);
cut_assert_equal_int (0, res, cut_message ("mifare_desfire_get_key_version()")); cut_assert_equal_int(0, res, cut_message("mifare_desfire_get_key_version()"));
MifareDESFireKey key; MifareDESFireKey key;
switch (key_version) { switch (key_version) {
case 0x00: case 0x00:
key = mifare_desfire_des_key_new_with_version (key_data_null); key = mifare_desfire_des_key_new_with_version(key_data_null);
break; break;
case 0x42: case 0x42:
key = mifare_desfire_aes_key_new_with_version (key_data_aes, key_data_aes_version); key = mifare_desfire_aes_key_new_with_version(key_data_aes, key_data_aes_version);
break; break;
case 0xAA: case 0xAA:
key = mifare_desfire_des_key_new_with_version (key_data_des); key = mifare_desfire_des_key_new_with_version(key_data_des);
break; break;
case 0xC7: case 0xC7:
key = mifare_desfire_3des_key_new_with_version (key_data_3des); key = mifare_desfire_3des_key_new_with_version(key_data_3des);
break; break;
case 0x55: case 0x55:
key = mifare_desfire_3k3des_key_new_with_version (key_data_3k3des); key = mifare_desfire_3k3des_key_new_with_version(key_data_3k3des);
break; break;
default: default:
cut_fail ("Unknown master key."); cut_fail("Unknown master key.");
} }
cut_assert_not_null (key, cut_message ("Cannot allocate key")); cut_assert_not_null(key, cut_message("Cannot allocate key"));
/* Authenticate with this key */ /* Authenticate with this key */
switch (key_version) { switch (key_version) {
case 0x00: case 0x00:
case 0xAA: case 0xAA:
case 0xC7: case 0xC7:
res = mifare_desfire_authenticate (tag, key_no, key); res = mifare_desfire_authenticate(tag, key_no, key);
break; break;
case 0x55: case 0x55:
res = mifare_desfire_authenticate_iso (tag, key_no, key); res = mifare_desfire_authenticate_iso(tag, key_no, key);
break; break;
case 0x42: case 0x42:
res = mifare_desfire_authenticate_aes (tag, key_no, key); res = mifare_desfire_authenticate_aes(tag, key_no, key);
break; break;
} }
cut_assert_equal_int (0, res, cut_message ("mifare_desfire_authenticate()")); cut_assert_equal_int(0, res, cut_message("mifare_desfire_authenticate()"));
mifare_desfire_key_free (key); mifare_desfire_key_free(key);
} }

View file

@ -25,6 +25,6 @@ extern uint8_t key_data_aes[16];
extern uint8_t key_data_3k3des[24]; extern uint8_t key_data_3k3des[24];
extern const uint8_t key_data_aes_version; extern const uint8_t key_data_aes_version;
void mifare_desfire_auto_authenticate (FreefareTag tag, uint8_t key_no); void mifare_desfire_auto_authenticate(FreefareTag tag, uint8_t key_no);
#endif #endif

View file

@ -26,52 +26,52 @@ static FreefareTag *tags = NULL;
FreefareTag tag = NULL; FreefareTag tag = NULL;
void void
cut_setup (void) cut_setup(void)
{ {
int res; int res;
nfc_connstring devices[8]; nfc_connstring devices[8];
size_t device_count; size_t device_count;
nfc_init (&context); nfc_init(&context);
cut_assert_not_null (context, cut_message ("Unable to init libnfc (malloc)")); cut_assert_not_null(context, cut_message("Unable to init libnfc (malloc)"));
device_count = nfc_list_devices (context, devices, 8); device_count = nfc_list_devices(context, devices, 8);
if (device_count <= 0) if (device_count <= 0)
cut_omit ("No device found"); cut_omit("No device found");
for (size_t i = 0; i < device_count; i++) { for (size_t i = 0; i < device_count; i++) {
device = nfc_open (context, devices[i]); device = nfc_open(context, devices[i]);
if (!device) if (!device)
cut_omit ("nfc_open() failed."); cut_omit("nfc_open() failed.");
tags = freefare_get_tags (device); tags = freefare_get_tags(device);
cut_assert_not_null (tags, cut_message ("freefare_get_tags() failed")); cut_assert_not_null(tags, cut_message("freefare_get_tags() failed"));
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]) == FELICA) { if (freefare_get_tag_type(tags[i]) == FELICA) {
tag = tags[i]; tag = tags[i];
return; return;
} }
} }
nfc_close (device); nfc_close(device);
device = NULL; device = NULL;
freefare_free_tags (tags); freefare_free_tags(tags);
tags = NULL; tags = NULL;
} }
cut_omit ("No FeliCa tag on NFC device"); cut_omit("No FeliCa tag on NFC device");
} }
void void
cut_teardown (void) cut_teardown(void)
{ {
if (tags) { if (tags) {
freefare_free_tags (tags); freefare_free_tags(tags);
tags = NULL; tags = NULL;
} }
if (device) if (device)
nfc_close (device); nfc_close(device);
nfc_exit (context); nfc_exit(context);
} }

View file

@ -27,59 +27,59 @@ static FreefareTag *tags = NULL;
FreefareTag tag = NULL; FreefareTag tag = NULL;
void void
cut_setup (void) cut_setup(void)
{ {
int res; int res;
nfc_connstring devices[8]; nfc_connstring devices[8];
size_t device_count; size_t device_count;
nfc_init (&context); nfc_init(&context);
cut_assert_not_null (context, cut_message ("Unable to init libnfc (malloc)")); cut_assert_not_null(context, cut_message("Unable to init libnfc (malloc)"));
device_count = nfc_list_devices (context, devices, 8); device_count = nfc_list_devices(context, devices, 8);
if (device_count <= 0) if (device_count <= 0)
cut_omit ("No device found"); cut_omit("No device found");
for (size_t i = 0; i < device_count; i++) { for (size_t i = 0; i < device_count; i++) {
device = nfc_open (context, devices[i]); device = nfc_open(context, devices[i]);
if (!device) if (!device)
cut_omit ("nfc_open() failed."); cut_omit("nfc_open() failed.");
tags = freefare_get_tags (device); tags = freefare_get_tags(device);
cut_assert_not_null (tags, cut_message ("freefare_get_tags() failed")); cut_assert_not_null(tags, cut_message("freefare_get_tags() failed"));
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]) == MIFARE_CLASSIC_1K) || if ((freefare_get_tag_type(tags[i]) == MIFARE_CLASSIC_1K) ||
(freefare_get_tag_type(tags[i]) == MIFARE_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"));
return; return;
} }
} }
nfc_close (device); nfc_close(device);
device = NULL; device = NULL;
freefare_free_tags (tags); freefare_free_tags(tags);
tags = NULL; tags = NULL;
} }
cut_omit ("No MIFARE Classic tag on NFC device"); cut_omit("No MIFARE Classic tag on NFC device");
} }
void void
cut_teardown (void) cut_teardown(void)
{ {
if (tag) if (tag)
mifare_classic_disconnect (tag); mifare_classic_disconnect(tag);
if (tags) { if (tags) {
freefare_free_tags (tags); freefare_free_tags(tags);
tags = NULL; tags = NULL;
} }
if (device) if (device)
nfc_close (device); nfc_close(device);
nfc_exit (context); nfc_exit(context);
} }

View file

@ -27,73 +27,73 @@ static FreefareTag *tags = NULL;
FreefareTag tag = NULL; FreefareTag tag = NULL;
void void
cut_setup (void) cut_setup(void)
{ {
int res; int res;
nfc_connstring devices[8]; nfc_connstring devices[8];
size_t device_count; size_t device_count;
nfc_init (&context); nfc_init(&context);
cut_assert_not_null (context, cut_message ("Unable to init libnfc (malloc)")); cut_assert_not_null(context, cut_message("Unable to init libnfc (malloc)"));
device_count = nfc_list_devices (context, devices, 8); device_count = nfc_list_devices(context, devices, 8);
if (device_count <= 0) if (device_count <= 0)
cut_omit ("No device found"); cut_omit("No device found");
for (size_t i = 0; i < device_count; i++) { for (size_t i = 0; i < device_count; i++) {
device = nfc_open (context, devices[i]); device = nfc_open(context, devices[i]);
if (!device) if (!device)
cut_omit ("nfc_open() failed."); cut_omit("nfc_open() failed.");
tags = freefare_get_tags (device); tags = freefare_get_tags(device);
cut_assert_not_null (tags, cut_message ("freefare_get_tags() failed")); cut_assert_not_null(tags, cut_message("freefare_get_tags() failed"));
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]) == MIFARE_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"));
struct mifare_desfire_version_info version_info; struct mifare_desfire_version_info version_info;
res = mifare_desfire_get_version (tag, &version_info); res = mifare_desfire_get_version(tag, &version_info);
cut_assert_equal_int (0, res, cut_message ("mifare_desfire_get_version")); cut_assert_equal_int(0, res, cut_message("mifare_desfire_get_version"));
if (version_info.hardware.storage_size < 0x18) { if (version_info.hardware.storage_size < 0x18) {
cut_omit ("DESFire EV1 tests require at least a 4K card"); cut_omit("DESFire EV1 tests require at least a 4K card");
} }
if ((version_info.hardware.version_major >= 1) && if ((version_info.hardware.version_major >= 1) &&
(version_info.software.version_major >= 1)) { (version_info.software.version_major >= 1)) {
return; return;
} }
mifare_desfire_disconnect (tag); mifare_desfire_disconnect(tag);
} }
} }
nfc_close (device); nfc_close(device);
device = NULL; device = NULL;
freefare_free_tags (tags); freefare_free_tags(tags);
tags = NULL; tags = NULL;
} }
cut_omit ("No MIFARE DESFire EV1 tag on NFC device"); cut_omit("No MIFARE DESFire EV1 tag on NFC device");
} }
void void
cut_teardown (void) cut_teardown(void)
{ {
if (tag) if (tag)
mifare_desfire_disconnect (tag); mifare_desfire_disconnect(tag);
if (tags) { if (tags) {
freefare_free_tags (tags); freefare_free_tags(tags);
tags = NULL; tags = NULL;
} }
if (device) if (device)
nfc_close (device); nfc_close(device);
nfc_exit (context); nfc_exit(context);
} }

View file

@ -27,68 +27,68 @@ static FreefareTag *tags = NULL;
FreefareTag tag = NULL; FreefareTag tag = NULL;
void void
cut_setup (void) cut_setup(void)
{ {
int res; int res;
nfc_connstring devices[8]; nfc_connstring devices[8];
size_t device_count; size_t device_count;
nfc_init (&context); nfc_init(&context);
cut_assert_not_null (context, cut_message ("Unable to init libnfc (malloc)")); cut_assert_not_null(context, cut_message("Unable to init libnfc (malloc)"));
device_count = nfc_list_devices (context, devices, 8); device_count = nfc_list_devices(context, devices, 8);
if (device_count <= 0) if (device_count <= 0)
cut_omit ("No device found"); cut_omit("No device found");
for (size_t i = 0; i < device_count; i++) { for (size_t i = 0; i < device_count; i++) {
device = nfc_open (context, devices[i]); device = nfc_open(context, devices[i]);
if (!device) if (!device)
cut_omit ("nfc_open() failed."); cut_omit("nfc_open() failed.");
tags = freefare_get_tags (device); tags = freefare_get_tags(device);
cut_assert_not_null (tags, cut_message ("freefare_get_tags() failed")); cut_assert_not_null(tags, cut_message("freefare_get_tags() failed"));
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]) == MIFARE_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"));
struct mifare_desfire_version_info version_info; struct mifare_desfire_version_info version_info;
res = mifare_desfire_get_version (tag, &version_info); res = mifare_desfire_get_version(tag, &version_info);
cut_assert_equal_int (0, res, cut_message ("mifare_desfire_get_version")); cut_assert_equal_int(0, res, cut_message("mifare_desfire_get_version"));
if (version_info.hardware.storage_size < 0x18) { if (version_info.hardware.storage_size < 0x18) {
cut_omit ("DESFire tests require at least a 4K card"); cut_omit("DESFire tests require at least a 4K card");
} }
return; return;
} }
}
nfc_close(device);
device = NULL;
freefare_free_tags(tags);
tags = NULL;
} }
nfc_close (device); cut_omit("No MIFARE DESFire tag on NFC device");
device = NULL;
freefare_free_tags (tags);
tags = NULL;
}
cut_omit ("No MIFARE DESFire tag on NFC device");
} }
void void
cut_teardown (void) cut_teardown(void)
{ {
if (tag) if (tag)
mifare_desfire_disconnect (tag); mifare_desfire_disconnect(tag);
if (tags) { if (tags) {
freefare_free_tags (tags); freefare_free_tags(tags);
tags = NULL; tags = NULL;
} }
if (device) if (device)
nfc_close (device); nfc_close(device);
nfc_exit (context); nfc_exit(context);
} }

View file

@ -27,61 +27,61 @@ static FreefareTag *tags = NULL;
FreefareTag tag = NULL; FreefareTag tag = NULL;
void void
cut_setup (void) cut_setup(void)
{ {
int res; int res;
nfc_connstring devices[8]; nfc_connstring devices[8];
size_t device_count; size_t device_count;
nfc_init (&context); nfc_init(&context);
cut_assert_not_null (context, cut_message ("Unable to init libnfc (malloc)")); cut_assert_not_null(context, cut_message("Unable to init libnfc (malloc)"));
device_count = nfc_list_devices (context, devices, 8); device_count = nfc_list_devices(context, devices, 8);
if (device_count <= 0) if (device_count <= 0)
cut_omit ("No device found"); cut_omit("No device found");
for (size_t i = 0; i < device_count; i++) { for (size_t i = 0; i < device_count; i++) {
device = nfc_open (context, devices[i]); device = nfc_open(context, devices[i]);
if (!device) if (!device)
cut_omit ("nfc_open() failed."); cut_omit("nfc_open() failed.");
tags = freefare_get_tags (device); tags = freefare_get_tags(device);
cut_assert_not_null (tags, cut_message ("freefare_get_tags() failed")); cut_assert_not_null(tags, cut_message("freefare_get_tags() failed"));
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]) == MIFARE_ULTRALIGHT) || if ((freefare_get_tag_type(tags[i]) == MIFARE_ULTRALIGHT) ||
(freefare_get_tag_type(tags[i]) == MIFARE_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"));
return; return;
} }
} }
nfc_close (device); nfc_close(device);
device = NULL; device = NULL;
freefare_free_tags (tags); freefare_free_tags(tags);
tags = NULL; tags = NULL;
} }
cut_omit ("No MIFARE UltraLight tag on NFC device"); cut_omit("No MIFARE UltraLight tag on NFC device");
} }
void void
cut_teardown (void) cut_teardown(void)
{ {
if (tag) if (tag)
mifare_ultralight_disconnect (tag); mifare_ultralight_disconnect(tag);
if (tags) { if (tags) {
freefare_free_tags (tags); freefare_free_tags(tags);
tags = NULL; tags = NULL;
} }
if (device) if (device)
nfc_close (device); nfc_close(device);
nfc_exit (context); nfc_exit(context);
} }

View file

@ -5,12 +5,12 @@
#include "felica_fixture.h" #include "felica_fixture.h"
void void
test_felica_read_without_encryption (void) test_felica_read_without_encryption(void)
{ {
uint8_t buffer[64]; uint8_t buffer[64];
int res = felica_read (tag, FELICA_SC_RO, 0x00, buffer, 16); int res = felica_read(tag, FELICA_SC_RO, 0x00, buffer, 16);
cut_assert_equal_int (16, res); cut_assert_equal_int(16, res);
uint8_t blocks[] = { uint8_t blocks[] = {
0x02, 0x02,
@ -18,12 +18,12 @@ test_felica_read_without_encryption (void)
0x04, 0x04,
}; };
res = felica_read_ex (tag, FELICA_SC_RO, 3, blocks, buffer, 3 * 16); res = felica_read_ex(tag, FELICA_SC_RO, 3, blocks, buffer, 3 * 16);
cut_assert_equal_int (3 * 16, res); cut_assert_equal_int(3 * 16, res);
} }
void void
test_felica_write_without_encryption (void) test_felica_write_without_encryption(void)
{ {
uint8_t buffer[16] = { uint8_t buffer[16] = {
0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03,
@ -32,7 +32,7 @@ test_felica_write_without_encryption (void)
0x0b, 0x0c, 0x0d, 0x0e, 0x0b, 0x0c, 0x0d, 0x0e,
}; };
int res = felica_write (tag, FELICA_SC_RW, 0x0a, buffer, sizeof (buffer)); int res = felica_write(tag, FELICA_SC_RW, 0x0a, buffer, sizeof(buffer));
cut_assert_equal_int (0, res); cut_assert_equal_int(0, res);
} }

View file

@ -4,23 +4,23 @@
#include "freefare_internal.h" #include "freefare_internal.h"
void void
test_is_mifare_ultralight (void) test_is_mifare_ultralight(void)
{ {
FreefareTag tag; FreefareTag tag;
nfc_target target; nfc_target target;
tag = mifare_ultralight_tag_new (NULL, target); tag = mifare_ultralight_tag_new(NULL, target);
cut_assert_true (is_mifare_ultralight (tag)); cut_assert_true(is_mifare_ultralight(tag));
mifare_ultralight_tag_free (tag); mifare_ultralight_tag_free(tag);
} }
void void
test_is_mifare_ultralightc (void) test_is_mifare_ultralightc(void)
{ {
FreefareTag tag; FreefareTag tag;
nfc_target target; nfc_target target;
tag = mifare_ultralightc_tag_new (NULL, target); tag = mifare_ultralightc_tag_new(NULL, target);
cut_assert_true (is_mifare_ultralightc (tag)); cut_assert_true(is_mifare_ultralightc(tag));
mifare_ultralightc_tag_free (tag); mifare_ultralightc_tag_free(tag);
} }

View file

@ -21,54 +21,54 @@
#include "freefare_internal.h" #include "freefare_internal.h"
void void
test_mad (void) test_mad(void)
{ {
int res; int res;
Mad mad = mad_new (1); Mad mad = mad_new(1);
cut_assert_not_null (mad, cut_message ("Can create a new MAD")); cut_assert_not_null(mad, cut_message("Can create a new MAD"));
cut_assert_equal_int (1, mad_get_version (mad), cut_message ("Wrong default MAD version")); cut_assert_equal_int(1, mad_get_version(mad), cut_message("Wrong default MAD version"));
mad_set_version (mad, 2); mad_set_version(mad, 2);
cut_assert_equal_int (2, mad_get_version (mad), cut_message ("Can't change MAD version")); cut_assert_equal_int(2, mad_get_version(mad), cut_message("Can't change MAD version"));
cut_assert_equal_int (0, mad_get_card_publisher_sector (mad), cut_message ("Wrong default MAD publisher")); cut_assert_equal_int(0, mad_get_card_publisher_sector(mad), cut_message("Wrong default MAD publisher"));
res = mad_set_card_publisher_sector (mad, 13); res = mad_set_card_publisher_sector(mad, 13);
cut_assert_equal_int (0, res, cut_message ("mad_set_card_publisher_sector() returned an error.")); cut_assert_equal_int(0, res, cut_message("mad_set_card_publisher_sector() returned an error."));
cut_assert_equal_int (13, mad_get_card_publisher_sector (mad), cut_message ("Wrong publisher sector")); cut_assert_equal_int(13, mad_get_card_publisher_sector(mad), cut_message("Wrong publisher sector"));
res = mad_set_card_publisher_sector (mad, 0xff); res = mad_set_card_publisher_sector(mad, 0xff);
cut_assert_equal_int (-1, res, cut_message ("Invalid sector")); cut_assert_equal_int(-1, res, cut_message("Invalid sector"));
cut_assert_equal_int (13, mad_get_card_publisher_sector (mad), cut_message ("Previous publisher sector value")); cut_assert_equal_int(13, mad_get_card_publisher_sector(mad), cut_message("Previous publisher sector value"));
MadAid aid = { MadAid aid = {
.function_cluster_code = 0, .function_cluster_code = 0,
.application_code = 0 .application_code = 0
}; };
res = mad_get_aid (mad, 3, &aid); res = mad_get_aid(mad, 3, &aid);
cut_assert_equal_int (0, res, cut_message ("mad_get_aid() failed")); cut_assert_equal_int(0, res, cut_message("mad_get_aid() failed"));
cut_assert_equal_int (0, aid.function_cluster_code, cut_message ("Invalid default value")); cut_assert_equal_int(0, aid.function_cluster_code, cut_message("Invalid default value"));
cut_assert_equal_int (0, aid.application_code, cut_message ("Invalid default value")); cut_assert_equal_int(0, aid.application_code, cut_message("Invalid default value"));
aid.function_cluster_code = 0xc0; aid.function_cluster_code = 0xc0;
aid.application_code = 0x42; aid.application_code = 0x42;
res = mad_set_aid (mad, 3, aid); res = mad_set_aid(mad, 3, aid);
cut_assert_equal_int (0, res, cut_message ("mad_set_aid() failed")); cut_assert_equal_int(0, res, cut_message("mad_set_aid() failed"));
res = mad_get_aid (mad, 3, &aid); res = mad_get_aid(mad, 3, &aid);
cut_assert_equal_int (0, res, cut_message ("mad_get_aid() failed")); cut_assert_equal_int(0, res, cut_message("mad_get_aid() failed"));
cut_assert_equal_int (0xC0, aid.function_cluster_code, cut_message ("Invalid value")); cut_assert_equal_int(0xC0, aid.function_cluster_code, cut_message("Invalid value"));
cut_assert_equal_int (0x42, aid.application_code, cut_message ("Invalid value")); cut_assert_equal_int(0x42, aid.application_code, cut_message("Invalid value"));
mad_free (mad); mad_free(mad);
} }
#define CRC_PRESET 0xc7 #define CRC_PRESET 0xc7
void void
test_mad_crc8_basic (void) test_mad_crc8_basic(void)
{ {
uint8_t crc; uint8_t crc;
const uint8_t crc_value = 0x42; const uint8_t crc_value = 0x42;
@ -81,14 +81,14 @@ test_mad_crc8_basic (void)
crc = CRC_PRESET; crc = CRC_PRESET;
nxp_crc(&crc, crc_value); nxp_crc(&crc, crc_value);
nxp_crc(&crc, save); nxp_crc(&crc, save);
cut_assert_equal_int (0x00, crc, cut_message ("CRC should verify crc(message + crc(message)) = 0")); cut_assert_equal_int(0x00, crc, cut_message("CRC should verify crc(message + crc(message)) = 0"));
} }
/* /*
* The following MAD values where extracted from documentation. * The following MAD values where extracted from documentation.
*/ */
void void
test_mad_crc8_doc_example (void) test_mad_crc8_doc_example(void)
{ {
/* Preset */ /* Preset */
uint8_t crc = CRC_PRESET; uint8_t crc = CRC_PRESET;
@ -134,14 +134,14 @@ test_mad_crc8_doc_example (void)
/* Append zeros of augmented message */ /* Append zeros of augmented message */
cut_assert_equal_int (0x89, crc, cut_message ("Sample CRC should match")); cut_assert_equal_int(0x89, crc, cut_message("Sample CRC should match"));
} }
/* /*
* The following MAD values where extracted from a MIFARE dump. * The following MAD values where extracted from a MIFARE dump.
*/ */
void void
test_mad_crc8_real_example_1 (void) test_mad_crc8_real_example_1(void)
{ {
/* Preset */ /* Preset */
uint8_t crc = CRC_PRESET; uint8_t crc = CRC_PRESET;
@ -187,14 +187,14 @@ test_mad_crc8_real_example_1 (void)
/* Append zeros of augmented message */ /* Append zeros of augmented message */
cut_assert_equal_int (0xc4, crc, cut_message ("Read example 1 CRC should match")); cut_assert_equal_int(0xc4, crc, cut_message("Read example 1 CRC should match"));
} }
/* /*
* The following MAD values where extracted from a MIFARE dump. * The following MAD values where extracted from a MIFARE dump.
*/ */
void void
test_mad_crc8_real_example_2 (void) test_mad_crc8_real_example_2(void)
{ {
/* Preset */ /* Preset */
uint8_t crc = CRC_PRESET; uint8_t crc = CRC_PRESET;
@ -240,48 +240,48 @@ test_mad_crc8_real_example_2 (void)
/* Append zeros of augmented message */ /* Append zeros of augmented message */
cut_assert_equal_int (0xab, crc, cut_message ("Read example 1 CRC should match")); cut_assert_equal_int(0xab, crc, cut_message("Read example 1 CRC should match"));
} }
void void
test_mad_sector_0x00_crc8 (void) test_mad_sector_0x00_crc8(void)
{ {
int res; int res;
Mad mad = mad_new (1); Mad mad = mad_new(1);
cut_assert_not_null (mad, cut_message ("mad_new() failed")); cut_assert_not_null(mad, cut_message("mad_new() failed"));
res = mad_set_card_publisher_sector (mad, 0x01); res = mad_set_card_publisher_sector(mad, 0x01);
/* Block 1 */ /* Block 1 */
MadAid aid1 = { 0x01, 0x08 }; MadAid aid1 = { 0x01, 0x08 };
mad_set_aid (mad, 1, aid1); mad_set_aid(mad, 1, aid1);
mad_set_aid (mad, 2, aid1); mad_set_aid(mad, 2, aid1);
mad_set_aid (mad, 3, aid1); mad_set_aid(mad, 3, aid1);
/* Block 2 */ /* Block 2 */
MadAid empty_aid = { 0x00, 0x00 }; MadAid empty_aid = { 0x00, 0x00 };
mad_set_aid (mad, 4, empty_aid); mad_set_aid(mad, 4, empty_aid);
mad_set_aid (mad, 5, empty_aid); mad_set_aid(mad, 5, empty_aid);
mad_set_aid (mad, 6, empty_aid); mad_set_aid(mad, 6, empty_aid);
MadAid aid2 = { 0x04, 0x00 }; MadAid aid2 = { 0x04, 0x00 };
mad_set_aid (mad, 7, aid2); mad_set_aid(mad, 7, aid2);
/* Block 3 */ /* Block 3 */
MadAid aid3 = { 0x03, 0x10 }; MadAid aid3 = { 0x03, 0x10 };
mad_set_aid (mad, 8, aid3); mad_set_aid(mad, 8, aid3);
mad_set_aid (mad, 9, aid3); mad_set_aid(mad, 9, aid3);
MadAid aid4 = { 0x02, 0x10 }; MadAid aid4 = { 0x02, 0x10 };
mad_set_aid (mad, 10, aid4); mad_set_aid(mad, 10, aid4);
mad_set_aid (mad, 11, aid4); mad_set_aid(mad, 11, aid4);
mad_set_aid (mad, 12, empty_aid); mad_set_aid(mad, 12, empty_aid);
mad_set_aid (mad, 13, empty_aid); mad_set_aid(mad, 13, empty_aid);
mad_set_aid (mad, 14, empty_aid); mad_set_aid(mad, 14, empty_aid);
MadAid aid5 = { 0x11, 0x30 }; MadAid aid5 = { 0x11, 0x30 };
mad_set_aid (mad, 15, aid5); mad_set_aid(mad, 15, aid5);
res = sector_0x00_crc8 (mad); res = sector_0x00_crc8(mad);
cut_assert_equal_int(0x89, res, cut_message ("Sample CRC should match")); cut_assert_equal_int(0x89, res, cut_message("Sample CRC should match"));
mad_free (mad); mad_free(mad);
} }

View file

@ -19,61 +19,61 @@
#include <freefare.h> #include <freefare.h>
void void
test_mifare_application (void) test_mifare_application(void)
{ {
/* Card publisher part */ /* Card publisher part */
MadAid aid = { 0x22, 0x42 }; MadAid aid = { 0x22, 0x42 };
Mad mad = mad_new (2); Mad mad = mad_new(2);
int i; int i;
cut_assert_not_null (mad, cut_message ("mad_new() failed")); cut_assert_not_null(mad, cut_message("mad_new() failed"));
MifareClassicSectorNumber *s_alloc = mifare_application_alloc (mad, aid, 3*3*16); MifareClassicSectorNumber *s_alloc = mifare_application_alloc(mad, aid, 3 * 3 * 16);
cut_assert_not_null (s_alloc, cut_message ("mifare_application_alloc() failed")); cut_assert_not_null(s_alloc, cut_message("mifare_application_alloc() failed"));
MifareClassicSectorNumber *s_found = mifare_application_find (mad, aid); MifareClassicSectorNumber *s_found = mifare_application_find(mad, aid);
cut_assert_not_null (s_found, cut_message ("mifare_application_alloc() failed")); cut_assert_not_null(s_found, cut_message("mifare_application_alloc() failed"));
for (i = 0; s_alloc[i]; i++) { for (i = 0; s_alloc[i]; i++) {
cut_assert_equal_int (s_alloc[i], s_found[i], cut_message ("Allocated and found blocks don't match at position %d", i)); cut_assert_equal_int(s_alloc[i], s_found[i], cut_message("Allocated and found blocks don't match at position %d", i));
} }
cut_assert_equal_int (0, s_alloc[i], cut_message ("Invalid size")); cut_assert_equal_int(0, s_alloc[i], cut_message("Invalid size"));
cut_assert_equal_int (0, s_found[i], cut_message ("Invalid size")); cut_assert_equal_int(0, s_found[i], cut_message("Invalid size"));
mifare_application_free (mad, aid); mifare_application_free(mad, aid);
free (s_alloc); free(s_alloc);
free (s_found); free(s_found);
s_found = mifare_application_find (mad, aid); s_found = mifare_application_find(mad, aid);
cut_assert_null (s_found, cut_message ("mifare_application_free() failed")); cut_assert_null(s_found, cut_message("mifare_application_free() failed"));
s_alloc = mifare_application_alloc (mad, aid, 15*16 + 1*16 + 1); s_alloc = mifare_application_alloc(mad, aid, 15 * 16 + 1 * 16 + 1);
cut_assert_not_null (s_alloc, cut_message ("mifare_application_alloc() failed")); cut_assert_not_null(s_alloc, cut_message("mifare_application_alloc() failed"));
s_found = mifare_application_find (mad, aid); s_found = mifare_application_find(mad, aid);
cut_assert_not_null (s_found, cut_message ("mifare_application_alloc() failed")); cut_assert_not_null(s_found, cut_message("mifare_application_alloc() failed"));
for (i = 0; s_alloc[i]; i++) { for (i = 0; s_alloc[i]; i++) {
cut_assert_equal_int (s_alloc[i], s_found[i], cut_message ("Allocated and found blocks don't match at position %d", i)); cut_assert_equal_int(s_alloc[i], s_found[i], cut_message("Allocated and found blocks don't match at position %d", i));
} }
cut_assert_equal_int (0, s_alloc[i], cut_message ("Invalid size")); cut_assert_equal_int(0, s_alloc[i], cut_message("Invalid size"));
cut_assert_equal_int (0, s_found[i], cut_message ("Invalid size")); cut_assert_equal_int(0, s_found[i], cut_message("Invalid size"));
mifare_application_free (mad, aid); mifare_application_free(mad, aid);
free (s_alloc); free(s_alloc);
free (s_found); free(s_found);
s_found = mifare_application_find (mad, aid); s_found = mifare_application_find(mad, aid);
cut_assert_null (s_found, cut_message ("mifare_application_free() failed")); cut_assert_null(s_found, cut_message("mifare_application_free() failed"));
mad_free (mad); mad_free(mad);
} }

View file

@ -25,86 +25,86 @@
#include "mifare_classic_fixture.h" #include "mifare_classic_fixture.h"
void void
test_mifare_classic_authenticate (void) test_mifare_classic_authenticate(void)
{ {
int res; int res;
MifareClassicKey k = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; MifareClassicKey k = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
res = mifare_classic_authenticate (tag, 0x00, k, MFC_KEY_A); res = mifare_classic_authenticate(tag, 0x00, k, MFC_KEY_A);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_authenticate() failed")); cut_assert_equal_int(0, res, cut_message("mifare_classic_authenticate() failed"));
} }
void void
test_mifare_classic_get_data_block_permission (void) test_mifare_classic_get_data_block_permission(void)
{ {
int res; int res;
MifareClassicKey k = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; MifareClassicKey k = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
res = mifare_classic_authenticate (tag, 0x04, k, MFC_KEY_A); res = mifare_classic_authenticate(tag, 0x04, k, MFC_KEY_A);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_authenticate() failed")); cut_assert_equal_int(0, res, cut_message("mifare_classic_authenticate() failed"));
cut_assert_equal_int (1, mifare_classic_get_data_block_permission(tag, 0x04, MCAB_R, MFC_KEY_A), cut_message ("Wrong permission")); cut_assert_equal_int(1, mifare_classic_get_data_block_permission(tag, 0x04, MCAB_R, MFC_KEY_A), cut_message("Wrong permission"));
cut_assert_equal_int (1, mifare_classic_get_data_block_permission(tag, 0x04, MCAB_R, MFC_KEY_B), cut_message ("Wrong permission")); cut_assert_equal_int(1, mifare_classic_get_data_block_permission(tag, 0x04, MCAB_R, MFC_KEY_B), cut_message("Wrong permission"));
cut_assert_equal_int (1, mifare_classic_get_data_block_permission(tag, 0x04, MCAB_W, MFC_KEY_A), cut_message ("Wrong permission")); cut_assert_equal_int(1, mifare_classic_get_data_block_permission(tag, 0x04, MCAB_W, MFC_KEY_A), cut_message("Wrong permission"));
cut_assert_equal_int (1, mifare_classic_get_data_block_permission(tag, 0x04, MCAB_W, MFC_KEY_B), cut_message ("Wrong permission")); cut_assert_equal_int(1, mifare_classic_get_data_block_permission(tag, 0x04, MCAB_W, MFC_KEY_B), cut_message("Wrong permission"));
cut_assert_equal_int (1, mifare_classic_get_data_block_permission(tag, 0x04, MCAB_D, MFC_KEY_A), cut_message ("Wrong permission")); cut_assert_equal_int(1, mifare_classic_get_data_block_permission(tag, 0x04, MCAB_D, MFC_KEY_A), cut_message("Wrong permission"));
cut_assert_equal_int (1, mifare_classic_get_data_block_permission(tag, 0x04, MCAB_D, MFC_KEY_B), cut_message ("Wrong permission")); cut_assert_equal_int(1, mifare_classic_get_data_block_permission(tag, 0x04, MCAB_D, MFC_KEY_B), cut_message("Wrong permission"));
cut_assert_equal_int (1, mifare_classic_get_data_block_permission(tag, 0x04, MCAB_I, MFC_KEY_A), cut_message ("Wrong permission")); cut_assert_equal_int(1, mifare_classic_get_data_block_permission(tag, 0x04, MCAB_I, MFC_KEY_A), cut_message("Wrong permission"));
cut_assert_equal_int (1, mifare_classic_get_data_block_permission(tag, 0x04, MCAB_I, MFC_KEY_B), cut_message ("Wrong permission")); cut_assert_equal_int(1, mifare_classic_get_data_block_permission(tag, 0x04, MCAB_I, MFC_KEY_B), cut_message("Wrong permission"));
cut_assert_equal_int (-1, mifare_classic_get_trailer_block_permission(tag, 0x04, MCAB_READ_KEYA, MFC_KEY_A), cut_message ("Wrong permission")); cut_assert_equal_int(-1, mifare_classic_get_trailer_block_permission(tag, 0x04, MCAB_READ_KEYA, MFC_KEY_A), cut_message("Wrong permission"));
cut_assert_equal_int (-1, mifare_classic_get_trailer_block_permission(tag, 0x04, MCAB_READ_KEYA, MFC_KEY_B), cut_message ("Wrong permission")); cut_assert_equal_int(-1, mifare_classic_get_trailer_block_permission(tag, 0x04, MCAB_READ_KEYA, MFC_KEY_B), cut_message("Wrong permission"));
cut_assert_equal_int (-1, mifare_classic_get_trailer_block_permission(tag, 0x04, MCAB_WRITE_KEYA, MFC_KEY_A), cut_message ("Wrong permission")); cut_assert_equal_int(-1, mifare_classic_get_trailer_block_permission(tag, 0x04, MCAB_WRITE_KEYA, MFC_KEY_A), cut_message("Wrong permission"));
cut_assert_equal_int (-1, mifare_classic_get_trailer_block_permission(tag, 0x04, MCAB_WRITE_KEYA, MFC_KEY_B), cut_message ("Wrong permission")); cut_assert_equal_int(-1, mifare_classic_get_trailer_block_permission(tag, 0x04, MCAB_WRITE_KEYA, MFC_KEY_B), cut_message("Wrong permission"));
cut_assert_equal_int (-1, mifare_classic_get_trailer_block_permission(tag, 0x04, MCAB_READ_ACCESS_BITS, MFC_KEY_A), cut_message ("Wrong permission")); cut_assert_equal_int(-1, mifare_classic_get_trailer_block_permission(tag, 0x04, MCAB_READ_ACCESS_BITS, MFC_KEY_A), cut_message("Wrong permission"));
cut_assert_equal_int (-1, mifare_classic_get_trailer_block_permission(tag, 0x04, MCAB_READ_ACCESS_BITS, MFC_KEY_B), cut_message ("Wrong permission")); cut_assert_equal_int(-1, mifare_classic_get_trailer_block_permission(tag, 0x04, MCAB_READ_ACCESS_BITS, MFC_KEY_B), cut_message("Wrong permission"));
cut_assert_equal_int (-1, mifare_classic_get_trailer_block_permission(tag, 0x04, MCAB_WRITE_ACCESS_BITS, MFC_KEY_A), cut_message ("Wrong permission")); cut_assert_equal_int(-1, mifare_classic_get_trailer_block_permission(tag, 0x04, MCAB_WRITE_ACCESS_BITS, MFC_KEY_A), cut_message("Wrong permission"));
cut_assert_equal_int (-1, mifare_classic_get_trailer_block_permission(tag, 0x04, MCAB_WRITE_ACCESS_BITS, MFC_KEY_B), cut_message ("Wrong permission")); cut_assert_equal_int(-1, mifare_classic_get_trailer_block_permission(tag, 0x04, MCAB_WRITE_ACCESS_BITS, MFC_KEY_B), cut_message("Wrong permission"));
cut_assert_equal_int (-1, mifare_classic_get_trailer_block_permission(tag, 0x04, MCAB_READ_KEYB, MFC_KEY_A), cut_message ("Wrong permission")); cut_assert_equal_int(-1, mifare_classic_get_trailer_block_permission(tag, 0x04, MCAB_READ_KEYB, MFC_KEY_A), cut_message("Wrong permission"));
cut_assert_equal_int (-1, mifare_classic_get_trailer_block_permission(tag, 0x04, MCAB_READ_KEYB, MFC_KEY_B), cut_message ("Wrong permission")); cut_assert_equal_int(-1, mifare_classic_get_trailer_block_permission(tag, 0x04, MCAB_READ_KEYB, MFC_KEY_B), cut_message("Wrong permission"));
cut_assert_equal_int (-1, mifare_classic_get_trailer_block_permission(tag, 0x04, MCAB_WRITE_KEYB, MFC_KEY_A), cut_message ("Wrong permission")); cut_assert_equal_int(-1, mifare_classic_get_trailer_block_permission(tag, 0x04, MCAB_WRITE_KEYB, MFC_KEY_A), cut_message("Wrong permission"));
cut_assert_equal_int (-1, mifare_classic_get_trailer_block_permission(tag, 0x04, MCAB_WRITE_KEYB, MFC_KEY_B), cut_message ("Wrong permission")); cut_assert_equal_int(-1, mifare_classic_get_trailer_block_permission(tag, 0x04, MCAB_WRITE_KEYB, MFC_KEY_B), cut_message("Wrong permission"));
} }
void void
test_mifare_classic_get_trailer_permission (void) test_mifare_classic_get_trailer_permission(void)
{ {
int res; int res;
MifareClassicKey k = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; MifareClassicKey k = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
res = mifare_classic_authenticate (tag, 0x07, k, MFC_KEY_A); res = mifare_classic_authenticate(tag, 0x07, k, MFC_KEY_A);
cut_assert_equal_int (res, 0, cut_message ("mifare_classic_authenticate() failed")); cut_assert_equal_int(res, 0, cut_message("mifare_classic_authenticate() failed"));
cut_assert_equal_int (-1, mifare_classic_get_data_block_permission(tag, 0x07, MCAB_R, MFC_KEY_A), cut_message ("Wrong permission")); cut_assert_equal_int(-1, mifare_classic_get_data_block_permission(tag, 0x07, MCAB_R, MFC_KEY_A), cut_message("Wrong permission"));
cut_assert_equal_int (-1, mifare_classic_get_data_block_permission(tag, 0x07, MCAB_R, MFC_KEY_B), cut_message ("Wrong permission")); cut_assert_equal_int(-1, mifare_classic_get_data_block_permission(tag, 0x07, MCAB_R, MFC_KEY_B), cut_message("Wrong permission"));
cut_assert_equal_int (-1, mifare_classic_get_data_block_permission(tag, 0x07, MCAB_W, MFC_KEY_A), cut_message ("Wrong permission")); cut_assert_equal_int(-1, mifare_classic_get_data_block_permission(tag, 0x07, MCAB_W, MFC_KEY_A), cut_message("Wrong permission"));
cut_assert_equal_int (-1, mifare_classic_get_data_block_permission(tag, 0x07, MCAB_W, MFC_KEY_B), cut_message ("Wrong permission")); cut_assert_equal_int(-1, mifare_classic_get_data_block_permission(tag, 0x07, MCAB_W, MFC_KEY_B), cut_message("Wrong permission"));
cut_assert_equal_int (-1, mifare_classic_get_data_block_permission(tag, 0x07, MCAB_D, MFC_KEY_A), cut_message ("Wrong permission")); cut_assert_equal_int(-1, mifare_classic_get_data_block_permission(tag, 0x07, MCAB_D, MFC_KEY_A), cut_message("Wrong permission"));
cut_assert_equal_int (-1, mifare_classic_get_data_block_permission(tag, 0x07, MCAB_D, MFC_KEY_B), cut_message ("Wrong permission")); cut_assert_equal_int(-1, mifare_classic_get_data_block_permission(tag, 0x07, MCAB_D, MFC_KEY_B), cut_message("Wrong permission"));
cut_assert_equal_int (-1, mifare_classic_get_data_block_permission(tag, 0x07, MCAB_I, MFC_KEY_A), cut_message ("Wrong permission")); cut_assert_equal_int(-1, mifare_classic_get_data_block_permission(tag, 0x07, MCAB_I, MFC_KEY_A), cut_message("Wrong permission"));
cut_assert_equal_int (-1, mifare_classic_get_data_block_permission(tag, 0x07, MCAB_I, MFC_KEY_B), cut_message ("Wrong permission")); cut_assert_equal_int(-1, mifare_classic_get_data_block_permission(tag, 0x07, MCAB_I, MFC_KEY_B), cut_message("Wrong permission"));
cut_assert_equal_int (0, mifare_classic_get_trailer_block_permission(tag, 0x07, MCAB_READ_KEYA, MFC_KEY_A), cut_message ("Wrong permission")); cut_assert_equal_int(0, mifare_classic_get_trailer_block_permission(tag, 0x07, MCAB_READ_KEYA, MFC_KEY_A), cut_message("Wrong permission"));
cut_assert_equal_int (0, mifare_classic_get_trailer_block_permission(tag, 0x07, MCAB_READ_KEYA, MFC_KEY_B), cut_message ("Wrong permission")); cut_assert_equal_int(0, mifare_classic_get_trailer_block_permission(tag, 0x07, MCAB_READ_KEYA, MFC_KEY_B), cut_message("Wrong permission"));
cut_assert_equal_int (1, mifare_classic_get_trailer_block_permission(tag, 0x07, MCAB_WRITE_KEYA, MFC_KEY_A), cut_message ("Wrong permission")); cut_assert_equal_int(1, mifare_classic_get_trailer_block_permission(tag, 0x07, MCAB_WRITE_KEYA, MFC_KEY_A), cut_message("Wrong permission"));
cut_assert_equal_int (0, mifare_classic_get_trailer_block_permission(tag, 0x07, MCAB_WRITE_KEYA, MFC_KEY_B), cut_message ("Wrong permission")); cut_assert_equal_int(0, mifare_classic_get_trailer_block_permission(tag, 0x07, MCAB_WRITE_KEYA, MFC_KEY_B), cut_message("Wrong permission"));
cut_assert_equal_int (1, mifare_classic_get_trailer_block_permission(tag, 0x07, MCAB_READ_ACCESS_BITS, MFC_KEY_A), cut_message ("Wrong permission")); cut_assert_equal_int(1, mifare_classic_get_trailer_block_permission(tag, 0x07, MCAB_READ_ACCESS_BITS, MFC_KEY_A), cut_message("Wrong permission"));
cut_assert_equal_int (0, mifare_classic_get_trailer_block_permission(tag, 0x07, MCAB_READ_ACCESS_BITS, MFC_KEY_B), cut_message ("Wrong permission")); cut_assert_equal_int(0, mifare_classic_get_trailer_block_permission(tag, 0x07, MCAB_READ_ACCESS_BITS, MFC_KEY_B), cut_message("Wrong permission"));
cut_assert_equal_int (1, mifare_classic_get_trailer_block_permission(tag, 0x07, MCAB_WRITE_ACCESS_BITS, MFC_KEY_A), cut_message ("Wrong permission")); cut_assert_equal_int(1, mifare_classic_get_trailer_block_permission(tag, 0x07, MCAB_WRITE_ACCESS_BITS, MFC_KEY_A), cut_message("Wrong permission"));
cut_assert_equal_int (0, mifare_classic_get_trailer_block_permission(tag, 0x07, MCAB_WRITE_ACCESS_BITS, MFC_KEY_B), cut_message ("Wrong permission")); cut_assert_equal_int(0, mifare_classic_get_trailer_block_permission(tag, 0x07, MCAB_WRITE_ACCESS_BITS, MFC_KEY_B), cut_message("Wrong permission"));
cut_assert_equal_int (1, mifare_classic_get_trailer_block_permission(tag, 0x07, MCAB_READ_KEYB, MFC_KEY_A), cut_message ("Wrong permission")); cut_assert_equal_int(1, mifare_classic_get_trailer_block_permission(tag, 0x07, MCAB_READ_KEYB, MFC_KEY_A), cut_message("Wrong permission"));
cut_assert_equal_int (0, mifare_classic_get_trailer_block_permission(tag, 0x07, MCAB_READ_KEYB, MFC_KEY_B), cut_message ("Wrong permission")); cut_assert_equal_int(0, mifare_classic_get_trailer_block_permission(tag, 0x07, MCAB_READ_KEYB, MFC_KEY_B), cut_message("Wrong permission"));
cut_assert_equal_int (1, mifare_classic_get_trailer_block_permission(tag, 0x07, MCAB_WRITE_KEYB, MFC_KEY_A), cut_message ("Wrong permission")); cut_assert_equal_int(1, mifare_classic_get_trailer_block_permission(tag, 0x07, MCAB_WRITE_KEYB, MFC_KEY_A), cut_message("Wrong permission"));
cut_assert_equal_int (0, mifare_classic_get_trailer_block_permission(tag, 0x07, MCAB_WRITE_KEYB, MFC_KEY_B), cut_message ("Wrong permission")); cut_assert_equal_int(0, mifare_classic_get_trailer_block_permission(tag, 0x07, MCAB_WRITE_KEYB, MFC_KEY_B), cut_message("Wrong permission"));
} }
void void
test_mifare_classic_format_first_sector (void) test_mifare_classic_format_first_sector(void)
{ {
int res; int res;
MifareClassicKey k = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; MifareClassicKey k = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
res = mifare_classic_authenticate (tag, 0x00, k, MFC_KEY_A); res = mifare_classic_authenticate(tag, 0x00, k, MFC_KEY_A);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_authenticate() failed")); cut_assert_equal_int(0, res, cut_message("mifare_classic_authenticate() failed"));
MifareClassicBlock data = { MifareClassicBlock data = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
@ -112,54 +112,54 @@ test_mifare_classic_format_first_sector (void)
}; };
MifareClassicBlock empty; MifareClassicBlock empty;
memset (empty, '\x00', sizeof (empty)); memset(empty, '\x00', sizeof(empty));
MifareClassicBlock b0; MifareClassicBlock b0;
res = mifare_classic_read (tag, 0x00, &b0); res = mifare_classic_read(tag, 0x00, &b0);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_read() failed")); cut_assert_equal_int(0, res, cut_message("mifare_classic_read() failed"));
res = mifare_classic_write (tag, 0x00, data); res = mifare_classic_write(tag, 0x00, data);
cut_assert_equal_int (-1, res, cut_message ("mifare_classic_write() succeeded")); cut_assert_equal_int(-1, res, cut_message("mifare_classic_write() succeeded"));
res = mifare_classic_disconnect (tag); res = mifare_classic_disconnect(tag);
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"));
res = mifare_classic_authenticate (tag, 0x00, k, MFC_KEY_A); res = mifare_classic_authenticate(tag, 0x00, k, MFC_KEY_A);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_authenticate() failed")); cut_assert_equal_int(0, res, cut_message("mifare_classic_authenticate() failed"));
res = mifare_classic_write (tag, 0x01, data); res = mifare_classic_write(tag, 0x01, data);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_write() failed")); cut_assert_equal_int(0, res, cut_message("mifare_classic_write() failed"));
res = mifare_classic_write (tag, 0x02, data); res = mifare_classic_write(tag, 0x02, data);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_write() failed")); cut_assert_equal_int(0, res, cut_message("mifare_classic_write() failed"));
res = mifare_classic_format_sector (tag, 0x00); res = mifare_classic_format_sector(tag, 0x00);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_format_sector() failed")); cut_assert_equal_int(0, res, cut_message("mifare_classic_format_sector() failed"));
res = mifare_classic_read (tag, 0x00, &data); res = mifare_classic_read(tag, 0x00, &data);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_read() failed")); cut_assert_equal_int(0, res, cut_message("mifare_classic_read() failed"));
cut_assert_equal_memory (data, sizeof (data), b0, sizeof (b0), cut_message ("Data changed in first block (block 1/3)")); cut_assert_equal_memory(data, sizeof(data), b0, sizeof(b0), cut_message("Data changed in first block (block 1/3)"));
res = mifare_classic_read (tag, 0x01, &data); res = mifare_classic_read(tag, 0x01, &data);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_read() failed")); cut_assert_equal_int(0, res, cut_message("mifare_classic_read() failed"));
cut_assert_equal_memory (data, sizeof (data), empty, sizeof (data), cut_message ("Wrong data in formatted sector (block 2/3)")); cut_assert_equal_memory(data, sizeof(data), empty, sizeof(data), cut_message("Wrong data in formatted sector (block 2/3)"));
res = mifare_classic_read (tag, 0x02, &data); res = mifare_classic_read(tag, 0x02, &data);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_read() failed")); cut_assert_equal_int(0, res, cut_message("mifare_classic_read() failed"));
cut_assert_equal_memory (data, sizeof (data), empty, sizeof (data), cut_message ("Wrong data in formatted sector (block 3/3)")); cut_assert_equal_memory(data, sizeof(data), empty, sizeof(data), cut_message("Wrong data in formatted sector (block 3/3)"));
res = mifare_classic_read (tag, 0x03, &data); res = mifare_classic_read(tag, 0x03, &data);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_read() failed")); cut_assert_equal_int(0, res, cut_message("mifare_classic_read() failed"));
cut_assert_equal_memory (data, sizeof (data), "\x00\x00\x00\x00\x00\x00\xff\x07\x80\x69\xff\xff\xff\xff\xff\xff", sizeof (data), cut_message ("Wrong permissions in formatted sector")); cut_assert_equal_memory(data, sizeof(data), "\x00\x00\x00\x00\x00\x00\xff\x07\x80\x69\xff\xff\xff\xff\xff\xff", sizeof(data), cut_message("Wrong permissions in formatted sector"));
} }
void void
test_mifare_classic_format (void) test_mifare_classic_format(void)
{ {
int res; int res;
MifareClassicKey k = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; MifareClassicKey k = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
res = mifare_classic_authenticate (tag, 0x3c, k, MFC_KEY_A); res = mifare_classic_authenticate(tag, 0x3c, k, MFC_KEY_A);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_authenticate() failed")); cut_assert_equal_int(0, res, cut_message("mifare_classic_authenticate() failed"));
MifareClassicBlock data = { MifareClassicBlock data = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
@ -167,140 +167,140 @@ test_mifare_classic_format (void)
}; };
MifareClassicBlock empty; MifareClassicBlock empty;
memset (empty, 0, sizeof (empty)); memset(empty, 0, sizeof(empty));
res = mifare_classic_write (tag, 0x3c, data); res = mifare_classic_write(tag, 0x3c, data);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_write() failed")); cut_assert_equal_int(0, res, cut_message("mifare_classic_write() failed"));
res = mifare_classic_write (tag, 0x3d, data); res = mifare_classic_write(tag, 0x3d, data);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_write() failed")); cut_assert_equal_int(0, res, cut_message("mifare_classic_write() failed"));
res = mifare_classic_write (tag, 0x3e, data); res = mifare_classic_write(tag, 0x3e, data);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_write() failed")); cut_assert_equal_int(0, res, cut_message("mifare_classic_write() failed"));
res = mifare_classic_format_sector (tag, mifare_classic_block_sector (0x3c)); res = mifare_classic_format_sector(tag, mifare_classic_block_sector(0x3c));
cut_assert_equal_int (0, res, cut_message ("mifare_classic_format_sector() failed")); cut_assert_equal_int(0, res, cut_message("mifare_classic_format_sector() failed"));
res = mifare_classic_read (tag, 0x3c, &data); res = mifare_classic_read(tag, 0x3c, &data);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_read() failed")); cut_assert_equal_int(0, res, cut_message("mifare_classic_read() failed"));
cut_assert_equal_memory (data, sizeof (data), empty, sizeof (data), cut_message ("Wrong data in formatted sector (block 1/3)")); cut_assert_equal_memory(data, sizeof(data), empty, sizeof(data), cut_message("Wrong data in formatted sector (block 1/3)"));
res = mifare_classic_read (tag, 0x3d, &data); res = mifare_classic_read(tag, 0x3d, &data);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_read() failed")); cut_assert_equal_int(0, res, cut_message("mifare_classic_read() failed"));
cut_assert_equal_memory (data, sizeof (data), empty, sizeof (data), cut_message ("Wrong data in formatted sector (block 2/3)")); cut_assert_equal_memory(data, sizeof(data), empty, sizeof(data), cut_message("Wrong data in formatted sector (block 2/3)"));
res = mifare_classic_read (tag, 0x3e, &data); res = mifare_classic_read(tag, 0x3e, &data);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_read() failed")); cut_assert_equal_int(0, res, cut_message("mifare_classic_read() failed"));
cut_assert_equal_memory (data, sizeof (data), empty, sizeof (data), cut_message ("Wrong data in formatted sector (block 3/3)")); cut_assert_equal_memory(data, sizeof(data), empty, sizeof(data), cut_message("Wrong data in formatted sector (block 3/3)"));
res = mifare_classic_read (tag, 0x3f, &data); res = mifare_classic_read(tag, 0x3f, &data);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_read() failed")); cut_assert_equal_int(0, res, cut_message("mifare_classic_read() failed"));
cut_assert_equal_memory (data, sizeof (data), "\x00\x00\x00\x00\x00\x00\xff\x07\x80\x69\xff\xff\xff\xff\xff\xff", sizeof (data), cut_message ("Wrong permissions in formatted sector")); cut_assert_equal_memory(data, sizeof(data), "\x00\x00\x00\x00\x00\x00\xff\x07\x80\x69\xff\xff\xff\xff\xff\xff", sizeof(data), cut_message("Wrong permissions in formatted sector"));
} }
void void
test_mifare_classic_value_block_increment (void) test_mifare_classic_value_block_increment(void)
{ {
int res; int res;
MifareClassicBlockNumber block = 0x04; MifareClassicBlockNumber block = 0x04;
MifareClassicKey k = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; MifareClassicKey k = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
res = mifare_classic_authenticate (tag, block, k, MFC_KEY_A); res = mifare_classic_authenticate(tag, block, k, MFC_KEY_A);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_authenticate() failed")); cut_assert_equal_int(0, res, cut_message("mifare_classic_authenticate() failed"));
res = mifare_classic_init_value (tag, block, 1000, 0x00); res = mifare_classic_init_value(tag, block, 1000, 0x00);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_init_value() failed")); cut_assert_equal_int(0, res, cut_message("mifare_classic_init_value() failed"));
/* Initialize value block */ /* Initialize value block */
int32_t value; int32_t value;
MifareClassicBlockNumber adr; MifareClassicBlockNumber adr;
res = mifare_classic_read_value (tag, block, &value, &adr); res = mifare_classic_read_value(tag, block, &value, &adr);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_read_value() failed")); cut_assert_equal_int(0, res, cut_message("mifare_classic_read_value() failed"));
cut_assert_equal_int (1000, value, cut_message ("Wrong value block value")); cut_assert_equal_int(1000, value, cut_message("Wrong value block value"));
cut_assert_equal_int (0x00, adr, cut_message ("Wrong value block address")); cut_assert_equal_int(0x00, adr, cut_message("Wrong value block address"));
/* Increment by 1 */ /* Increment by 1 */
res = mifare_classic_increment (tag, block, 1); res = mifare_classic_increment(tag, block, 1);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_increment() failed")); cut_assert_equal_int(0, res, cut_message("mifare_classic_increment() failed"));
res = mifare_classic_transfer (tag, block); res = mifare_classic_transfer(tag, block);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_transfer() failed")); cut_assert_equal_int(0, res, cut_message("mifare_classic_transfer() failed"));
res = mifare_classic_read_value (tag, block, &value, &adr); res = mifare_classic_read_value(tag, block, &value, &adr);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_read_value() failed")); cut_assert_equal_int(0, res, cut_message("mifare_classic_read_value() failed"));
cut_assert_equal_int (1001, value, cut_message ("Wrong value block value")); cut_assert_equal_int(1001, value, cut_message("Wrong value block value"));
cut_assert_equal_int (0x00, adr, cut_message ("Wrong value block address")); cut_assert_equal_int(0x00, adr, cut_message("Wrong value block address"));
/* Increment by 10 */ /* Increment by 10 */
res = mifare_classic_increment (tag, block, 10); res = mifare_classic_increment(tag, block, 10);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_increment() failed")); cut_assert_equal_int(0, res, cut_message("mifare_classic_increment() failed"));
res = mifare_classic_transfer (tag, block); res = mifare_classic_transfer(tag, block);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_transfer() failed")); cut_assert_equal_int(0, res, cut_message("mifare_classic_transfer() failed"));
res = mifare_classic_read_value (tag, block, &value, &adr); res = mifare_classic_read_value(tag, block, &value, &adr);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_read_value() failed")); cut_assert_equal_int(0, res, cut_message("mifare_classic_read_value() failed"));
cut_assert_equal_int (1011, value, cut_message ("Wrong value block value")); cut_assert_equal_int(1011, value, cut_message("Wrong value block value"));
cut_assert_equal_int (0x00, adr, cut_message ("Wrong value block address")); cut_assert_equal_int(0x00, adr, cut_message("Wrong value block address"));
} }
void void
test_mifare_classic_value_block_decrement (void) test_mifare_classic_value_block_decrement(void)
{ {
int res; int res;
MifareClassicBlockNumber block = 0x04; MifareClassicBlockNumber block = 0x04;
MifareClassicKey k = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; MifareClassicKey k = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
res = mifare_classic_authenticate (tag, block, k, MFC_KEY_A); res = mifare_classic_authenticate(tag, block, k, MFC_KEY_A);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_authenticate() failed")); cut_assert_equal_int(0, res, cut_message("mifare_classic_authenticate() failed"));
res = mifare_classic_init_value (tag, block, 1000, 0x00); res = mifare_classic_init_value(tag, block, 1000, 0x00);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_init_value() failed")); cut_assert_equal_int(0, res, cut_message("mifare_classic_init_value() failed"));
/* Initialize value block */ /* Initialize value block */
int32_t value; int32_t value;
MifareClassicBlockNumber adr; MifareClassicBlockNumber adr;
res = mifare_classic_read_value (tag, block, &value, &adr); res = mifare_classic_read_value(tag, block, &value, &adr);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_read_value() failed")); cut_assert_equal_int(0, res, cut_message("mifare_classic_read_value() failed"));
cut_assert_equal_int (1000, value, cut_message ("Wrong value block value")); cut_assert_equal_int(1000, value, cut_message("Wrong value block value"));
cut_assert_equal_int (0x00, adr, cut_message ("Wrong value block address")); cut_assert_equal_int(0x00, adr, cut_message("Wrong value block address"));
/* Decrement */ /* Decrement */
res = mifare_classic_decrement (tag, block, 1); res = mifare_classic_decrement(tag, block, 1);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_decrement() failed")); cut_assert_equal_int(0, res, cut_message("mifare_classic_decrement() failed"));
res = mifare_classic_transfer (tag, block); res = mifare_classic_transfer(tag, block);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_transfer() failed")); cut_assert_equal_int(0, res, cut_message("mifare_classic_transfer() failed"));
res = mifare_classic_read_value (tag, block, &value, &adr); res = mifare_classic_read_value(tag, block, &value, &adr);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_read_value() failed")); cut_assert_equal_int(0, res, cut_message("mifare_classic_read_value() failed"));
cut_assert_equal_int (999, value, cut_message ("Wrong value block value")); cut_assert_equal_int(999, value, cut_message("Wrong value block value"));
cut_assert_equal_int (0x00, adr, cut_message ("Wrong value block address")); cut_assert_equal_int(0x00, adr, cut_message("Wrong value block address"));
res = mifare_classic_decrement (tag, block, 1000); res = mifare_classic_decrement(tag, block, 1000);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_decrement() failed")); cut_assert_equal_int(0, res, cut_message("mifare_classic_decrement() failed"));
res = mifare_classic_transfer (tag, block); res = mifare_classic_transfer(tag, block);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_transfer() failed")); cut_assert_equal_int(0, res, cut_message("mifare_classic_transfer() failed"));
res = mifare_classic_read_value (tag, block, &value, &adr); res = mifare_classic_read_value(tag, block, &value, &adr);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_read_value() failed")); cut_assert_equal_int(0, res, cut_message("mifare_classic_read_value() failed"));
cut_assert_equal_int (-1, value, cut_message ("Wrong value block value")); cut_assert_equal_int(-1, value, cut_message("Wrong value block value"));
cut_assert_equal_int (0x00, adr, cut_message ("Wrong value block address")); cut_assert_equal_int(0x00, adr, cut_message("Wrong value block address"));
} }
void void
test_mifare_classic_value_block_restore (void) test_mifare_classic_value_block_restore(void)
{ {
int res; int res;
MifareClassicBlockNumber block = 0x04; MifareClassicBlockNumber block = 0x04;
MifareClassicKey k = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; MifareClassicKey k = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
res = mifare_classic_authenticate (tag, block, k, MFC_KEY_A); res = mifare_classic_authenticate(tag, block, k, MFC_KEY_A);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_authenticate() failed")); cut_assert_equal_int(0, res, cut_message("mifare_classic_authenticate() failed"));
/* Restore */ /* Restore */
@ -326,49 +326,49 @@ test_mifare_classic_value_block_restore (void)
0xff 0xff
}; };
res = mifare_classic_write (tag, block, sample); res = mifare_classic_write(tag, block, sample);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_write() failed")); cut_assert_equal_int(0, res, cut_message("mifare_classic_write() failed"));
res = mifare_classic_read (tag, block, &data); res = mifare_classic_read(tag, block, &data);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_read() failed")); cut_assert_equal_int(0, res, cut_message("mifare_classic_read() failed"));
cut_assert_equal_memory (sample, sizeof (sample), data, sizeof (data), cut_message ("Wrong value block contents")); cut_assert_equal_memory(sample, sizeof(sample), data, sizeof(data), cut_message("Wrong value block contents"));
res = mifare_classic_write (tag, block+1, nul); res = mifare_classic_write(tag, block + 1, nul);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_write() failed")); cut_assert_equal_int(0, res, cut_message("mifare_classic_write() failed"));
res = mifare_classic_read (tag, block+1, &data); res = mifare_classic_read(tag, block + 1, &data);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_read() failed")); cut_assert_equal_int(0, res, cut_message("mifare_classic_read() failed"));
cut_assert_equal_memory (nul, sizeof (sample), data, sizeof (data), cut_message ("Wrong value block contents")); cut_assert_equal_memory(nul, sizeof(sample), data, sizeof(data), cut_message("Wrong value block contents"));
res = mifare_classic_restore (tag, block); res = mifare_classic_restore(tag, block);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_restore() failed")); cut_assert_equal_int(0, res, cut_message("mifare_classic_restore() failed"));
res = mifare_classic_transfer (tag, block+1); res = mifare_classic_transfer(tag, block + 1);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_transfer() failed")); cut_assert_equal_int(0, res, cut_message("mifare_classic_transfer() failed"));
res = mifare_classic_read (tag, block+1, &data); res = mifare_classic_read(tag, block + 1, &data);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_read() failed")); cut_assert_equal_int(0, res, cut_message("mifare_classic_read() failed"));
cut_assert_equal_memory (sample, sizeof (sample), data, sizeof (data), cut_message ("Wrong value block contents")); cut_assert_equal_memory(sample, sizeof(sample), data, sizeof(data), cut_message("Wrong value block contents"));
} }
void void
test_mifare_classic_get_uid (void) test_mifare_classic_get_uid(void)
{ {
char *uid; char *uid;
uid = freefare_get_tag_uid (tag); uid = freefare_get_tag_uid(tag);
cut_assert_not_null (uid, cut_message ("freefare_get_tag_uid() failed")); cut_assert_not_null(uid, cut_message("freefare_get_tag_uid() failed"));
cut_assert (((strlen (uid) == 8)||(strlen (uid) == 14)), cut_message ("Wrong UID length")); cut_assert(((strlen(uid) == 8) || (strlen(uid) == 14)), cut_message("Wrong UID length"));
free (uid); free(uid);
} }
void void
test_mifare_classic_get_tag_friendly_name (void) test_mifare_classic_get_tag_friendly_name(void)
{ {
const char *name = freefare_get_tag_friendly_name (tag); const char *name = freefare_get_tag_friendly_name(tag);
cut_assert_not_null (name, cut_message ("freefare_get_tag_friendly_name() failed")); cut_assert_not_null(name, cut_message("freefare_get_tag_friendly_name() failed"));
} }

View file

@ -20,15 +20,15 @@
#include <freefare.h> #include <freefare.h>
void void
test_mifare_classic_create_trailer_block (void) test_mifare_classic_create_trailer_block(void)
{ {
MifareClassicBlock data; MifareClassicBlock data;
MifareClassicKey key_a = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; MifareClassicKey key_a = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
MifareClassicKey key_b = { 0xde, 0xad, 0xbe, 0xef, 0xff, 0xff }; MifareClassicKey key_b = { 0xde, 0xad, 0xbe, 0xef, 0xff, 0xff };
mifare_classic_trailer_block (&data, key_a, 0, 0, 0, 4, 0x42, key_b); mifare_classic_trailer_block(&data, key_a, 0, 0, 0, 4, 0x42, key_b);
cut_assert_equal_memory (data, sizeof (data), "\xff\xff\xff\xff\xff\xff\xff\x07\x80\x42\xde\xad\xbe\xef\xff\xff", sizeof (data), cut_message ("Wrong generated block")); cut_assert_equal_memory(data, sizeof(data), "\xff\xff\xff\xff\xff\xff\xff\x07\x80\x42\xde\xad\xbe\xef\xff\xff", sizeof(data), cut_message("Wrong generated block"));
} }

View file

@ -22,11 +22,11 @@
#include "mifare_classic_fixture.h" #include "mifare_classic_fixture.h"
void void
test_mifare_classic_mad (void) test_mifare_classic_mad(void)
{ {
MifareClassicKey key_a_transport = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; MifareClassicKey key_a_transport = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
MifareClassicKey key_b_sector_00 = { 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; MifareClassicKey key_b_sector_00 = { 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff };
MifareClassicKey key_b_sector_10 = { 0x1a, 0x98, 0x2c, 0x7e, 0x45 ,0x9a }; MifareClassicKey key_b_sector_10 = { 0x1a, 0x98, 0x2c, 0x7e, 0x45, 0x9a };
MifareClassicBlock tb; MifareClassicBlock tb;
Mad mad; Mad mad;
int res; int res;
@ -37,21 +37,21 @@ test_mifare_classic_mad (void)
* |_| |_/_/ \_\___/ \_/|_| * |_| |_/_/ \_\___/ \_/|_|
*/ */
mad = mad_new (1); mad = mad_new(1);
cut_assert_not_null (mad, cut_message ("mad_new() failed")); cut_assert_not_null(mad, cut_message("mad_new() failed"));
// Prepare sector 0x00 for writing a MAD. // Prepare sector 0x00 for writing a MAD.
res = mifare_classic_authenticate (tag, 0x00, key_a_transport, MFC_KEY_A); res = mifare_classic_authenticate(tag, 0x00, key_a_transport, MFC_KEY_A);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_authenticate() failed")); cut_assert_equal_int(0, res, cut_message("mifare_classic_authenticate() failed"));
mifare_classic_trailer_block (&tb, key_a_transport, 00, 00, 00, 06, 0x00, key_b_sector_00); mifare_classic_trailer_block(&tb, key_a_transport, 00, 00, 00, 06, 0x00, key_b_sector_00);
res = mifare_classic_write (tag, 0x03, tb); res = mifare_classic_write(tag, 0x03, tb);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_write() failed")); cut_assert_equal_int(0, res, cut_message("mifare_classic_write() failed"));
// Write the empty MAD // Write the empty MAD
res = mad_write (tag, mad, key_b_sector_00, NULL); res = mad_write(tag, mad, key_b_sector_00, NULL);
cut_assert_equal_int (0, res, cut_message ("mad_write() failed")); cut_assert_equal_int(0, res, cut_message("mad_write() failed"));
// Check the empty MAD // Check the empty MAD
@ -65,27 +65,27 @@ test_mifare_classic_mad (void)
}; };
MifareClassicBlock data; MifareClassicBlock data;
res = mifare_classic_authenticate (tag, 0x01, mad_public_key_a, MFC_KEY_A); res = mifare_classic_authenticate(tag, 0x01, mad_public_key_a, MFC_KEY_A);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_authenticate() failed")); cut_assert_equal_int(0, res, cut_message("mifare_classic_authenticate() failed"));
res = mifare_classic_read (tag, 0x01, &data); res = mifare_classic_read(tag, 0x01, &data);
cut_assert_equal_int (0, res, cut_message ("mad_read() failed")); cut_assert_equal_int(0, res, cut_message("mad_read() failed"));
cut_assert_equal_memory (ref_01, sizeof (ref_01), data, sizeof (data), cut_message ("Wrong data")); cut_assert_equal_memory(ref_01, sizeof(ref_01), data, sizeof(data), cut_message("Wrong data"));
res = mifare_classic_read (tag, 0x02, &data); res = mifare_classic_read(tag, 0x02, &data);
cut_assert_equal_int (0, res, cut_message ("mad_read() failed")); cut_assert_equal_int(0, res, cut_message("mad_read() failed"));
cut_assert_equal_memory (ref_02, sizeof (ref_02), data, sizeof (data), cut_message ("Wrong data")); cut_assert_equal_memory(ref_02, sizeof(ref_02), data, sizeof(data), cut_message("Wrong data"));
Mad mad2 = mad_read (tag); Mad mad2 = mad_read(tag);
cut_assert_not_null (mad2, cut_message ("mad_read() failed")); cut_assert_not_null(mad2, cut_message("mad_read() failed"));
cut_assert_equal_memory (mad, sizeof (mad), mad2, sizeof (mad2), cut_message ("Wrong MAD")); cut_assert_equal_memory(mad, sizeof(mad), mad2, sizeof(mad2), cut_message("Wrong MAD"));
const char application_data[] = "APPLICATION DATA >> APPLICATION DATA >> APPLICATION DATA >> " \ const char application_data[] = "APPLICATION DATA >> APPLICATION DATA >> APPLICATION DATA >> " \
"APPLICATION DATA >> APPLICATION DATA >> APPLICATION DATA >> " \ "APPLICATION DATA >> APPLICATION DATA >> APPLICATION DATA >> " \
"APPLICATION DATA >> APPLICATION DATA >> APPLICATION DATA >> " \ "APPLICATION DATA >> APPLICATION DATA >> APPLICATION DATA >> " \
"APPLICATION DATA >> APPLICATION DATA >> APPLICATION DATA >> " \ "APPLICATION DATA >> APPLICATION DATA >> APPLICATION DATA >> " \
"APPLICATION DATA >> APPLICATION DATA >> APPLICATION DATA >> " \ "APPLICATION DATA >> APPLICATION DATA >> APPLICATION DATA >> " \
"APPLICATION DATA >> APPLICATION DATA >> APPLICATION DATA >> "; "APPLICATION DATA >> APPLICATION DATA >> APPLICATION DATA >> ";
MadAid aid = { MadAid aid = {
.function_cluster_code = 0x01, .function_cluster_code = 0x01,
@ -93,78 +93,78 @@ test_mifare_classic_mad (void)
}; };
// Write some data in the application // Write some data in the application
MifareClassicSectorNumber *sectors = mifare_application_alloc (mad, aid, sizeof (application_data)); MifareClassicSectorNumber *sectors = mifare_application_alloc(mad, aid, sizeof(application_data));
cut_assert_not_null (sectors, cut_message ("mifare_application_alloc() failed")); cut_assert_not_null(sectors, cut_message("mifare_application_alloc() failed"));
free (sectors); free(sectors);
res = mad_write (tag, mad, key_b_sector_00, NULL); res = mad_write(tag, mad, key_b_sector_00, NULL);
cut_assert_equal_int (0, res, cut_message ("mad_write() failed")); cut_assert_equal_int(0, res, cut_message("mad_write() failed"));
ssize_t s = mifare_application_write (tag, mad, aid, &application_data, sizeof (application_data), key_a_transport, MFC_KEY_A); ssize_t s = mifare_application_write(tag, mad, aid, &application_data, sizeof(application_data), key_a_transport, MFC_KEY_A);
cut_assert_equal_int (sizeof (application_data), s, cut_message ("mifare_application_write() failed")); cut_assert_equal_int(sizeof(application_data), s, cut_message("mifare_application_write() failed"));
char read_buf[500]; char read_buf[500];
// Read it again // Read it again
s = mifare_application_read (tag, mad, aid, read_buf, sizeof (application_data), key_a_transport, MFC_KEY_A); s = mifare_application_read(tag, mad, aid, read_buf, sizeof(application_data), key_a_transport, MFC_KEY_A);
cut_assert_equal_int (sizeof (application_data), s, cut_message ("mifare_application_read() failed")); cut_assert_equal_int(sizeof(application_data), s, cut_message("mifare_application_read() failed"));
cut_assert_equal_memory (application_data, sizeof (application_data), read_buf, s, cut_message ("Wrong application data")); cut_assert_equal_memory(application_data, sizeof(application_data), read_buf, s, cut_message("Wrong application data"));
mad_free (mad); mad_free(mad);
mad_free (mad2); mad_free(mad2);
// Revert to the transport configuration // Revert to the transport configuration
res = mifare_classic_authenticate (tag, 0x00, key_b_sector_00, MFC_KEY_B); res = mifare_classic_authenticate(tag, 0x00, key_b_sector_00, MFC_KEY_B);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_authenticate() failed")); cut_assert_equal_int(0, res, cut_message("mifare_classic_authenticate() failed"));
res = mifare_classic_format_sector (tag, 0x00); res = mifare_classic_format_sector(tag, 0x00);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_format_sector() failed")); cut_assert_equal_int(0, res, cut_message("mifare_classic_format_sector() failed"));
/* __ __ _ ___ ___ /* __ __ _ ___ ___
* | \/ | /_\ | \__ _|_ ) * | \/ | /_\ | \__ _|_ )
* | |\/| |/ _ \| |) \ V // / * | |\/| |/ _ \| |) \ V // /
* |_| |_/_/ \_\___/ \_//___| * |_| |_/_/ \_\___/ \_//___|
*/ */
if (freefare_get_tag_type (tag) != MIFARE_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");
} }
mad = mad_new (2); mad = mad_new(2);
cut_assert_not_null (mad, cut_message ("mad_new() failed")); cut_assert_not_null(mad, cut_message("mad_new() failed"));
// Prepare sector 0x00 for writing a MAD. // Prepare sector 0x00 for writing a MAD.
res = mifare_classic_authenticate (tag, 0x00, key_a_transport, MFC_KEY_A); res = mifare_classic_authenticate(tag, 0x00, key_a_transport, MFC_KEY_A);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_authenticate() failed")); cut_assert_equal_int(0, res, cut_message("mifare_classic_authenticate() failed"));
mifare_classic_trailer_block (&tb, key_a_transport, 00, 00, 00, 06, 0x00, key_b_sector_00); mifare_classic_trailer_block(&tb, key_a_transport, 00, 00, 00, 06, 0x00, key_b_sector_00);
res = mifare_classic_write (tag, 0x03, tb); res = mifare_classic_write(tag, 0x03, tb);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_write() failed")); cut_assert_equal_int(0, res, cut_message("mifare_classic_write() failed"));
// Prepare sector 0x10 for writing a MAD. // Prepare sector 0x10 for writing a MAD.
res = mifare_classic_authenticate (tag, 0x40, key_a_transport, MFC_KEY_A); res = mifare_classic_authenticate(tag, 0x40, key_a_transport, MFC_KEY_A);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_authenticate() failed")); cut_assert_equal_int(0, res, cut_message("mifare_classic_authenticate() failed"));
mifare_classic_trailer_block (&tb, key_a_transport, 00, 00, 00, 06, 0x00, key_b_sector_10); mifare_classic_trailer_block(&tb, key_a_transport, 00, 00, 00, 06, 0x00, key_b_sector_10);
res = mifare_classic_write (tag, 0x43, tb); res = mifare_classic_write(tag, 0x43, tb);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_write() failed")); cut_assert_equal_int(0, res, cut_message("mifare_classic_write() failed"));
// Write the empty MAD // Write the empty MAD
res = mad_write (tag, mad, key_b_sector_00, key_b_sector_10); res = mad_write(tag, mad, key_b_sector_00, key_b_sector_10);
cut_assert_equal_int (0, res, cut_message ("mad_write() failed")); cut_assert_equal_int(0, res, cut_message("mad_write() failed"));
// Check the empty MAD // Check the empty MAD
res = mifare_classic_authenticate (tag, 0x01, mad_public_key_a, MFC_KEY_A); res = mifare_classic_authenticate(tag, 0x01, mad_public_key_a, MFC_KEY_A);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_authenticate() failed")); cut_assert_equal_int(0, res, cut_message("mifare_classic_authenticate() failed"));
res = mifare_classic_read (tag, 0x01, &data); res = mifare_classic_read(tag, 0x01, &data);
cut_assert_equal_int (0, res, cut_message ("mad_read() failed")); cut_assert_equal_int(0, res, cut_message("mad_read() failed"));
cut_assert_equal_memory (ref_01, sizeof (ref_01), data, sizeof (data), cut_message ("Wrong data")); cut_assert_equal_memory(ref_01, sizeof(ref_01), data, sizeof(data), cut_message("Wrong data"));
res = mifare_classic_read (tag, 0x02, &data); res = mifare_classic_read(tag, 0x02, &data);
cut_assert_equal_int (0, res, cut_message ("mad_read() failed")); cut_assert_equal_int(0, res, cut_message("mad_read() failed"));
cut_assert_equal_memory (ref_02, sizeof (ref_02), data, sizeof (data), cut_message ("Wrong data")); cut_assert_equal_memory(ref_02, sizeof(ref_02), data, sizeof(data), cut_message("Wrong data"));
MifareClassicBlock ref_40 = { MifareClassicBlock ref_40 = {
0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@ -179,54 +179,54 @@ test_mifare_classic_mad (void)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}; };
res = mifare_classic_authenticate (tag, 0x40, mad_public_key_a, MFC_KEY_A); res = mifare_classic_authenticate(tag, 0x40, mad_public_key_a, MFC_KEY_A);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_authenticate() failed")); cut_assert_equal_int(0, res, cut_message("mifare_classic_authenticate() failed"));
res = mifare_classic_read (tag, 0x40, &data); res = mifare_classic_read(tag, 0x40, &data);
cut_assert_equal_int (0, res, cut_message ("mad_read() failed")); cut_assert_equal_int(0, res, cut_message("mad_read() failed"));
cut_assert_equal_memory (ref_40, sizeof (ref_01), data, sizeof (data), cut_message ("Wrong data")); cut_assert_equal_memory(ref_40, sizeof(ref_01), data, sizeof(data), cut_message("Wrong data"));
res = mifare_classic_read (tag, 0x41, &data); res = mifare_classic_read(tag, 0x41, &data);
cut_assert_equal_int (0, res, cut_message ("mad_read() failed")); cut_assert_equal_int(0, res, cut_message("mad_read() failed"));
cut_assert_equal_memory (ref_41, sizeof (ref_02), data, sizeof (data), cut_message ("Wrong data")); cut_assert_equal_memory(ref_41, sizeof(ref_02), data, sizeof(data), cut_message("Wrong data"));
res = mifare_classic_read (tag, 0x42, &data); res = mifare_classic_read(tag, 0x42, &data);
cut_assert_equal_int (0, res, cut_message ("mad_read() failed")); cut_assert_equal_int(0, res, cut_message("mad_read() failed"));
cut_assert_equal_memory (ref_42, sizeof (ref_02), data, sizeof (data), cut_message ("Wrong data")); cut_assert_equal_memory(ref_42, sizeof(ref_02), data, sizeof(data), cut_message("Wrong data"));
mad2 = mad_read (tag); mad2 = mad_read(tag);
cut_assert_not_null (mad2, cut_message ("mad_read() failed")); cut_assert_not_null(mad2, cut_message("mad_read() failed"));
cut_assert_equal_memory (mad, sizeof (mad), mad2, sizeof (mad2), cut_message ("Wrong MAD")); cut_assert_equal_memory(mad, sizeof(mad), mad2, sizeof(mad2), cut_message("Wrong MAD"));
// Write some data in the application // Write some data in the application
sectors = mifare_application_alloc (mad, aid, sizeof (application_data)); sectors = mifare_application_alloc(mad, aid, sizeof(application_data));
cut_assert_not_null (sectors, cut_message ("mifare_application_alloc() failed")); cut_assert_not_null(sectors, cut_message("mifare_application_alloc() failed"));
free (sectors); free(sectors);
res = mad_write (tag, mad, key_b_sector_00, key_b_sector_10); res = mad_write(tag, mad, key_b_sector_00, key_b_sector_10);
cut_assert_equal_int (0, res, cut_message ("mad_write() failed")); cut_assert_equal_int(0, res, cut_message("mad_write() failed"));
s = mifare_application_write (tag, mad, aid, &application_data, sizeof (application_data), key_a_transport, MFC_KEY_A); s = mifare_application_write(tag, mad, aid, &application_data, sizeof(application_data), key_a_transport, MFC_KEY_A);
cut_assert_equal_int (sizeof (application_data), s, cut_message ("mifare_application_write() failed")); cut_assert_equal_int(sizeof(application_data), s, cut_message("mifare_application_write() failed"));
// Read it again // Read it again
s = mifare_application_read (tag, mad, aid, read_buf, sizeof (application_data), key_a_transport, MFC_KEY_A); s = mifare_application_read(tag, mad, aid, read_buf, sizeof(application_data), key_a_transport, MFC_KEY_A);
cut_assert_equal_int (sizeof (application_data), s, cut_message ("mifare_application_read() failed")); cut_assert_equal_int(sizeof(application_data), s, cut_message("mifare_application_read() failed"));
cut_assert_equal_memory (application_data, sizeof (application_data), read_buf, s, cut_message ("Wrong application data")); cut_assert_equal_memory(application_data, sizeof(application_data), read_buf, s, cut_message("Wrong application data"));
mad_free (mad); mad_free(mad);
mad_free (mad2); mad_free(mad2);
// Revert to the transport configuration // Revert to the transport configuration
res = mifare_classic_authenticate (tag, 0x00, key_b_sector_00, MFC_KEY_B); res = mifare_classic_authenticate(tag, 0x00, key_b_sector_00, MFC_KEY_B);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_authenticate() failed")); cut_assert_equal_int(0, res, cut_message("mifare_classic_authenticate() failed"));
res = mifare_classic_format_sector (tag, 0x00); res = mifare_classic_format_sector(tag, 0x00);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_format_sector() failed")); cut_assert_equal_int(0, res, cut_message("mifare_classic_format_sector() failed"));
res = mifare_classic_authenticate (tag, 0x40, key_b_sector_10, MFC_KEY_B); res = mifare_classic_authenticate(tag, 0x40, key_b_sector_10, MFC_KEY_B);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_authenticate() failed")); cut_assert_equal_int(0, res, cut_message("mifare_classic_authenticate() failed"));
res = mifare_classic_format_sector (tag, 0x10); res = mifare_classic_format_sector(tag, 0x10);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_format_sector() failed")); cut_assert_equal_int(0, res, cut_message("mifare_classic_format_sector() failed"));
} }

View file

@ -21,19 +21,19 @@
#include "freefare_internal.h" #include "freefare_internal.h"
void void
test_mifare_classic_sector_boundaries (void) test_mifare_classic_sector_boundaries(void)
{ {
for (int i=0; i < 32; i++) { for (int i = 0; i < 32; i++) {
for (int j=0; j < 4; j++) { for (int j = 0; j < 4; j++) {
cut_assert_equal_int (4 * i, mifare_classic_sector_first_block (mifare_classic_block_sector (4 * i)), cut_message ("Wrong first block number for block %d", i)); cut_assert_equal_int(4 * i, mifare_classic_sector_first_block(mifare_classic_block_sector(4 * i)), cut_message("Wrong first block number for block %d", i));
cut_assert_equal_int (4 * i + 3, mifare_classic_sector_last_block (mifare_classic_block_sector (4 * i + j)), cut_message ("Wrong last block number for block %d", i)); cut_assert_equal_int(4 * i + 3, mifare_classic_sector_last_block(mifare_classic_block_sector(4 * i + j)), cut_message("Wrong last block number for block %d", i));
} }
} }
for (int i=0; i < 8; i++) { for (int i = 0; i < 8; i++) {
for (int j=0; j < 16; j++) { for (int j = 0; j < 16; j++) {
cut_assert_equal_int (128 + 16 * i, mifare_classic_sector_first_block (mifare_classic_block_sector (128 + 16 * i)), cut_message ("Wrong last block number for block %d", i)); cut_assert_equal_int(128 + 16 * i, mifare_classic_sector_first_block(mifare_classic_block_sector(128 + 16 * i)), cut_message("Wrong last block number for block %d", i));
cut_assert_equal_int (128 + 16 * i + 15, mifare_classic_sector_last_block (mifare_classic_block_sector (128 + 16 * i + j)), cut_message ("Wrong last block number for block %d", i)); cut_assert_equal_int(128 + 16 * i + 15, mifare_classic_sector_last_block(mifare_classic_block_sector(128 + 16 * i + j)), cut_message("Wrong last block number for block %d", i));
} }
} }
} }

File diff suppressed because it is too large Load diff

View file

@ -38,7 +38,7 @@ uint8_t key_data[] = {
void void
test_mifare_desfire_aes_generate_subkeys (void) test_mifare_desfire_aes_generate_subkeys(void)
{ {
uint8_t sk1[] = { uint8_t sk1[] = {
0xfb, 0xee, 0xd6, 0x18, 0xfb, 0xee, 0xd6, 0x18,
@ -54,23 +54,23 @@ test_mifare_desfire_aes_generate_subkeys (void)
0xe4, 0x6d, 0x51, 0x3b 0xe4, 0x6d, 0x51, 0x3b
}; };
MifareDESFireKey key = mifare_desfire_aes_key_new (key_data); MifareDESFireKey key = mifare_desfire_aes_key_new(key_data);
cmac_generate_subkeys (key); cmac_generate_subkeys(key);
cut_assert_equal_memory (sk1, 16, key->cmac_sk1, 16, cut_message ("Wrong sub-key 1")); cut_assert_equal_memory(sk1, 16, key->cmac_sk1, 16, cut_message("Wrong sub-key 1"));
cut_assert_equal_memory (sk2, 16, key->cmac_sk2, 16, cut_message ("Wrong sub-key 2")); cut_assert_equal_memory(sk2, 16, key->cmac_sk2, 16, cut_message("Wrong sub-key 2"));
mifare_desfire_key_free (key); mifare_desfire_key_free(key);
} }
void void
test_mifare_desfire_aes_cmac_empty (void) test_mifare_desfire_aes_cmac_empty(void)
{ {
MifareDESFireKey key = mifare_desfire_aes_key_new (key_data); MifareDESFireKey key = mifare_desfire_aes_key_new(key_data);
cmac_generate_subkeys (key); cmac_generate_subkeys(key);
uint8_t ivect[16]; uint8_t ivect[16];
memset (ivect, 0, sizeof (ivect)); memset(ivect, 0, sizeof(ivect));
uint8_t expected_cmac[] = { uint8_t expected_cmac[] = {
0xbb, 0x1d, 0x69, 0x29, 0xbb, 0x1d, 0x69, 0x29,
@ -80,21 +80,21 @@ test_mifare_desfire_aes_cmac_empty (void)
}; };
uint8_t my_cmac[16]; uint8_t my_cmac[16];
cmac (key, ivect, NULL, 0, my_cmac); cmac(key, ivect, NULL, 0, my_cmac);
cut_assert_equal_memory (expected_cmac, 16, my_cmac, 16, cut_message ("Wrong CMAC")); cut_assert_equal_memory(expected_cmac, 16, my_cmac, 16, cut_message("Wrong CMAC"));
mifare_desfire_key_free (key); mifare_desfire_key_free(key);
} }
void void
test_mifare_desfire_aes_cmac_128 (void) test_mifare_desfire_aes_cmac_128(void)
{ {
MifareDESFireKey key = mifare_desfire_aes_key_new (key_data); MifareDESFireKey key = mifare_desfire_aes_key_new(key_data);
cmac_generate_subkeys (key); cmac_generate_subkeys(key);
uint8_t ivect[16]; uint8_t ivect[16];
memset (ivect, 0, sizeof (ivect)); memset(ivect, 0, sizeof(ivect));
uint8_t message[] = { uint8_t message[] = {
0x6b, 0xc1, 0xbe, 0xe2, 0x6b, 0xc1, 0xbe, 0xe2,
@ -111,21 +111,21 @@ test_mifare_desfire_aes_cmac_128 (void)
}; };
uint8_t my_cmac[16]; uint8_t my_cmac[16];
cmac (key, ivect, message, 16, my_cmac); cmac(key, ivect, message, 16, my_cmac);
cut_assert_equal_memory (expected_cmac, 16, my_cmac, sizeof (message), cut_message ("Wrong CMAC")); cut_assert_equal_memory(expected_cmac, 16, my_cmac, sizeof(message), cut_message("Wrong CMAC"));
mifare_desfire_key_free (key); mifare_desfire_key_free(key);
} }
void void
test_mifare_desfire_aes_cmac_320 (void) test_mifare_desfire_aes_cmac_320(void)
{ {
MifareDESFireKey key = mifare_desfire_aes_key_new (key_data); MifareDESFireKey key = mifare_desfire_aes_key_new(key_data);
cmac_generate_subkeys (key); cmac_generate_subkeys(key);
uint8_t ivect[16]; uint8_t ivect[16];
memset (ivect, 0, sizeof (ivect)); memset(ivect, 0, sizeof(ivect));
uint8_t message[] = { uint8_t message[] = {
0x6b, 0xc1, 0xbe, 0xe2, 0x6b, 0xc1, 0xbe, 0xe2,
@ -148,21 +148,21 @@ test_mifare_desfire_aes_cmac_320 (void)
}; };
uint8_t my_cmac[16]; uint8_t my_cmac[16];
cmac (key, ivect, message, sizeof (message), my_cmac); cmac(key, ivect, message, sizeof(message), my_cmac);
cut_assert_equal_memory (expected_cmac, 16, my_cmac, 16, cut_message ("Wrong CMAC")); cut_assert_equal_memory(expected_cmac, 16, my_cmac, 16, cut_message("Wrong CMAC"));
mifare_desfire_key_free (key); mifare_desfire_key_free(key);
} }
void void
test_mifare_desfire_aes_cmac_512 (void) test_mifare_desfire_aes_cmac_512(void)
{ {
MifareDESFireKey key = mifare_desfire_aes_key_new (key_data); MifareDESFireKey key = mifare_desfire_aes_key_new(key_data);
cmac_generate_subkeys (key); cmac_generate_subkeys(key);
uint8_t ivect[16]; uint8_t ivect[16];
memset (ivect, 0, sizeof (ivect)); memset(ivect, 0, sizeof(ivect));
uint8_t message[] = { uint8_t message[] = {
0x6b, 0xc1, 0xbe, 0xe2, 0x6b, 0xc1, 0xbe, 0xe2,
@ -191,9 +191,9 @@ test_mifare_desfire_aes_cmac_512 (void)
}; };
uint8_t my_cmac[16]; uint8_t my_cmac[16];
cmac (key, ivect, message, sizeof (message), my_cmac); cmac(key, ivect, message, sizeof(message), my_cmac);
cut_assert_equal_memory (expected_cmac, 16, my_cmac, 16, cut_message ("Wrong CMAC")); cut_assert_equal_memory(expected_cmac, 16, my_cmac, 16, cut_message("Wrong CMAC"));
mifare_desfire_key_free (key); mifare_desfire_key_free(key);
} }

View file

@ -21,7 +21,7 @@
#include "freefare_internal.h" #include "freefare_internal.h"
void void
test_mifare_desfire_aid (void) test_mifare_desfire_aid(void)
{ {
/* /*
* <-- LSB MSB --> * <-- LSB MSB -->
@ -33,17 +33,17 @@ test_mifare_desfire_aid (void)
* *
* 0xF21438 -> 0x83412F * 0xF21438 -> 0x83412F
*/ */
MifareDESFireAID desfire_aid = mifare_desfire_aid_new (0x00f12ab8); MifareDESFireAID desfire_aid = mifare_desfire_aid_new(0x00f12ab8);
MadAid mad_aid = { MadAid mad_aid = {
.function_cluster_code = 0x12, .function_cluster_code = 0x12,
.application_code = 0xab, .application_code = 0xab,
}; };
MifareDESFireAID desfire_aid2 = mifare_desfire_aid_new_with_mad_aid (mad_aid, 8); MifareDESFireAID desfire_aid2 = mifare_desfire_aid_new_with_mad_aid(mad_aid, 8);
cut_assert_equal_memory (desfire_aid->data,3, desfire_aid2->data, 3, cut_message ("wrong aid")); cut_assert_equal_memory(desfire_aid->data, 3, desfire_aid2->data, 3, cut_message("wrong aid"));
cut_assert_equal_int (mifare_desfire_aid_get_aid (desfire_aid), 0x00f12ab8, cut_message ("wrong aid")); cut_assert_equal_int(mifare_desfire_aid_get_aid(desfire_aid), 0x00f12ab8, cut_message("wrong aid"));
free (desfire_aid); free(desfire_aid);
free (desfire_aid2); free(desfire_aid2);
} }

View file

@ -20,73 +20,73 @@
#include "freefare_internal.h" #include "freefare_internal.h"
void void
test_mifare_rol (void) test_mifare_rol(void)
{ {
uint8_t data[8] = "01234567"; uint8_t data[8] = "01234567";
rol (data, 8); rol(data, 8);
cut_assert_equal_memory ("12345670", 8, data, 8, cut_message ("Wrong data")); cut_assert_equal_memory("12345670", 8, data, 8, cut_message("Wrong data"));
uint8_t data2[16] = "0123456789abcdef"; uint8_t data2[16] = "0123456789abcdef";
rol (data2, 16); rol(data2, 16);
cut_assert_equal_memory (data2, 16, "123456789abcdef0", 16, cut_message ("Wrong data")); cut_assert_equal_memory(data2, 16, "123456789abcdef0", 16, cut_message("Wrong data"));
} }
void void
test_mifare_desfire_des_receive (void) test_mifare_desfire_des_receive(void)
{ {
uint8_t null_ivect[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; uint8_t null_ivect[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
uint8_t data[8] = { 0xd6, 0x59, 0xe1, 0x70, 0x43, 0xa8, 0x40, 0x68 }; uint8_t data[8] = { 0xd6, 0x59, 0xe1, 0x70, 0x43, 0xa8, 0x40, 0x68 };
uint8_t key_data[8] = { 1, 1, 1, 1, 1, 1, 1, 1 }; uint8_t key_data[8] = { 1, 1, 1, 1, 1, 1, 1, 1 };
MifareDESFireKey key = mifare_desfire_des_key_new_with_version (key_data); MifareDESFireKey key = mifare_desfire_des_key_new_with_version(key_data);
uint8_t expected_data[8] = { 0x73, 0x0d, 0xdf, 0xad, 0xa4, 0xd2, 0x07, 0x89 }; uint8_t expected_data[8] = { 0x73, 0x0d, 0xdf, 0xad, 0xa4, 0xd2, 0x07, 0x89 };
uint8_t expected_key[8] = { 1, 1, 1, 1, 1, 1, 1, 1 }; uint8_t expected_key[8] = { 1, 1, 1, 1, 1, 1, 1, 1 };
mifare_cypher_blocks_chained (NULL, key, null_ivect, data, 8, MCD_RECEIVE, MCO_DECYPHER); mifare_cypher_blocks_chained(NULL, key, null_ivect, data, 8, MCD_RECEIVE, MCO_DECYPHER);
cut_assert_equal_memory (&expected_data, 8, &data, 8, cut_message ("Wrong data")); cut_assert_equal_memory(&expected_data, 8, &data, 8, cut_message("Wrong data"));
cut_assert_equal_memory (&expected_key, 8, key->data, 8, cut_message ("Wrong key")); cut_assert_equal_memory(&expected_key, 8, key->data, 8, cut_message("Wrong key"));
mifare_desfire_key_free (key); mifare_desfire_key_free(key);
} }
void void
test_mifare_desfire_des_send (void) test_mifare_desfire_des_send(void)
{ {
uint8_t null_ivect[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; uint8_t null_ivect[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
uint8_t data[8] = { 0x73, 0x0d, 0xdf, 0xad, 0xa4, 0xd2, 0x07, 0x89 }; uint8_t data[8] = { 0x73, 0x0d, 0xdf, 0xad, 0xa4, 0xd2, 0x07, 0x89 };
uint8_t key_data[8] = { 1, 1, 1, 1, 1, 1, 1, 1 }; uint8_t key_data[8] = { 1, 1, 1, 1, 1, 1, 1, 1 };
MifareDESFireKey key = mifare_desfire_des_key_new_with_version (key_data); MifareDESFireKey key = mifare_desfire_des_key_new_with_version(key_data);
uint8_t expected_data[8] = { 0xd6, 0x59, 0xe1, 0x70, 0x43, 0xa8, 0x40, 0x68 }; uint8_t expected_data[8] = { 0xd6, 0x59, 0xe1, 0x70, 0x43, 0xa8, 0x40, 0x68 };
uint8_t expected_key[8] = { 1, 1, 1, 1, 1, 1, 1, 1 }; uint8_t expected_key[8] = { 1, 1, 1, 1, 1, 1, 1, 1 };
mifare_cypher_blocks_chained (NULL, key, null_ivect, data, 8, MCD_SEND, MCO_DECYPHER); mifare_cypher_blocks_chained(NULL, key, null_ivect, data, 8, MCD_SEND, MCO_DECYPHER);
cut_assert_equal_memory (&expected_data, 8, &data, 8, cut_message ("Wrong data")); cut_assert_equal_memory(&expected_data, 8, &data, 8, cut_message("Wrong data"));
cut_assert_equal_memory (&expected_key, 8, key->data, 8, cut_message ("Wrong key")); cut_assert_equal_memory(&expected_key, 8, key->data, 8, cut_message("Wrong key"));
mifare_desfire_key_free (key); mifare_desfire_key_free(key);
} }
void void
test_mifare_desfire_padded_data_length (void) test_mifare_desfire_padded_data_length(void)
{ {
size_t res; size_t res;
res = padded_data_length (0, 8); res = padded_data_length(0, 8);
cut_assert_equal_int (res, 8, cut_message ("Invalid size")); cut_assert_equal_int(res, 8, cut_message("Invalid size"));
res = padded_data_length (1, 8); res = padded_data_length(1, 8);
cut_assert_equal_int (res, 8, cut_message ("Invalid size")); cut_assert_equal_int(res, 8, cut_message("Invalid size"));
res = padded_data_length (8, 8); res = padded_data_length(8, 8);
cut_assert_equal_int (res, 8, cut_message ("Invalid size")); cut_assert_equal_int(res, 8, cut_message("Invalid size"));
res = padded_data_length (9, 8); res = padded_data_length(9, 8);
cut_assert_equal_int (res, 16, cut_message ("Invalid size")); cut_assert_equal_int(res, 16, cut_message("Invalid size"));
res = padded_data_length (0, 16); res = padded_data_length(0, 16);
cut_assert_equal_int (res, 16, cut_message ("Invalid size")); cut_assert_equal_int(res, 16, cut_message("Invalid size"));
res = padded_data_length (33, 16); res = padded_data_length(33, 16);
cut_assert_equal_int (res, 48, cut_message ("Invalid size")); cut_assert_equal_int(res, 48, cut_message("Invalid size"));
} }

View file

@ -28,128 +28,128 @@
#define cut_assert_success(last_command) \ #define cut_assert_success(last_command) \
do { \ do { \
cut_assert_equal_int (OPERATION_OK, mifare_desfire_last_picc_error (tag), cut_message ("PICC replied %s", mifare_desfire_error_lookup (mifare_desfire_last_picc_error (tag)))); \ cut_assert_equal_int (OPERATION_OK, mifare_desfire_last_picc_error (tag), cut_message ("PICC replied %s", mifare_desfire_error_lookup (mifare_desfire_last_picc_error (tag)))); \
cut_assert_not_equal_int (-1, res, cut_message ("Wrong return value")); \ cut_assert_not_equal_int (-1, res, cut_message ("Wrong return value")); \
} while (0) } while (0)
void void
test_mifare_desfire_ev1_aes2 (void) test_mifare_desfire_ev1_aes2(void)
{ {
int res; int res;
MifareDESFireKey key; MifareDESFireKey key;
mifare_desfire_auto_authenticate (tag, 0); mifare_desfire_auto_authenticate(tag, 0);
// Setup the AES key // Setup the AES key
key = mifare_desfire_aes_key_new_with_version (key_data_aes, key_data_aes_version); key = mifare_desfire_aes_key_new_with_version(key_data_aes, key_data_aes_version);
res = mifare_desfire_change_key (tag, 0x80, key, NULL); res = mifare_desfire_change_key(tag, 0x80, key, NULL);
cut_assert_success ("mifare_desfire_change_key"); cut_assert_success("mifare_desfire_change_key");
mifare_desfire_key_free (key); mifare_desfire_key_free(key);
// Authenticate with the AES key // Authenticate with the AES key
key = mifare_desfire_aes_key_new_with_version (key_data_aes, key_data_aes_version); key = mifare_desfire_aes_key_new_with_version(key_data_aes, key_data_aes_version);
res = mifare_desfire_authenticate_aes (tag, 0, key); res = mifare_desfire_authenticate_aes(tag, 0, key);
cut_assert_success ("mifare_desfire_authenticate"); cut_assert_success("mifare_desfire_authenticate");
mifare_desfire_key_free (key); mifare_desfire_key_free(key);
res = mifare_desfire_format_picc (tag); res = mifare_desfire_format_picc(tag);
cut_assert_success ("mifare_desfire_format_picc()"); cut_assert_success("mifare_desfire_format_picc()");
key = mifare_desfire_aes_key_new_with_version (key_data_aes, key_data_aes_version); key = mifare_desfire_aes_key_new_with_version(key_data_aes, key_data_aes_version);
res = mifare_desfire_authenticate_aes (tag, 0, key); res = mifare_desfire_authenticate_aes(tag, 0, key);
cut_assert_success ("mifare_desfire_authenticate"); cut_assert_success("mifare_desfire_authenticate");
mifare_desfire_key_free (key); mifare_desfire_key_free(key);
uint32_t size; uint32_t size;
res = mifare_desfire_free_mem (tag, &size); res = mifare_desfire_free_mem(tag, &size);
cut_assert_success ("mifare_desfire_free_mem"); cut_assert_success("mifare_desfire_free_mem");
// Do some commands to check CMAC is properly handled // Do some commands to check CMAC is properly handled
res = mifare_desfire_free_mem (tag, &size); res = mifare_desfire_free_mem(tag, &size);
cut_assert_success ("mifare_desfire_free_mem"); cut_assert_success("mifare_desfire_free_mem");
struct mifare_desfire_version_info info; struct mifare_desfire_version_info info;
res = mifare_desfire_get_version (tag, &info); res = mifare_desfire_get_version(tag, &info);
cut_assert_success ("mifare_desfire_get_version"); cut_assert_success("mifare_desfire_get_version");
res = mifare_desfire_change_key_settings (tag, 0x0F); res = mifare_desfire_change_key_settings(tag, 0x0F);
cut_assert_success ("mifare_desfire_change_key_settings"); cut_assert_success("mifare_desfire_change_key_settings");
res = mifare_desfire_free_mem (tag, &size); res = mifare_desfire_free_mem(tag, &size);
cut_assert_success ("mifare_desfire_free_mem"); cut_assert_success("mifare_desfire_free_mem");
MifareDESFireAID aid = mifare_desfire_aid_new (0x112233); MifareDESFireAID aid = mifare_desfire_aid_new(0x112233);
mifare_desfire_delete_application (tag, aid); mifare_desfire_delete_application(tag, aid);
res = mifare_desfire_create_application (tag, aid, 0xff, 0x81); res = mifare_desfire_create_application(tag, aid, 0xff, 0x81);
cut_assert_success ("mifare_desfire_create_application"); cut_assert_success("mifare_desfire_create_application");
res = mifare_desfire_select_application (tag, aid); res = mifare_desfire_select_application(tag, aid);
cut_assert_success ("mifare_desfire_select_application"); cut_assert_success("mifare_desfire_select_application");
key = mifare_desfire_aes_key_new (key_data_aes); key = mifare_desfire_aes_key_new(key_data_aes);
res = mifare_desfire_authenticate_aes (tag, 0, key); res = mifare_desfire_authenticate_aes(tag, 0, key);
cut_assert_success ("mifare_desfire_authenticate"); cut_assert_success("mifare_desfire_authenticate");
free (key); free(key);
key = mifare_desfire_aes_key_new_with_version (key_data_aes, key_data_aes_version); key = mifare_desfire_aes_key_new_with_version(key_data_aes, key_data_aes_version);
res = mifare_desfire_change_key (tag, 0x00, key, NULL); res = mifare_desfire_change_key(tag, 0x00, key, NULL);
cut_assert_success ("mifare_desfire_change_key"); cut_assert_success("mifare_desfire_change_key");
mifare_desfire_key_free (key); mifare_desfire_key_free(key);
key = mifare_desfire_aes_key_new (key_data_aes); key = mifare_desfire_aes_key_new(key_data_aes);
res = mifare_desfire_authenticate_aes (tag, 0, key); res = mifare_desfire_authenticate_aes(tag, 0, key);
cut_assert_success ("mifare_desfire_authenticate"); cut_assert_success("mifare_desfire_authenticate");
free (key); free(key);
res = mifare_desfire_create_std_data_file (tag, 1, MDCM_MACED, 0x0000, 512); res = mifare_desfire_create_std_data_file(tag, 1, MDCM_MACED, 0x0000, 512);
if ((mifare_desfire_last_picc_error (tag) != DUPLICATE_ERROR) && (mifare_desfire_last_picc_error(tag) != OPERATION_OK)) if ((mifare_desfire_last_picc_error(tag) != DUPLICATE_ERROR) && (mifare_desfire_last_picc_error(tag) != OPERATION_OK))
cut_assert_success ("mifare_desfire_create_std_data_file"); cut_assert_success("mifare_desfire_create_std_data_file");
char sample_data[] = "Hello World! I'm a string that is probably too long " char sample_data[] = "Hello World! I'm a string that is probably too long "
"to feet in a single frame. For this reason, it will be split and like" "to feet in a single frame. For this reason, it will be split and like"
"ly, some failure in the algorirthm should trigger an error in this uni" "ly, some failure in the algorirthm should trigger an error in this uni"
"t test."; "t test.";
res = mifare_desfire_write_data_ex (tag, 1, 0, strlen (sample_data), sample_data, MDCM_MACED); res = mifare_desfire_write_data_ex(tag, 1, 0, strlen(sample_data), sample_data, MDCM_MACED);
cut_assert_success ("mifare_desfire_write_data"); cut_assert_success("mifare_desfire_write_data");
char buffer[1024]; char buffer[1024];
res = mifare_desfire_read_data_ex (tag, 1, 0, 27, buffer, MDCM_MACED); res = mifare_desfire_read_data_ex(tag, 1, 0, 27, buffer, MDCM_MACED);
cut_assert_success ("mifare_desfire_read_data"); cut_assert_success("mifare_desfire_read_data");
cut_assert_equal_memory (buffer, res, sample_data, 27, cut_message ("AES crypto failed")); cut_assert_equal_memory(buffer, res, sample_data, 27, cut_message("AES crypto failed"));
char canaries[] = "Canaries Canaries Canaries Canaries Canaries"; char canaries[] = "Canaries Canaries Canaries Canaries Canaries";
res = mifare_desfire_read_data_ex (tag, 1, 0, 1, canaries, MDCM_MACED); res = mifare_desfire_read_data_ex(tag, 1, 0, 1, canaries, MDCM_MACED);
cut_assert_success ("mifare_desfire_read_data"); cut_assert_success("mifare_desfire_read_data");
cut_assert_equal_int (1, res, cut_message ("Reading 1 byte should return 1 byte")); cut_assert_equal_int(1, res, cut_message("Reading 1 byte should return 1 byte"));
cut_assert_equal_memory (canaries, 44, "Hanaries Canaries Canaries Canaries Canaries", 44, cut_message ("Canaries got smashed!")); cut_assert_equal_memory(canaries, 44, "Hanaries Canaries Canaries Canaries Canaries", 44, cut_message("Canaries got smashed!"));
uint8_t s, c; uint8_t s, c;
res = mifare_desfire_get_key_settings (tag, &s, &c); res = mifare_desfire_get_key_settings(tag, &s, &c);
cut_assert_success ("mifare_desfire_get__key_settings"); cut_assert_success("mifare_desfire_get__key_settings");
res = mifare_desfire_read_data_ex (tag, 1, 27, 27, buffer, MDCM_MACED); res = mifare_desfire_read_data_ex(tag, 1, 27, 27, buffer, MDCM_MACED);
cut_assert_success ("mifare_desfire_read_data"); cut_assert_success("mifare_desfire_read_data");
cut_assert_equal_memory (buffer, res, sample_data + 27, 27, cut_message ("AES crypto failed")); cut_assert_equal_memory(buffer, res, sample_data + 27, 27, cut_message("AES crypto failed"));
res = mifare_desfire_read_data_ex (tag, 1, 0, 0, buffer, MDCM_MACED); res = mifare_desfire_read_data_ex(tag, 1, 0, 0, buffer, MDCM_MACED);
cut_assert_success ("mifare_desfire_read_data"); cut_assert_success("mifare_desfire_read_data");
cut_assert_equal_memory (buffer, strlen (buffer), sample_data, strlen (sample_data), cut_message ("AES crypto failed")); cut_assert_equal_memory(buffer, strlen(buffer), sample_data, strlen(sample_data), cut_message("AES crypto failed"));
// Revert to the default DES key // Revert to the default DES key
res = mifare_desfire_select_application (tag, NULL); res = mifare_desfire_select_application(tag, NULL);
cut_assert_success ("mifare_desfire_select_application"); cut_assert_success("mifare_desfire_select_application");
key = mifare_desfire_aes_key_new_with_version (key_data_aes, key_data_aes_version); key = mifare_desfire_aes_key_new_with_version(key_data_aes, key_data_aes_version);
res = mifare_desfire_authenticate_aes (tag, 0, key); res = mifare_desfire_authenticate_aes(tag, 0, key);
cut_assert_success ("mifare_desfire_authenticate"); cut_assert_success("mifare_desfire_authenticate");
mifare_desfire_key_free (key); mifare_desfire_key_free(key);
key = mifare_desfire_des_key_new (key_data_null); key = mifare_desfire_des_key_new(key_data_null);
res = mifare_desfire_change_key (tag, 0x00, key, NULL); res = mifare_desfire_change_key(tag, 0x00, key, NULL);
cut_assert_success ("mifare_desfire_change_key"); cut_assert_success("mifare_desfire_change_key");
mifare_desfire_key_free (key); mifare_desfire_key_free(key);
} }

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -25,105 +25,105 @@
#define cut_assert_success(last_command) \ #define cut_assert_success(last_command) \
do { \ do { \
cut_assert_equal_int (OPERATION_OK, mifare_desfire_last_picc_error (tag), cut_message ("PICC replied %s", mifare_desfire_error_lookup (mifare_desfire_last_picc_error (tag)))); \ cut_assert_equal_int (OPERATION_OK, mifare_desfire_last_picc_error (tag), cut_message ("PICC replied %s", mifare_desfire_error_lookup (mifare_desfire_last_picc_error (tag)))); \
cut_assert_not_equal_int (-1, res, cut_message ("Wrong return value")); \ cut_assert_not_equal_int (-1, res, cut_message ("Wrong return value")); \
} while (0) } while (0)
void void
test_mifare_desfire_ev1_iso (void) test_mifare_desfire_ev1_iso(void)
{ {
int res; int res;
mifare_desfire_auto_authenticate (tag, 0); mifare_desfire_auto_authenticate(tag, 0);
res = mifare_desfire_format_picc (tag); res = mifare_desfire_format_picc(tag);
cut_assert_equal_int (res, 0, cut_message ("mifare_desfire_format_picc()")); cut_assert_equal_int(res, 0, cut_message("mifare_desfire_format_picc()"));
MifareDESFireDF *dfs; MifareDESFireDF *dfs;
size_t count; size_t count;
res = mifare_desfire_get_df_names (tag, &dfs, &count); res = mifare_desfire_get_df_names(tag, &dfs, &count);
cut_assert_equal_int (res, 0, cut_message ("mifare_desfire_get_df_names()")); cut_assert_equal_int(res, 0, cut_message("mifare_desfire_get_df_names()"));
cut_assert_equal_int (count, 0, cut_message ("Wrong DF count")); cut_assert_equal_int(count, 0, cut_message("Wrong DF count"));
cut_assert_null (dfs, cut_message ("DF should be NULL")); cut_assert_null(dfs, cut_message("DF should be NULL"));
MifareDESFireAID aid = mifare_desfire_aid_new (0x111110); MifareDESFireAID aid = mifare_desfire_aid_new(0x111110);
res = mifare_desfire_create_application_iso (tag, aid, 0xFF, 1, 0, 0x111F, NULL, 0); res = mifare_desfire_create_application_iso(tag, aid, 0xFF, 1, 0, 0x111F, NULL, 0);
cut_assert_success ("mifare_desfire_create_application_iso"); cut_assert_success("mifare_desfire_create_application_iso");
free (aid); free(aid);
uint8_t app2[] = "App2"; uint8_t app2[] = "App2";
aid = mifare_desfire_aid_new (0x222220); aid = mifare_desfire_aid_new(0x222220);
res = mifare_desfire_create_application_iso (tag, aid, 0xFF, 1, 0, 0x222F, app2, sizeof (app2)); res = mifare_desfire_create_application_iso(tag, aid, 0xFF, 1, 0, 0x222F, app2, sizeof(app2));
cut_assert_success ("mifare_desfire_create_application_iso"); cut_assert_success("mifare_desfire_create_application_iso");
free (aid); free(aid);
uint8_t app3[] = "App3"; uint8_t app3[] = "App3";
aid = mifare_desfire_aid_new (0x333330); aid = mifare_desfire_aid_new(0x333330);
res = mifare_desfire_create_application_iso (tag, aid, 0xFF, 1, 0, 0x333F, app3, sizeof (app3)); res = mifare_desfire_create_application_iso(tag, aid, 0xFF, 1, 0, 0x333F, app3, sizeof(app3));
cut_assert_success ("mifare_desfire_create_application_iso"); cut_assert_success("mifare_desfire_create_application_iso");
free (aid); free(aid);
aid = mifare_desfire_aid_new (0x444440); aid = mifare_desfire_aid_new(0x444440);
res = mifare_desfire_create_application_iso (tag, aid, 0xFF, 1, 0, 0x111F, NULL, 0); res = mifare_desfire_create_application_iso(tag, aid, 0xFF, 1, 0, 0x111F, NULL, 0);
cut_assert_equal_int (-1, res, cut_message ("Should fail")); cut_assert_equal_int(-1, res, cut_message("Should fail"));
cut_assert_equal_int (DUPLICATE_ERROR, mifare_desfire_last_picc_error (tag), cut_message ("Should be a duplicate error")); cut_assert_equal_int(DUPLICATE_ERROR, mifare_desfire_last_picc_error(tag), cut_message("Should be a duplicate error"));
res = mifare_desfire_create_application_iso (tag, aid, 0xFF, 1, 0, 0x444F, app2, sizeof (app2)); res = mifare_desfire_create_application_iso(tag, aid, 0xFF, 1, 0, 0x444F, app2, sizeof(app2));
cut_assert_equal_int (-1, res, cut_message ("Should fail")); cut_assert_equal_int(-1, res, cut_message("Should fail"));
cut_assert_equal_int (DUPLICATE_ERROR, mifare_desfire_last_picc_error (tag), cut_message ("Should be a duplicate error")); cut_assert_equal_int(DUPLICATE_ERROR, mifare_desfire_last_picc_error(tag), cut_message("Should be a duplicate error"));
free (aid); free(aid);
res = mifare_desfire_get_df_names (tag, &dfs, &count); res = mifare_desfire_get_df_names(tag, &dfs, &count);
cut_assert_equal_int (0, res, cut_message ("mifare_desfire_get_df_names()")); cut_assert_equal_int(0, res, cut_message("mifare_desfire_get_df_names()"));
cut_assert_equal_int (3, count, cut_message ("Wrong DF count")); cut_assert_equal_int(3, count, cut_message("Wrong DF count"));
cut_assert_not_null (dfs, cut_message ("DF should not be NULL")); cut_assert_not_null(dfs, cut_message("DF should not be NULL"));
cut_assert_equal_int (0x111110, dfs[0].aid, cut_message ("Wrong value")); cut_assert_equal_int(0x111110, dfs[0].aid, cut_message("Wrong value"));
cut_assert_equal_int (0x111F, dfs[0].fid, cut_message ("Wrong value")); cut_assert_equal_int(0x111F, dfs[0].fid, cut_message("Wrong value"));
cut_assert_equal_int (0, dfs[0].df_name_len, cut_message ("Wrong value")); cut_assert_equal_int(0, dfs[0].df_name_len, cut_message("Wrong value"));
cut_assert_equal_int (0x222220, dfs[1].aid, cut_message ("Wrong value")); cut_assert_equal_int(0x222220, dfs[1].aid, cut_message("Wrong value"));
cut_assert_equal_int (0x222F, dfs[1].fid, cut_message ("Wrong value")); cut_assert_equal_int(0x222F, dfs[1].fid, cut_message("Wrong value"));
cut_assert_equal_int (sizeof (app2), dfs[1].df_name_len, cut_message ("Wrong value")); cut_assert_equal_int(sizeof(app2), dfs[1].df_name_len, cut_message("Wrong value"));
cut_assert_equal_memory (app2, sizeof (app2), dfs[1].df_name, dfs[1].df_name_len, cut_message ("Wrong value")); cut_assert_equal_memory(app2, sizeof(app2), dfs[1].df_name, dfs[1].df_name_len, cut_message("Wrong value"));
cut_assert_equal_int (0x333330, dfs[2].aid, cut_message ("Wrong value")); cut_assert_equal_int(0x333330, dfs[2].aid, cut_message("Wrong value"));
cut_assert_equal_int (0x333F, dfs[2].fid, cut_message ("Wrong value")); cut_assert_equal_int(0x333F, dfs[2].fid, cut_message("Wrong value"));
cut_assert_equal_int (sizeof (app3), dfs[2].df_name_len, cut_message ("Wrong value")); cut_assert_equal_int(sizeof(app3), dfs[2].df_name_len, cut_message("Wrong value"));
cut_assert_equal_memory (app3, sizeof (app3), dfs[2].df_name, dfs[2].df_name_len, cut_message ("Wrong value")); cut_assert_equal_memory(app3, sizeof(app3), dfs[2].df_name, dfs[2].df_name_len, cut_message("Wrong value"));
free (dfs); free(dfs);
aid = mifare_desfire_aid_new (0x555550); aid = mifare_desfire_aid_new(0x555550);
res = mifare_desfire_create_application_iso (tag, aid, 0xff, 1, 1, 0x555F, NULL, 0); res = mifare_desfire_create_application_iso(tag, aid, 0xff, 1, 1, 0x555F, NULL, 0);
cut_assert_success ("mifare_desfire_create_application_iso"); cut_assert_success("mifare_desfire_create_application_iso");
res = mifare_desfire_select_application (tag, aid); res = mifare_desfire_select_application(tag, aid);
cut_assert_success ("mifare_desfire_select_application"); cut_assert_success("mifare_desfire_select_application");
res = mifare_desfire_create_std_data_file_iso (tag, 1, MDCM_PLAIN, 0xEEEE, 32, 0x1234); res = mifare_desfire_create_std_data_file_iso(tag, 1, MDCM_PLAIN, 0xEEEE, 32, 0x1234);
cut_assert_success ("mifare_desfire_create_std_data_file_iso"); cut_assert_success("mifare_desfire_create_std_data_file_iso");
res = mifare_desfire_create_backup_data_file_iso (tag, 2, MDCM_PLAIN, 0xEEEE, 32, 0x2345); res = mifare_desfire_create_backup_data_file_iso(tag, 2, MDCM_PLAIN, 0xEEEE, 32, 0x2345);
cut_assert_success ("mifare_desfire_create_std_data_file_iso"); cut_assert_success("mifare_desfire_create_std_data_file_iso");
res = mifare_desfire_create_linear_record_file_iso (tag, 3, MDCM_PLAIN, 0xEEEE, 32, 10, 0x3456); res = mifare_desfire_create_linear_record_file_iso(tag, 3, MDCM_PLAIN, 0xEEEE, 32, 10, 0x3456);
cut_assert_success ("mifare_desfire_create_linear_record_file_iso"); cut_assert_success("mifare_desfire_create_linear_record_file_iso");
res = mifare_desfire_create_cyclic_record_file_iso (tag, 4, MDCM_PLAIN, 0xEEEE, 32, 10, 0x4567); res = mifare_desfire_create_cyclic_record_file_iso(tag, 4, MDCM_PLAIN, 0xEEEE, 32, 10, 0x4567);
cut_assert_success ("mifare_desfire_create_cyclic_record_file_iso"); cut_assert_success("mifare_desfire_create_cyclic_record_file_iso");
uint16_t *ids; uint16_t *ids;
res = mifare_desfire_get_iso_file_ids (tag, &ids, &count); res = mifare_desfire_get_iso_file_ids(tag, &ids, &count);
cut_assert_success ("mifare_desfire_get_iso_file_ids"); cut_assert_success("mifare_desfire_get_iso_file_ids");
cut_assert_equal_int (4, count, cut_message ("Invalid file count")); cut_assert_equal_int(4, count, cut_message("Invalid file count"));
cut_assert_equal_int (0x1234, ids[0], cut_message ("Wrong file ID")); cut_assert_equal_int(0x1234, ids[0], cut_message("Wrong file ID"));
cut_assert_equal_int (0x2345, ids[1], cut_message ("Wrong file ID")); cut_assert_equal_int(0x2345, ids[1], cut_message("Wrong file ID"));
cut_assert_equal_int (0x3456, ids[2], cut_message ("Wrong file ID")); cut_assert_equal_int(0x3456, ids[2], cut_message("Wrong file ID"));
cut_assert_equal_int (0x4567, ids[3], cut_message ("Wrong file ID")); cut_assert_equal_int(0x4567, ids[3], cut_message("Wrong file ID"));
free (ids); free(ids);
free (aid); free(aid);
} }

View file

@ -21,76 +21,76 @@
void void
test_mifare_desfire_key (void) test_mifare_desfire_key(void)
{ {
MifareDESFireKey key; MifareDESFireKey key;
int version; int version;
uint8_t key1_des_data[8] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 }; uint8_t key1_des_data[8] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 };
key = mifare_desfire_des_key_new (key1_des_data); key = mifare_desfire_des_key_new(key1_des_data);
version = mifare_desfire_key_get_version (key); version = mifare_desfire_key_get_version(key);
cut_assert_equal_int (0x00, version, cut_message ("Wrong MifareDESFireKey version")); cut_assert_equal_int(0x00, version, cut_message("Wrong MifareDESFireKey version"));
mifare_desfire_key_free (key); mifare_desfire_key_free(key);
key = mifare_desfire_des_key_new_with_version (key1_des_data); key = mifare_desfire_des_key_new_with_version(key1_des_data);
version = mifare_desfire_key_get_version (key); version = mifare_desfire_key_get_version(key);
cut_assert_equal_int (0x55, version, cut_message ("Wrong MifareDESFireKey version")); cut_assert_equal_int(0x55, version, cut_message("Wrong MifareDESFireKey version"));
mifare_desfire_key_set_version (key, 0xaa); mifare_desfire_key_set_version(key, 0xaa);
version = mifare_desfire_key_get_version (key); version = mifare_desfire_key_get_version(key);
cut_assert_equal_int (0xaa, version, cut_message ("Wrong MifareDESFireKey version")); cut_assert_equal_int(0xaa, version, cut_message("Wrong MifareDESFireKey version"));
mifare_desfire_key_free (key); mifare_desfire_key_free(key);
uint8_t key2_des_data[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; uint8_t key2_des_data[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
key = mifare_desfire_des_key_new (key2_des_data); key = mifare_desfire_des_key_new(key2_des_data);
version = mifare_desfire_key_get_version (key); version = mifare_desfire_key_get_version(key);
cut_assert_equal_int (0x00, version, cut_message ("Wrong MifareDESFireKey version")); cut_assert_equal_int(0x00, version, cut_message("Wrong MifareDESFireKey version"));
mifare_desfire_key_free (key); mifare_desfire_key_free(key);
key = mifare_desfire_des_key_new_with_version (key2_des_data); key = mifare_desfire_des_key_new_with_version(key2_des_data);
version = mifare_desfire_key_get_version (key); version = mifare_desfire_key_get_version(key);
cut_assert_equal_int (0x00, version, cut_message ("Wrong MifareDESFireKey version")); cut_assert_equal_int(0x00, version, cut_message("Wrong MifareDESFireKey version"));
mifare_desfire_key_free (key); mifare_desfire_key_free(key);
uint8_t key1_3des_data[16] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0XEE, 0xFF }; uint8_t key1_3des_data[16] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0XEE, 0xFF };
key = mifare_desfire_3des_key_new (key1_3des_data); key = mifare_desfire_3des_key_new(key1_3des_data);
version = mifare_desfire_key_get_version (key); version = mifare_desfire_key_get_version(key);
cut_assert_equal_int (0x00, version, cut_message ("Wrong MifareDESFireKey version")); cut_assert_equal_int(0x00, version, cut_message("Wrong MifareDESFireKey version"));
mifare_desfire_key_free (key); mifare_desfire_key_free(key);
key = mifare_desfire_3des_key_new_with_version (key1_3des_data); key = mifare_desfire_3des_key_new_with_version(key1_3des_data);
version = mifare_desfire_key_get_version (key); version = mifare_desfire_key_get_version(key);
cut_assert_equal_int (0x55, version, cut_message ("Wrong MifareDESFireKey version")); cut_assert_equal_int(0x55, version, cut_message("Wrong MifareDESFireKey version"));
mifare_desfire_key_set_version (key, 0xaa); mifare_desfire_key_set_version(key, 0xaa);
version = mifare_desfire_key_get_version (key); version = mifare_desfire_key_get_version(key);
cut_assert_equal_int (0xaa, version, cut_message ("Wrong MifareDESFireKey version")); cut_assert_equal_int(0xaa, version, cut_message("Wrong MifareDESFireKey version"));
mifare_desfire_key_free (key); mifare_desfire_key_free(key);
uint8_t key2_3des_data[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0X01, 0x00, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 }; uint8_t key2_3des_data[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0X01, 0x00, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 };
key = mifare_desfire_3des_key_new (key2_3des_data); key = mifare_desfire_3des_key_new(key2_3des_data);
version = mifare_desfire_key_get_version (key); version = mifare_desfire_key_get_version(key);
cut_assert_equal_int (0x00, version, cut_message ("Wrong MifareDESFireKey version")); cut_assert_equal_int(0x00, version, cut_message("Wrong MifareDESFireKey version"));
mifare_desfire_key_free (key); mifare_desfire_key_free(key);
key = mifare_desfire_3des_key_new_with_version (key2_3des_data); key = mifare_desfire_3des_key_new_with_version(key2_3des_data);
version = mifare_desfire_key_get_version (key); version = mifare_desfire_key_get_version(key);
cut_assert_equal_int (0x02, version, cut_message ("Wrong MifareDESFireKey version")); cut_assert_equal_int(0x02, version, cut_message("Wrong MifareDESFireKey version"));
mifare_desfire_key_free (key); mifare_desfire_key_free(key);
uint8_t key3_3des_data[16] = { 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0X00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77 }; uint8_t key3_3des_data[16] = { 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0X00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77 };
key = mifare_desfire_3des_key_new (key3_3des_data); key = mifare_desfire_3des_key_new(key3_3des_data);
version = mifare_desfire_key_get_version (key); version = mifare_desfire_key_get_version(key);
cut_assert_equal_int (0x00, version, cut_message ("Wrong MifareDESFireKey version")); cut_assert_equal_int(0x00, version, cut_message("Wrong MifareDESFireKey version"));
mifare_desfire_key_free (key); mifare_desfire_key_free(key);
key = mifare_desfire_3des_key_new_with_version (key3_3des_data); key = mifare_desfire_3des_key_new_with_version(key3_3des_data);
version = mifare_desfire_key_get_version (key); version = mifare_desfire_key_get_version(key);
cut_assert_equal_int (0x10, version, cut_message ("Wrong MifareDESFireKey version")); cut_assert_equal_int(0x10, version, cut_message("Wrong MifareDESFireKey version"));
mifare_desfire_key_free (key); mifare_desfire_key_free(key);
} }

View file

@ -25,7 +25,7 @@
#include "mifare_ultralight_fixture.h" #include "mifare_ultralight_fixture.h"
void void
test_mifare_ultralight_write (void) test_mifare_ultralight_write(void)
{ {
int res; int res;
@ -37,158 +37,158 @@ test_mifare_ultralight_write (void)
MifareUltralightPageNumber n = 7; MifareUltralightPageNumber n = 7;
/* Read and save current value (should be { 0x00 0x00 0x00 0x00 }) */ /* Read and save current value (should be { 0x00 0x00 0x00 0x00 }) */
res = mifare_ultralight_read (tag, n, &initial); res = mifare_ultralight_read(tag, n, &initial);
cut_assert_equal_int (0, res, cut_message ("mifare_ultralight_read() failed")); cut_assert_equal_int(0, res, cut_message("mifare_ultralight_read() failed"));
/* Write payload1 */ /* Write payload1 */
res = mifare_ultralight_write (tag, n, payload1); res = mifare_ultralight_write(tag, n, payload1);
cut_assert_equal_int (0, res, cut_message ("mifare_ultralight_write() failed")); cut_assert_equal_int(0, res, cut_message("mifare_ultralight_write() failed"));
/* Check it */ /* Check it */
res = mifare_ultralight_read (tag, n, &page); res = mifare_ultralight_read(tag, n, &page);
cut_assert_equal_int (0, res, cut_message ("mifare_ultralight_read() failed")); cut_assert_equal_int(0, res, cut_message("mifare_ultralight_read() failed"));
cut_assert_equal_memory (payload1, sizeof (payload1), page, sizeof (page), cut_message ("Wrong data")); cut_assert_equal_memory(payload1, sizeof(payload1), page, sizeof(page), cut_message("Wrong data"));
/* Write payload2 */ /* Write payload2 */
res = mifare_ultralight_write (tag, n, payload2); res = mifare_ultralight_write(tag, n, payload2);
cut_assert_equal_int (0, res, cut_message ("mifare_ultralight_write() failed")); cut_assert_equal_int(0, res, cut_message("mifare_ultralight_write() failed"));
/* Check it */ /* Check it */
res = mifare_ultralight_read (tag, n, &page); res = mifare_ultralight_read(tag, n, &page);
cut_assert_equal_int (0, res, cut_message ("mifare_ultralight_read() failed")); cut_assert_equal_int(0, res, cut_message("mifare_ultralight_read() failed"));
cut_assert_equal_memory (payload2, sizeof (payload2), page, sizeof (page), cut_message ("Wrong data")); cut_assert_equal_memory(payload2, sizeof(payload2), page, sizeof(page), cut_message("Wrong data"));
/* Write initial data */ /* Write initial data */
res = mifare_ultralight_write (tag, n, initial); res = mifare_ultralight_write(tag, n, initial);
cut_assert_equal_int (0, res, cut_message ("mifare_ultralight_write() failed")); cut_assert_equal_int(0, res, cut_message("mifare_ultralight_write() failed"));
/* While here check it (no reason to fail since the rest of the test passed) */ /* While here check it (no reason to fail since the rest of the test passed) */
res = mifare_ultralight_read (tag, n, &page); res = mifare_ultralight_read(tag, n, &page);
cut_assert_equal_int (0, res, cut_message ("mifare_ultralight_read() failed")); cut_assert_equal_int(0, res, cut_message("mifare_ultralight_read() failed"));
cut_assert_equal_memory (initial, sizeof (initial), page, sizeof (page), cut_message ("Wrong data")); cut_assert_equal_memory(initial, sizeof(initial), page, sizeof(page), cut_message("Wrong data"));
} }
void void
test_mifare_ultralight_invalid_page (void) test_mifare_ultralight_invalid_page(void)
{ {
int res; int res;
MifareUltralightPage page = { 0x00, 0x00, 0x00, 0x00 }; MifareUltralightPage page = { 0x00, 0x00, 0x00, 0x00 };
int invalid_page; int invalid_page;
if (is_mifare_ultralightc (tag)) { if (is_mifare_ultralightc(tag)) {
invalid_page = MIFARE_ULTRALIGHT_C_PAGE_COUNT; invalid_page = MIFARE_ULTRALIGHT_C_PAGE_COUNT;
} else { } else {
invalid_page = MIFARE_ULTRALIGHT_PAGE_COUNT; invalid_page = MIFARE_ULTRALIGHT_PAGE_COUNT;
} }
res = mifare_ultralight_read (tag, invalid_page, &page); res = mifare_ultralight_read(tag, invalid_page, &page);
cut_assert_equal_int (-1, res, cut_message ("mifare_ultralight_read() succeeded")); cut_assert_equal_int(-1, res, cut_message("mifare_ultralight_read() succeeded"));
cut_assert_equal_int (EINVAL, errno, cut_message ("Wrong errno value")); cut_assert_equal_int(EINVAL, errno, cut_message("Wrong errno value"));
res = mifare_ultralight_write (tag, invalid_page, page); res = mifare_ultralight_write(tag, invalid_page, page);
cut_assert_equal_int (-1, res, cut_message ("mifare_ultralight_write() succeeded")); cut_assert_equal_int(-1, res, cut_message("mifare_ultralight_write() succeeded"));
cut_assert_equal_int (EINVAL, errno, cut_message ("Wrong errno value")); cut_assert_equal_int(EINVAL, errno, cut_message("Wrong errno value"));
} }
void void
test_mifare_ultralight_cache (void) test_mifare_ultralight_cache(void)
{ {
int res; int res;
MifareUltralightPage page; MifareUltralightPage page;
res = mifare_ultralight_read (tag, 0, &page); res = mifare_ultralight_read(tag, 0, &page);
cut_assert_equal_int (0, res, cut_message ("mifare_ultralight_read() failed")); cut_assert_equal_int(0, res, cut_message("mifare_ultralight_read() failed"));
/* Check cached pages consistency */ /* Check cached pages consistency */
for (int i = 0; i <= 3; i++) { for (int i = 0; i <= 3; i++) {
cut_assert_equal_int (1, MIFARE_ULTRALIGHT(tag)->cached_pages[i], cut_message ("Wrong page cache value for tag->cached_pages[%d]", i)); cut_assert_equal_int(1, MIFARE_ULTRALIGHT(tag)->cached_pages[i], cut_message("Wrong page cache value for tag->cached_pages[%d]", i));
} }
for (int i = 4; i < MIFARE_ULTRALIGHT_PAGE_COUNT; i++) { for (int i = 4; i < MIFARE_ULTRALIGHT_PAGE_COUNT; i++) {
cut_assert_equal_int (0, MIFARE_ULTRALIGHT(tag)->cached_pages[i], cut_message ("Wrong page cache value for tag->cached_pages[%d]", i)); cut_assert_equal_int(0, MIFARE_ULTRALIGHT(tag)->cached_pages[i], cut_message("Wrong page cache value for tag->cached_pages[%d]", i));
} }
} }
void void
test_mifare_ultralight_cache_hit (void) test_mifare_ultralight_cache_hit(void)
{ {
int res; int res;
MifareUltralightPage page1; MifareUltralightPage page1;
MifareUltralightPage page2; MifareUltralightPage page2;
res = mifare_ultralight_read (tag, 0, &page1); res = mifare_ultralight_read(tag, 0, &page1);
cut_assert_equal_int (0, res, cut_message ("mifare_ultralight_read() failed")); cut_assert_equal_int(0, res, cut_message("mifare_ultralight_read() failed"));
res = mifare_ultralight_read (tag, 0, &page2); res = mifare_ultralight_read(tag, 0, &page2);
cut_assert_equal_int (0, res, cut_message ("mifare_ultralight_read() failed")); cut_assert_equal_int(0, res, cut_message("mifare_ultralight_read() failed"));
cut_assert_equal_memory (page1, sizeof (page1), page2, sizeof (page2), cut_message ("Wrong cached data")); cut_assert_equal_memory(page1, sizeof(page1), page2, sizeof(page2), cut_message("Wrong cached data"));
} }
void void
test_mifare_ultralight_cache_wrap (void) test_mifare_ultralight_cache_wrap(void)
{ {
int res; int res;
MifareUltralightPage page; MifareUltralightPage page;
int last_page; int last_page;
if (is_mifare_ultralightc (tag)) { if (is_mifare_ultralightc(tag)) {
// Last 4 blocks are for 3DES key and cannot be read, read will wrap from 0x2b // Last 4 blocks are for 3DES key and cannot be read, read will wrap from 0x2b
last_page = MIFARE_ULTRALIGHT_C_PAGE_COUNT_READ -1; last_page = MIFARE_ULTRALIGHT_C_PAGE_COUNT_READ - 1;
// Actually engineering samples require auth to read above page 0x28 so we skip the test entirely // Actually engineering samples require auth to read above page 0x28 so we skip the test entirely
cut_omit("mifare_ultralight_read() on last page skipped on UltralightC"); cut_omit("mifare_ultralight_read() on last page skipped on UltralightC");
} else { } else {
last_page = MIFARE_ULTRALIGHT_PAGE_COUNT -1; last_page = MIFARE_ULTRALIGHT_PAGE_COUNT - 1;
} }
res = mifare_ultralight_read (tag, last_page, &page); res = mifare_ultralight_read(tag, last_page, &page);
cut_assert_equal_int (0, res, cut_message ("mifare_ultralight_read() failed")); cut_assert_equal_int(0, res, cut_message("mifare_ultralight_read() failed"));
/* Check cached pages consistency */ /* Check cached pages consistency */
for (int i = 0; i <= 2; i++) { for (int i = 0; i <= 2; i++) {
cut_assert_equal_int (1, MIFARE_ULTRALIGHT(tag)->cached_pages[i], cut_message ("Wrong page cache value for tag->cached_pages[%d]", i)); cut_assert_equal_int(1, MIFARE_ULTRALIGHT(tag)->cached_pages[i], cut_message("Wrong page cache value for tag->cached_pages[%d]", i));
} }
for (int i = 3; i < last_page; i++) { for (int i = 3; i < last_page; i++) {
cut_assert_equal_int (0, MIFARE_ULTRALIGHT(tag)->cached_pages[i], cut_message ("Wrong page cache value for tag->cached_pages[%d]", i)); cut_assert_equal_int(0, MIFARE_ULTRALIGHT(tag)->cached_pages[i], cut_message("Wrong page cache value for tag->cached_pages[%d]", i));
} }
cut_assert_equal_int (1, MIFARE_ULTRALIGHT(tag)->cached_pages[last_page], cut_message ("Wrong page cache value for tag->cached_pages[%d]", last_page)); cut_assert_equal_int(1, MIFARE_ULTRALIGHT(tag)->cached_pages[last_page], cut_message("Wrong page cache value for tag->cached_pages[%d]", last_page));
} }
void void
test_mifare_ultralight_get_uid (void) test_mifare_ultralight_get_uid(void)
{ {
char *uid; char *uid;
uid = freefare_get_tag_uid (tag); uid = freefare_get_tag_uid(tag);
cut_assert_not_null (uid, cut_message ("mifare_ultralight_get_uid() failed")); cut_assert_not_null(uid, cut_message("mifare_ultralight_get_uid() failed"));
cut_assert_equal_int (14, strlen (uid), cut_message ("Wrong UID length")); cut_assert_equal_int(14, strlen(uid), cut_message("Wrong UID length"));
free (uid); free(uid);
} }
void void
test_mifare_ultralight_tag_friendly_name (void) test_mifare_ultralight_tag_friendly_name(void)
{ {
const char *name = freefare_get_tag_friendly_name (tag); const char *name = freefare_get_tag_friendly_name(tag);
cut_assert_not_null (name, cut_message ("freefare_get_tag_friendly_name() failed")); cut_assert_not_null(name, cut_message("freefare_get_tag_friendly_name() failed"));
} }
void void
test_mifare_ultralightc_authenticate (void) test_mifare_ultralightc_authenticate(void)
{ {
int res; int res;
MifareDESFireKey key; MifareDESFireKey key;
if (is_mifare_ultralightc (tag)) { if (is_mifare_ultralightc(tag)) {
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);
cut_assert_equal_int (0, res, cut_message ("mifare_ultralightc_authenticate() failed")); cut_assert_equal_int(0, res, cut_message("mifare_ultralightc_authenticate() failed"));
mifare_desfire_key_free (key); mifare_desfire_key_free(key);
MifareUltralightPage page; MifareUltralightPage page;
int last_page = MIFARE_ULTRALIGHT_C_PAGE_COUNT_READ -1; int last_page = MIFARE_ULTRALIGHT_C_PAGE_COUNT_READ - 1;
res = mifare_ultralight_read (tag, last_page, &page); res = mifare_ultralight_read(tag, last_page, &page);
cut_assert_equal_int (0, res, cut_message ("mifare_ultralight_read() failed")); cut_assert_equal_int(0, res, cut_message("mifare_ultralight_read() failed"));
} else { } else {
cut_omit("mifare_ultralightc_authenticate() skipped on Ultralight"); cut_omit("mifare_ultralightc_authenticate() skipped on Ultralight");
} }

View file

@ -28,120 +28,120 @@ const uint8_t eshortdata[11] = "\x03" "\x08" "elephant" "\xfe";
* OS / compiler does not support UTF-8 ;-) * OS / compiler does not support UTF-8 ;-)
*/ */
const uint8_t longdata[660] = "Dans une terre grasse et pleine d'escargots\n" \ const uint8_t longdata[660] = "Dans une terre grasse et pleine d'escargots\n" \
"Je veux creuser moi-même une fosse profonde,\n" \ "Je veux creuser moi-même une fosse profonde,\n" \
"Où je puisse à loisir étaler mes vieux os\n" \ "Où je puisse à loisir étaler mes vieux os\n" \
"Et dormir dans l'oubli comme un requin dans l'onde.\n" \ "Et dormir dans l'oubli comme un requin dans l'onde.\n" \
"Je hais les testaments et je hais les tombeaux;\n" \ "Je hais les testaments et je hais les tombeaux;\n" \
"Plutôt que d'implorer une larme du monde,\n" \ "Plutôt que d'implorer une larme du monde,\n" \
"Vivant, j'aimerais mieux inviter les corbeaux\n" \ "Vivant, j'aimerais mieux inviter les corbeaux\n" \
"À saigner tous les bouts de ma carcasse immonde.\n" \ "À saigner tous les bouts de ma carcasse immonde.\n" \
"Ô vers! noirs compagnons sans oreille et sans yeux,\n" \ "Ô vers! noirs compagnons sans oreille et sans yeux,\n" \
"Voyez venir à vous un mort libre et joyeux;\n" \ "Voyez venir à vous un mort libre et joyeux;\n" \
"Philosophes viveurs, fils de la pourriture,\n" \ "Philosophes viveurs, fils de la pourriture,\n" \
"À travers ma ruine allez donc sans remords,\n" \ "À travers ma ruine allez donc sans remords,\n" \
"Et dites-moi s'il est encor quelque torture\n" \ "Et dites-moi s'il est encor quelque torture\n" \
"Pour ce vieux corps sans âme et mort parmi les morts!\n"; "Pour ce vieux corps sans âme et mort parmi les morts!\n";
const uint8_t elongdata[665] = "\x07" "\xff\x02\x94" \ const uint8_t elongdata[665] = "\x07" "\xff\x02\x94" \
"Dans une terre grasse et pleine d'escargots\n" \ "Dans une terre grasse et pleine d'escargots\n" \
"Je veux creuser moi-même une fosse profonde,\n" \ "Je veux creuser moi-même une fosse profonde,\n" \
"Où je puisse à loisir étaler mes vieux os\n" \ "Où je puisse à loisir étaler mes vieux os\n" \
"Et dormir dans l'oubli comme un requin dans l'onde.\n" \ "Et dormir dans l'oubli comme un requin dans l'onde.\n" \
"Je hais les testaments et je hais les tombeaux;\n" \ "Je hais les testaments et je hais les tombeaux;\n" \
"Plutôt que d'implorer une larme du monde,\n" \ "Plutôt que d'implorer une larme du monde,\n" \
"Vivant, j'aimerais mieux inviter les corbeaux\n" \ "Vivant, j'aimerais mieux inviter les corbeaux\n" \
"À saigner tous les bouts de ma carcasse immonde.\n" \ "À saigner tous les bouts de ma carcasse immonde.\n" \
"Ô vers! noirs compagnons sans oreille et sans yeux,\n" \ "Ô vers! noirs compagnons sans oreille et sans yeux,\n" \
"Voyez venir à vous un mort libre et joyeux;\n" \ "Voyez venir à vous un mort libre et joyeux;\n" \
"Philosophes viveurs, fils de la pourriture,\n" \ "Philosophes viveurs, fils de la pourriture,\n" \
"À travers ma ruine allez donc sans remords,\n" \ "À travers ma ruine allez donc sans remords,\n" \
"Et dites-moi s'il est encor quelque torture\n" \ "Et dites-moi s'il est encor quelque torture\n" \
"Pour ce vieux corps sans âme et mort parmi les morts!\n" "Pour ce vieux corps sans âme et mort parmi les morts!\n"
"\xfe"; "\xfe";
void void
test_tlv_encode_short (void) test_tlv_encode_short(void)
{ {
uint8_t *res; uint8_t *res;
size_t osize; size_t osize;
res = tlv_encode (3, shortdata, sizeof (shortdata), &osize); res = tlv_encode(3, shortdata, sizeof(shortdata), &osize);
cut_assert_equal_int (sizeof (eshortdata), osize, cut_message ("Wrong encoded message length.")); cut_assert_equal_int(sizeof(eshortdata), osize, cut_message("Wrong encoded message length."));
cut_assert_equal_int (3, res[0], cut_message ("Wrong type")); cut_assert_equal_int(3, res[0], cut_message("Wrong type"));
cut_assert_equal_int (sizeof (shortdata), res[1], cut_message ("Wrong value length")); cut_assert_equal_int(sizeof(shortdata), res[1], cut_message("Wrong value length"));
cut_assert_equal_memory (eshortdata, sizeof (eshortdata), res, osize, cut_message ("Wrong encoded value")); cut_assert_equal_memory(eshortdata, sizeof(eshortdata), res, osize, cut_message("Wrong encoded value"));
free (res); free(res);
} }
void void
test_tlv_encode_long (void) test_tlv_encode_long(void)
{ {
uint8_t *res; uint8_t *res;
size_t osize; size_t osize;
res = tlv_encode (7, longdata, sizeof (longdata), &osize); res = tlv_encode(7, longdata, sizeof(longdata), &osize);
cut_assert_equal_int (sizeof (elongdata), osize, cut_message ("Wrong encoded message length.")); cut_assert_equal_int(sizeof(elongdata), osize, cut_message("Wrong encoded message length."));
cut_assert_equal_int (7, res[0], cut_message ("Wrong type")); cut_assert_equal_int(7, res[0], cut_message("Wrong type"));
cut_assert_equal_int (0xff, res[1], cut_message ("Wrong value length")); cut_assert_equal_int(0xff, res[1], cut_message("Wrong value length"));
cut_assert_equal_int (0x02, res[2], cut_message ("Wrong value length")); cut_assert_equal_int(0x02, res[2], cut_message("Wrong value length"));
cut_assert_equal_int (0x94, res[3], cut_message ("Wrong value length")); cut_assert_equal_int(0x94, res[3], cut_message("Wrong value length"));
cut_assert_equal_memory (elongdata, sizeof (elongdata), res, osize, cut_message ("Wrong encoded value")); cut_assert_equal_memory(elongdata, sizeof(elongdata), res, osize, cut_message("Wrong encoded value"));
free (res); free(res);
} }
void void
test_tlv_decode_short (void) test_tlv_decode_short(void)
{ {
uint8_t *res; uint8_t *res;
uint16_t size; uint16_t size;
uint8_t type; uint8_t type;
res = tlv_decode (eshortdata, &type, &size); res = tlv_decode(eshortdata, &type, &size);
cut_assert_equal_int (3, type, cut_message ("Wrong type")); cut_assert_equal_int(3, type, cut_message("Wrong type"));
cut_assert_equal_int (sizeof (shortdata), size, cut_message ("Wrong value length")); cut_assert_equal_int(sizeof(shortdata), size, cut_message("Wrong value length"));
cut_assert_equal_memory (shortdata, sizeof (shortdata), res, size, cut_message ("Wrong decoded value")); cut_assert_equal_memory(shortdata, sizeof(shortdata), res, size, cut_message("Wrong decoded value"));
free (res); free(res);
} }
void void
test_tlv_decode_long (void) test_tlv_decode_long(void)
{ {
uint8_t *res; uint8_t *res;
uint16_t size; uint16_t size;
uint8_t type; uint8_t type;
res = tlv_decode (elongdata, &type, &size); res = tlv_decode(elongdata, &type, &size);
cut_assert_equal_int (7, type, cut_message ("Wrong type")); cut_assert_equal_int(7, type, cut_message("Wrong type"));
cut_assert_equal_int (sizeof (longdata), size, cut_message ("Wrong value length")); cut_assert_equal_int(sizeof(longdata), size, cut_message("Wrong value length"));
cut_assert_equal_memory (longdata, sizeof (longdata), res, size, cut_message ("Wrong decoded value")); cut_assert_equal_memory(longdata, sizeof(longdata), res, size, cut_message("Wrong decoded value"));
free (res); free(res);
} }
void void
test_tlv_rfu (void) test_tlv_rfu(void)
{ {
uint8_t *data = malloc (0xffff); uint8_t *data = malloc(0xffff);
cut_assert_not_null (data, cut_message ("Out of memory")); cut_assert_not_null(data, cut_message("Out of memory"));
uint8_t *res = tlv_encode (7, data, 0xffff, NULL); uint8_t *res = tlv_encode(7, data, 0xffff, NULL);
cut_assert_null (res, cut_message ("Size reserved for future use")); cut_assert_null(res, cut_message("Size reserved for future use"));
free (data); free(data);
} }
void void
test_tlv_append (void) test_tlv_append(void)
{ {
const uint8_t a[] = { 0xde, 0xad, 0xbe, 0xef }; const uint8_t a[] = { 0xde, 0xad, 0xbe, 0xef };
const uint8_t b[] = { 0x42 }; const uint8_t b[] = { 0x42 };
uint8_t ndef_ab_ref[] = { 0x03, 0x04, 0xde, 0xad, 0xbe, 0xef, 0x03, 0x01, 0x42, 0xfe }; uint8_t ndef_ab_ref[] = { 0x03, 0x04, 0xde, 0xad, 0xbe, 0xef, 0x03, 0x01, 0x42, 0xfe };
uint8_t *ndef_a = tlv_encode (3, a, 4, NULL); uint8_t *ndef_a = tlv_encode(3, a, 4, NULL);
uint8_t *ndef_b = tlv_encode (3, b, 1, NULL); uint8_t *ndef_b = tlv_encode(3, b, 1, NULL);
ndef_a = tlv_append (ndef_a, ndef_b); ndef_a = tlv_append(ndef_a, ndef_b);
cut_assert_equal_memory (ndef_ab_ref, sizeof (ndef_ab_ref), ndef_a, sizeof (ndef_ab_ref), cut_message ("Wrong appended data")); cut_assert_equal_memory(ndef_ab_ref, sizeof(ndef_ab_ref), ndef_a, sizeof(ndef_ab_ref), cut_message("Wrong appended data"));
free (ndef_a); free(ndef_a);
free (ndef_b); free(ndef_b);
} }