Run make style to fix style

This commit is contained in:
Romain Tartière 2017-06-27 13:58:31 +02:00
parent 187481bb4c
commit 73dc0529fa
66 changed files with 5945 additions and 5949 deletions

View file

@ -1,11 +1,11 @@
/*-
* Copyright (C) 2015, Romain Tartiere.
*
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
@ -23,56 +23,56 @@
#include <freefare.h>
int
main (void)
main(void)
{
nfc_device *device = NULL;
FreefareTag *tags = NULL;
nfc_connstring devices[8];
nfc_context *context;
nfc_init (&context);
nfc_init(&context);
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)
errx (EXIT_FAILURE, "No NFC device found.");
errx(EXIT_FAILURE, "No NFC device found.");
for (size_t d = 0; d < device_count; d++) {
device = nfc_open (context, devices[d]);
device = nfc_open(context, devices[d]);
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) {
nfc_close (device);
errx (EXIT_FAILURE, "Error listing FeliCa tag.");
nfc_close(device);
errx(EXIT_FAILURE, "Error listing FeliCa tag.");
}
for (int i = 0; tags[i]; i++) {
if (FELICA != freefare_get_tag_type (tags[i]))
if (FELICA != freefare_get_tag_type(tags[i]))
continue;
char *uid = freefare_get_tag_uid (tags[i]);
printf ("Dumping %s tag %s\n", freefare_get_tag_friendly_name (tags[i]), uid);
free (uid);
printf ("Number\tName\tData\n");
char *uid = freefare_get_tag_uid(tags[i]);
printf("Dumping %s tag %s\n", freefare_get_tag_friendly_name(tags[i]), uid);
free(uid);
printf("Number\tName\tData\n");
for (int block = 0x00; block < 0x0f; block++) {
uint8_t buffer[16];
if (felica_read (tags[i], FELICA_SC_RO, block, buffer, sizeof (buffer)) < 0)
errx (EXIT_FAILURE, "Error reading block %d", block);
if (felica_read(tags[i], FELICA_SC_RO, block, buffer, sizeof(buffer)) < 0)
errx(EXIT_FAILURE, "Error reading block %d", block);
if (block < 0x0e)
printf ("0x%02x\tS_PAD%d\t", block, block);
printf("0x%02x\tS_PAD%d\t", block, block);
else
printf ("0x%02x\tREG\t", block);
printf("0x%02x\tREG\t", block);
for (int j = 0; j < 16; j++) {
printf ("%02x ", buffer[j]);
printf("%02x ", buffer[j]);
}
printf ("\n");
printf("\n");
}
char *block_names[] = {
@ -84,19 +84,19 @@ main (void)
for (int block = 0x80; block < 0x89; block++) {
uint8_t buffer[16];
if (felica_read (tags[i], FELICA_SC_RO, block, buffer, sizeof (buffer)) < 0)
errx (EXIT_FAILURE, "Error reading block %d", block);
if (felica_read(tags[i], FELICA_SC_RO, block, buffer, sizeof(buffer)) < 0)
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++) {
printf ("%02x ", buffer[j]);
printf("%02x ", buffer[j]);
}
printf ("\n");
printf("\n");
}
}
freefare_free_tags (tags);
nfc_close (device);
freefare_free_tags(tags);
nfc_close(device);
}
exit(EXIT_SUCCESS);

View file

@ -1,11 +1,11 @@
/*-
* Copyright (C) 2015, Romain Tartiere.
*
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
@ -44,15 +44,15 @@
#define NDEF_BUFFER_SIZE 512
void
usage (char *progname)
usage(char *progname)
{
fprintf (stderr, "usage: %s [options]\n", progname);
fprintf (stderr, "\nAvailable options:\n");
fprintf (stderr, " -o FILE Write NDEF message to FILE\n");
fprintf(stderr, "usage: %s [options]\n", progname);
fprintf(stderr, "\nAvailable options:\n");
fprintf(stderr, " -o FILE Write NDEF message to FILE\n");
}
int
main (int argc, char *argv[])
main(int argc, char *argv[])
{
int error = EXIT_SUCCESS;
nfc_device *device = NULL;
@ -60,14 +60,14 @@ main (int argc, char *argv[])
int ch;
char *ndef_file = NULL;
while ((ch = getopt (argc, argv, "o:")) != -1) {
while ((ch = getopt(argc, argv, "o:")) != -1) {
switch (ch) {
case 'o':
ndef_file = optarg;
break;
case '?':
usage (argv[0]);
exit (EXIT_FAILURE);
usage(argv[0]);
exit(EXIT_FAILURE);
}
}
@ -76,26 +76,26 @@ main (int argc, char *argv[])
size_t device_count;
nfc_context *context;
nfc_init (&context);
nfc_init(&context);
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)
errx (EXIT_FAILURE, "No NFC device found.");
errx(EXIT_FAILURE, "No NFC device found.");
for (size_t d = 0; d < device_count; d++) {
device = nfc_open (context, devices[d]);
device = nfc_open(context, devices[d]);
if (!device) {
warnx ("nfc_open() failed.");
warnx("nfc_open() failed.");
error = EXIT_FAILURE;
continue;
}
tags = freefare_get_tags (device);
tags = freefare_get_tags(device);
if (!tags) {
nfc_close (device);
errx (EXIT_FAILURE, "Error listing FeliCa tag.");
nfc_close(device);
errx(EXIT_FAILURE, "Error listing FeliCa tag.");
}
for (int i = 0; (!error) && tags[i]; i++) {
@ -106,7 +106,7 @@ main (int argc, char *argv[])
ssize_t s;
// 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;
ndef_space_left -= s;
}
@ -127,7 +127,7 @@ main (int argc, char *argv[])
payload_length = ndef_record[2];
payload_length_length = 1;
} else {
payload_length = be32toh (*(uint32_t *)(ndef_record + 2));
payload_length = be32toh(*(uint32_t *)(ndef_record + 2));
payload_length_length = 4;
}
ndef_record_length += payload_length_length;
@ -139,28 +139,28 @@ main (int argc, char *argv[])
ndef_message_length += ndef_record_length;
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);
}
if (ndef_message_length == 0)
errx (EXIT_FAILURE, "No NDEF message found");
errx(EXIT_FAILURE, "No NDEF message found");
FILE *f;
if (ndef_file)
f = fopen (ndef_file, "w");
f = fopen(ndef_file, "w");
else
f = stdout;
if (fwrite (ndef_message, ndef_message_length, 1, f) != 1)
err (EXIT_FAILURE, "Can't write NDEF message");
if (fwrite(ndef_message, ndef_message_length, 1, f) != 1)
err(EXIT_FAILURE, "Can't write NDEF message");
fclose (f);
fclose(f);
}
freefare_free_tags (tags);
nfc_close (device);
freefare_free_tags(tags);
nfc_close(device);
}
exit(EXIT_SUCCESS);
}

View file

@ -1,12 +1,12 @@
/*-
* Copyright (C) 2010, Romain Tartiere, Romuald Conty.
* Copyright (C) 2012, Romuald Conty.
*
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
@ -35,18 +35,18 @@
MifareClassicKey default_keys[40];
MifareClassicKey default_keys_int[] = {
{ 0xff,0xff,0xff,0xff,0xff,0xff },
{ 0xd3,0xf7,0xd3,0xf7,0xd3,0xf7 },
{ 0xa0,0xa1,0xa2,0xa3,0xa4,0xa5 },
{ 0xb0,0xb1,0xb2,0xb3,0xb4,0xb5 },
{ 0x4d,0x3a,0x99,0xc3,0x51,0xdd },
{ 0x1a,0x98,0x2c,0x7e,0x45,0x9a },
{ 0xaa,0xbb,0xcc,0xdd,0xee,0xff },
{ 0x00,0x00,0x00,0x00,0x00,0x00 }
{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
{ 0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7 },
{ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5 },
{ 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5 },
{ 0x4d, 0x3a, 0x99, 0xc3, 0x51, 0xdd },
{ 0x1a, 0x98, 0x2c, 0x7e, 0x45, 0x9a },
{ 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
};
int format_mifare_classic_1k (FreefareTag tag);
int format_mifare_classic_4k (FreefareTag tag);
int try_format_sector (FreefareTag tag, MifareClassicSectorNumber sector);
int format_mifare_classic_1k(FreefareTag tag);
int format_mifare_classic_4k(FreefareTag tag);
int try_format_sector(FreefareTag tag, MifareClassicSectorNumber sector);
static int at_block = 0;
static int mod_block = 10;
@ -60,81 +60,81 @@ struct {
};
static void
display_progress (void)
display_progress(void)
{
at_block++;
if (0 == (at_block % mod_block)) {
printf ("%d", at_block);
fflush (stdout);
printf("%d", at_block);
fflush(stdout);
} else {
printf (".");
fflush (stdout);
printf(".");
fflush(stdout);
}
}
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++) {
if (!try_format_sector (tag, sector))
if (!try_format_sector(tag, sector))
return 0;
}
printf (DONE_FORMAT);
printf(DONE_FORMAT);
return 1;
}
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++) {
if (!try_format_sector (tag, sector))
if (!try_format_sector(tag, sector))
return 0;
}
printf (DONE_FORMAT);
printf(DONE_FORMAT);
return 1;
}
int
try_format_sector (FreefareTag tag, MifareClassicSectorNumber sector)
try_format_sector(FreefareTag tag, MifareClassicSectorNumber sector)
{
display_progress ();
for (size_t i = 0; i < (sizeof (default_keys) / sizeof (MifareClassicKey)); i++) {
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_format_sector (tag, sector)) {
mifare_classic_disconnect (tag);
display_progress();
for (size_t i = 0; i < (sizeof(default_keys) / sizeof(MifareClassicKey)); i++) {
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_format_sector(tag, sector)) {
mifare_classic_disconnect(tag);
return 1;
} 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_format_sector (tag, sector)) {
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_format_sector(tag, sector)) {
mifare_classic_disconnect(tag);
return 1;
} 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;
}
static void
usage(char *progname)
{
fprintf (stderr, "usage: %s [-fy] [keyfile]\n", progname);
fprintf (stderr, "\nOptions:\n");
fprintf (stderr, " -f Fast format (only erase MAD)\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, "usage: %s [-fy] [keyfile]\n", progname);
fprintf(stderr, "\nOptions:\n");
fprintf(stderr, " -f Fast format (only erase MAD)\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");
}
int
@ -145,47 +145,45 @@ main(int argc, char *argv[])
nfc_device *device = NULL;
FreefareTag *tags = NULL;
while ((ch = getopt (argc, argv, "fhy")) != -1) {
while ((ch = getopt(argc, argv, "fhy")) != -1) {
switch (ch) {
case 'f':
format_options.fast = true;
break;
case 'h':
usage(argv[0]);
exit (EXIT_SUCCESS);
exit(EXIT_SUCCESS);
break;
case 'y':
format_options.interactive = false;
break;
default:
usage(argv[0]);
exit (EXIT_FAILURE);
exit(EXIT_FAILURE);
}
}
// Remaining args, if any, are in argv[optind .. (argc-1)]
memcpy(default_keys, default_keys_int, sizeof(default_keys_int));
if ((argc - optind) > 0)
{
int i, rc;
char kbuffer[1024] = {0};
memset ( kbuffer, 0, sizeof kbuffer);
FILE *fp = fopen(argv[optind], "rb");
if (fp == NULL)
errx(EXIT_FAILURE, "Unable to open file");
for (i = 0; (rc = getc(fp)) != EOF && i < 1024; kbuffer[i++] = rc) { }
fclose(fp);
if ((argc - optind) > 0) {
int i, rc;
char kbuffer[1024] = {0};
memset(kbuffer, 0, sizeof kbuffer);
FILE *fp = fopen(argv[optind], "rb");
if (fp == NULL)
errx(EXIT_FAILURE, "Unable to open file");
for (i = 0; (rc = getc(fp)) != EOF && i < 1024; kbuffer[i++] = rc) { }
fclose(fp);
i = sizeof(default_keys_int) / 6;
for(int s = 0; s<16; s++)
{
int startblock = s * 4;
int pos_a = (startblock + 3) * 16;
int pos_b = (startblock + 3) * 16 + 10;
memcpy((default_keys + i++), kbuffer + pos_a, 6);
memcpy((default_keys + i++), kbuffer + pos_b, 6);
}
i = sizeof(default_keys_int) / 6;
for (int s = 0; s < 16; s++) {
int startblock = s * 4;
int pos_a = (startblock + 3) * 16;
int pos_b = (startblock + 3) * 16 + 10;
memcpy((default_keys + i++), kbuffer + pos_a, 6);
memcpy((default_keys + i++), kbuffer + pos_b, 6);
}
}
nfc_connstring devices[8];
@ -193,30 +191,30 @@ main(int argc, char *argv[])
size_t device_count;
nfc_context *context;
nfc_init (&context);
nfc_init(&context);
if (context == NULL)
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)
errx (EXIT_FAILURE, "No NFC device found.");
errx(EXIT_FAILURE, "No NFC device found.");
for (size_t d = 0; d < device_count; d++) {
device = nfc_open (context, devices[d]);
device = nfc_open(context, devices[d]);
if (!device) {
warnx ("nfc_open() failed.");
warnx("nfc_open() failed.");
error = EXIT_FAILURE;
continue;
}
tags = freefare_get_tags (device);
tags = freefare_get_tags(device);
if (!tags) {
nfc_close (device);
errx (EXIT_FAILURE, "Error listing Mifare Classic tag.");
nfc_close(device);
errx(EXIT_FAILURE, "Error listing Mifare Classic tag.");
}
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_4K:
break;
@ -224,44 +222,44 @@ main(int argc, char *argv[])
continue;
}
char *tag_uid = freefare_get_tag_uid (tags[i]);
char *tag_uid = freefare_get_tag_uid(tags[i]);
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;
if (format_options.interactive) {
printf ("Format [yN] ");
fgets (buffer, BUFSIZ, stdin);
printf("Format [yN] ");
fgets(buffer, BUFSIZ, stdin);
format = ((buffer[0] == 'y') || (buffer[0] == 'Y'));
} else {
printf ("\n");
printf("\n");
}
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;
if (format_options.fast) {
printf (START_FORMAT_N, (tt == MIFARE_CLASSIC_1K) ? 1 : 2);
if (!try_format_sector (tags[i], 0x00))
printf(START_FORMAT_N, (tt == MIFARE_CLASSIC_1K) ? 1 : 2);
if (!try_format_sector(tags[i], 0x00))
break;
if (tt == MIFARE_CLASSIC_4K)
if (!try_format_sector (tags[i], 0x10))
if (!try_format_sector(tags[i], 0x10))
break;
printf (DONE_FORMAT);
printf(DONE_FORMAT);
continue;
}
switch (tt) {
case MIFARE_CLASSIC_1K:
mod_block = 4;
if (!format_mifare_classic_1k (tags[i]))
if (!format_mifare_classic_1k(tags[i]))
error = 1;
break;
case MIFARE_CLASSIC_4K:
mod_block = 10;
if (!format_mifare_classic_4k (tags[i]))
if (!format_mifare_classic_4k(tags[i]))
error = 1;
break;
default:
@ -270,13 +268,13 @@ main(int argc, char *argv[])
}
}
free (tag_uid);
free(tag_uid);
}
freefare_free_tags (tags);
nfc_close (device);
freefare_free_tags(tags);
nfc_close(device);
}
nfc_exit (context);
exit (error);
nfc_exit(context);
exit(error);
}

View file

@ -1,11 +1,11 @@
/*-
* Copyright (C) 2011, Romain Tartiere, Romuald Conty.
*
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
@ -56,10 +56,10 @@ struct {
static void
usage(char *progname)
{
fprintf (stderr, "usage: %s -o FILE\n", progname);
fprintf (stderr, "\nOptions:\n");
fprintf (stderr, " -y Do not ask for confirmation\n");
fprintf (stderr, " -o Extract NDEF message if available in FILE\n");
fprintf(stderr, "usage: %s -o FILE\n", progname);
fprintf(stderr, "\nOptions:\n");
fprintf(stderr, " -y Do not ask for confirmation\n");
fprintf(stderr, " -o Extract NDEF message if available in FILE\n");
}
int
@ -72,11 +72,11 @@ main(int argc, char *argv[])
int ch;
char *ndef_output = NULL;
while ((ch = getopt (argc, argv, "hyo:")) != -1) {
while ((ch = getopt(argc, argv, "hyo:")) != -1) {
switch (ch) {
case 'h':
usage(argv[0]);
exit (EXIT_SUCCESS);
exit(EXIT_SUCCESS);
break;
case 'y':
read_options.interactive = false;
@ -86,30 +86,30 @@ main(int argc, char *argv[])
break;
case '?':
if (optopt == 'o')
fprintf (stderr, "Option -%c requires an argument.\n", optopt);
/* FALLTHROUGH */
fprintf(stderr, "Option -%c requires an argument.\n", optopt);
/* FALLTHROUGH */
default:
usage (argv[0]);
exit (EXIT_FAILURE);
usage(argv[0]);
exit(EXIT_FAILURE);
}
}
if (ndef_output == NULL) {
usage (argv[0]);
exit (EXIT_FAILURE);
usage(argv[0]);
exit(EXIT_FAILURE);
}
FILE* message_stream = NULL;
FILE* ndef_stream = NULL;
FILE *message_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;
ndef_stream = stdout;
} else {
message_stream = stdout;
ndef_stream = fopen(ndef_output, "wb");
if (!ndef_stream) {
fprintf (stderr, "Could not open file %s.\n", ndef_output);
exit (EXIT_FAILURE);
fprintf(stderr, "Could not open file %s.\n", ndef_output);
exit(EXIT_FAILURE);
}
}
@ -117,30 +117,30 @@ main(int argc, char *argv[])
size_t device_count;
nfc_context *context;
nfc_init (&context);
nfc_init(&context);
if (context == NULL)
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)
errx (EXIT_FAILURE, "No NFC device found.");
errx(EXIT_FAILURE, "No NFC device found.");
for (size_t d = 0; d < device_count; d++) {
device = nfc_open (context, devices[d]);
if (!device) {
warnx ("nfc_open() failed.");
error = EXIT_FAILURE;
continue;
}
device = nfc_open(context, devices[d]);
if (!device) {
warnx("nfc_open() failed.");
error = EXIT_FAILURE;
continue;
}
tags = freefare_get_tags (device);
tags = freefare_get_tags(device);
if (!tags) {
nfc_close (device);
errx (EXIT_FAILURE, "Error listing MIFARE classic tag.");
nfc_close(device);
errx(EXIT_FAILURE, "Error listing MIFARE classic tag.");
}
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_4K:
break;
@ -148,100 +148,100 @@ main(int argc, char *argv[])
continue;
}
char *tag_uid = freefare_get_tag_uid (tags[i]);
char *tag_uid = freefare_get_tag_uid(tags[i]);
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;
if (read_options.interactive) {
fprintf (message_stream, "Read NDEF [yN] ");
fgets (buffer, BUFSIZ, stdin);
fprintf(message_stream, "Read NDEF [yN] ");
fgets(buffer, BUFSIZ, stdin);
read_ndef = ((buffer[0] == 'y') || (buffer[0] == 'Y'));
} else {
fprintf (message_stream, "\n");
fprintf(message_stream, "\n");
}
if (read_ndef) {
// NFCForum card has a MAD, load it.
if (0 == mifare_classic_connect (tags[i])) {
if (0 == mifare_classic_connect(tags[i])) {
} else {
nfc_perror (device, "mifare_classic_connect");
nfc_perror(device, "mifare_classic_connect");
error = EXIT_FAILURE;
goto error;
}
if ((mad = mad_read (tags[i]))) {
if ((mad = mad_read(tags[i]))) {
// Dump the NFCForum application using MAD information
uint8_t buffer[4096];
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;
uint16_t tlv_data_len;
uint8_t * tlv_data;
uint8_t * pbuffer = buffer;
uint8_t *tlv_data;
uint8_t *pbuffer = buffer;
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) {
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.
pbuffer += tlv_record_length(pbuffer, NULL, NULL);
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");
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.
pbuffer += tlv_record_length(pbuffer, NULL, NULL);
if (pbuffer >= buffer + sizeof(buffer)) {
error = EXIT_FAILURE;
goto error;
break;
default:
fprintf (stderr, "NFC Forum application contains an invalid TLV.\n");
}
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;
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) {
fprintf (stderr, "Could not write to file.\n");
if (fwrite(tlv_data, 1, tlv_data_len, ndef_stream) != tlv_data_len) {
fprintf(stderr, "Could not write to file.\n");
error = EXIT_FAILURE;
goto error;
}
free (tlv_data);
free(tlv_data);
} else {
fprintf (stderr, "No NFC Forum application.\n");
fprintf(stderr, "No NFC Forum application.\n");
error = EXIT_FAILURE;
goto error;
}
} else {
fprintf (stderr, "No MAD detected.\n");
fprintf(stderr, "No MAD detected.\n");
error = EXIT_FAILURE;
goto error;
}
free (mad);
free(mad);
}
error:
free (tag_uid);
free(tag_uid);
}
fclose (ndef_stream);
freefare_free_tags (tags);
nfc_close (device);
fclose(ndef_stream);
freefare_free_tags(tags);
nfc_close(device);
}
nfc_exit (context);
exit (error);
nfc_exit(context);
exit(error);
}

View file

@ -1,11 +1,11 @@
/*-
* Copyright (C) 2010, Romain Tartiere, Romuald Conty.
*
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
@ -33,14 +33,14 @@
#define MIN(a,b) ((a < b) ? a: b)
MifareClassicKey default_keys[] = {
{ 0xff,0xff,0xff,0xff,0xff,0xff },
{ 0xd3,0xf7,0xd3,0xf7,0xd3,0xf7 },
{ 0xa0,0xa1,0xa2,0xa3,0xa4,0xa5 },
{ 0xb0,0xb1,0xb2,0xb3,0xb4,0xb5 },
{ 0x4d,0x3a,0x99,0xc3,0x51,0xdd },
{ 0x1a,0x98,0x2c,0x7e,0x45,0x9a },
{ 0xaa,0xbb,0xcc,0xdd,0xee,0xff },
{ 0x00,0x00,0x00,0x00,0x00,0x00 }
{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
{ 0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7 },
{ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5 },
{ 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5 },
{ 0x4d, 0x3a, 0x99, 0xc3, 0x51, 0xdd },
{ 0x1a, 0x98, 0x2c, 0x7e, 0x45, 0x9a },
{ 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
};
struct mifare_classic_key_and_type {
@ -69,54 +69,54 @@ uint8_t *ndef_msg;
size_t ndef_msg_len;
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
* we also have a full access to data blocks.
*/
mifare_classic_disconnect (tag);
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 ((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_KEYB, MFC_KEY_A))) {
memcpy (key, &default_keys[i], sizeof (MifareClassicKey));
mifare_classic_disconnect(tag);
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 ((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_KEYB, MFC_KEY_A))) {
memcpy(key, &default_keys[i], sizeof(MifareClassicKey));
*key_type = MFC_KEY_A;
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 ((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_KEYB, MFC_KEY_B))) {
memcpy (key, &default_keys[i], sizeof (MifareClassicKey));
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)) &&
(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))) {
memcpy(key, &default_keys[i], sizeof(MifareClassicKey));
*key_type = MFC_KEY_B;
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;
}
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;
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) {
nfc_perror (device, "fix_mad_trailer_block mifare_classic_authenticate");
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) {
nfc_perror(device, "fix_mad_trailer_block mifare_classic_authenticate");
return -1;
}
if (mifare_classic_write (tag, mifare_classic_sector_last_block (sector), block) < 0) {
nfc_perror (device, "mifare_classic_write");
if (mifare_classic_write(tag, mifare_classic_sector_last_block(sector), block) < 0) {
nfc_perror(device, "mifare_classic_write");
return -1;
}
return 0;
@ -125,10 +125,10 @@ fix_mad_trailer_block (nfc_device *device, FreefareTag tag, MifareClassicSectorN
static void
usage(char *progname)
{
fprintf (stderr, "usage: %s -i FILE\n", progname);
fprintf (stderr, "\nOptions:\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, "usage: %s -i FILE\n", progname);
fprintf(stderr, "\nOptions:\n");
fprintf(stderr, " -y Do not ask for confirmation\n");
fprintf(stderr, " -i Use FILE as NDEF message to write on card (\"-\" = stdin)\n");
}
int
@ -142,11 +142,11 @@ main(int argc, char *argv[])
int ch;
char *ndef_input = NULL;
while ((ch = getopt (argc, argv, "hyi:")) != -1) {
while ((ch = getopt(argc, argv, "hyi:")) != -1) {
switch (ch) {
case 'h':
usage(argv[0]);
exit (EXIT_SUCCESS);
exit(EXIT_SUCCESS);
break;
case 'y':
write_options.interactive = false;
@ -156,81 +156,81 @@ main(int argc, char *argv[])
break;
case '?':
if (optopt == 'i')
fprintf (stderr, "Option -%c requires an argument.\n", optopt);
/* FALLTHROUGH */
fprintf(stderr, "Option -%c requires an argument.\n", optopt);
/* FALLTHROUGH */
default:
usage (argv[0]);
exit (EXIT_FAILURE);
usage(argv[0]);
exit(EXIT_FAILURE);
}
}
if (ndef_input == NULL) {
ndef_msg = (uint8_t*)ndef_default_msg;
ndef_msg_len = sizeof(ndef_default_msg);
ndef_msg = (uint8_t *)ndef_default_msg;
ndef_msg_len = sizeof(ndef_default_msg);
} else {
FILE* ndef_stream = NULL;
if ((strlen (ndef_input) == 1) && (ndef_input[0] == '-')) {
// FIXME stdin as input have to be readed and buffered in ndef_msg
FILE *ndef_stream = NULL;
if ((strlen(ndef_input) == 1) && (ndef_input[0] == '-')) {
// FIXME stdin as input have to be readed and buffered in ndef_msg
ndef_stream = stdin;
fprintf (stderr, "stdin as NDEF is not implemented");
exit (EXIT_FAILURE);
fprintf(stderr, "stdin as NDEF is not implemented");
exit(EXIT_FAILURE);
} else {
ndef_stream = fopen(ndef_input, "rb");
if (!ndef_stream) {
fprintf (stderr, "Could not open file %s.\n", ndef_input);
exit (EXIT_FAILURE);
fprintf(stderr, "Could not open file %s.\n", ndef_input);
exit(EXIT_FAILURE);
}
fseek(ndef_stream, 0L, SEEK_END);
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))) {
err (EXIT_FAILURE, "malloc");
if (!(ndef_msg = malloc(ndef_msg_len))) {
err(EXIT_FAILURE, "malloc");
}
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);
fclose (ndef_stream);
free (ndef_msg);
exit (EXIT_FAILURE);
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);
fclose(ndef_stream);
free(ndef_msg);
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;
if (!(card_write_keys = malloc (40 * sizeof (*card_write_keys)))) {
err (EXIT_FAILURE, "malloc");
if (!(card_write_keys = malloc(40 * sizeof(*card_write_keys)))) {
err(EXIT_FAILURE, "malloc");
}
nfc_connstring devices[8];
size_t device_count;
nfc_context *context;
nfc_init (&context);
nfc_init(&context);
if (context == NULL)
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)
errx (EXIT_FAILURE, "No NFC device found.");
errx(EXIT_FAILURE, "No NFC device found.");
for (size_t d = 0; d < device_count; d++) {
device = nfc_open (context, devices[d]);
if (!device) {
warnx ("nfc_open() failed.");
error = EXIT_FAILURE;
continue;
}
device = nfc_open(context, devices[d]);
if (!device) {
warnx("nfc_open() failed.");
error = EXIT_FAILURE;
continue;
}
tags = freefare_get_tags (device);
tags = freefare_get_tags(device);
if (!tags) {
nfc_close (device);
errx (EXIT_FAILURE, "Error listing MIFARE classic tag.");
nfc_close(device);
errx(EXIT_FAILURE, "Error listing MIFARE classic tag.");
}
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_4K:
break;
@ -238,35 +238,35 @@ main(int argc, char *argv[])
continue;
}
char *tag_uid = freefare_get_tag_uid (tags[i]);
char *tag_uid = freefare_get_tag_uid(tags[i]);
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;
if (write_options.interactive) {
printf ("Write NDEF [yN] ");
fgets (buffer, BUFSIZ, stdin);
printf("Write NDEF [yN] ");
fgets(buffer, BUFSIZ, stdin);
write_ndef = ((buffer[0] == 'y') || (buffer[0] == 'Y'));
} else {
printf ("\n");
printf("\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;
}
if (write_ndef) {
switch (freefare_get_tag_type (tags[i])) {
switch (freefare_get_tag_type(tags[i])) {
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;
goto error;
}
/* fallthrough */
/* fallthrough */
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;
goto error;
}
@ -278,24 +278,24 @@ main(int argc, char *argv[])
if (!error) {
/* 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:
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;
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;
}
/* fallthrough */
/* fallthrough */
case MIFARE_CLASSIC_1K:
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;
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;
}
break;
@ -306,7 +306,7 @@ main(int argc, char *argv[])
}
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
@ -314,38 +314,38 @@ main(int argc, char *argv[])
*/
// 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.
MifareClassicSectorNumber *sectors, *p;
sectors = p = mifare_application_find (mad, mad_nfcforum_aid);
sectors = p = mifare_application_find(mad, mad_nfcforum_aid);
if (sectors) {
while (*p) {
if (mifare_classic_authenticate (tags[i], mifare_classic_sector_last_block(*p), default_keyb, MFC_KEY_B) < 0) {
nfc_perror (device, "mifare_classic_authenticate");
if (mifare_classic_authenticate(tags[i], mifare_classic_sector_last_block(*p), default_keyb, MFC_KEY_B) < 0) {
nfc_perror(device, "mifare_classic_authenticate");
error = 1;
goto error;
}
if (mifare_classic_format_sector (tags[i], *p) < 0) {
nfc_perror (device, "mifare_classic_format_sector");
if (mifare_classic_format_sector(tags[i], *p) < 0) {
nfc_perror(device, "mifare_classic_format_sector");
error = 1;
goto error;
}
p++;
}
}
free (sectors);
mifare_application_free (mad, mad_nfcforum_aid);
free(sectors);
mifare_application_free(mad, mad_nfcforum_aid);
} else {
// 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))) {
perror ("mad_new");
if (!(mad = mad_new((freefare_get_tag_type(tags[i]) == MIFARE_CLASSIC_4K) ? 2 : 1))) {
perror("mad_new");
error = 1;
goto error;
}
MifareClassicSectorNumber max_s = 0;
switch (freefare_get_tag_type (tags[i])) {
switch (freefare_get_tag_type(tags[i])) {
case MIFARE_CLASSIC_1K:
max_s = 15;
break;
@ -360,13 +360,13 @@ main(int argc, char *argv[])
// Mark unusable sectors as so
for (size_t s = max_s; s; s--) {
if (s == 0x10) continue;
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);
} else if ((memcmp (card_write_keys[s].key, transport_key, sizeof (transport_key)) != 0) &&
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);
} else if ((memcmp(card_write_keys[s].key, transport_key, sizeof(transport_key)) != 0) &&
(card_write_keys[s].type != MFC_KEY_A)) {
// Revert to transport configuration
if (mifare_classic_format_sector (tags[i], s) < 0) {
nfc_perror (device, "mifare_classic_format_sector");
if (mifare_classic_format_sector(tags[i], s) < 0) {
nfc_perror(device, "mifare_classic_format_sector");
error = 1;
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) {
nfc_perror (device, "mifare_application_alloc");
nfc_perror(device, "mifare_application_alloc");
error = EXIT_FAILURE;
goto error;
}
if (mad_write (tags[i], mad, card_write_keys[0x00].key, card_write_keys[0x10].key) < 0) {
nfc_perror (device, "mad_write");
if (mad_write(tags[i], mad, card_write_keys[0x00].key, card_write_keys[0x10].key) < 0) {
nfc_perror(device, "mad_write");
error = EXIT_FAILURE;
goto error;
}
int s = 0;
while (sectors[s]) {
MifareClassicBlockNumber block = mifare_classic_sector_last_block (sectors[s]);
MifareClassicBlockNumber block = mifare_classic_sector_last_block(sectors[s]);
MifareClassicBlock block_data;
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) {
nfc_perror (device, "mifare_classic_authenticate");
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) {
nfc_perror(device, "mifare_classic_authenticate");
error = EXIT_FAILURE;
goto error;
}
if (mifare_classic_write (tags[i], block, block_data) < 0) {
nfc_perror (device, "mifare_classic_write");
if (mifare_classic_write(tags[i], block, block_data) < 0) {
nfc_perror(device, "mifare_classic_write");
error = EXIT_FAILURE;
goto error;
}
s++;
}
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");
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");
error = EXIT_FAILURE;
goto error;
}
free (sectors);
free(sectors);
free (tlv_data);
free(tlv_data);
free (mad);
free(mad);
}
error:
free (tag_uid);
free(tag_uid);
}
if (ndef_msg != ndef_default_msg)
free (ndef_msg);
freefare_free_tags (tags);
nfc_close (device);
free(ndef_msg);
freefare_free_tags(tags);
nfc_close(device);
}
free (card_write_keys);
nfc_exit (context);
exit (error);
free(card_write_keys);
nfc_exit(context);
exit(error);
}

View file

@ -1,11 +1,11 @@
/*-
* Copyright (C) 2010, Romain Tartiere.
*
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
@ -34,105 +34,105 @@ main(int argc, char *argv[])
FreefareTag *tags = NULL;
if (argc > 1)
errx (EXIT_FAILURE, "usage: %s", argv[0]);
errx(EXIT_FAILURE, "usage: %s", argv[0]);
nfc_connstring devices[8];
size_t device_count;
nfc_context *context;
nfc_init (&context);
nfc_init(&context);
if (context == NULL)
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)
errx (EXIT_FAILURE, "No NFC device found.");
errx(EXIT_FAILURE, "No NFC device found.");
for (size_t d = 0; d < device_count; d++) {
device = nfc_open (context, devices[d]);
if (!device) {
warnx ("nfc_open() failed.");
error = EXIT_FAILURE;
continue;
}
device = nfc_open(context, devices[d]);
if (!device) {
warnx("nfc_open() failed.");
error = EXIT_FAILURE;
continue;
}
tags = freefare_get_tags (device);
tags = freefare_get_tags(device);
if (!tags) {
nfc_close (device);
errx (EXIT_FAILURE, "Error listing tags.");
nfc_close(device);
errx(EXIT_FAILURE, "Error listing tags.");
}
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;
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) {
warnx ("Can't connect to Mifare DESFire target.");
warnx("Can't connect to Mifare DESFire target.");
error = EXIT_FAILURE;
break;
}
MifareDESFireKey key = mifare_desfire_des_key_new_with_version (key_data_null);
res = mifare_desfire_authenticate (tags[i], 0, key);
MifareDESFireKey key = mifare_desfire_des_key_new_with_version(key_data_null);
res = mifare_desfire_authenticate(tags[i], 0, key);
if (res < 0)
errx (EXIT_FAILURE, "Authentication on master application failed");
errx(EXIT_FAILURE, "Authentication on master application failed");
MadAid mad_aid = { 0x12, 0x34 };
MifareDESFireAID aid = mifare_desfire_aid_new_with_mad_aid (mad_aid, 0x5);
res = mifare_desfire_create_application (tags[i], aid, 0xFF, 0x1);
MifareDESFireAID aid = mifare_desfire_aid_new_with_mad_aid(mad_aid, 0x5);
res = mifare_desfire_create_application(tags[i], aid, 0xFF, 0x1);
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)
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)
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)
errx (EXIT_FAILURE, "File creation failed");
errx(EXIT_FAILURE, "File creation failed");
const char *s= "Hello World";
res = mifare_desfire_write_data (tags[i], 1, 0, strlen (s), s);
const char *s = "Hello World";
res = mifare_desfire_write_data(tags[i], 1, 0, strlen(s), s);
if (res < 0)
errx (EXIT_FAILURE, "File write failed");
errx(EXIT_FAILURE, "File write failed");
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)
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)
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)
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)
errx (EXIT_FAILURE, "PICC format failed");
errx(EXIT_FAILURE, "PICC format failed");
mifare_desfire_key_free (key);
free (tag_uid);
free (aid);
mifare_desfire_key_free(key);
free(tag_uid);
free(aid);
mifare_desfire_disconnect (tags[i]);
mifare_desfire_disconnect(tags[i]);
}
freefare_free_tags (tags);
nfc_close (device);
freefare_free_tags(tags);
nfc_close(device);
}
nfc_exit (context);
exit (error);
nfc_exit(context);
exit(error);
} /* main() */

View file

@ -50,11 +50,11 @@ struct {
static void
usage(char *progname)
{
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, "\nOptions:\n");
fprintf (stderr, " -y Do not ask for confirmation\n");
fprintf (stderr, " -K Provide another PICC key than the default one\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, "\nOptions:\n");
fprintf(stderr, " -y Do not ask for confirmation\n");
fprintf(stderr, " -K Provide another PICC key than the default one\n");
}
int
@ -65,31 +65,31 @@ main(int argc, char *argv[])
nfc_device *device = NULL;
FreefareTag *tags = NULL;
while ((ch = getopt (argc, argv, "hyK:")) != -1) {
switch (ch) {
case 'h':
usage(argv[0]);
exit (EXIT_SUCCESS);
break;
case 'y':
create_options.interactive = false;
break;
case 'K':
if (strlen(optarg) != 16) {
usage(argv[0]);
exit (EXIT_FAILURE);
}
uint64_t n = strtoull(optarg, NULL, 16);
int i;
for (i=7; i>=0; i--) {
key_data_picc[i] = (uint8_t) n;
n >>= 8;
}
break;
default:
usage(argv[0]);
exit (EXIT_FAILURE);
}
while ((ch = getopt(argc, argv, "hyK:")) != -1) {
switch (ch) {
case 'h':
usage(argv[0]);
exit(EXIT_SUCCESS);
break;
case 'y':
create_options.interactive = false;
break;
case 'K':
if (strlen(optarg) != 16) {
usage(argv[0]);
exit(EXIT_FAILURE);
}
uint64_t n = strtoull(optarg, NULL, 16);
int i;
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)]
@ -97,54 +97,54 @@ main(int argc, char *argv[])
size_t device_count;
nfc_context *context;
nfc_init (&context);
nfc_init(&context);
if (context == NULL)
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)
errx (EXIT_FAILURE, "No NFC device found.");
errx(EXIT_FAILURE, "No NFC device found.");
for (size_t d = 0; d < device_count; d++) {
device = nfc_open (context, devices[d]);
device = nfc_open(context, devices[d]);
if (!device) {
warnx ("nfc_open() failed.");
error = EXIT_FAILURE;
continue;
}
if (!device) {
warnx("nfc_open() failed.");
error = EXIT_FAILURE;
continue;
}
tags = freefare_get_tags (device);
tags = freefare_get_tags(device);
if (!tags) {
nfc_close (device);
errx (EXIT_FAILURE, "Error listing tags.");
nfc_close(device);
errx(EXIT_FAILURE, "Error listing tags.");
}
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;
char *tag_uid = freefare_get_tag_uid (tags[i]);
char *tag_uid = freefare_get_tag_uid(tags[i]);
char buffer[BUFSIZ];
int res;
res = mifare_desfire_connect (tags[i]);
res = mifare_desfire_connect(tags[i]);
if (res < 0) {
warnx ("Can't connect to Mifare DESFire target.");
warnx("Can't connect to Mifare DESFire target.");
error = EXIT_FAILURE;
break;
}
// We've to track DESFire version as NDEF mapping is different
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) {
freefare_perror (tags[i], "mifare_desfire_get_version");
freefare_perror(tags[i], "mifare_desfire_get_version");
error = 1;
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;
int ndef_mapping;
switch (info.software.version_major) {
@ -159,11 +159,11 @@ main(int argc, char *argv[])
ndef_mapping = 2;
}
if (create_options.interactive) {
printf ("Create NDEF app v%d [yN] ", ndef_mapping);
fgets (buffer, BUFSIZ, stdin);
printf("Create NDEF app v%d [yN] ", ndef_mapping);
fgets(buffer, BUFSIZ, stdin);
create_ndef = ((buffer[0] == 'y') || (buffer[0] == 'Y'));
} else {
printf ("\n");
printf("\n");
}
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
res = mifare_desfire_select_application(tags[i], NULL);
if (res < 0)
errx (EXIT_FAILURE, "Application selection failed");
errx(EXIT_FAILURE, "Application selection failed");
MifareDESFireKey key_picc;
MifareDESFireKey key_app;
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_picc = mifare_desfire_des_key_new_with_version(key_data_picc);
key_app = mifare_desfire_des_key_new_with_version(key_data_app);
// 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)
errx (EXIT_FAILURE, "Authentication with PICC master key failed");
errx(EXIT_FAILURE, "Authentication with PICC master key failed");
MifareDESFireAID aid;
if (ndef_mapping == 1) {
uint8_t key_settings;
uint8_t max_keys;
mifare_desfire_get_key_settings(tags[i], &key_settings,&max_keys);
if ((key_settings & 0x08) == 0x08){
mifare_desfire_get_key_settings(tags[i], &key_settings, &max_keys);
if ((key_settings & 0x08) == 0x08) {
// Send Mifare DESFire ChangeKeySetting to change the PICC master key settings into :
// 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
// 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
res = mifare_desfire_change_key_settings (tags[i],0x09);
res = mifare_desfire_change_key_settings(tags[i], 0x09);
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
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)
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)
res = mifare_desfire_select_application(tags[i], aid);
if (res < 0)
errx (EXIT_FAILURE, "Application selection failed");
free (aid);
errx(EXIT_FAILURE, "Application selection failed");
free(aid);
// 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)
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
res = mifare_desfire_change_key_settings (tags[i],0x09);
res = mifare_desfire_change_key_settings(tags[i], 0x09);
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,
// 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)
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,
// 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)
@ -239,39 +239,38 @@ main(int argc, char *argv[])
0x00, // free read access
0x00 // free write acces
};
res = mifare_desfire_write_data(tags[i],0x03,0,sizeof(capability_container_file_content),capability_container_file_content);
if (res>0){
res = mifare_desfire_write_data(tags[i], 0x03, 0, sizeof(capability_container_file_content), capability_container_file_content);
if (res > 0) {
// 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)
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)
errx (EXIT_FAILURE, "CreateStdDataFile failed");
errx(EXIT_FAILURE, "CreateStdDataFile failed");
} 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,
// 2 bytes File Identifiers supported, File-ID equal to E110h
aid = mifare_desfire_aid_new(0x000001);
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)
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)
res = mifare_desfire_select_application(tags[i], aid);
if (res < 0)
errx (EXIT_FAILURE, "Application selection failed");
free (aid);
errx(EXIT_FAILURE, "Application selection failed");
free(aid);
// 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)
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,
// 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)
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,
// 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)
@ -295,26 +294,26 @@ main(int argc, char *argv[])
ndefmaxsize = 0x1E00;
capability_container_file_content[11] = ndefmaxsize >> 8;
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);
if (res>0){
res = mifare_desfire_write_data(tags[i], 0x01, 0, sizeof(capability_container_file_content), capability_container_file_content);
if (res > 0) {
// 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)
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)
errx (EXIT_FAILURE, "CreateStdDataFileIso failed");
errx(EXIT_FAILURE, "CreateStdDataFileIso failed");
} 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_app);
mifare_desfire_key_free(key_picc);
mifare_desfire_key_free(key_app);
}
mifare_desfire_disconnect (tags[i]);
free (tag_uid);
mifare_desfire_disconnect(tags[i]);
free(tag_uid);
}
freefare_free_tags (tags);
nfc_close (device);
freefare_free_tags(tags);
nfc_close(device);
}
nfc_exit (context);
exit (error);
nfc_exit(context);
exit(error);
}

View file

@ -1,11 +1,11 @@
/*-
* Copyright (C) 2010, Romain Tartiere.
*
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
@ -44,10 +44,10 @@ struct {
static void
usage(char *progname)
{
fprintf (stderr, "usage: %s [-y] [-K 11223344AABBCCDD]\n", progname);
fprintf (stderr, "\nOptions:\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, "usage: %s [-y] [-K 11223344AABBCCDD]\n", progname);
fprintf(stderr, "\nOptions:\n");
fprintf(stderr, " -y Do not ask for confirmation (dangerous)\n");
fprintf(stderr, " -K Provide another PICC key than the default one\n");
}
int
@ -58,11 +58,11 @@ main(int argc, char *argv[])
nfc_device *device = NULL;
FreefareTag *tags = NULL;
while ((ch = getopt (argc, argv, "hyK:")) != -1) {
while ((ch = getopt(argc, argv, "hyK:")) != -1) {
switch (ch) {
case 'h':
usage(argv[0]);
exit (EXIT_SUCCESS);
exit(EXIT_SUCCESS);
break;
case 'y':
configure_options.interactive = false;
@ -70,18 +70,18 @@ main(int argc, char *argv[])
case 'K':
if (strlen(optarg) != 16) {
usage(argv[0]);
exit (EXIT_FAILURE);
exit(EXIT_FAILURE);
}
uint64_t n = strtoull(optarg, NULL, 16);
int i;
for (i=7; i>=0; i--) {
for (i = 7; i >= 0; i--) {
key_data_picc[i] = (uint8_t) n;
n >>= 8;
}
break;
default:
usage(argv[0]);
exit (EXIT_FAILURE);
exit(EXIT_FAILURE);
}
}
// Remaining args, if any, are in argv[optind .. (argc-1)]
@ -90,94 +90,94 @@ main(int argc, char *argv[])
size_t device_count;
nfc_context *context;
nfc_init (&context);
nfc_init(&context);
if (context == NULL)
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)
errx (EXIT_FAILURE, "No NFC device found.");
errx(EXIT_FAILURE, "No NFC device found.");
for (size_t d = 0; (!error) && (d < device_count); d++) {
device = nfc_open (context, devices[d]);
if (!device) {
warnx ("nfc_open() failed.");
error = EXIT_FAILURE;
continue;
}
device = nfc_open(context, devices[d]);
if (!device) {
warnx("nfc_open() failed.");
error = EXIT_FAILURE;
continue;
}
tags = freefare_get_tags (device);
tags = freefare_get_tags(device);
if (!tags) {
nfc_close (device);
errx (EXIT_FAILURE, "Error listing Mifare DESFire tags.");
nfc_close(device);
errx(EXIT_FAILURE, "Error listing Mifare DESFire tags.");
}
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;
char *tag_uid = freefare_get_tag_uid (tags[i]);
char *tag_uid = freefare_get_tag_uid(tags[i]);
char buffer[BUFSIZ];
int res;
res = mifare_desfire_connect (tags[i]);
res = mifare_desfire_connect(tags[i]);
if (res < 0) {
warnx ("Can't connect to Mifare DESFire target.");
warnx("Can't connect to Mifare DESFire target.");
error = EXIT_FAILURE;
break;
}
// Make sure we've at least an EV1 version
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) {
freefare_perror (tags[i], "mifare_desfire_get_version");
freefare_perror(tags[i], "mifare_desfire_get_version");
error = 1;
break;
}
if (info.software.version_major < 1) {
warnx ("Found old DESFire, skipping");
warnx("Found old DESFire, skipping");
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;
if (configure_options.interactive) {
printf ("Change ATS? [yN] ");
fgets (buffer, BUFSIZ, stdin);
printf("Change ATS? [yN] ");
fgets(buffer, BUFSIZ, stdin);
do_it = ((buffer[0] == 'y') || (buffer[0] == 'Y'));
} else {
printf ("\n");
printf("\n");
}
if (do_it) {
MifareDESFireKey key_picc = mifare_desfire_des_key_new_with_version (key_data_picc);
res = mifare_desfire_authenticate (tags[i], 0, key_picc);
MifareDESFireKey key_picc = mifare_desfire_des_key_new_with_version(key_data_picc);
res = mifare_desfire_authenticate(tags[i], 0, key_picc);
if (res < 0) {
freefare_perror (tags[i], "mifare_desfire_authenticate");
freefare_perror(tags[i], "mifare_desfire_authenticate");
error = EXIT_FAILURE;
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) {
freefare_perror (tags[i], "mifare_desfire_set_ats");
freefare_perror(tags[i], "mifare_desfire_set_ats");
error = EXIT_FAILURE;
break;
}
}
mifare_desfire_disconnect (tags[i]);
free (tag_uid);
mifare_desfire_disconnect(tags[i]);
free(tag_uid);
}
freefare_free_tags (tags);
nfc_close (device);
freefare_free_tags(tags);
nfc_close(device);
}
nfc_exit (context);
exit (error);
nfc_exit(context);
exit(error);
} /* main() */

View file

@ -1,11 +1,11 @@
/*-
* Copyright (C) 2010, Romain Tartiere.
*
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
@ -43,9 +43,9 @@ struct {
static void
usage(char *progname)
{
fprintf (stderr, "usage: %s [-y]\n", progname);
fprintf (stderr, "\nOptions:\n");
fprintf (stderr, " -y Do not ask for confirmation\n");
fprintf(stderr, "usage: %s [-y]\n", progname);
fprintf(stderr, "\nOptions:\n");
fprintf(stderr, " -y Do not ask for confirmation\n");
}
int
@ -56,18 +56,18 @@ main(int argc, char *argv[])
nfc_device *device = NULL;
FreefareTag *tags = NULL;
while ((ch = getopt (argc, argv, "hy")) != -1) {
while ((ch = getopt(argc, argv, "hy")) != -1) {
switch (ch) {
case 'h':
usage(argv[0]);
exit (EXIT_SUCCESS);
exit(EXIT_SUCCESS);
break;
case 'y':
configure_options.interactive = false;
break;
default:
usage(argv[0]);
exit (EXIT_FAILURE);
exit(EXIT_FAILURE);
}
}
// Remaining args, if any, are in argv[optind .. (argc-1)]
@ -76,85 +76,85 @@ main(int argc, char *argv[])
size_t device_count;
nfc_context *context;
nfc_init (&context);
nfc_init(&context);
if (context == NULL)
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)
errx (EXIT_FAILURE, "No NFC device found.");
errx(EXIT_FAILURE, "No NFC device found.");
for (size_t d = 0; (!error) && (d < device_count); d++) {
device = nfc_open (context, devices[d]);
if (!device) {
warnx ("nfc_open() failed.");
error = EXIT_FAILURE;
continue;
}
device = nfc_open(context, devices[d]);
if (!device) {
warnx("nfc_open() failed.");
error = EXIT_FAILURE;
continue;
}
tags = freefare_get_tags (device);
tags = freefare_get_tags(device);
if (!tags) {
nfc_close (device);
errx (EXIT_FAILURE, "Error listing Mifare DESFire tags.");
nfc_close(device);
errx(EXIT_FAILURE, "Error listing Mifare DESFire tags.");
}
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;
char *tag_uid = freefare_get_tag_uid (tags[i]);
char *tag_uid = freefare_get_tag_uid(tags[i]);
char buffer[BUFSIZ];
int res;
res = mifare_desfire_connect (tags[i]);
res = mifare_desfire_connect(tags[i]);
if (res < 0) {
warnx ("Can't connect to Mifare DESFire target.");
warnx("Can't connect to Mifare DESFire target.");
error = EXIT_FAILURE;
break;
}
// Make sure we've at least an EV1 version
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) {
freefare_perror (tags[i], "mifare_desfire_get_version");
freefare_perror(tags[i], "mifare_desfire_get_version");
error = 1;
break;
}
if (info.software.version_major < 1) {
warnx ("Found old DESFire, skipping");
warnx("Found old DESFire, skipping");
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;
if (configure_options.interactive) {
printf ("Change default key? [yN] ");
fgets (buffer, BUFSIZ, stdin);
printf("Change default key? [yN] ");
fgets(buffer, BUFSIZ, stdin);
do_it = ((buffer[0] == 'y') || (buffer[0] == 'Y'));
} else {
printf ("\n");
printf("\n");
}
if (do_it) {
MifareDESFireKey default_key = mifare_desfire_des_key_new_with_version (null_key_data);
res = mifare_desfire_authenticate (tags[i], 0, default_key);
MifareDESFireKey default_key = mifare_desfire_des_key_new_with_version(null_key_data);
res = mifare_desfire_authenticate(tags[i], 0, default_key);
if (res < 0) {
freefare_perror (tags[i], "mifare_desfire_authenticate");
freefare_perror(tags[i], "mifare_desfire_authenticate");
error = EXIT_FAILURE;
break;
}
mifare_desfire_key_free (default_key);
mifare_desfire_key_free(default_key);
MifareDESFireKey new_key = mifare_desfire_des_key_new (new_key_data);
mifare_desfire_key_set_version (new_key, NEW_KEY_VERSION);
res = mifare_desfire_set_default_key (tags[i], new_key);
free (new_key);
MifareDESFireKey new_key = mifare_desfire_des_key_new(new_key_data);
mifare_desfire_key_set_version(new_key, NEW_KEY_VERSION);
res = mifare_desfire_set_default_key(tags[i], new_key);
free(new_key);
if (res < 0) {
freefare_perror (tags[i], "mifare_desfire_set_default_key");
freefare_perror(tags[i], "mifare_desfire_set_default_key");
error = EXIT_FAILURE;
break;
}
@ -164,92 +164,92 @@ main(int argc, char *argv[])
* (it's hard to create a unit-test to do so).
*/
MifareDESFireAID aid = mifare_desfire_aid_new (0x112233);
res = mifare_desfire_create_application (tags[i], aid, 0xFF, 1);
MifareDESFireAID aid = mifare_desfire_aid_new(0x112233);
res = mifare_desfire_create_application(tags[i], aid, 0xFF, 1);
if (res < 0) {
freefare_perror (tags[i], "mifare_desfire_create_application");
freefare_perror(tags[i], "mifare_desfire_create_application");
error = EXIT_FAILURE;
break;
}
res = mifare_desfire_select_application (tags[i], aid);
res = mifare_desfire_select_application(tags[i], aid);
if (res < 0) {
freefare_perror (tags[i], "mifare_desfire_select_application");
freefare_perror(tags[i], "mifare_desfire_select_application");
error = EXIT_FAILURE;
break;
}
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) {
freefare_perror (tags[i], "mifare_desfire_get_key_version");
freefare_perror(tags[i], "mifare_desfire_get_key_version");
error = EXIT_FAILURE;
break;
}
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;
/* continue */
}
new_key = mifare_desfire_des_key_new (new_key_data);
res = mifare_desfire_authenticate (tags[i], 0, new_key);
free (new_key);
new_key = mifare_desfire_des_key_new(new_key_data);
res = mifare_desfire_authenticate(tags[i], 0, new_key);
free(new_key);
if (res < 0) {
freefare_perror (tags[i], "mifare_desfire_authenticate");
freefare_perror(tags[i], "mifare_desfire_authenticate");
error = EXIT_FAILURE;
break;
}
free (aid);
free(aid);
/* Resetdefault settings */
res = mifare_desfire_select_application (tags[i], NULL);
res = mifare_desfire_select_application(tags[i], NULL);
if (res < 0) {
freefare_perror (tags[i], "mifare_desfire_select_application");
freefare_perror(tags[i], "mifare_desfire_select_application");
error = EXIT_FAILURE;
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) {
freefare_perror (tags[i], "mifare_desfire_authenticate");
freefare_perror(tags[i], "mifare_desfire_authenticate");
error = EXIT_FAILURE;
break;
}
res = mifare_desfire_set_default_key (tags[i], default_key);
res = mifare_desfire_set_default_key(tags[i], default_key);
if (res < 0) {
freefare_perror (tags[i], "mifare_desfire_set_default_key");
freefare_perror(tags[i], "mifare_desfire_set_default_key");
error = EXIT_FAILURE;
break;
}
mifare_desfire_key_free (default_key);
mifare_desfire_key_free(default_key);
/* Wipeout the card */
res = mifare_desfire_format_picc (tags[i]);
res = mifare_desfire_format_picc(tags[i]);
if (res < 0) {
freefare_perror (tags[i], "mifare_desfire_format_picc");
freefare_perror(tags[i], "mifare_desfire_format_picc");
error = EXIT_FAILURE;
break;
}
}
mifare_desfire_disconnect (tags[i]);
free (tag_uid);
mifare_desfire_disconnect(tags[i]);
free(tag_uid);
}
freefare_free_tags (tags);
nfc_close (device);
freefare_free_tags(tags);
nfc_close(device);
}
nfc_exit (context);
exit (error);
nfc_exit(context);
exit(error);
}

View file

@ -1,11 +1,11 @@
/*-
* Copyright (C) 2010, Romain Tartiere.
*
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
@ -40,10 +40,10 @@ struct {
static void
usage(char *progname)
{
fprintf (stderr, "usage: %s [-y] [-K 11223344AABBCCDD]\n", progname);
fprintf (stderr, "\nOptions:\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, "usage: %s [-y] [-K 11223344AABBCCDD]\n", progname);
fprintf(stderr, "\nOptions:\n");
fprintf(stderr, " -y Do not ask for confirmation (dangerous)\n");
fprintf(stderr, " -K Provide another PICC key than the default one\n");
}
int
@ -54,11 +54,11 @@ main(int argc, char *argv[])
nfc_device *device = NULL;
FreefareTag *tags = NULL;
while ((ch = getopt (argc, argv, "hyK:")) != -1) {
while ((ch = getopt(argc, argv, "hyK:")) != -1) {
switch (ch) {
case 'h':
usage(argv[0]);
exit (EXIT_SUCCESS);
exit(EXIT_SUCCESS);
break;
case 'y':
configure_options.interactive = false;
@ -66,18 +66,18 @@ main(int argc, char *argv[])
case 'K':
if (strlen(optarg) != 16) {
usage(argv[0]);
exit (EXIT_FAILURE);
exit(EXIT_FAILURE);
}
uint64_t n = strtoull(optarg, NULL, 16);
int i;
for (i=7; i>=0; i--) {
for (i = 7; i >= 0; i--) {
key_data_picc[i] = (uint8_t) n;
n >>= 8;
}
break;
default:
usage(argv[0]);
exit (EXIT_FAILURE);
exit(EXIT_FAILURE);
}
}
// Remaining args, if any, are in argv[optind .. (argc-1)]
@ -86,127 +86,127 @@ main(int argc, char *argv[])
size_t device_count;
nfc_context *context;
nfc_init (&context);
nfc_init(&context);
if (context == NULL)
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)
errx (EXIT_FAILURE, "No NFC device found.");
errx(EXIT_FAILURE, "No NFC device found.");
for (size_t d = 0; (!error) && (d < device_count); d++) {
device = nfc_open (context, devices[d]);
if (!device) {
warnx ("nfc_open() failed.");
error = EXIT_FAILURE;
continue;
}
device = nfc_open(context, devices[d]);
if (!device) {
warnx("nfc_open() failed.");
error = EXIT_FAILURE;
continue;
}
tags = freefare_get_tags (device);
tags = freefare_get_tags(device);
if (!tags) {
nfc_close (device);
errx (EXIT_FAILURE, "Error listing Mifare DESFire tags.");
nfc_close(device);
errx(EXIT_FAILURE, "Error listing Mifare DESFire tags.");
}
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;
char *tag_uid = freefare_get_tag_uid (tags[i]);
char *tag_uid = freefare_get_tag_uid(tags[i]);
char buffer[BUFSIZ];
int res;
res = mifare_desfire_connect (tags[i]);
res = mifare_desfire_connect(tags[i]);
if (res < 0) {
warnx ("Can't connect to Mifare DESFire target.");
warnx("Can't connect to Mifare DESFire target.");
error = EXIT_FAILURE;
break;
}
// Make sure we've at least an EV1 version
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) {
freefare_perror (tags[i], "mifare_desfire_get_version");
freefare_perror(tags[i], "mifare_desfire_get_version");
error = 1;
break;
}
if (info.software.version_major < 1) {
warnx ("Found old DESFire, skipping");
warnx("Found old DESFire, skipping");
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;
size_t tag_uid_len = strlen (tag_uid) / 2;
size_t tag_uid_len = strlen(tag_uid) / 2;
switch (tag_uid_len) {
case 7: // Regular UID
if (configure_options.interactive) {
printf ("Configure random UID (this cannot be undone) [yN] ");
fgets (buffer, BUFSIZ, stdin);
printf("Configure random UID (this cannot be undone) [yN] ");
fgets(buffer, BUFSIZ, stdin);
do_it = ((buffer[0] == 'y') || (buffer[0] == 'Y'));
} else {
printf ("\n");
printf("\n");
}
if (do_it) {
MifareDESFireKey key_picc = mifare_desfire_des_key_new_with_version (key_data_picc);
res = mifare_desfire_authenticate (tags[i], 0, key_picc);
MifareDESFireKey key_picc = mifare_desfire_des_key_new_with_version(key_data_picc);
res = mifare_desfire_authenticate(tags[i], 0, key_picc);
if (res < 0) {
freefare_perror (tags[i], "mifare_desfire_authenticate");
freefare_perror(tags[i], "mifare_desfire_authenticate");
error = EXIT_FAILURE;
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) {
freefare_perror (tags[i], "mifare_desfire_set_configuration");
freefare_perror(tags[i], "mifare_desfire_set_configuration");
error = EXIT_FAILURE;
break;
}
}
break;
case 4: // Random UID
{} // 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);
res = mifare_desfire_authenticate (tags[i], 0, key_picc);
if (res < 0) {
freefare_perror (tags[i], "mifare_desfire_authenticate");
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);
{} // 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);
res = mifare_desfire_authenticate(tags[i], 0, key_picc);
if (res < 0) {
freefare_perror(tags[i], "mifare_desfire_authenticate");
error = EXIT_FAILURE;
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;
break;
}
mifare_desfire_disconnect (tags[i]);
free (tag_uid);
printf("Old card UID: %s\n", old_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);
nfc_close (device);
freefare_free_tags(tags);
nfc_close(device);
}
nfc_exit (context);
exit (error);
nfc_exit(context);
exit(error);
} /* main() */

View file

@ -1,11 +1,11 @@
/*-
* Copyright (C) 2010, Romain Tartiere.
*
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
@ -40,10 +40,10 @@ struct {
static void
usage(char *progname)
{
fprintf (stderr, "usage: %s [-y] [-K 11223344AABBCCDD]\n", progname);
fprintf (stderr, "\nOptions:\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, "usage: %s [-y] [-K 11223344AABBCCDD]\n", progname);
fprintf(stderr, "\nOptions:\n");
fprintf(stderr, " -y Do not ask for confirmation (dangerous)\n");
fprintf(stderr, " -K Provide another PICC key than the default one\n");
}
int
@ -54,30 +54,30 @@ main(int argc, char *argv[])
nfc_device *device = NULL;
FreefareTag *tags = NULL;
while ((ch = getopt (argc, argv, "hyK:")) != -1) {
while ((ch = getopt(argc, argv, "hyK:")) != -1) {
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]);
exit (EXIT_SUCCESS);
break;
case 'y':
format_options.interactive = false;
break;
case 'K':
if (strlen(optarg) != 16) {
usage(argv[0]);
exit (EXIT_FAILURE);
}
uint64_t n = strtoull(optarg, NULL, 16);
int i;
for (i=7; i>=0; i--) {
key_data_picc[i] = (uint8_t) n;
n >>= 8;
}
break;
default:
usage(argv[0]);
exit (EXIT_FAILURE);
exit(EXIT_FAILURE);
}
uint64_t n = strtoull(optarg, NULL, 16);
int i;
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)]
@ -86,63 +86,63 @@ main(int argc, char *argv[])
size_t device_count;
nfc_context *context;
nfc_init (&context);
nfc_init(&context);
if (context == NULL)
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)
errx (EXIT_FAILURE, "No NFC device found.");
errx(EXIT_FAILURE, "No NFC device found.");
for (size_t d = 0; (!error) && (d < device_count); d++) {
device = nfc_open (context, devices[d]);
if (!device) {
warnx ("nfc_open() failed.");
error = EXIT_FAILURE;
continue;
}
device = nfc_open(context, devices[d]);
if (!device) {
warnx("nfc_open() failed.");
error = EXIT_FAILURE;
continue;
}
tags = freefare_get_tags (device);
tags = freefare_get_tags(device);
if (!tags) {
nfc_close (device);
errx (EXIT_FAILURE, "Error listing Mifare DESFire tags.");
nfc_close(device);
errx(EXIT_FAILURE, "Error listing Mifare DESFire tags.");
}
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;
char *tag_uid = freefare_get_tag_uid (tags[i]);
char *tag_uid = freefare_get_tag_uid(tags[i]);
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;
if (format_options.interactive) {
printf ("Format [yN] ");
fgets (buffer, BUFSIZ, stdin);
printf("Format [yN] ");
fgets(buffer, BUFSIZ, stdin);
format = ((buffer[0] == 'y') || (buffer[0] == 'Y'));
} else {
printf ("\n");
printf("\n");
}
if (format) {
int res;
res = mifare_desfire_connect (tags[i]);
res = mifare_desfire_connect(tags[i]);
if (res < 0) {
warnx ("Can't connect to Mifare DESFire target.");
warnx("Can't connect to Mifare DESFire target.");
error = EXIT_FAILURE;
break;
}
MifareDESFireKey key_picc = mifare_desfire_des_key_new_with_version (key_data_picc);
res = mifare_desfire_authenticate (tags[i], 0, key_picc);
MifareDESFireKey key_picc = mifare_desfire_des_key_new_with_version(key_data_picc);
res = mifare_desfire_authenticate(tags[i], 0, key_picc);
if (res < 0) {
warnx ("Can't authenticate on Mifare DESFire target.");
warnx("Can't authenticate on Mifare DESFire target.");
error = EXIT_FAILURE;
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 :
// 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
// 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
res = mifare_desfire_change_key_settings (tags[i],0x0F);
res = mifare_desfire_change_key_settings(tags[i], 0x0F);
if (res < 0)
errx (EXIT_FAILURE, "ChangeKeySettings failed");
res = mifare_desfire_format_picc (tags[i]);
errx(EXIT_FAILURE, "ChangeKeySettings failed");
res = mifare_desfire_format_picc(tags[i]);
if (res < 0) {
warn ("Can't format PICC.");
warn("Can't format PICC.");
error = EXIT_FAILURE;
break;
}
mifare_desfire_disconnect (tags[i]);
mifare_desfire_disconnect(tags[i]);
}
free (tag_uid);
free(tag_uid);
}
freefare_free_tags (tags);
nfc_close (device);
freefare_free_tags(tags);
nfc_close(device);
}
nfc_exit (context);
exit (error);
nfc_exit(context);
exit(error);
} /* main() */

View file

@ -1,11 +1,11 @@
/*-
* Copyright (C) 2010, Romain Tartiere.
*
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
@ -32,117 +32,117 @@ main(int argc, char *argv[])
FreefareTag *tags = NULL;
if (argc > 1)
errx (EXIT_FAILURE, "usage: %s", argv[0]);
errx(EXIT_FAILURE, "usage: %s", argv[0]);
nfc_connstring devices[8];
size_t device_count;
nfc_context *context;
nfc_init (&context);
nfc_init(&context);
if (context == NULL)
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)
errx (EXIT_FAILURE, "No NFC device found.");
errx(EXIT_FAILURE, "No NFC device found.");
for (size_t d = 0; d < device_count; d++) {
device = nfc_open (context, devices[d]);
if (!device) {
warnx ("nfc_open() failed.");
error = EXIT_FAILURE;
continue;
}
device = nfc_open(context, devices[d]);
if (!device) {
warnx("nfc_open() failed.");
error = EXIT_FAILURE;
continue;
}
tags = freefare_get_tags (device);
tags = freefare_get_tags(device);
if (!tags) {
nfc_close (device);
errx (EXIT_FAILURE, "Error listing tags.");
nfc_close(device);
errx(EXIT_FAILURE, "Error listing tags.");
}
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;
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;
res = mifare_desfire_connect (tags[i]);
res = mifare_desfire_connect(tags[i]);
if (res < 0) {
warnx ("Can't connect to Mifare DESFire target.");
warnx("Can't connect to Mifare DESFire target.");
error = 1;
break;
}
res = mifare_desfire_get_version (tags[i], &info);
res = mifare_desfire_get_version(tags[i], &info);
if (res < 0) {
freefare_perror (tags[i], "mifare_desfire_get_version");
freefare_perror(tags[i], "mifare_desfire_get_version");
error = 1;
break;
}
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 ("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 ("Hardware Information:\n");
printf (" Vendor ID: 0x%02x\n", info.hardware.vendor_id);
printf (" Type: 0x%02x\n", info.hardware.type);
printf (" Subtype: 0x%02x\n", info.hardware.subtype);
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 (" Protocol: 0x%02x\n", info.hardware.protocol);
printf ("Software Information:\n");
printf (" Vendor ID: 0x%02x\n", info.software.vendor_id);
printf (" Type: 0x%02x\n", info.software.type);
printf (" Subtype: 0x%02x\n", info.software.subtype);
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 (" Protocol: 0x%02x\n", info.software.protocol);
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("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("Hardware Information:\n");
printf(" Vendor ID: 0x%02x\n", info.hardware.vendor_id);
printf(" Type: 0x%02x\n", info.hardware.type);
printf(" Subtype: 0x%02x\n", info.hardware.subtype);
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(" Protocol: 0x%02x\n", info.hardware.protocol);
printf("Software Information:\n");
printf(" Vendor ID: 0x%02x\n", info.software.vendor_id);
printf(" Type: 0x%02x\n", info.software.type);
printf(" Subtype: 0x%02x\n", info.software.subtype);
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(" Protocol: 0x%02x\n", info.software.protocol);
uint8_t settings;
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) {
printf ("Master Key settings (0x%02x):\n", settings);
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 Free directory list access without PICC Master Key;\n", settings & 0x02);
printf (" 0x%02x Allow changing the Master Key;\n", settings & 0x01);
} else if (AUTHENTICATION_ERROR == mifare_desfire_last_picc_error (tags[i])) {
printf ("Master Key settings: LOCKED\n");
printf("Master Key settings (0x%02x):\n", settings);
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 Free directory list access without PICC Master Key;\n", settings & 0x02);
printf(" 0x%02x Allow changing the Master Key;\n", settings & 0x01);
} else if (AUTHENTICATION_ERROR == mifare_desfire_last_picc_error(tags[i])) {
printf("Master Key settings: LOCKED\n");
} else {
freefare_perror (tags[i], "mifare_desfire_get_key_settings");
freefare_perror(tags[i], "mifare_desfire_get_key_settings");
error = 1;
break;
}
uint8_t version;
mifare_desfire_get_key_version (tags[i], 0, &version);
printf ("Master Key version: %d (0x%02x)\n", version, version);
mifare_desfire_get_key_version(tags[i], 0, &version);
printf("Master Key version: %d (0x%02x)\n", version, version);
uint32_t size;
res = mifare_desfire_free_mem (tags[i], &size);
printf ("Free memory: ");
res = mifare_desfire_free_mem(tags[i], &size);
printf("Free memory: ");
if (0 == res) {
printf ("%d bytes\n", size);
printf("%d bytes\n", size);
} 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);
nfc_close (device);
freefare_free_tags(tags);
nfc_close(device);
}
nfc_exit (context);
exit (error);
nfc_exit(context);
exit(error);
} /* main() */

View file

@ -54,12 +54,12 @@ struct {
static void
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, "usage: %s [-y] -o FILE [-k 11223344AABBCCDD]\n", progname);
fprintf (stderr, "\nOptions:\n");
fprintf (stderr, " -y Do not ask for confirmation\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, "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, "\nOptions:\n");
fprintf(stderr, " -y Do not ask for confirmation\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");
}
int
@ -71,53 +71,53 @@ main(int argc, char *argv[])
FreefareTag *tags = NULL;
char *ndef_output = NULL;
while ((ch = getopt (argc, argv, "hyo:k:")) != -1) {
switch (ch) {
case 'h':
usage(argv[0]);
exit (EXIT_SUCCESS);
break;
case 'y':
read_options.interactive = false;
break;
case 'o':
ndef_output = optarg;
break;
case 'k':
if (strlen(optarg) != 16) {
usage(argv[0]);
exit (EXIT_FAILURE);
}
uint64_t n = strtoull(optarg, NULL, 16);
int i;
for (i=7; i>=0; i--) {
key_data_app[i] = (uint8_t) n;
n >>= 8;
}
break;
default:
usage(argv[0]);
exit (EXIT_FAILURE);
}
while ((ch = getopt(argc, argv, "hyo:k:")) != -1) {
switch (ch) {
case 'h':
usage(argv[0]);
exit(EXIT_SUCCESS);
break;
case 'y':
read_options.interactive = false;
break;
case 'o':
ndef_output = optarg;
break;
case 'k':
if (strlen(optarg) != 16) {
usage(argv[0]);
exit(EXIT_FAILURE);
}
uint64_t n = strtoull(optarg, NULL, 16);
int i;
for (i = 7; i >= 0; i--) {
key_data_app[i] = (uint8_t) n;
n >>= 8;
}
break;
default:
usage(argv[0]);
exit(EXIT_FAILURE);
}
}
// Remaining args, if any, are in argv[optind .. (argc-1)]
if (ndef_output == NULL) {
usage (argv[0]);
exit (EXIT_FAILURE);
usage(argv[0]);
exit(EXIT_FAILURE);
}
FILE* message_stream = NULL;
FILE* ndef_stream = NULL;
FILE *message_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;
ndef_stream = stdout;
} else {
message_stream = stdout;
ndef_stream = fopen(ndef_output, "wb");
if (!ndef_stream) {
fprintf (stderr, "Could not open file %s.\n", ndef_output);
exit (EXIT_FAILURE);
fprintf(stderr, "Could not open file %s.\n", ndef_output);
exit(EXIT_FAILURE);
}
}
@ -125,72 +125,72 @@ main(int argc, char *argv[])
size_t device_count;
nfc_context *context;
nfc_init (&context);
nfc_init(&context);
if (context == NULL)
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)
errx (EXIT_FAILURE, "No NFC device found.");
errx(EXIT_FAILURE, "No NFC device found.");
for (size_t d = 0; d < device_count; d++) {
device = nfc_open (context, devices[d]);
device = nfc_open(context, devices[d]);
if (!device) {
warnx ("nfc_open() failed.");
error = EXIT_FAILURE;
continue;
}
if (!device) {
warnx("nfc_open() failed.");
error = EXIT_FAILURE;
continue;
}
tags = freefare_get_tags (device);
tags = freefare_get_tags(device);
if (!tags) {
nfc_close (device);
errx (EXIT_FAILURE, "Error listing tags.");
nfc_close(device);
errx(EXIT_FAILURE, "Error listing tags.");
}
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;
char *tag_uid = freefare_get_tag_uid (tags[i]);
char *tag_uid = freefare_get_tag_uid(tags[i]);
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;
if (read_options.interactive) {
fprintf (message_stream, "Read NDEF [yN] ");
fgets (buffer, BUFSIZ, stdin);
fprintf(message_stream, "Read NDEF [yN] ");
fgets(buffer, BUFSIZ, stdin);
read_ndef = ((buffer[0] == 'y') || (buffer[0] == 'Y'));
} else {
fprintf (message_stream, "\n");
fprintf(message_stream, "\n");
}
if (read_ndef) {
int res;
res = mifare_desfire_connect (tags[i]);
res = mifare_desfire_connect(tags[i]);
if (res < 0) {
warnx ("Can't connect to Mifare DESFire target.");
warnx("Can't connect to Mifare DESFire target.");
error = EXIT_FAILURE;
break;
}
// We've to track DESFire version as NDEF mapping is different
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) {
freefare_perror (tags[i], "mifare_desfire_get_version");
freefare_perror(tags[i], "mifare_desfire_get_version");
error = 1;
break;
}
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)
MifareDESFireAID aid;
if (info.software.version_major==0)
if (info.software.version_major == 0)
aid = mifare_desfire_aid_new(0xEEEE10);
else
// 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);
res = mifare_desfire_select_application(tags[i], aid);
if (res < 0)
errx (EXIT_FAILURE, "Application selection failed. Try mifare-desfire-create-ndef before running %s.", argv[0]);
free (aid);
errx(EXIT_FAILURE, "Application selection failed. Try mifare-desfire-create-ndef before running %s.", argv[0]);
free(aid);
// 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)
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
uint8_t lendata[20]; // cf FIXME in mifare_desfire.c read_data()
if (info.software.version_major==0)
res = mifare_desfire_read_data (tags[i], 0x03, 0, 2, lendata);
if (info.software.version_major == 0)
res = mifare_desfire_read_data(tags[i], 0x03, 0, 2, lendata);
else
// There is no more relationship between DESFire FID and ISO FileID...
// 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)
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]);
if (cclen < 15)
errx (EXIT_FAILURE, "CC too short IMHO");
if (!(cc_data = malloc(cclen+20))) // cf FIXME in mifare_desfire.c read_data()
errx (EXIT_FAILURE, "malloc");
if (info.software.version_major==0)
res = mifare_desfire_read_data (tags[i], 0x03, 0, cclen, cc_data);
errx(EXIT_FAILURE, "CC too short IMHO");
if (!(cc_data = malloc(cclen + 20))) // cf FIXME in mifare_desfire.c read_data()
errx(EXIT_FAILURE, "malloc");
if (info.software.version_major == 0)
res = mifare_desfire_read_data(tags[i], 0x03, 0, cclen, cc_data);
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)
errx (EXIT_FAILURE, "Read CC data failed");
errx(EXIT_FAILURE, "Read CC data failed");
// Search NDEF File Control TLV
uint8_t off = 7;
while (((off+7) < cclen) && (cc_data[off] != 0x04)) {
while (((off + 7) < cclen) && (cc_data[off] != 0x04)) {
// Skip TLV
off += cc_data[off+1] + 2;
off += cc_data[off + 1] + 2;
}
if (off+7 >= cclen)
errx (EXIT_FAILURE, "CC does not contain expected NDEF File Control TLV");
if (cc_data[off+2] != 0xE1)
errx (EXIT_FAILURE, "Unknown NDEF File reference in CC");
if (off + 7 >= cclen)
errx(EXIT_FAILURE, "CC does not contain expected NDEF File Control TLV");
if (cc_data[off + 2] != 0xE1)
errx(EXIT_FAILURE, "Unknown NDEF File reference in CC");
uint8_t file_no;
if (info.software.version_major==0)
file_no = cc_data[off+3];
if (info.software.version_major == 0)
file_no = cc_data[off + 3];
else
// There is no more relationship between DESFire FID and ISO FileID...
// Let's assume it's in FID 02h as proposed in the spec
file_no = 2;
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);
if (!(ndef_msg = malloc(ndefmaxlen+20))) // cf FIXME in mifare_desfire.c read_data()
errx (EXIT_FAILURE, "malloc");
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);
if (!(ndef_msg = malloc(ndefmaxlen + 20))) // cf FIXME in mifare_desfire.c read_data()
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)
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]);
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)
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);
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);
if (res < 0)
errx (EXIT_FAILURE, "Read data failed");
if (fwrite (ndef_msg, 1, ndef_msg_len, ndef_stream) != ndef_msg_len)
errx (EXIT_FAILURE, "Write to file failed");
free (cc_data);
free (ndef_msg);
mifare_desfire_key_free (key_app);
errx(EXIT_FAILURE, "Read data failed");
if (fwrite(ndef_msg, 1, ndef_msg_len, ndef_stream) != ndef_msg_len)
errx(EXIT_FAILURE, "Write to file failed");
free(cc_data);
free(ndef_msg);
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);
nfc_close (device);
freefare_free_tags(tags);
nfc_close(device);
}
nfc_exit (context);
exit (error);
nfc_exit(context);
exit(error);
}

View file

@ -62,12 +62,12 @@ struct {
static void
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, "usage: %s [-y] -i FILE [-k 11223344AABBCCDD]\n", progname);
fprintf (stderr, "\nOptions:\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, " -k Provide another NDEF Tag Application key than the default one\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, "\nOptions:\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, " -k Provide another NDEF Tag Application key than the default one\n");
}
int
@ -79,146 +79,146 @@ main(int argc, char *argv[])
FreefareTag *tags = NULL;
char *ndef_input = NULL;
while ((ch = getopt (argc, argv, "hyi:k:")) != -1) {
switch (ch) {
case 'h':
usage(argv[0]);
exit (EXIT_SUCCESS);
break;
case 'y':
write_options.interactive = false;
break;
case 'i':
ndef_input = optarg;
break;
case 'k':
if (strlen(optarg) != 16) {
usage(argv[0]);
exit (EXIT_FAILURE);
}
uint64_t n = strtoull(optarg, NULL, 16);
int i;
for (i=7; i>=0; i--) {
key_data_app[i] = (uint8_t) n;
n >>= 8;
}
break;
default:
usage(argv[0]);
exit (EXIT_FAILURE);
}
while ((ch = getopt(argc, argv, "hyi:k:")) != -1) {
switch (ch) {
case 'h':
usage(argv[0]);
exit(EXIT_SUCCESS);
break;
case 'y':
write_options.interactive = false;
break;
case 'i':
ndef_input = optarg;
break;
case 'k':
if (strlen(optarg) != 16) {
usage(argv[0]);
exit(EXIT_FAILURE);
}
uint64_t n = strtoull(optarg, NULL, 16);
int i;
for (i = 7; i >= 0; i--) {
key_data_app[i] = (uint8_t) n;
n >>= 8;
}
break;
default:
usage(argv[0]);
exit(EXIT_FAILURE);
}
}
// Remaining args, if any, are in argv[optind .. (argc-1)]
if (ndef_input == NULL) {
ndef_msg_len = sizeof(ndef_default_msg) + 2;
if (!(ndef_msg = malloc (ndef_msg_len))) {
err (EXIT_FAILURE, "malloc");
}
ndef_msg[0] = (uint8_t) ((ndef_msg_len - 2) >> 8);
ndef_msg[1] = (uint8_t) (ndef_msg_len - 2);
memcpy(ndef_msg + 2, ndef_default_msg, ndef_msg_len - 2);
ndef_msg_len = sizeof(ndef_default_msg) + 2;
if (!(ndef_msg = malloc(ndef_msg_len))) {
err(EXIT_FAILURE, "malloc");
}
ndef_msg[0] = (uint8_t)((ndef_msg_len - 2) >> 8);
ndef_msg[1] = (uint8_t)(ndef_msg_len - 2);
memcpy(ndef_msg + 2, ndef_default_msg, ndef_msg_len - 2);
} else {
FILE* ndef_stream = NULL;
if ((strlen (ndef_input) == 1) && (ndef_input[0] == '-')) {
// FIXME stdin as input have to be readed and buffered in ndef_msg
FILE *ndef_stream = NULL;
if ((strlen(ndef_input) == 1) && (ndef_input[0] == '-')) {
// FIXME stdin as input have to be readed and buffered in ndef_msg
ndef_stream = stdin;
fprintf (stderr, "stdin as NDEF is not implemented");
exit (EXIT_FAILURE);
fprintf(stderr, "stdin as NDEF is not implemented");
exit(EXIT_FAILURE);
} else {
ndef_stream = fopen(ndef_input, "rb");
if (!ndef_stream) {
fprintf (stderr, "Could not open file %s.\n", ndef_input);
exit (EXIT_FAILURE);
fprintf(stderr, "Could not open file %s.\n", ndef_input);
exit(EXIT_FAILURE);
}
fseek(ndef_stream, 0L, SEEK_END);
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))) {
err (EXIT_FAILURE, "malloc");
if (!(ndef_msg = malloc(ndef_msg_len))) {
err(EXIT_FAILURE, "malloc");
}
ndef_msg[0] = (uint8_t) ((ndef_msg_len - 2) >> 8);
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) {
fprintf (stderr, "Could not read NDEF from file: %s\n", ndef_input);
fclose (ndef_stream);
exit (EXIT_FAILURE);
ndef_msg[0] = (uint8_t)((ndef_msg_len - 2) >> 8);
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) {
fprintf(stderr, "Could not read NDEF from file: %s\n", ndef_input);
fclose(ndef_stream);
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];
size_t device_count;
nfc_context *context;
nfc_init (&context);
nfc_init(&context);
if (context == NULL)
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)
errx (EXIT_FAILURE, "No NFC device found.");
errx(EXIT_FAILURE, "No NFC device found.");
for (size_t d = 0; d < device_count; d++) {
device = nfc_open (context, devices[d]);
device = nfc_open(context, devices[d]);
if (!device) {
warnx ("nfc_open() failed.");
error = EXIT_FAILURE;
continue;
}
if (!device) {
warnx("nfc_open() failed.");
error = EXIT_FAILURE;
continue;
}
tags = freefare_get_tags (device);
tags = freefare_get_tags(device);
if (!tags) {
nfc_close (device);
errx (EXIT_FAILURE, "Error listing tags.");
nfc_close(device);
errx(EXIT_FAILURE, "Error listing tags.");
}
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;
char *tag_uid = freefare_get_tag_uid (tags[i]);
char *tag_uid = freefare_get_tag_uid(tags[i]);
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;
if (write_options.interactive) {
printf ("Write NDEF [yN] ");
fgets (buffer, BUFSIZ, stdin);
printf("Write NDEF [yN] ");
fgets(buffer, BUFSIZ, stdin);
write_ndef = ((buffer[0] == 'y') || (buffer[0] == 'Y'));
} else {
printf ("\n");
printf("\n");
}
if (write_ndef) {
int res;
res = mifare_desfire_connect (tags[i]);
res = mifare_desfire_connect(tags[i]);
if (res < 0) {
warnx ("Can't connect to Mifare DESFire target.");
warnx("Can't connect to Mifare DESFire target.");
error = EXIT_FAILURE;
break;
}
// We've to track DESFire version as NDEF mapping is different
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) {
freefare_perror (tags[i], "mifare_desfire_get_version");
freefare_perror(tags[i], "mifare_desfire_get_version");
error = 1;
break;
}
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)
MifareDESFireAID aid;
if (info.software.version_major==0)
if (info.software.version_major == 0)
aid = mifare_desfire_aid_new(0xEEEE10);
else
// 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);
if (res < 0)
errx (EXIT_FAILURE, "Application selection failed. Try mifare-desfire-create-ndef before running %s.", argv[0]);
free (aid);
errx(EXIT_FAILURE, "Application selection failed. Try mifare-desfire-create-ndef before running %s.", argv[0]);
free(aid);
// 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)
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
uint8_t lendata[20]; // cf FIXME in mifare_desfire.c read_data()
if (info.software.version_major==0)
res = mifare_desfire_read_data (tags[i], 0x03, 0, 2, lendata);
if (info.software.version_major == 0)
res = mifare_desfire_read_data(tags[i], 0x03, 0, 2, lendata);
else
// There is no more relationship between DESFire FID and ISO FileID...
// 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)
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]);
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()
errx (EXIT_FAILURE, "malloc");
if (info.software.version_major==0)
res = mifare_desfire_read_data (tags[i], 0x03, 0, cclen, cc_data);
errx(EXIT_FAILURE, "malloc");
if (info.software.version_major == 0)
res = mifare_desfire_read_data(tags[i], 0x03, 0, cclen, cc_data);
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)
errx (EXIT_FAILURE, "Read CC data failed");
errx(EXIT_FAILURE, "Read CC data failed");
// Search NDEF File Control TLV
uint8_t off = 7;
while (((off+7) < cclen) && (cc_data[off] != 0x04)) {
while (((off + 7) < cclen) && (cc_data[off] != 0x04)) {
// Skip TLV
off += cc_data[off+1] + 2;
off += cc_data[off + 1] + 2;
}
if (off+7 >= cclen)
errx (EXIT_FAILURE, "CC does not contain expected NDEF File Control TLV");
if (cc_data[off+2] != 0xE1)
errx (EXIT_FAILURE, "Unknown NDEF File reference in CC");
if (off + 7 >= cclen)
errx(EXIT_FAILURE, "CC does not contain expected NDEF File Control TLV");
if (cc_data[off + 2] != 0xE1)
errx(EXIT_FAILURE, "Unknown NDEF File reference in CC");
uint8_t file_no;
if (info.software.version_major==0)
file_no = cc_data[off+3];
if (info.software.version_major == 0)
file_no = cc_data[off + 3];
else
// There is no more relationship between DESFire FID and ISO FileID...
// Let's assume it's in FID 02h as proposed in the spec
file_no = 2;
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);
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);
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
res = mifare_desfire_write_data(tags[i], file_no, 0, ndef_msg_len, (uint8_t *) ndef_msg);
if (res < 0)
errx (EXIT_FAILURE, " Write data failed");
errx(EXIT_FAILURE, " Write data failed");
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);
freefare_free_tags (tags);
nfc_close (device);
free(ndef_msg);
freefare_free_tags(tags);
nfc_close(device);
}
nfc_exit (context);
exit (error);
nfc_exit(context);
exit(error);
}

View file

@ -1,11 +1,11 @@
/*-
* Copyright (C) 2012, Romain Tartiere.
*
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
@ -22,41 +22,41 @@
#include <freefare.h>
int
main (int argc, char *argv[])
main(int argc, char *argv[])
{
int error = EXIT_SUCCESS;
nfc_device *device = NULL;
FreefareTag *tags = NULL;
if (argc > 1)
errx (EXIT_FAILURE, "usage: %s", argv[0]);
errx(EXIT_FAILURE, "usage: %s", argv[0]);
nfc_connstring devices[8];
size_t device_count;
nfc_context *context;
nfc_init (&context);
nfc_init(&context);
if (context == NULL)
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)
errx (EXIT_FAILURE, "No NFC device found");
errx(EXIT_FAILURE, "No NFC device found");
for (size_t d = 0; d < device_count; d++) {
if (!(device = nfc_open (context, devices[d]))) {
warnx ("nfc_open() failed.");
if (!(device = nfc_open(context, devices[d]))) {
warnx("nfc_open() failed.");
error = EXIT_FAILURE;
continue;
}
if (!(tags = freefare_get_tags (device))) {
nfc_close (device);
errx (EXIT_FAILURE, "Error listing tags.");
if (!(tags = freefare_get_tags(device))) {
nfc_close(device);
errx(EXIT_FAILURE, "Error listing tags.");
}
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_C:
break;
@ -64,28 +64,28 @@ main (int argc, char *argv[])
continue;
}
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]));
if (freefare_get_tag_type (tags[i]) == MIFARE_ULTRALIGHT_C) {
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]));
if (freefare_get_tag_type(tags[i]) == MIFARE_ULTRALIGHT_C) {
FreefareTag tag = tags[i];
int res;
MifareDESFireKey key;
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);
if (mifare_ultralight_connect (tag) < 0)
errx (EXIT_FAILURE, "Error connecting to tag.");
res = mifare_ultralightc_authenticate (tag, key);
printf ("Authentication with default key: %s\n", res ? "fail" : "success");
mifare_desfire_key_free (key);
mifare_ultralight_disconnect (tag);
}
free (tag_uid);
key = mifare_desfire_3des_key_new(key1_3des_data);
if (mifare_ultralight_connect(tag) < 0)
errx(EXIT_FAILURE, "Error connecting to tag.");
res = mifare_ultralightc_authenticate(tag, key);
printf("Authentication with default key: %s\n", res ? "fail" : "success");
mifare_desfire_key_free(key);
mifare_ultralight_disconnect(tag);
}
free(tag_uid);
}
freefare_free_tags (tags);
nfc_close (device);
freefare_free_tags(tags);
nfc_close(device);
}
nfc_exit (context);
nfc_exit(context);
exit(error);
}

View file

@ -39,7 +39,7 @@ main(int argc, char *argv[])
if (context == NULL)
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)
errx(EXIT_FAILURE, "No NFC device found");

View file

@ -40,7 +40,7 @@ main(int argc, char *argv[])
if (context == NULL)
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)
errx(EXIT_FAILURE, "No NFC device found");
@ -71,14 +71,14 @@ main(int argc, char *argv[])
if (ntag21x_connect(tag) < 0)
errx(EXIT_FAILURE, "Error connecting to tag.");
uint8_t pwd[4] = {0xff,0xff,0xff,0xff};
uint8_t pack[2] = {0xaa,0xaa};
uint8_t pack_old[2] = {0x00,0x00};
uint8_t pwd[4] = {0xff, 0xff, 0xff, 0xff};
uint8_t pack[2] = {0xaa, 0xaa};
uint8_t pack_old[2] = {0x00, 0x00};
NTAG21xKey key;
NTAG21xKey key_old;
key = ntag21x_key_new(pwd,pack); // Creating key
key_old = ntag21x_key_new(pwd,pack_old); // Creating key
key = ntag21x_key_new(pwd, pack); // Creating key
key_old = ntag21x_key_new(pwd, pack_old); // Creating key
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
*/
res = ntag21x_get_info(tag);
if(res < 0) {
if (res < 0) {
printf("Error getting info from tag\n");
break;
}
// Authenticate with tag
res = ntag21x_authenticate(tag,key);
if(res < 0) {
res = ntag21x_authenticate(tag, key);
if (res < 0) {
printf("Error getting info from tag\n");
break;
}
// Get auth byte from tag
res = ntag21x_get_auth(tag,&auth0);
if(res < 0) {
res = ntag21x_get_auth(tag, &auth0);
if (res < 0) {
printf("Error getting auth0 byte from tag\n");
break;
}
printf("Old auth0: %#02x\n",auth0);
printf("Old auth0: %#02x\n", auth0);
// Set old key
res = ntag21x_set_key(tag,key_old);
if(res < 0) {
res = ntag21x_set_key(tag, key_old);
if (res < 0) {
printf("Error setting key tag\n");
break;
}
// Disable password protection (when auth0 byte > last page)
res = ntag21x_set_auth(tag,0xff);
if(res<0) {
res = ntag21x_set_auth(tag, 0xff);
if (res < 0) {
printf("Error setting auth0 byte \n");
break;
}
// Disable read & write pwd protection -> (default: write only protection)
res = ntag21x_access_disable(tag,NTAG_PROT);
if(res < 0) {
res = ntag21x_access_disable(tag, NTAG_PROT);
if (res < 0) {
printf("Error setting access byte \n");
break;
}
// Get auth byte from tag
res = ntag21x_get_auth(tag,&auth0);
if(res < 0) {
res = ntag21x_get_auth(tag, &auth0);
if (res < 0) {
printf("Error getting auth0 byte from tag\n");
break;
}
printf("New auth0: %#02x\n",auth0);
printf("New auth0: %#02x\n", auth0);
}
ntag21x_disconnect(tag);

View file

@ -36,22 +36,22 @@ main(int argc, char *argv[])
size_t device_count;
nfc_context *context;
nfc_init (&context);
nfc_init(&context);
if (context == NULL)
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)
errx(EXIT_FAILURE, "No NFC device found");
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.");
error = EXIT_FAILURE;
continue;
}
if (!(tags = freefare_get_tags (device))) {
if (!(tags = freefare_get_tags(device))) {
nfc_close(device);
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]));
FreefareTag tag = tags[i];
int res;
if (ntag21x_connect (tag) < 0)
if (ntag21x_connect(tag) < 0)
errx(EXIT_FAILURE, "Error connecting to tag.");
uint8_t pwd[4] = {0xff,0xff,0xff,0xff};
uint8_t pack[2] = {0xaa,0xaa};
uint8_t pwd[4] = {0xff, 0xff, 0xff, 0xff};
uint8_t pack[2] = {0xaa, 0xaa};
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 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
*/
res = ntag21x_get_info(tag);
if(res < 0) {
if (res < 0) {
printf("Error getting info from tag\n");
break;
}
// Get auth byte from tag
res = ntag21x_get_auth(tag,&auth0);
if(res < 0) {
res = ntag21x_get_auth(tag, &auth0);
if (res < 0) {
printf("Error getting auth0 byte from tag\n");
break;
}
printf("Old auth0: %#02x\n",auth0);
res = ntag21x_get_authentication_limit(tag,&authlim);
if(res < 0) {
printf("Old auth0: %#02x\n", auth0);
res = ntag21x_get_authentication_limit(tag, &authlim);
if (res < 0) {
printf("Error getting auth0 byte from tag\n");
break;
}
printf("Authlim: %#02x\n",authlim);
printf("Authlim: %#02x\n", authlim);
// 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");
break;
}
// Set key
res = ntag21x_set_key(tag,key);
if(res < 0) {
res = ntag21x_set_key(tag, key);
if (res < 0) {
printf("Error setting key tag\n");
break;
}
// 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);
if(res < 0) {
res = ntag21x_set_auth(tag, ntag21x_get_last_page(tag) - 5);
if (res < 0) {
printf("Error setting auth0 byte \n");
break;
}
// Enable read & write pwd protection (default: write only protection)
res = ntag21x_access_enable(tag,NTAG_PROT);
if(res < 0) {
res = ntag21x_access_enable(tag, NTAG_PROT);
if (res < 0) {
printf("Error setting access byte \n");
break;
}
// Get auth byte from tag
res = ntag21x_get_auth(tag,&auth0);
if(res < 0) {
res = ntag21x_get_auth(tag, &auth0);
if (res < 0) {
printf("Error getting auth0 byte from tag\n");
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
free (tag_uid);
free(tag_uid);
}
freefare_free_tags(tags);
nfc_close(device);

View file

@ -40,7 +40,7 @@ main(int argc, char *argv[])
if (context == NULL)
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)
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]);
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];
int res;
if (ntag21x_connect(tag) < 0)
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
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
*/
res = ntag21x_get_info(tag);
if(res < 0) {
if (res < 0) {
printf("Error getting info from tag\n");
break;
}
// writing to tag 4 bytes on page 0x27 (check specs for NTAG21x before changing page number !!!)
res = ntag21x_write(tag,0x27,data);
if(res < 0) {
res = ntag21x_write(tag, 0x27, data);
if (res < 0) {
printf("Error writing to tag\n");
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)
if(res < 0) {
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) {
printf("Error reading tag\n");
break;
}
for(int i=0;i < 4;i++) // Checking if we can read what we have written earlyer
if(data[i] != read[i]) {
for (int i = 0; i < 4; i++) // Checking if we can read what we have written earlyer
if (data[i] != read[i]) {
flag_match = false;
break;
}
if(!flag_match)
if (!flag_match)
printf("Data don't match\n");
else
printf("Data match\n");

View file

@ -1,11 +1,11 @@
/*-
* Copyright (C) 2015, Romain Tartiere.
*
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
@ -44,27 +44,27 @@
#define MAX_BLOCK_COUNT 8
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], "===> ");
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_in, data_in[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, "<=== ");
return res;
}
bool
felica_taste (nfc_device *device, nfc_target target)
felica_taste(nfc_device *device, nfc_target target)
{
(void) device;
return target.nm.nmt == NMT_FELICA;
}
FreefareTag
felica_tag_new (nfc_device *device, nfc_target target)
felica_tag_new(nfc_device *device, nfc_target target)
{
FreefareTag tag;
if ((tag = malloc (sizeof (struct felica_tag)))) {
if ((tag = malloc(sizeof(struct felica_tag)))) {
tag->type = FELICA;
tag->free_tag = felica_tag_free;
tag->device = device;
@ -76,18 +76,18 @@ felica_tag_new (nfc_device *device, nfc_target target)
}
void
felica_tag_free (FreefareTag tag)
felica_tag_free(FreefareTag tag)
{
free (tag);
free(tag);
}
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 (length == 16 * block_count);
assert(block_count <= MAX_BLOCK_COUNT);
assert(length == 16 * block_count);
DEBUG_FUNCTION();
@ -104,43 +104,43 @@ felica_read_ex (FreefareTag tag, uint16_t service, uint8_t block_count, uint8_t
uint8_t res[100];
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[12] = service >> 8;
cmd[13] = block_count;
for (int i = 0; i < block_count; i++) {
cmd[14 + 2*i] = 0x80;
cmd[14 + 2*i + 1] = blocks[i];
cmd[14 + 2 * i] = 0x80;
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) {
return -1;
}
size_t len = MIN(res[12] * 16, length);
memcpy (data, res + 13, len);
memcpy(data, res + 13, len);
return len;
}
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[] = {
block
};
return felica_read_ex (tag, service, 1, blocks, data, length);
return felica_read_ex(tag, service, 1, blocks, data, length);
}
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();
assert (block_count <= MAX_BLOCK_COUNT);
assert (length == 16 * block_count);
assert(block_count <= MAX_BLOCK_COUNT);
assert(length == 16 * block_count);
uint8_t cmd[1 + 1 + 8 + 1 + 2 + 1 + 2 + 16 * MAX_BLOCK_COUNT] = {
0x00, /* Length */
@ -156,32 +156,32 @@ felica_write_ex (FreefareTag tag, uint16_t service, uint8_t block_count, uint8_t
uint8_t res[12];
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[12] = service >> 8;
cmd[13] = block_count;
for (int i = 0; i < block_count; i++) {
cmd[14 + 2*i] = 0x80;
cmd[14 + 2*i + 1] = blocks[i];
cmd[14 + 2 * i] = 0x80;
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 res[10] == 0 ? 0 : -1;
}
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[] = {
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.
*/
FreefareTag
freefare_tag_new (nfc_device *device, nfc_target target)
freefare_tag_new(nfc_device *device, nfc_target target)
{
FreefareTag tag = NULL;
if (felica_taste (device, target)) {
tag = felica_tag_new (device, target);
} else if (mifare_mini_taste (device, target)) {
tag = mifare_mini_tag_new (device, target);
} else if (mifare_classic1k_taste (device, target)) {
tag = mifare_classic1k_tag_new (device, target);
} else if (mifare_classic4k_taste (device, target)) {
tag = mifare_classic4k_tag_new (device, target);
} else if (mifare_desfire_taste (device, target)) {
tag = mifare_desfire_tag_new (device, target);
} else if (ntag21x_taste (device, target)) {
tag = ntag21x_tag_new (device, target);
} else if (mifare_ultralightc_taste (device, target)) {
tag = mifare_ultralightc_tag_new (device, target);
} else if (mifare_ultralight_taste (device, target)) {
tag = mifare_ultralight_tag_new (device, target);
if (felica_taste(device, target)) {
tag = felica_tag_new(device, target);
} else if (mifare_mini_taste(device, target)) {
tag = mifare_mini_tag_new(device, target);
} else if (mifare_classic1k_taste(device, target)) {
tag = mifare_classic1k_tag_new(device, target);
} else if (mifare_classic4k_taste(device, target)) {
tag = mifare_classic4k_tag_new(device, target);
} else if (mifare_desfire_taste(device, target)) {
tag = mifare_desfire_tag_new(device, target);
} else if (ntag21x_taste(device, target)) {
tag = ntag21x_tag_new(device, target);
} else if (mifare_ultralightc_taste(device, target)) {
tag = mifare_ultralightc_tag_new(device, target);
} else if (mifare_ultralight_taste(device, target)) {
tag = mifare_ultralight_tag_new(device, target);
}
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.
*/
FreefareTag *
freefare_get_tags (nfc_device *device)
freefare_get_tags(nfc_device *device)
{
FreefareTag *tags = NULL;
int tag_count = 0;
@ -82,15 +82,15 @@ freefare_get_tags (nfc_device *device)
nfc_initiator_init(device);
// 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
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_AUTO_ISO14443_4,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_AUTO_ISO14443_4, true);
// 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
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)
return NULL;
tags = malloc(sizeof (void *));
if(!tags) return NULL;
tags = malloc(sizeof(void *));
if (!tags) return NULL;
tags[0] = NULL;
for (int c = 0; c < candidates_count; c++) {
FreefareTag t;
if ((t = freefare_tag_new(device, candidates[c]))) {
/* (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)
tags = p;
else
@ -130,7 +130,7 @@ freefare_get_tags (nfc_device *device)
FreefareTag t;
if ((t = freefare_tag_new(device, candidates[c]))) {
/* (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)
tags = p;
else
@ -147,8 +147,7 @@ freefare_get_tags (nfc_device *device)
* Returns the type of the provided tag.
*/
enum freefare_tag_type
freefare_get_tag_type (FreefareTag tag)
{
freefare_get_tag_type(FreefareTag tag) {
return tag->type;
}
@ -156,13 +155,13 @@ freefare_get_tag_type (FreefareTag tag)
* Returns the friendly name of the provided tag.
*/
const char *
freefare_get_tag_friendly_name (FreefareTag tag)
freefare_get_tag_friendly_name(FreefareTag tag)
{
switch (tag->type) {
case FELICA:
return "FeliCA";
case MIFARE_MINI:
return "Mifare Mini 0.3k";
return "Mifare Mini 0.3k";
case MIFARE_CLASSIC_1K:
return "Mifare Classic 1k";
case MIFARE_CLASSIC_4K:
@ -184,20 +183,20 @@ freefare_get_tag_friendly_name (FreefareTag tag)
* Returns the UID of the provided tag.
*/
char *
freefare_get_tag_uid (FreefareTag tag)
freefare_get_tag_uid(FreefareTag tag)
{
char *res = NULL;
switch (tag->info.nm.nmt) {
case NMT_FELICA:
if ((res = malloc (17))) {
if ((res = malloc(17))) {
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;
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++)
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;
case NMT_DEP:
@ -206,7 +205,7 @@ freefare_get_tag_uid (FreefareTag tag)
case NMT_ISO14443B:
case NMT_ISO14443BI:
case NMT_JEWEL:
res = strdup ("UNKNOWN");
res = strdup("UNKNOWN");
}
return res;
}
@ -223,54 +222,54 @@ bool freefare_selected_tag_is_present(nfc_device *device)
* Free the provided tag.
*/
void
freefare_free_tag (FreefareTag tag)
freefare_free_tag(FreefareTag tag)
{
if (tag) {
tag->free_tag (tag);
tag->free_tag(tag);
}
}
const char *
freefare_strerror (FreefareTag tag)
freefare_strerror(FreefareTag tag)
{
const char *p = "Unknown error";
if (nfc_device_get_last_error (tag->device) < 0) {
p = nfc_strerror (tag->device);
if (nfc_device_get_last_error(tag->device) < 0) {
p = nfc_strerror(tag->device);
} else {
if (tag->type == MIFARE_DESFIRE) {
if (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) {
p = mifare_desfire_error_lookup (MIFARE_DESFIRE (tag)->last_picc_error);
}
}
if (tag->type == MIFARE_DESFIRE) {
if (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) {
p = mifare_desfire_error_lookup(MIFARE_DESFIRE(tag)->last_picc_error);
}
}
}
return p;
}
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
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.
*/
void
freefare_free_tags (FreefareTag *tags)
freefare_free_tags(FreefareTag *tags)
{
if (tags) {
for (int i=0; tags[i]; i++) {
for (int i = 0; tags[i]; i++) {
freefare_free_tag(tags[i]);
}
free (tags);
free(tags);
}
}
@ -280,11 +279,11 @@ freefare_free_tags (FreefareTag *tags)
*/
void *
memdup (const void *p, const size_t n)
memdup(const void *p, const size_t n)
{
void *res;
if ((res = malloc (n))) {
memcpy (res, p, n);
if ((res = malloc(n))) {
memcpy(res, p, n);
}
return res;
}

View file

@ -1,11 +1,11 @@
/*-
* Copyright (C) 2009, 2010, Romain Tartiere, Romuald Conty.
*
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
@ -25,7 +25,7 @@
#include <nfc/nfc.h>
#ifdef __cplusplus
extern "C" {
extern "C" {
#endif // __cplusplus
enum freefare_tag_type {
@ -47,7 +47,7 @@ struct freefare_tag;
typedef struct freefare_tag *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;
typedef struct mifare_desfire_key *MifareDESFireKey;
@ -58,57 +58,57 @@ typedef struct ntag21x_key *NTAG21xKey;
typedef uint8_t MifareUltralightPageNumber;
typedef unsigned char MifareUltralightPage[4];
FreefareTag *freefare_get_tags (nfc_device *device);
FreefareTag freefare_tag_new (nfc_device *device, nfc_target target);
enum freefare_tag_type freefare_get_tag_type (FreefareTag tag);
const char *freefare_get_tag_friendly_name (FreefareTag tag);
char *freefare_get_tag_uid (FreefareTag tag);
void freefare_free_tag (FreefareTag tag);
void freefare_free_tags (FreefareTag *tags);
FreefareTag *freefare_get_tags(nfc_device *device);
FreefareTag freefare_tag_new(nfc_device *device, nfc_target target);
enum freefare_tag_type freefare_get_tag_type(FreefareTag tag);
const char *freefare_get_tag_friendly_name(FreefareTag tag);
char *freefare_get_tag_uid(FreefareTag tag);
void freefare_free_tag(FreefareTag tag);
void freefare_free_tags(FreefareTag *tags);
bool freefare_selected_tag_is_present(nfc_device *device);
const char *freefare_strerror (FreefareTag tag);
int freefare_strerror_r (FreefareTag tag, char *buffer, size_t len);
void freefare_perror (FreefareTag tag, const char *string);
const char *freefare_strerror(FreefareTag tag);
int freefare_strerror_r(FreefareTag tag, char *buffer, size_t len);
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_RO 0x000b
FreefareTag felica_tag_new (nfc_device *device, nfc_target target);
void felica_tag_free (FreefareTag tag);
FreefareTag felica_tag_new(nfc_device *device, nfc_target target);
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_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_ex (FreefareTag tag, uint16_t service, uint8_t block_count, uint8_t blocks[], 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_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);
bool mifare_ultralight_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_ultralightc_tag_new (nfc_device *device, nfc_target target);
void mifare_ultralight_tag_free (FreefareTag tag);
void mifare_ultralightc_tag_free (FreefareTag tag);
bool mifare_ultralight_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_ultralightc_tag_new(nfc_device *device, nfc_target target);
void mifare_ultralight_tag_free(FreefareTag tag);
void mifare_ultralightc_tag_free(FreefareTag tag);
int mifare_ultralight_connect (FreefareTag tag);
int mifare_ultralight_disconnect (FreefareTag tag);
int mifare_ultralight_connect(FreefareTag tag);
int mifare_ultralight_disconnect(FreefareTag tag);
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_read(FreefareTag tag, const MifareUltralightPageNumber page, MifareUltralightPage *data);
int mifare_ultralight_write(FreefareTag tag, const MifareUltralightPageNumber page, const MifareUltralightPage data);
int mifare_ultralightc_authenticate (FreefareTag tag, const MifareDESFireKey key);
bool is_mifare_ultralight (FreefareTag tag);
bool is_mifare_ultralightc (FreefareTag tag);
bool is_mifare_ultralightc_on_reader (nfc_device *device, nfc_iso14443a_info nai);
int mifare_ultralightc_authenticate(FreefareTag tag, const MifareDESFireKey key);
bool is_mifare_ultralight(FreefareTag tag);
bool is_mifare_ultralightc(FreefareTag tag);
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 */
#define NTAG_PROT 0x80
@ -123,48 +123,48 @@ enum ntag_tag_subtype {
NTAG_216
};
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 */
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_tag_free (FreefareTag tag);
int ntag21x_connect (FreefareTag tag);
int ntag21x_disconnect (FreefareTag tag);
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 */
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_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_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_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_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_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_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_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_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_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_authenticate (FreefareTag tag, const NTAG21xKey key); /* Authenticate with tag */
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 */
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 */
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_tag_free(FreefareTag tag);
int ntag21x_connect(FreefareTag tag);
int ntag21x_disconnect(FreefareTag tag);
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 */
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_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_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_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_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_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_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_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_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_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_authenticate(FreefareTag tag, const NTAG21xKey key); /* Authenticate with tag */
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 mifare_mini_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);
FreefareTag mifare_mini_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);
void mifare_classic_tag_free (FreefareTag tag);
bool mifare_mini_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);
FreefareTag mifare_mini_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);
void mifare_classic_tag_free(FreefareTag tag);
typedef unsigned char MifareClassicBlock[16];
@ -177,31 +177,31 @@ typedef unsigned char MifareClassicKey[6];
/* NFC Forum public key */
extern const MifareClassicKey mifare_classic_nfcforum_public_key_a;
int mifare_classic_connect (FreefareTag tag);
int mifare_classic_disconnect (FreefareTag tag);
int mifare_classic_connect(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_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_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_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_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_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_decrement (FreefareTag tag, const MifareClassicBlockNumber block, const uint32_t amount);
int mifare_classic_restore (FreefareTag tag, const MifareClassicBlockNumber block);
int mifare_classic_transfer (FreefareTag tag, const MifareClassicBlockNumber block);
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_restore(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_data_block_permission (FreefareTag tag, const MifareClassicBlockNumber block, const unsigned char 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_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);
MifareClassicBlockNumber mifare_classic_sector_first_block (MifareClassicSectorNumber sector);
size_t mifare_classic_sector_block_count (MifareClassicSectorNumber sector);
MifareClassicBlockNumber mifare_classic_sector_last_block (MifareClassicSectorNumber sector);
MifareClassicSectorNumber mifare_classic_block_sector(MifareClassicBlockNumber block);
MifareClassicBlockNumber mifare_classic_sector_first_block(MifareClassicSectorNumber sector);
size_t mifare_classic_sector_block_count(MifareClassicSectorNumber sector);
MifareClassicBlockNumber mifare_classic_sector_last_block(MifareClassicSectorNumber sector);
#define C_000 0
#define C_001 1
@ -248,28 +248,28 @@ extern const MadAid mad_not_applicable_aid;
/* NFC Forum AID */
extern const MadAid mad_nfcforum_aid;
Mad mad_new (const uint8_t version);
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_get_version (Mad mad);
void mad_set_version (Mad mad, const uint8_t version);
MifareClassicSectorNumber mad_get_card_publisher_sector (Mad mad);
int mad_set_card_publisher_sector (Mad mad, const MifareClassicSectorNumber cps);
int mad_get_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);
void mad_free (Mad mad);
Mad mad_new(const uint8_t version);
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_get_version(Mad mad);
void mad_set_version(Mad mad, const uint8_t version);
MifareClassicSectorNumber mad_get_card_publisher_sector(Mad mad);
int mad_set_card_publisher_sector(Mad mad, const MifareClassicSectorNumber cps);
int mad_get_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);
void mad_free(Mad mad);
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_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);
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_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);
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 */
@ -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) ( \
(key_no_for_key_changing << 4) | \
(config_changeable << 3) | \
(free_listing_contents << 1) | \
(app_master_key_changeable) \
)
(key_no_for_key_changing << 4) | \
(config_changeable << 3) | \
(free_listing_contents << 1) | \
(app_master_key_changeable) \
)
/* Access right */
#define MDAR(read,write,read_write,change_access_rights) ( \
(read << 12) | \
(write << 8) | \
(read_write << 4) | \
(change_access_rights) \
)
(read << 12) | \
(write << 8) | \
(read_write << 4) | \
(change_access_rights) \
)
#define MDAR_READ(ar) (((ar) >> 12) & 0x0f)
#define MDAR_WRITE(ar) (((ar) >> 8) & 0x0f)
#define MDAR_READ_WRITE(ar) (((ar) >> 4) & 0x0f)
@ -379,12 +379,12 @@ struct mifare_desfire_df {
};
typedef struct mifare_desfire_df MifareDESFireDF;
MifareDESFireAID mifare_desfire_aid_new (uint32_t aid);
MifareDESFireAID mifare_desfire_aid_new_with_mad_aid (MadAid mad_aid, uint8_t n);
uint32_t mifare_desfire_aid_get_aid (MifareDESFireAID aid);
MifareDESFireAID mifare_desfire_aid_new(uint32_t aid);
MifareDESFireAID mifare_desfire_aid_new_with_mad_aid(MadAid mad_aid, uint8_t n);
uint32_t mifare_desfire_aid_get_aid(MifareDESFireAID aid);
uint8_t mifare_desfire_last_pcd_error (FreefareTag tag);
uint8_t mifare_desfire_last_picc_error (FreefareTag tag);
uint8_t mifare_desfire_last_pcd_error(FreefareTag tag);
uint8_t mifare_desfire_last_picc_error(FreefareTag tag);
#pragma pack (push)
#pragma pack (1)
@ -436,93 +436,93 @@ struct mifare_desfire_file_settings {
} settings;
};
FreefareTag mifare_desfire_tag_new (nfc_device *device, nfc_target target);
void mifare_desfire_tag_free (FreefareTag tags);
FreefareTag mifare_desfire_tag_new(nfc_device *device, nfc_target target);
void mifare_desfire_tag_free(FreefareTag tags);
int mifare_desfire_connect (FreefareTag tag);
int mifare_desfire_disconnect (FreefareTag tag);
int mifare_desfire_connect(FreefareTag tag);
int mifare_desfire_disconnect(FreefareTag tag);
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_aes (FreefareTag tag, uint8_t key_no, MifareDESFireKey key);
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_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_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_aes (FreefareTag tag, MifareDESFireAID aid, uint8_t settings, uint8_t key_no);
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_aes(FreefareTag tag, uint8_t key_no, MifareDESFireKey key);
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_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_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_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_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_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_delete_application (FreefareTag tag, MifareDESFireAID aid);
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);
void mifare_desfire_free_application_ids (MifareDESFireAID aids[]);
int mifare_desfire_select_application (FreefareTag tag, MifareDESFireAID aid);
int mifare_desfire_format_picc (FreefareTag tag);
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_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_ats (FreefareTag tag, uint8_t *ats);
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_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_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_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_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_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_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_delete_file (FreefareTag tag, uint8_t file_no);
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_df_names(FreefareTag tag, MifareDESFireDF *dfs[], size_t *count);
void mifare_desfire_free_application_ids(MifareDESFireAID aids[]);
int mifare_desfire_select_application(FreefareTag tag, MifareDESFireAID aid);
int mifare_desfire_format_picc(FreefareTag tag);
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_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_ats(FreefareTag tag, uint8_t *ats);
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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_commit_transaction (FreefareTag tag);
int mifare_desfire_abort_transaction (FreefareTag tag);
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_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);
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_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_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_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);
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_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);
int mifare_desfire_clear_record_file(FreefareTag tag, uint8_t file_no);
int mifare_desfire_commit_transaction(FreefareTag tag);
int mifare_desfire_abort_transaction(FreefareTag tag);
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_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_3k3des_key_new (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_with_version (const uint8_t value[16], uint8_t version);
uint8_t mifare_desfire_key_get_version (MifareDESFireKey key);
void mifare_desfire_key_set_version (MifareDESFireKey key, uint8_t version);
void mifare_desfire_key_free (MifareDESFireKey key);
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_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_3k3des_key_new(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_with_version(const uint8_t value[16], uint8_t version);
uint8_t mifare_desfire_key_get_version(MifareDESFireKey key);
void mifare_desfire_key_set_version(MifareDESFireKey key, uint8_t version);
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_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);
uint8_t *tlv_append (uint8_t *a, uint8_t *b);
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);
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);
#ifdef __cplusplus
}
}
#endif // __cplusplus
#endif /* !__FREEFARE_H__ */

View file

@ -98,14 +98,14 @@
#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_0x10;
void nxp_crc (uint8_t *crc, const uint8_t value);
uint8_t sector_0x00_crc8 (Mad mad);
uint8_t sector_0x10_crc8 (Mad mad);
void nxp_crc(uint8_t *crc, const uint8_t value);
uint8_t sector_0x00_crc8(Mad mad);
uint8_t sector_0x10_crc8(Mad mad);
typedef enum {
MCD_SEND,
@ -137,21 +137,21 @@ typedef enum {
#define MAC_MASK 0x0F0
#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_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_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 desfire_crc32 (const uint8_t *data, const size_t len, uint8_t *crc);
void desfire_crc32_append (uint8_t *data, const size_t len);
size_t key_block_size (const MifareDESFireKey key);
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 enciphered_data_length (const FreefareTag tag, const size_t nbytes, 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_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 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_append(uint8_t *data, const size_t len);
size_t key_block_size(const MifareDESFireKey key);
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 enciphered_data_length(const FreefareTag tag, const size_t nbytes, int communication_settings);
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 *assert_crypto_buffer_size (FreefareTag tag, size_t nbytes);
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 *assert_crypto_buffer_size(FreefareTag tag, size_t nbytes);
#define MIFARE_ULTRALIGHT_PAGE_COUNT 0x10
#define MIFARE_ULTRALIGHT_C_PAGE_COUNT 0x30
@ -172,7 +172,7 @@ struct freefare_tag {
nfc_target info;
int type;
int active;
void (*free_tag) (FreefareTag tag);
void (*free_tag)(FreefareTag tag);
};
struct felica_tag {
@ -189,10 +189,10 @@ struct mifare_classic_tag {
* address and avoid false cache hit with inconsistent data.
*/
struct {
int16_t sector_trailer_block_number;
uint16_t sector_access_bits;
int16_t block_number;
uint8_t block_access_bits;
int16_t sector_trailer_block_number;
uint16_t sector_access_bits;
int16_t block_number;
uint8_t block_access_bits;
} cached_access_bits;
};
@ -232,8 +232,8 @@ struct mifare_desfire_tag {
uint32_t selected_application;
};
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);
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);
struct mifare_ultralight_tag {
struct freefare_tag __tag;
@ -274,7 +274,7 @@ struct ntag21x_key {
#define ASSERT_ACTIVE(tag) do { if (!tag->active) return errno = ENXIO, -1; } while (0)
#define ASSERT_INACTIVE(tag) do { if (tag->active) return errno = ENXIO, -1; } while (0)
/*
/*
* FreefareTag cast macros
*
* This macros are intended to provide a convenient way to cast abstract
@ -303,7 +303,7 @@ struct ntag21x_key {
/*
* Buffer management macros.
*
*
* The following macros ease setting-up and using buffers:
* BUFFER_INIT (data, 5); // data -> [ xx, xx, xx, xx, xx ]
* BUFFER_SIZE (data); // size -> 0
@ -345,7 +345,7 @@ struct ntag21x_key {
*/
#define BUFFER_APPEND(buffer_name, data) \
do { \
buffer_name[__##buffer_name##_n++] = data; \
buffer_name[__##buffer_name##_n++] = data; \
} while (0)
/*
@ -353,10 +353,10 @@ struct ntag21x_key {
*/
#define BUFFER_APPEND_BYTES(buffer_name, data, size) \
do { \
size_t __n = 0; \
while (__n < size) { \
buffer_name[__##buffer_name##_n++] = ((uint8_t *)data)[__n++]; \
} \
size_t __n = 0; \
while (__n < size) { \
buffer_name[__##buffer_name##_n++] = ((uint8_t *)data)[__n++]; \
} \
} while (0)
/*
@ -371,17 +371,17 @@ struct ntag21x_key {
#if defined(_BYTE_ORDER) && (_BYTE_ORDER != _LITTLE_ENDIAN)
#define BUFFER_APPEND_LE(buffer, data, data_size, field_size) \
do { \
size_t __data_size = data_size; \
size_t __field_size = field_size; \
while (__field_size--, __data_size--) { \
buffer[__##buffer##_n++] = ((uint8_t *)&data)[__field_size]; \
} \
size_t __data_size = data_size; \
size_t __field_size = field_size; \
while (__field_size--, __data_size--) { \
buffer[__##buffer##_n++] = ((uint8_t *)&data)[__field_size]; \
} \
} while (0)
#else
#define BUFFER_APPEND_LE(buffer, data, data_size, field_size) \
do { \
memcpy (buffer + __##buffer##_n, &data, data_size); \
__##buffer##_n += data_size; \
memcpy (buffer + __##buffer##_n, &data, data_size); \
__##buffer##_n += data_size; \
} while (0)
#endif

View file

@ -110,16 +110,16 @@ const MadAid mad_nfcforum_aid = {
* Allocate an empty new MAD.
*/
Mad
mad_new (uint8_t version)
mad_new(uint8_t version)
{
Mad mad = malloc (sizeof (*mad));
Mad mad = malloc(sizeof(*mad));
if (!mad)
return NULL;
mad->version = version;
memset (&(mad->sector_0x00), 0, sizeof (mad->sector_0x00));
memset (&(mad->sector_0x10), 0, sizeof (mad->sector_0x10));
memset(&(mad->sector_0x00), 0, sizeof(mad->sector_0x00));
memset(&(mad->sector_0x10), 0, sizeof(mad->sector_0x10));
return mad;
}
@ -128,7 +128,7 @@ mad_new (uint8_t version)
* Compute CRC.
*/
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 */
const uint8_t poly = 0x1d;
@ -144,30 +144,30 @@ nxp_crc (uint8_t *crc, const uint8_t value)
}
uint8_t
sector_0x00_crc8 (Mad mad)
sector_0x00_crc8(Mad mad)
{
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++) {
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].application_code);
nxp_crc(&crc, mad->sector_0x00.aids[n].function_cluster_code);
}
return crc;
}
uint8_t
sector_0x10_crc8 (Mad mad)
sector_0x10_crc8(Mad mad)
{
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++) {
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].application_code);
nxp_crc(&crc, mad->sector_0x10.aids[n].function_cluster_code);
}
return crc;
@ -177,21 +177,21 @@ sector_0x10_crc8 (Mad mad)
* Read a MAD from the provided MIFARE tag.
*/
Mad
mad_read (FreefareTag tag)
mad_read(FreefareTag tag)
{
Mad mad = malloc (sizeof (*mad));
Mad mad = malloc(sizeof(*mad));
if (!mad)
goto error;
/* 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;
}
/* Read first sector trailer block */
MifareClassicBlock data;
if (mifare_classic_read (tag, 0x03, &data) < 0) {
if (mifare_classic_read(tag, 0x03, &data) < 0) {
goto error;
}
uint8_t gpb = data[9];
@ -216,20 +216,20 @@ mad_read (FreefareTag tag)
}
/* 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;
uint8_t *p = (uint8_t *) &(mad->sector_0x00);
memcpy (p, data, sizeof (data));
uint8_t *p = (uint8_t *) & (mad->sector_0x00);
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;
memcpy (p, data, sizeof (data));
memcpy(p, data, sizeof(data));
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)
goto error;
@ -237,30 +237,30 @@ mad_read (FreefareTag tag)
if (mad->version == 2) {
/* 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;
}
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;
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;
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;
memcpy (p, data, sizeof (data));
memcpy(p, data, sizeof(data));
crc = mad->sector_0x10.crc;
computed_crc = sector_0x10_crc8 (mad);
computed_crc = sector_0x10_crc8(mad);
if (crc != computed_crc)
goto error;
}
@ -268,7 +268,7 @@ mad_read (FreefareTag tag)
return mad;
error:
free (mad);
free(mad);
return NULL;
}
@ -276,17 +276,17 @@ error:
* Write the mad to the provided MIFARE tad using the provided Key-B keys.
*/
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;
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;
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_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))) {
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_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))) {
errno = EPERM;
return -1;
}
@ -309,42 +309,42 @@ mad_write (FreefareTag tag, Mad mad, const MifareClassicKey key_b_sector_00, con
}
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;
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, 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_ACCESS_BITS, 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, 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_ACCESS_BITS, MFC_KEY_B))) {
errno = EPERM;
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));
if (mifare_classic_write (tag, 0x40, data) < 0) return -1;
memcpy (data, (uint8_t *)&(mad->sector_0x10) + sizeof (data), sizeof (data));
if (mifare_classic_write (tag, 0x41, data) < 0) return -1;
memcpy (data, (uint8_t *)&(mad->sector_0x10) + sizeof (data) * 2, sizeof (data));
if (mifare_classic_write (tag, 0x42, data) < 0) return -1;
memcpy(data, (uint8_t *) & (mad->sector_0x10), sizeof(data));
if (mifare_classic_write(tag, 0x40, data) < 0) return -1;
memcpy(data, (uint8_t *) & (mad->sector_0x10) + sizeof(data), sizeof(data));
if (mifare_classic_write(tag, 0x41, data) < 0) return -1;
memcpy(data, (uint8_t *) & (mad->sector_0x10) + sizeof(data) * 2, sizeof(data));
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);
if (mifare_classic_write (tag, 0x43, data) < 0) return -1;
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;
}
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;
memcpy (data, (uint8_t *)&(mad->sector_0x00), sizeof (data));
if (mifare_classic_write (tag, 0x01, data) < 0) return -1;
memcpy (data, (uint8_t *)&(mad->sector_0x00) + sizeof (data), sizeof (data));
if (mifare_classic_write (tag, 0x02, data) < 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));
if (mifare_classic_write(tag, 0x01, data) < 0) return -1;
memcpy(data, (uint8_t *) & (mad->sector_0x00) + sizeof(data), sizeof(data));
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);
if (mifare_classic_write (tag, 0x03, data) < 0) return -1;
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;
return 0;
}
@ -353,7 +353,7 @@ mad_write (FreefareTag tag, Mad mad, const MifareClassicKey key_b_sector_00, con
* Return a MAD version.
*/
int
mad_get_version (Mad mad)
mad_get_version(Mad mad)
{
return mad->version;
}
@ -362,11 +362,11 @@ mad_get_version (Mad mad)
* Set a MAD version.
*/
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)) {
/* 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;
}
@ -449,7 +449,7 @@ mad_set_aid(Mad mad, const MifareClassicSectorNumber sector, MadAid aid)
}
bool
mad_sector_reserved (const MifareClassicSectorNumber sector)
mad_sector_reserved(const MifareClassicSectorNumber 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().
*/
void
mad_free (Mad mad)
mad_free(Mad mad)
{
free (mad);
free(mad);
}

View file

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

View file

@ -1,11 +1,11 @@
/*-
* Copyright (C) 2009, 2010, Romain Tartiere, Romuald Conty.
*
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
@ -87,19 +87,19 @@
#define CLASSIC_TRANSCEIVE_EX(tag, msg, res, disconnect) \
do { \
errno = 0; \
DEBUG_XFER (msg, __##msg##_n, "===> "); \
int _res; \
if ((_res = nfc_initiator_transceive_bytes (tag->device, msg, __##msg##_n, res, __##res##_size, 0)) < 0) { \
if (disconnect) { \
tag->active = false; \
} \
if (_res == NFC_EMFCAUTHFAIL) \
return errno = EACCES, -1; \
return errno = EIO, -1; \
} \
__##res##_n = _res; \
DEBUG_XFER (res, __##res##_n, "<=== "); \
errno = 0; \
DEBUG_XFER (msg, __##msg##_n, "===> "); \
int _res; \
if ((_res = nfc_initiator_transceive_bytes (tag->device, msg, __##msg##_n, res, __##res##_size, 0)) < 0) { \
if (disconnect) { \
tag->active = false; \
} \
if (_res == NFC_EMFCAUTHFAIL) \
return errno = EACCES, -1; \
return errno = EIO, -1; \
} \
__##res##_n = _res; \
DEBUG_XFER (res, __##res##_n, "<=== "); \
} while (0)
@ -187,8 +187,8 @@ uint16_t mifare_trailer_access_permissions[] = {
* Private functions
*/
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_shift(MifareClassicBlockNumber block, MifareClassicBlockNumber trailer);
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
mifare_mini_taste (nfc_device *device, nfc_target target)
mifare_mini_taste(nfc_device *device, nfc_target target)
{
(void) device;
return target.nm.nmt == NMT_ISO14443A &&
(
target.nti.nai.btSak == 0x09
);
(
target.nti.nai.btSak == 0x09
);
}
bool
mifare_classic1k_taste (nfc_device *device, nfc_target target)
mifare_classic1k_taste(nfc_device *device, nfc_target target)
{
(void) device;
return target.nm.nmt == NMT_ISO14443A &&
(
target.nti.nai.btSak == 0x08 ||
target.nti.nai.btSak == 0x28 ||
target.nti.nai.btSak == 0x68 ||
target.nti.nai.btSak == 0x88
);
(
target.nti.nai.btSak == 0x08 ||
target.nti.nai.btSak == 0x28 ||
target.nti.nai.btSak == 0x68 ||
target.nti.nai.btSak == 0x88
);
}
bool
mifare_classic4k_taste (nfc_device *device, nfc_target target)
mifare_classic4k_taste(nfc_device *device, nfc_target target)
{
(void) device;
return target.nm.nmt == NMT_ISO14443A &&
(
target.nti.nai.btSak == 0x18 ||
target.nti.nai.btSak == 0x38
);
(
target.nti.nai.btSak == 0x18 ||
target.nti.nai.btSak == 0x38
);
}
/*
@ -234,11 +234,11 @@ mifare_classic4k_taste (nfc_device *device, nfc_target target)
*/
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;
if ((tag = malloc (sizeof (struct mifare_classic_tag)))) {
if ((tag = malloc(sizeof(struct mifare_classic_tag)))) {
tag->type = tag_type;
tag->free_tag = mifare_classic_tag_free;
tag->device = device;
@ -251,30 +251,30 @@ _mifare_classic_tag_new (nfc_device *device, nfc_target target, int tag_type)
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
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
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.
*/
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.
*/
int
mifare_classic_connect (FreefareTag tag)
mifare_classic_connect(FreefareTag tag)
{
ASSERT_INACTIVE (tag);
ASSERT_INACTIVE(tag);
nfc_target pnti;
nfc_modulation modulation = {
.nmt = NMT_ISO14443A,
.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;
} else {
errno = EIO;
@ -312,11 +312,11 @@ mifare_classic_connect (FreefareTag tag)
* Terminate connection with the provided tag.
*/
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;
} else {
errno = EIO;
@ -337,57 +337,57 @@ mifare_classic_disconnect (FreefareTag tag)
* Send an authentification command to the provided MIFARE target.
*/
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 (res, 1);
BUFFER_INIT(cmd, 12);
BUFFER_INIT(res, 1);
if (key_type == MFC_KEY_A)
BUFFER_APPEND (cmd, MC_AUTH_A);
BUFFER_APPEND(cmd, MC_AUTH_A);
else
BUFFER_APPEND (cmd, MC_AUTH_B);
BUFFER_APPEND(cmd, MC_AUTH_B);
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:
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_access_bits = 0x00;
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.
*/
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_ALIAS (res, data, sizeof(MifareClassicBlock));
BUFFER_INIT(cmd, 2);
BUFFER_ALIAS(res, data, sizeof(MifareClassicBlock));
BUFFER_APPEND (cmd, MC_READ);
BUFFER_APPEND (cmd, block);
BUFFER_APPEND(cmd, MC_READ);
BUFFER_APPEND(cmd, block);
CLASSIC_TRANSCEIVE (tag, cmd, res);
CLASSIC_TRANSCEIVE(tag, cmd, res);
return 0;
}
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;
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;
@ -398,18 +398,18 @@ mifare_classic_init_value (FreefareTag tag, const MifareClassicBlockNumber block
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 0;
}
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;
if (mifare_classic_read (tag, block, &b.data) < 0)
if (mifare_classic_read(tag, block, &b.data) < 0)
return -1;
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)
*value = le32toh (b.value.value);
*value = le32toh(b.value.value);
if (adr)
*adr = b.value.address;
@ -435,20 +435,20 @@ mifare_classic_read_value (FreefareTag tag, const MifareClassicBlockNumber block
* Write data to the provided MIFARE target.
*/
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 (res, 1);
BUFFER_INIT(cmd, 2 + sizeof(MifareClassicBlock));
BUFFER_INIT(res, 1);
BUFFER_APPEND (cmd, MC_WRITE);
BUFFER_APPEND (cmd, block);
BUFFER_APPEND_BYTES (cmd, data, sizeof (MifareClassicBlock));
BUFFER_APPEND(cmd, MC_WRITE);
BUFFER_APPEND(cmd, block);
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.
*/
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 (res, 1);
BUFFER_INIT(cmd, 6);
BUFFER_INIT(res, 1);
BUFFER_APPEND (cmd, MC_INCREMENT);
BUFFER_APPEND (cmd, block);
BUFFER_APPEND_LE (cmd, amount, 4, sizeof (amount));
BUFFER_APPEND(cmd, MC_INCREMENT);
BUFFER_APPEND(cmd, block);
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.
*/
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 (res, 1);
BUFFER_INIT(cmd, 6);
BUFFER_INIT(res, 1);
BUFFER_APPEND (cmd, MC_DECREMENT);
BUFFER_APPEND (cmd, block);
BUFFER_APPEND_LE (cmd, amount, 4, sizeof (amount));
BUFFER_APPEND(cmd, MC_DECREMENT);
BUFFER_APPEND(cmd, block);
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.
*/
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
* two bytes are actually used. The 4 bytes after the block number are
* meaningless but required (NULL-filled).
*/
BUFFER_INIT (cmd, 6);
BUFFER_INIT (res, 1);
BUFFER_INIT(cmd, 6);
BUFFER_INIT(res, 1);
BUFFER_APPEND (cmd, MC_RESTORE);
BUFFER_APPEND (cmd, block);
BUFFER_APPEND (cmd, 0x00);
BUFFER_APPEND (cmd, 0x00);
BUFFER_APPEND (cmd, 0x00);
BUFFER_APPEND (cmd, 0x00);
BUFFER_APPEND(cmd, MC_RESTORE);
BUFFER_APPEND(cmd, block);
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.
*/
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 (res, 1);
BUFFER_INIT(cmd, 2);
BUFFER_INIT(res, 1);
BUFFER_APPEND (cmd, MC_TRANSFER);
BUFFER_APPEND (cmd, block);
BUFFER_APPEND(cmd, MC_TRANSFER);
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
@ -543,7 +543,7 @@ mifare_classic_transfer (FreefareTag tag, const MifareClassicBlockNumber block)
* meaning that the action was performed correctly (e.g. Snapper Feeder,
* 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;
else
return res[0];
@ -576,7 +576,7 @@ mifare_classic_transfer (FreefareTag tag, const MifareClassicBlockNumber block)
*
*/
int
get_block_access_bits_shift (MifareClassicBlockNumber block, MifareClassicBlockNumber trailer)
get_block_access_bits_shift(MifareClassicBlockNumber block, MifareClassicBlockNumber trailer)
{
if (block == trailer) {
return 3;
@ -593,7 +593,7 @@ get_block_access_bits_shift (MifareClassicBlockNumber block, MifareClassicBlockN
* block.
*/
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
@ -606,7 +606,7 @@ get_block_access_bits (FreefareTag tag, const MifareClassicBlockNumber block, Mi
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
@ -623,7 +623,7 @@ get_block_access_bits (FreefareTag tag, const MifareClassicBlockNumber block, Mi
} else {
MifareClassicBlock trailer_data;
if (mifare_classic_read (tag, trailer, &trailer_data) < 0) {
if (mifare_classic_read(tag, trailer, &trailer_data) < 0) {
return -1;
}
@ -653,7 +653,7 @@ get_block_access_bits (FreefareTag tag, const MifareClassicBlockNumber block, Mi
* |,------C2
* ||,---- 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.
*/
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;
if (get_block_access_bits (tag, block, &access_bits) < 0) {
if (get_block_access_bits(tag, block, &access_bits) < 0) {
return -1;
}
@ -693,15 +693,15 @@ mifare_classic_get_trailer_block_permission (FreefareTag tag, const MifareClassi
* Get information about data blocks.
*/
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;
if (get_block_access_bits (tag, block, &access_bits) < 0) {
if (get_block_access_bits(tag, block, &access_bits) < 0) {
return -1;
}
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 {
errno = EINVAL;
return -1;
@ -717,12 +717,12 @@ mifare_classic_get_data_block_permission (FreefareTag tag, const MifareClassicBl
* Reset a MIFARE target sector to factory default.
*/
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 last_sector_block = mifare_classic_sector_last_block (sector);
MifareClassicBlockNumber first_sector_block = mifare_classic_sector_first_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.
*/
@ -743,7 +743,7 @@ mifare_classic_format_sector (FreefareTag tag, const MifareClassicSectorNumber s
}
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 = {
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++) {
if (mifare_classic_write (tag, n, empty_data_block) < 0) {
if (mifare_classic_write(tag, n, empty_data_block) < 0) {
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;
}
@ -765,14 +765,14 @@ mifare_classic_format_sector (FreefareTag tag, const MifareClassicSectorNumber s
}
MifareClassicSectorNumber
mifare_classic_block_sector (MifareClassicBlockNumber block)
mifare_classic_block_sector(MifareClassicBlockNumber block)
{
MifareClassicSectorNumber res;
if (block < 32 * 4)
res = block / 4;
else
res = 32 + ( (block - (32 * 4)) / 16 );
res = 32 + ((block - (32 * 4)) / 16);
return res;
}
@ -781,7 +781,7 @@ mifare_classic_block_sector (MifareClassicBlockNumber block)
* Get the sector's first block number
*/
MifareClassicBlockNumber
mifare_classic_sector_first_block (MifareClassicSectorNumber sector)
mifare_classic_sector_first_block(MifareClassicSectorNumber sector)
{
int res;
if (sector < 32) {
@ -794,7 +794,7 @@ mifare_classic_sector_first_block (MifareClassicSectorNumber sector)
}
size_t
mifare_classic_sector_block_count (MifareClassicSectorNumber sector)
mifare_classic_sector_block_count(MifareClassicSectorNumber sector)
{
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)
*/
MifareClassicBlockNumber
mifare_classic_sector_last_block (MifareClassicSectorNumber sector)
mifare_classic_sector_last_block(MifareClassicSectorNumber sector)
{
return mifare_classic_sector_first_block (sector) +
mifare_classic_sector_block_count (sector) - 1;
return mifare_classic_sector_first_block(sector) +
mifare_classic_sector_block_count(sector) - 1;
}
/*
* Generates a MIFARE trailer block.
*/
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));
@ -822,9 +822,9 @@ mifare_classic_trailer_block (MifareClassicBlock *block, const MifareClassicKey
ab_2 = DB_AB(ab_2);
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_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));
@ -832,8 +832,8 @@ mifare_classic_trailer_block (MifareClassicBlock *block, const MifareClassicKey
uint32_t access_bits_ = ((~access_bits) & 0x00000fff);
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;
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

@ -1,11 +1,11 @@
/*-
* Copyright (C) 2010, Romain Tartiere.
*
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
@ -57,16 +57,16 @@
// Theorically, it should be an uint24_t ...
MifareDESFireAID
mifare_desfire_aid_new (uint32_t aid)
mifare_desfire_aid_new(uint32_t aid)
{
if (aid > 0x00ffffff)
return errno = EINVAL, NULL;
MifareDESFireAID res;
uint32_t aid_le = htole32 (aid);
uint32_t aid_le = htole32(aid);
if ((res = malloc (sizeof (*res)))) {
memcpy(res->data, ((uint8_t*)&aid_le), 3);
if ((res = malloc(sizeof(*res)))) {
memcpy(res->data, ((uint8_t *)&aid_le), 3);
}
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)
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)
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
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);
}

View file

@ -1,11 +1,11 @@
/*-
* Copyright (C) 2010, Romain Tartiere.
*
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
@ -71,12 +71,12 @@
#define MAC_LENGTH 4
#define CMAC_LENGTH 8
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 size_t key_macing_length (MifareDESFireKey key);
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 size_t key_macing_length(MifareDESFireKey key);
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++) {
data[i] ^= ivect[i];
@ -84,87 +84,87 @@ xor (const uint8_t *ivect, uint8_t *data, const size_t len)
}
void
rol (uint8_t *data, const size_t len)
rol(uint8_t *data, const size_t len)
{
uint8_t first = data[0];
for (size_t i = 0; i < len-1; i++) {
data[i] = data[i+1];
for (size_t i = 0; i < len - 1; i++) {
data[i] = data[i + 1];
}
data[len-1] = first;
data[len - 1] = first;
}
void
lsl (uint8_t *data, size_t len)
lsl(uint8_t *data, size_t len)
{
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;
}
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;
uint8_t l[kbs];
memset (l, 0, kbs);
memset(l, 0, 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;
// Used to compute CMAC on complete blocks
memcpy (key->cmac_sk1, l, kbs);
memcpy(key->cmac_sk1, l, kbs);
xor = l[0] & 0x80;
lsl (key->cmac_sk1, kbs);
lsl(key->cmac_sk1, kbs);
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
memcpy (key->cmac_sk2, key->cmac_sk1, kbs);
memcpy(key->cmac_sk2, key->cmac_sk1, kbs);
xor = key->cmac_sk1[0] & 0x80;
lsl (key->cmac_sk2, kbs);
lsl(key->cmac_sk2, kbs);
if (xor)
key->cmac_sk2[kbs-1] ^= R;
key->cmac_sk2[kbs - 1] ^= R;
}
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);
uint8_t *buffer = malloc (padded_data_length (len, kbs));
int kbs = key_block_size(key);
uint8_t *buffer = malloc(padded_data_length(len, kbs));
if (!buffer)
abort();
memcpy (buffer, data, len);
memcpy(buffer, data, len);
if ((!len) || (len % kbs)) {
buffer[len++] = 0x80;
while (len % kbs) {
buffer[len++] = 0x00;
}
xor (key->cmac_sk2, buffer + len - kbs, kbs);
xor(key->cmac_sk2, buffer + len - kbs, kbs);
} 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
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 */
const uint32_t poly = 0xEDB88320;
@ -179,24 +179,24 @@ desfire_crc32_byte (uint32_t *crc, const uint8_t value)
}
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;
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
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
key_block_size (const MifareDESFireKey key)
key_block_size(const MifareDESFireKey key)
{
size_t block_size;
@ -218,7 +218,7 @@ key_block_size (const MifareDESFireKey key)
* Size of MACing produced with the key.
*/
static size_t
key_macing_length (const MifareDESFireKey key)
key_macing_length(const MifareDESFireKey key)
{
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_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))
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
*/
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.
*/
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;
if (!(communication_settings & NO_CRC)) {
switch (MIFARE_DESFIRE (tag)->authentication_scheme) {
switch (MIFARE_DESFIRE(tag)->authentication_scheme) {
case AS_LEGACY:
crc_length = 2;
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.
*/
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;
if (MIFARE_DESFIRE (tag)->crypto_buffer_size < nbytes) {
if ((res = realloc (MIFARE_DESFIRE (tag)->crypto_buffer, nbytes))) {
MIFARE_DESFIRE (tag)->crypto_buffer = res;
MIFARE_DESFIRE (tag)->crypto_buffer_size = nbytes;
void *res = MIFARE_DESFIRE(tag)->crypto_buffer;
if (MIFARE_DESFIRE(tag)->crypto_buffer_size < nbytes) {
if ((res = realloc(MIFARE_DESFIRE(tag)->crypto_buffer, nbytes))) {
MIFARE_DESFIRE(tag)->crypto_buffer = res;
MIFARE_DESFIRE(tag)->crypto_buffer_size = nbytes;
}
}
return res;
}
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 mac[4];
size_t edl, mdl;
bool append_mac = true;
MifareDESFireKey key = MIFARE_DESFIRE (tag)->session_key;
MifareDESFireKey key = MIFARE_DESFIRE(tag)->session_key;
if (!key)
return data;
switch (communication_settings & MDCM_MASK) {
case MDCM_PLAIN:
if (AS_LEGACY == MIFARE_DESFIRE (tag)->authentication_scheme)
if (AS_LEGACY == MIFARE_DESFIRE(tag)->authentication_scheme)
break;
/*
@ -325,53 +325,53 @@ mifare_cryto_preprocess_data (FreefareTag tag, void *data, size_t *nbytes, off_t
append_mac = false;
/* pass through */
/* pass through */
case MDCM_MACED:
switch (MIFARE_DESFIRE (tag)->authentication_scheme) {
switch (MIFARE_DESFIRE(tag)->authentication_scheme) {
case AS_LEGACY:
if (!(communication_settings & MAC_COMMAND))
break;
/* pass through */
edl = padded_data_length (*nbytes - offset, key_block_size (MIFARE_DESFIRE (tag)->session_key)) + offset;
if (!(res = assert_crypto_buffer_size (tag, edl)))
edl = padded_data_length(*nbytes - offset, key_block_size(MIFARE_DESFIRE(tag)->session_key)) + offset;
if (!(res = assert_crypto_buffer_size(tag, edl)))
abort();
// Fill in the crypto buffer with data ...
memcpy (res, data, *nbytes);
memcpy(res, data, *nbytes);
// ... 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)
memcpy (res, data, *nbytes);
memcpy(res, data, *nbytes);
if (!(communication_settings & MAC_COMMAND))
break;
// Append MAC
mdl = maced_data_length (MIFARE_DESFIRE (tag)->session_key, *nbytes - offset) + offset;
if (!(res = assert_crypto_buffer_size (tag, mdl)))
mdl = maced_data_length(MIFARE_DESFIRE(tag)->session_key, *nbytes - offset) + offset;
if (!(res = assert_crypto_buffer_size(tag, mdl)))
abort();
memcpy (res + *nbytes, mac, 4);
memcpy(res + *nbytes, mac, 4);
*nbytes += 4;
break;
case AS_NEW:
if (!(communication_settings & CMAC_COMMAND))
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) {
mdl = maced_data_length (key, *nbytes);
if (!(res = assert_crypto_buffer_size (tag, mdl)))
mdl = maced_data_length(key, *nbytes);
if (!(res = assert_crypto_buffer_size(tag, mdl)))
abort();
memcpy (res, data, *nbytes);
memcpy (res + *nbytes, MIFARE_DESFIRE (tag)->cmac, CMAC_LENGTH);
memcpy(res, data, *nbytes);
memcpy(res + *nbytes, MIFARE_DESFIRE(tag)->cmac, CMAC_LENGTH);
*nbytes += CMAC_LENGTH;
}
break;
@ -394,41 +394,41 @@ mifare_cryto_preprocess_data (FreefareTag tag, void *data, size_t *nbytes, off_t
* 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;
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;
default:
MIFARE_DESFIRE (tag)->last_pcd_error = CRYPTO_ERROR;
MIFARE_DESFIRE(tag)->last_pcd_error = CRYPTO_ERROR;
*nbytes = -1;
res = NULL;
#ifdef WITH_DEBUG
warnx ("Unknown communication settings");
abort ();
warnx("Unknown communication settings");
abort();
#endif
break;
}
@ -437,14 +437,14 @@ mifare_cryto_preprocess_data (FreefareTag tag, void *data, size_t *nbytes, off_t
}
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;
size_t edl;
void *edata = NULL;
uint8_t first_cmac_byte;
MifareDESFireKey key = MIFARE_DESFIRE (tag)->session_key;
MifareDESFireKey key = MIFARE_DESFIRE(tag)->session_key;
if (!key)
return data;
@ -456,42 +456,42 @@ mifare_cryto_postprocess_data (FreefareTag tag, void *data, ssize_t *nbytes, int
switch (communication_settings & MDCM_MASK) {
case MDCM_PLAIN:
if (AS_LEGACY == MIFARE_DESFIRE (tag)->authentication_scheme)
if (AS_LEGACY == MIFARE_DESFIRE(tag)->authentication_scheme)
break;
/* pass through */
/* pass through */
case MDCM_MACED:
switch (MIFARE_DESFIRE (tag)->authentication_scheme) {
switch (MIFARE_DESFIRE(tag)->authentication_scheme) {
case AS_LEGACY:
if (communication_settings & MAC_VERIFY) {
*nbytes -= key_macing_length (key);
*nbytes -= key_macing_length(key);
if (*nbytes <= 0) {
MIFARE_DESFIRE (tag)->last_pcd_error = CRYPTO_ERROR;
MIFARE_DESFIRE(tag)->last_pcd_error = CRYPTO_ERROR;
*nbytes = -1;
res = NULL;
#ifdef WITH_DEBUG
warnx ("No room for MAC!");
abort ();
warnx("No room for MAC!");
abort();
#endif
break;
}
edl = enciphered_data_length (tag, *nbytes - 1, communication_settings);
if (!(edata = malloc (edl)))
abort ();
edl = enciphered_data_length(tag, *nbytes - 1, communication_settings);
if (!(edata = malloc(edl)))
abort();
memcpy (edata, data, *nbytes - 1);
memset ((uint8_t *)edata + *nbytes - 1, 0, edl - *nbytes + 1);
memcpy(edata, data, *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
warnx ("MACing not verified");
hexdump ((uint8_t *)data + *nbytes - 1, key_macing_length (key), "Expect ", 0);
hexdump ((uint8_t *)edata + edl - 8, key_macing_length (key), "Actual ", 0);
warnx("MACing not verified");
hexdump((uint8_t *)data + *nbytes - 1, key_macing_length(key), "Expect ", 0);
hexdump((uint8_t *)edata + edl - 8, key_macing_length(key), "Actual ", 0);
#endif
MIFARE_DESFIRE (tag)->last_pcd_error = CRYPTO_ERROR;
MIFARE_DESFIRE(tag)->last_pcd_error = CRYPTO_ERROR;
*nbytes = -1;
res = NULL;
}
@ -502,31 +502,31 @@ mifare_cryto_postprocess_data (FreefareTag tag, void *data, ssize_t *nbytes, int
break;
if (communication_settings & CMAC_VERIFY) {
if (*nbytes < 9) {
MIFARE_DESFIRE (tag)->last_pcd_error = CRYPTO_ERROR;
MIFARE_DESFIRE(tag)->last_pcd_error = CRYPTO_ERROR;
*nbytes = -1;
res = NULL;
#ifdef WITH_DEBUG
warnx ("No room for CMAC!");
abort ();
warnx("No room for CMAC!");
abort();
#endif
break;
}
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;
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) {
((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
warnx ("CMAC NOT verified :-(");
hexdump ((uint8_t *)data + *nbytes - 9, 8, "Expect ", 0);
hexdump (MIFARE_DESFIRE (tag)->cmac, 8, "Actual ", 0);
warnx("CMAC NOT verified :-(");
hexdump((uint8_t *)data + *nbytes - 9, 8, "Expect ", 0);
hexdump(MIFARE_DESFIRE(tag)->cmac, 8, "Actual ", 0);
#endif
MIFARE_DESFIRE (tag)->last_pcd_error = CRYPTO_ERROR;
MIFARE_DESFIRE(tag)->last_pcd_error = CRYPTO_ERROR;
*nbytes = -1;
res = NULL;
} else {
@ -536,7 +536,7 @@ mifare_cryto_postprocess_data (FreefareTag tag, void *data, ssize_t *nbytes, int
break;
}
free (edata);
free(edata);
break;
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
* 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.
*/
switch (MIFARE_DESFIRE (tag)->authentication_scheme) {
switch (MIFARE_DESFIRE(tag)->authentication_scheme) {
case AS_LEGACY:
crc_pos = *nbytes - 8 - 1; // The CRC can be over two blocks
if (crc_pos < 0) {
@ -585,15 +585,15 @@ mifare_cryto_postprocess_data (FreefareTag tag, void *data, ssize_t *nbytes, int
break;
case AS_NEW:
/* Move status between payload and CRC */
res = assert_crypto_buffer_size (tag, (*nbytes) + 1);
memcpy (res, data, *nbytes);
res = assert_crypto_buffer_size(tag, (*nbytes) + 1);
memcpy(res, data, *nbytes);
crc_pos = (*nbytes) - 16 - 3;
if (crc_pos < 0) {
/* Single block */
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;
crc_pos++;
*nbytes += 1;
@ -603,28 +603,28 @@ mifare_cryto_postprocess_data (FreefareTag tag, void *data, ssize_t *nbytes, int
do {
uint16_t crc16;
uint32_t crc;
switch (MIFARE_DESFIRE (tag)->authentication_scheme) {
switch (MIFARE_DESFIRE(tag)->authentication_scheme) {
case AS_LEGACY:
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;
break;
case AS_NEW:
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;
}
if (!crc) {
verified = true;
for (int n = end_crc_pos; n < *nbytes - 1; 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;
}
}
if (verified) {
*nbytes = crc_pos;
switch (MIFARE_DESFIRE (tag)->authentication_scheme) {
switch (MIFARE_DESFIRE(tag)->authentication_scheme) {
case AS_LEGACY:
((uint8_t *)data)[(*nbytes)++] = 0x00;
break;
@ -633,7 +633,7 @@ mifare_cryto_postprocess_data (FreefareTag tag, void *data, ssize_t *nbytes, int
break;
}
} else {
switch (MIFARE_DESFIRE (tag)->authentication_scheme) {
switch (MIFARE_DESFIRE(tag)->authentication_scheme) {
case AS_LEGACY:
break;
case AS_NEW:
@ -649,21 +649,21 @@ mifare_cryto_postprocess_data (FreefareTag tag, void *data, ssize_t *nbytes, int
if (!verified) {
#ifdef WITH_DEBUG
/* FIXME In some configurations, the file is transmitted PLAIN */
warnx ("CRC not verified in decyphered stream");
warnx("CRC not verified in decyphered stream");
#endif
MIFARE_DESFIRE (tag)->last_pcd_error = CRYPTO_ERROR;
MIFARE_DESFIRE(tag)->last_pcd_error = CRYPTO_ERROR;
*nbytes = -1;
res = NULL;
}
break;
default:
MIFARE_DESFIRE (tag)->last_pcd_error = CRYPTO_ERROR;
MIFARE_DESFIRE(tag)->last_pcd_error = CRYPTO_ERROR;
*nbytes = -1;
res = NULL;
#ifdef WITH_DEBUG
warnx ("Unknown communication settings");
abort ();
warnx("Unknown communication settings");
abort();
#endif
break;
@ -672,15 +672,15 @@ mifare_cryto_postprocess_data (FreefareTag tag, void *data, ssize_t *nbytes, int
}
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;
uint8_t ovect[MAX_CRYPTO_BLOCK_SIZE];
if (direction == MCD_SEND) {
xor (ivect, data, block_size);
xor(ivect, data, block_size);
} else {
memcpy (ovect, data, block_size);
memcpy(ovect, data, 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:
switch (operation) {
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;
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;
case T_3DES:
switch (operation) {
case MCO_ENCYPHER:
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 *) 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 *) data, (DES_cblock *) edata, &(key->ks1), DES_ENCRYPT);
break;
case MCO_DECYPHER:
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 *) 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 *) data, (DES_cblock *) edata, &(key->ks1), DES_DECRYPT);
break;
}
break;
case T_3K3DES:
switch (operation) {
case MCO_ENCYPHER:
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 *) data, (DES_cblock *) edata, &(key->ks3), 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 *) data, (DES_cblock *) edata, &(key->ks3), DES_ENCRYPT);
break;
case MCO_DECYPHER:
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 *) data, (DES_cblock *) edata, &(key->ks1), 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 *) data, (DES_cblock *) edata, &(key->ks1), DES_DECRYPT);
break;
}
break;
case T_AES:
switch (operation) {
case MCO_ENCYPHER:
AES_set_encrypt_key (key->data, 8*16, &k);
AES_encrypt (data, edata, &k);
AES_set_encrypt_key(key->data, 8 * 16, &k);
AES_encrypt(data, edata, &k);
break;
case MCO_DECYPHER:
AES_set_decrypt_key (key->data, 8*16, &k);
AES_decrypt (data, edata, &k);
AES_set_decrypt_key(key->data, 8 * 16, &k);
AES_decrypt(data, edata, &k);
break;
}
break;
}
memcpy (data, edata, block_size);
memcpy(data, edata, block_size);
if (direction == MCD_SEND) {
memcpy (ivect, data, block_size);
memcpy(ivect, data, block_size);
} else {
xor (ivect, data, block_size);
memcpy (ivect, ovect, block_size);
xor(ivect, data, 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.
*/
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;
if (tag) {
if (!key)
key = MIFARE_DESFIRE (tag)->session_key;
key = MIFARE_DESFIRE(tag)->session_key;
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:
memset (ivect, 0, MAX_CRYPTO_BLOCK_SIZE);
memset(ivect, 0, MAX_CRYPTO_BLOCK_SIZE);
break;
case AS_NEW:
break;
@ -781,11 +781,11 @@ mifare_cypher_blocks_chained (FreefareTag tag, MifareDESFireKey key, uint8_t *iv
if (!key || !ivect)
abort();
block_size = key_block_size (key);
block_size = key_block_size(key);
size_t offset = 0;
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;
}
}

View file

@ -1,11 +1,11 @@
/*-
* Copyright (C) 2010, Romain Tartiere, Romuald Conty.
*
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
@ -57,7 +57,7 @@ static struct error_message {
};
const char *
mifare_desfire_error_lookup (uint8_t code)
mifare_desfire_error_lookup(uint8_t code)
{
struct error_message *e = error_messages;
while (e->message) {
@ -70,19 +70,19 @@ mifare_desfire_error_lookup (uint8_t code)
}
uint8_t
mifare_desfire_last_pcd_error (FreefareTag tag)
mifare_desfire_last_pcd_error(FreefareTag tag)
{
if (tag->type != MIFARE_DESFIRE)
return 0;
return MIFARE_DESFIRE (tag)->last_pcd_error;
return MIFARE_DESFIRE(tag)->last_pcd_error;
}
uint8_t
mifare_desfire_last_picc_error (FreefareTag tag)
mifare_desfire_last_picc_error(FreefareTag tag)
{
if (tag->type != MIFARE_DESFIRE)
return 0;
return MIFARE_DESFIRE (tag)->last_picc_error;
return MIFARE_DESFIRE(tag)->last_picc_error;
}

View file

@ -1,11 +1,11 @@
/*-
* Copyright (C) 2010, Romain Tartiere.
*
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
@ -23,103 +23,103 @@
#include <freefare.h>
#include "freefare_internal.h"
static inline void update_key_schedules (MifareDESFireKey key);
static inline void update_key_schedules(MifareDESFireKey key);
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 + 8), &(key->ks2));
DES_set_key((DES_cblock *)key->data, &(key->ks1));
DES_set_key((DES_cblock *)(key->data + 8), &(key->ks2));
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
mifare_desfire_des_key_new (const uint8_t value[8])
mifare_desfire_des_key_new(const uint8_t value[8])
{
uint8_t data[8];
memcpy (data, value, 8);
for (int n=0; n < 8; n++)
memcpy(data, value, 8);
for (int n = 0; n < 8; n++)
data[n] &= 0xfe;
return mifare_desfire_des_key_new_with_version (data);
return mifare_desfire_des_key_new_with_version(data);
}
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;
if ((key = malloc (sizeof (struct mifare_desfire_key)))) {
if ((key = malloc(sizeof(struct mifare_desfire_key)))) {
key->type = T_DES;
memcpy (key->data, value, 8);
memcpy (key->data+8, value, 8);
update_key_schedules (key);
memcpy(key->data, value, 8);
memcpy(key->data + 8, value, 8);
update_key_schedules(key);
}
return key;
}
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];
memcpy (data, value, 16);
for (int n=0; n < 8; n++)
memcpy(data, value, 16);
for (int n = 0; n < 8; n++)
data[n] &= 0xfe;
for (int n=8; n < 16; n++)
for (int n = 8; n < 16; n++)
data[n] |= 0x01;
return mifare_desfire_3des_key_new_with_version (data);
return mifare_desfire_3des_key_new_with_version(data);
}
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;
if ((key = malloc (sizeof (struct mifare_desfire_key)))) {
if ((key = malloc(sizeof(struct mifare_desfire_key)))) {
key->type = T_3DES;
memcpy (key->data, value, 16);
update_key_schedules (key);
memcpy(key->data, value, 16);
update_key_schedules(key);
}
return key;
}
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];
memcpy (data, value, 24);
for (int n=0; n < 8; n++)
memcpy(data, value, 24);
for (int n = 0; n < 8; n++)
data[n] &= 0xfe;
return mifare_desfire_3k3des_key_new_with_version (data);
return mifare_desfire_3k3des_key_new_with_version(data);
}
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;
if ((key = malloc (sizeof (struct mifare_desfire_key)))) {
if ((key = malloc(sizeof(struct mifare_desfire_key)))) {
key->type = T_3K3DES;
memcpy (key->data, value, 24);
update_key_schedules (key);
memcpy(key->data, value, 24);
update_key_schedules(key);
}
return key;
}
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
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;
if ((key = malloc (sizeof (struct mifare_desfire_key)))) {
memcpy (key->data, value, 16);
if ((key = malloc(sizeof(struct mifare_desfire_key)))) {
memcpy(key->data, value, 16);
key->type = T_AES;
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
mifare_desfire_key_get_version (MifareDESFireKey key)
mifare_desfire_key_get_version(MifareDESFireKey key)
{
uint8_t version = 0;
@ -139,24 +139,24 @@ mifare_desfire_key_get_version (MifareDESFireKey key)
}
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++) {
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] |= version_bit;
if (key->type == T_DES) {
key->data[n+8] = key->data[n];
key->data[n + 8] = key->data[n];
} else {
// Write ~version to avoid turning a 3DES key into a DES key
key->data[n+8] &= 0xfe;
key->data[n+8] |= ~version_bit;
key->data[n + 8] &= 0xfe;
key->data[n + 8] |= ~version_bit;
}
}
}
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;
@ -164,32 +164,32 @@ mifare_desfire_session_key_new (const uint8_t rnda[], const uint8_t rndb[], Mifa
switch (authentication_key->type) {
case T_DES:
memcpy (buffer, rnda, 4);
memcpy (buffer+4, rndb, 4);
key = mifare_desfire_des_key_new_with_version (buffer);
memcpy(buffer, rnda, 4);
memcpy(buffer + 4, rndb, 4);
key = mifare_desfire_des_key_new_with_version(buffer);
break;
case T_3DES:
memcpy (buffer, rnda, 4);
memcpy (buffer+4, rndb, 4);
memcpy (buffer+8, rnda+4, 4);
memcpy (buffer+12, rndb+4, 4);
key = mifare_desfire_3des_key_new_with_version (buffer);
memcpy(buffer, rnda, 4);
memcpy(buffer + 4, rndb, 4);
memcpy(buffer + 8, rnda + 4, 4);
memcpy(buffer + 12, rndb + 4, 4);
key = mifare_desfire_3des_key_new_with_version(buffer);
break;
case T_3K3DES:
memcpy (buffer, rnda, 4);
memcpy (buffer+4, rndb, 4);
memcpy (buffer+8, rnda+6, 4);
memcpy (buffer+12, rndb+6, 4);
memcpy (buffer+16, rnda+12, 4);
memcpy (buffer+20, rndb+12, 4);
key = mifare_desfire_3k3des_key_new (buffer);
memcpy(buffer, rnda, 4);
memcpy(buffer + 4, rndb, 4);
memcpy(buffer + 8, rnda + 6, 4);
memcpy(buffer + 12, rndb + 6, 4);
memcpy(buffer + 16, rnda + 12, 4);
memcpy(buffer + 20, rndb + 12, 4);
key = mifare_desfire_3k3des_key_new(buffer);
break;
case T_AES:
memcpy (buffer, rnda, 4);
memcpy (buffer+4, rndb, 4);
memcpy (buffer+8, rnda+12, 4);
memcpy (buffer+12, rndb+12, 4);
key = mifare_desfire_aes_key_new (buffer);
memcpy(buffer, rnda, 4);
memcpy(buffer + 4, rndb, 4);
memcpy(buffer + 8, rnda + 12, 4);
memcpy(buffer + 12, rndb + 12, 4);
key = mifare_desfire_aes_key_new(buffer);
break;
}
@ -197,7 +197,7 @@ mifare_desfire_session_key_new (const uint8_t rnda[], const uint8_t rndb[], Mifa
}
void
mifare_desfire_key_free (MifareDESFireKey key)
mifare_desfire_key_free(MifareDESFireKey key)
{
free (key);
free(key);
}

View file

@ -1,11 +1,11 @@
/*-
* Copyright (C) 2010, Romain Tartiere.
*
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
@ -47,66 +47,66 @@
#define ASSERT_VALID_PAGE(tag, page, mode_write) \
do { \
if (is_mifare_ultralightc (tag)) { \
if (mode_write) { \
if (page >= MIFARE_ULTRALIGHT_C_PAGE_COUNT) return errno = EINVAL, -1; \
} else { \
if (page >= MIFARE_ULTRALIGHT_C_PAGE_COUNT_READ) return errno = EINVAL, -1; \
} \
} else { \
if (page >= MIFARE_ULTRALIGHT_PAGE_COUNT) return errno = EINVAL, -1; \
} \
if (is_mifare_ultralightc (tag)) { \
if (mode_write) { \
if (page >= MIFARE_ULTRALIGHT_C_PAGE_COUNT) return errno = EINVAL, -1; \
} else { \
if (page >= MIFARE_ULTRALIGHT_C_PAGE_COUNT_READ) return errno = EINVAL, -1; \
} \
} else { \
if (page >= MIFARE_ULTRALIGHT_PAGE_COUNT) return errno = EINVAL, -1; \
} \
} while (0)
#define ULTRALIGHT_TRANSCEIVE(tag, msg, res) \
do { \
errno = 0; \
DEBUG_XFER (msg, __##msg##_n, "===> "); \
int _res; \
if ((_res = nfc_initiator_transceive_bytes (tag->device, msg, __##msg##_n, res, __##res##_size, 0)) < 0) { \
return errno = EIO, -1; \
} \
__##res##_n = _res; \
DEBUG_XFER (res, __##res##_n, "<=== "); \
errno = 0; \
DEBUG_XFER (msg, __##msg##_n, "===> "); \
int _res; \
if ((_res = nfc_initiator_transceive_bytes (tag->device, msg, __##msg##_n, res, __##res##_size, 0)) < 0) { \
return errno = EIO, -1; \
} \
__##res##_n = _res; \
DEBUG_XFER (res, __##res##_n, "<=== "); \
} while (0)
#define ULTRALIGHT_TRANSCEIVE_RAW(tag, msg, res) \
do { \
errno = 0; \
if (nfc_device_set_property_bool (tag->device, NP_EASY_FRAMING, false) < 0) { \
errno = EIO; \
return -1; \
} \
DEBUG_XFER (msg, __##msg##_n, "===> "); \
int _res; \
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); \
return errno = EIO, -1; \
} \
__##res##_n = _res; \
DEBUG_XFER (res, __##res##_n, "<=== "); \
if (nfc_device_set_property_bool (tag->device, NP_EASY_FRAMING, true) < 0) { \
errno = EIO; \
return -1; \
} \
errno = 0; \
if (nfc_device_set_property_bool (tag->device, NP_EASY_FRAMING, false) < 0) { \
errno = EIO; \
return -1; \
} \
DEBUG_XFER (msg, __##msg##_n, "===> "); \
int _res; \
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); \
return errno = EIO, -1; \
} \
__##res##_n = _res; \
DEBUG_XFER (res, __##res##_n, "<=== "); \
if (nfc_device_set_property_bool (tag->device, NP_EASY_FRAMING, true) < 0) { \
errno = EIO; \
return -1; \
} \
} while (0)
static bool
taste (nfc_target target)
taste(nfc_target target)
{
return target.nm.nmt == NMT_ISO14443A && target.nti.nai.btSak == 0x00;
}
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
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.
*/
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;
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->free_tag = mifare_ultralightc_tag_free;
tag->device = device;
@ -134,30 +134,30 @@ _mifare_ultralightc_tag_new (nfc_device *device, nfc_target target, bool is_ultr
}
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
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.
*/
void
mifare_ultralight_tag_free (FreefareTag tag)
mifare_ultralight_tag_free(FreefareTag tag)
{
free (tag);
free(tag);
}
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.
*/
int
mifare_ultralight_connect (FreefareTag tag)
mifare_ultralight_connect(FreefareTag tag)
{
ASSERT_INACTIVE (tag);
ASSERT_INACTIVE(tag);
nfc_target pnti;
nfc_modulation modulation = {
.nmt = NMT_ISO14443A,
.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;
for (int i = 0; i < MIFARE_ULTRALIGHT_MAX_PAGE_COUNT; i++)
MIFARE_ULTRALIGHT(tag)->cached_pages[i] = 0;
@ -198,11 +198,11 @@ mifare_ultralight_connect (FreefareTag tag)
* Terminate connection with the provided tag.
*/
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;
} else {
errno = EIO;
@ -223,29 +223,29 @@ mifare_ultralight_disconnect (FreefareTag tag)
* Read data from the provided MIFARE tag.
*/
int
mifare_ultralight_read (FreefareTag tag, MifareUltralightPageNumber page, MifareUltralightPage *data)
mifare_ultralight_read(FreefareTag tag, MifareUltralightPageNumber page, MifareUltralightPage *data)
{
ASSERT_ACTIVE (tag);
ASSERT_VALID_PAGE (tag, page, false);
ASSERT_ACTIVE(tag);
ASSERT_VALID_PAGE(tag, page, false);
if (!MIFARE_ULTRALIGHT(tag)->cached_pages[page]) {
BUFFER_INIT (cmd, 2);
BUFFER_ALIAS (res, MIFARE_ULTRALIGHT(tag)->cache[page], sizeof(MifareUltralightPage) * 4);
BUFFER_INIT(cmd, 2);
BUFFER_ALIAS(res, MIFARE_ULTRALIGHT(tag)->cache[page], sizeof(MifareUltralightPage) * 4);
BUFFER_APPEND (cmd, 0x30);
BUFFER_APPEND (cmd, page);
BUFFER_APPEND(cmd, 0x30);
BUFFER_APPEND(cmd, page);
ULTRALIGHT_TRANSCEIVE (tag, cmd, res);
ULTRALIGHT_TRANSCEIVE(tag, cmd, res);
/* Handle wrapped pages */
int iPageCount;
if (is_mifare_ultralightc (tag)) {
if (is_mifare_ultralightc(tag)) {
iPageCount = MIFARE_ULTRALIGHT_C_PAGE_COUNT_READ;
} else {
iPageCount = MIFARE_ULTRALIGHT_PAGE_COUNT;
}
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 */
@ -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;
}
@ -262,19 +262,19 @@ mifare_ultralight_read (FreefareTag tag, MifareUltralightPageNumber page, Mifare
* Read data to the provided MIFARE tag.
*/
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_VALID_PAGE (tag, page, true);
ASSERT_ACTIVE(tag);
ASSERT_VALID_PAGE(tag, page, true);
BUFFER_INIT (cmd, 6);
BUFFER_INIT (res, 1);
BUFFER_INIT(cmd, 6);
BUFFER_INIT(res, 1);
BUFFER_APPEND (cmd, 0xA2);
BUFFER_APPEND (cmd, page);
BUFFER_APPEND_BYTES (cmd, data, sizeof (MifareUltralightPage));
BUFFER_APPEND(cmd, 0xA2);
BUFFER_APPEND(cmd, page);
BUFFER_APPEND_BYTES(cmd, data, sizeof(MifareUltralightPage));
ULTRALIGHT_TRANSCEIVE (tag, cmd, res);
ULTRALIGHT_TRANSCEIVE(tag, cmd, res);
/* Invalidate page in cache */
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.
*/
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 (res, 9);
BUFFER_APPEND (cmd1, 0x1A);
BUFFER_APPEND (cmd1, 0x00);
BUFFER_INIT(cmd1, 2);
BUFFER_INIT(res, 9);
BUFFER_APPEND(cmd1, 0x1A);
BUFFER_APPEND(cmd1, 0x00);
ULTRALIGHT_TRANSCEIVE_RAW(tag, cmd1, res);
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];
memcpy (PICC_RndB, PICC_E_RndB, 8);
memcpy(PICC_RndB, PICC_E_RndB, 8);
uint8_t ivect[8];
memset (ivect, '\0', sizeof (ivect));
mifare_cypher_single_block (key, PICC_RndB, ivect, MCD_RECEIVE, MCO_DECYPHER, 8);
memset(ivect, '\0', sizeof(ivect));
mifare_cypher_single_block(key, PICC_RndB, ivect, MCD_RECEIVE, MCO_DECYPHER, 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];
memcpy (PCD_r_RndB, PICC_RndB, 8);
rol (PCD_r_RndB, 8);
memcpy(PCD_r_RndB, PICC_RndB, 8);
rol(PCD_r_RndB, 8);
uint8_t token[16];
memcpy (token, PCD_RndA, 8);
memcpy (token+8, PCD_r_RndB, 8);
memcpy(token, PCD_RndA, 8);
memcpy(token + 8, PCD_r_RndB, 8);
size_t offset = 0;
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;
}
BUFFER_INIT (cmd2, 17);
BUFFER_INIT(cmd2, 17);
BUFFER_APPEND (cmd2, 0xAF);
BUFFER_APPEND_BYTES (cmd2, token, 16);
BUFFER_APPEND(cmd2, 0xAF);
BUFFER_APPEND_BYTES(cmd2, token, 16);
ULTRALIGHT_TRANSCEIVE_RAW(tag, cmd2, res);
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];
memcpy (PICC_RndA_s, PICC_E_RndA_s, 8);
mifare_cypher_single_block (key, PICC_RndA_s, ivect, MCD_RECEIVE, MCO_DECYPHER, 8);
memcpy(PICC_RndA_s, PICC_E_RndA_s, 8);
mifare_cypher_single_block(key, PICC_RndA_s, ivect, MCD_RECEIVE, MCO_DECYPHER, 8);
uint8_t PCD_RndA_s[8];
memcpy (PCD_RndA_s, PCD_RndA, 8);
rol (PCD_RndA_s, 8);
memcpy(PCD_RndA_s, PCD_RndA, 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;
return -1;
}
@ -350,13 +350,13 @@ mifare_ultralightc_authenticate (FreefareTag tag, const MifareDESFireKey key)
}
bool
is_mifare_ultralight (FreefareTag tag)
is_mifare_ultralight(FreefareTag tag)
{
return tag->type == MIFARE_ULTRALIGHT;
}
bool
is_mifare_ultralightc (FreefareTag tag)
is_mifare_ultralightc(FreefareTag tag)
{
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.
*/
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;
uint8_t cmd_step1[2];
@ -378,10 +378,10 @@ is_mifare_ultralightc_on_reader (nfc_device *device, nfc_iso14443a_info nai)
.nmt = NMT_ISO14443A,
.nbr = NBR_106
};
nfc_initiator_select_passive_target (device, modulation, nai.abtUid, nai.szUidLen, &pnti);
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);
nfc_device_set_property_bool (device, NP_EASY_FRAMING, true);
nfc_initiator_deselect_target (device);
nfc_initiator_select_passive_target(device, modulation, nai.abtUid, nai.szUidLen, &pnti);
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);
nfc_device_set_property_bool(device, NP_EASY_FRAMING, true);
nfc_initiator_deselect_target(device);
return ret >= 0;
}

View file

@ -50,63 +50,63 @@
#define NTAG_ASSERT_VALID_PAGE(tag, page, mode_write) \
do { \
if (mode_write) { \
if (page<=0x02) \
{return errno = EINVAL, -1;} \
else if(NTAG_21x(tag)->subtype == NTAG_213&&page>0x2C) \
{return errno = EINVAL, -1;} \
else if(NTAG_21x(tag)->subtype == NTAG_215&&page>0x86) \
{return errno = EINVAL, -1;} \
else if(NTAG_21x(tag)->subtype == NTAG_216&&page>0xE6) \
{return errno = EINVAL, -1;} \
} else { \
if(NTAG_21x(tag)->subtype == NTAG_213&&page>0x2C) \
{return errno = EINVAL, -1;} \
else if(NTAG_21x(tag)->subtype == NTAG_215&&page>0x86) \
{return errno = EINVAL, -1;} \
else if(NTAG_21x(tag)->subtype == NTAG_216&&page>0xE6) \
{return errno = EINVAL, -1;} \
} \
if (mode_write) { \
if (page<=0x02) \
{return errno = EINVAL, -1;} \
else if(NTAG_21x(tag)->subtype == NTAG_213&&page>0x2C) \
{return errno = EINVAL, -1;} \
else if(NTAG_21x(tag)->subtype == NTAG_215&&page>0x86) \
{return errno = EINVAL, -1;} \
else if(NTAG_21x(tag)->subtype == NTAG_216&&page>0xE6) \
{return errno = EINVAL, -1;} \
} else { \
if(NTAG_21x(tag)->subtype == NTAG_213&&page>0x2C) \
{return errno = EINVAL, -1;} \
else if(NTAG_21x(tag)->subtype == NTAG_215&&page>0x86) \
{return errno = EINVAL, -1;} \
else if(NTAG_21x(tag)->subtype == NTAG_216&&page>0xE6) \
{return errno = EINVAL, -1;} \
} \
} while (0)
#define NTAG_TRANSCEIVE(tag, msg, res) \
do { \
errno = 0; \
DEBUG_XFER (msg, __##msg##_n, "===> "); \
int _res; \
if ((_res = nfc_initiator_transceive_bytes (tag->device, msg, __##msg##_n, res, __##res##_size, 0)) < 0) { \
return errno = EIO, -1; \
} \
__##res##_n = _res; \
DEBUG_XFER (res, __##res##_n, "<=== "); \
errno = 0; \
DEBUG_XFER (msg, __##msg##_n, "===> "); \
int _res; \
if ((_res = nfc_initiator_transceive_bytes (tag->device, msg, __##msg##_n, res, __##res##_size, 0)) < 0) { \
return errno = EIO, -1; \
} \
__##res##_n = _res; \
DEBUG_XFER (res, __##res##_n, "<=== "); \
} while (0)
#define NTAG_TRANSCEIVE_RAW(tag, msg, res) \
do { \
errno = 0; \
if (nfc_device_set_property_bool (tag->device, NP_EASY_FRAMING, false) < 0) { \
errno = EIO; \
return -1; \
} \
DEBUG_XFER (msg, __##msg##_n, "===> "); \
int _res; \
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); \
return errno = EIO, -1; \
} \
__##res##_n = _res; \
DEBUG_XFER (res, __##res##_n, "<=== "); \
if (nfc_device_set_property_bool (tag->device, NP_EASY_FRAMING, true) < 0) { \
errno = EIO; \
return -1; \
} \
errno = 0; \
if (nfc_device_set_property_bool (tag->device, NP_EASY_FRAMING, false) < 0) { \
errno = EIO; \
return -1; \
} \
DEBUG_XFER (msg, __##msg##_n, "===> "); \
int _res; \
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); \
return errno = EIO, -1; \
} \
__##res##_n = _res; \
DEBUG_XFER (res, __##res##_n, "<=== "); \
if (nfc_device_set_property_bool (tag->device, NP_EASY_FRAMING, true) < 0) { \
errno = EIO; \
return -1; \
} \
} while (0)
bool
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;
if ((tag = malloc (sizeof (struct ntag21x_tag)))) {
if ((tag = malloc(sizeof(struct ntag21x_tag)))) {
tag->type = NTAG_21x ;
tag->free_tag = ntag21x_tag_free;
tag->device = device;
@ -146,7 +146,7 @@ _ntag21x_tag_reuse(FreefareTag old_tag)
{
FreefareTag tag;
if ((tag = malloc (sizeof (struct ntag21x_tag)))) {
if ((tag = malloc(sizeof(struct ntag21x_tag)))) {
tag->type = NTAG_21x ;
tag->free_tag = ntag21x_tag_free;
tag->device = old_tag->device;
@ -168,25 +168,25 @@ _ntag21x_tag_reuse(FreefareTag old_tag)
FreefareTag
ntag21x_tag_new(nfc_device *device, nfc_target target)
{
return _ntag21x_tag_new (device, target);
return _ntag21x_tag_new(device, target);
}
FreefareTag
ntag21x_tag_reuse(FreefareTag tag)
{
return _ntag21x_tag_reuse (tag);
return _ntag21x_tag_reuse(tag);
}
/*
* Create new key for NTAG
*/
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;
if ((key = malloc (sizeof (struct ntag21x_key)))) {
memcpy(key->data,data,4);
memcpy(key->pack,pack,2);
if ((key = malloc(sizeof(struct ntag21x_key)))) {
memcpy(key->data, data, 4);
memcpy(key->pack, pack, 2);
}
return key;
}
@ -206,7 +206,7 @@ ntag21x_key_free(NTAG21xKey key)
void
ntag21x_tag_free(FreefareTag tag)
{
free (tag);
free(tag);
}
@ -226,14 +226,14 @@ ntag21x_tag_free(FreefareTag tag)
int
ntag21x_connect(FreefareTag tag)
{
ASSERT_INACTIVE (tag);
ASSERT_INACTIVE(tag);
nfc_target pnti;
nfc_modulation modulation = {
.nmt = NMT_ISO14443A,
.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;
} else {
@ -249,9 +249,9 @@ ntag21x_connect(FreefareTag tag)
int
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;
} else {
errno = EIO;
@ -266,16 +266,16 @@ ntag21x_disconnect(FreefareTag tag)
int
ntag21x_get_info(FreefareTag tag)
{
ASSERT_ACTIVE (tag);
ASSERT_ACTIVE(tag);
// Init buffers
BUFFER_INIT (cmd, 1);
BUFFER_INIT (res,8);
BUFFER_INIT(cmd, 1);
BUFFER_INIT(res, 8);
// 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)->product_type = res[2];
@ -286,7 +286,7 @@ ntag21x_get_info(FreefareTag tag)
NTAG_21x(tag)->protocol_type = res[7];
// Set ntag subtype based on storage size
switch(NTAG_21x(tag)->storage_size) {
switch (NTAG_21x(tag)->storage_size) {
case 0x0f:
NTAG_21x(tag)->subtype = NTAG_213;
break;
@ -306,8 +306,7 @@ ntag21x_get_info(FreefareTag tag)
* Get subtype of tag
*/
enum ntag_tag_subtype
ntag21x_get_subtype(FreefareTag tag)
{
ntag21x_get_subtype(FreefareTag tag) {
return NTAG_21x(tag)->subtype;
}
@ -333,21 +332,21 @@ ntag21x_get_last_page(FreefareTag tag)
* Read signature
*/
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
BUFFER_INIT (cmd, 2);
BUFFER_INIT (res,32);
BUFFER_INIT(cmd, 2);
BUFFER_INIT(res, 32);
// Append get version command to buffer
BUFFER_APPEND (cmd, 0x3C);
BUFFER_APPEND (cmd, 0x00);
BUFFER_APPEND(cmd, 0x3C);
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;
}
@ -365,147 +364,147 @@ int
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
int res = ntag21x_write(tag,page,data);
int res = ntag21x_write(tag, page, data);
return res;
}
int
ntag21x_set_pack(FreefareTag tag, uint8_t data[2]) // Set pack
{
BUFFER_INIT(buff,4);
BUFFER_APPEND_BYTES(buff,data,2);
BUFFER_APPEND(buff,0x00);
BUFFER_APPEND(buff,0x00);
BUFFER_INIT(buff, 4);
BUFFER_APPEND_BYTES(buff, data, 2);
BUFFER_APPEND(buff, 0x00);
BUFFER_APPEND(buff, 0x00);
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;
}
int
ntag21x_set_key(FreefareTag tag,const NTAG21xKey key) // Set key
ntag21x_set_key(FreefareTag tag, const NTAG21xKey key) // Set key
{
int res;
// Set password
res = ntag21x_set_pwd(tag,key->data);
if(res < 0)
res = ntag21x_set_pwd(tag, key->data);
if (res < 0)
return res;
// Set pack
res = ntag21x_set_pack(tag,key->pack);
res = ntag21x_set_pack(tag, key->pack);
return res;
}
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 res;
res = ntag21x_read4(tag,page,cdata); // Read current configuration from tag
if(res < 0)
res = ntag21x_read4(tag, page, cdata); // Read current configuration from tag
if (res < 0)
return res;
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;
}
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 res;
res = ntag21x_read4(tag,page,cdata); // Read current configuration from tag
if(res < 0)
res = ntag21x_read4(tag, page, cdata); // Read current configuration from tag
if (res < 0)
return res;
*byte = cdata[3]; // Get AUTH0 byte in buffer
return res;
}
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 res;
res = ntag21x_read4(tag,page,cdata); // Read current configuration from tag
if(res < 0)
res = ntag21x_read4(tag, page, cdata); // Read current configuration from tag
if (res < 0)
return res;
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;
}
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 res;
res = ntag21x_read4(tag,page,cdata); // Read current configuration from tag
if(res < 0)
res = ntag21x_read4(tag, page, cdata); // Read current configuration from tag
if (res < 0)
return res;
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;
}
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
int res;
res = ntag21x_read4(tag,page,cdata); // Read current configuration from tag
if(res < 0)
res = ntag21x_read4(tag, page, cdata); // Read current configuration from tag
if (res < 0)
return res;
memcpy(byte,cdata,1); // Return 1 byte of page
memcpy(byte, cdata, 1); // Return 1 byte of page
return res;
}
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;
res = ntag21x_get_access(tag,buff);
if(res<0)
res = ntag21x_get_access(tag, buff);
if (res < 0)
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;
}
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
int res;
res = ntag21x_read4(tag,page,cdata); // Read current configuration from tag
if(res < 0)
res = ntag21x_read4(tag, page, cdata); // Read current configuration from tag
if (res < 0)
return res;
cdata[0]&=0x07; // Extract last 3 bits from access byte
memcpy(byte,cdata,1); // Return 1 byte of page
cdata[0] &= 0x07; // Extract last 3 bits from access byte
memcpy(byte, cdata, 1); // Return 1 byte of page
return res;
}
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;
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 res;
res = ntag21x_read4(tag,page,cdata); // Read current configuration from tag
if(res < 0)
res = ntag21x_read4(tag, page, cdata); // Read current configuration from tag
if (res < 0)
return res;
cdata[0] &= 0xf8; // Reset auth limit bits
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;
}
@ -513,21 +512,21 @@ ntag21x_set_authentication_limit(FreefareTag tag,uint8_t byte) // Set authentica
* Read 16 bytes from NTAG.
*/
int
ntag21x_read(FreefareTag tag, uint8_t page,uint8_t *data)
ntag21x_read(FreefareTag tag, uint8_t page, uint8_t *data)
{
ASSERT_ACTIVE (tag);
NTAG_ASSERT_VALID_PAGE (tag, page, false);
ASSERT_ACTIVE(tag);
NTAG_ASSERT_VALID_PAGE(tag, page, false);
// Init buffers
BUFFER_INIT (cmd, 2);
BUFFER_INIT (res,16);
BUFFER_INIT(cmd, 2);
BUFFER_INIT(res, 16);
// Append read 16B command to buffer
BUFFER_APPEND (cmd, 0x30);
BUFFER_APPEND (cmd, page);
BUFFER_APPEND(cmd, 0x30);
BUFFER_APPEND(cmd, page);
NTAG_TRANSCEIVE (tag, cmd, res); // Send & receive to & from tag
memcpy (data, res, 16); // Copy first 4 bytes (selected page) to data output
NTAG_TRANSCEIVE(tag, cmd, res); // Send & receive to & from tag
memcpy(data, res, 16); // Copy first 4 bytes (selected page) to data output
return 0;
}
@ -535,11 +534,11 @@ ntag21x_read(FreefareTag tag, uint8_t page,uint8_t *data)
* Read 4 bytes from NTAG
*/
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);
int re = ntag21x_read(tag,page,res);
memcpy(data,res,4);
BUFFER_INIT(res, 16);
int re = ntag21x_read(tag, page, res);
memcpy(data, res, 4);
return re;
}
@ -547,33 +546,33 @@ ntag21x_read4(FreefareTag tag,uint8_t page,uint8_t *data)
* Read pages from [start,end] from NTAG
*/
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);
NTAG_ASSERT_VALID_PAGE (tag, start_page, false);
NTAG_ASSERT_VALID_PAGE (tag, end_page, false);
ASSERT_ACTIVE(tag);
NTAG_ASSERT_VALID_PAGE(tag, start_page, false);
NTAG_ASSERT_VALID_PAGE(tag, end_page, false);
// Init buffers
BUFFER_INIT (cmd, 3);
BUFFER_INIT (res,4*(end_page - start_page + 1));
BUFFER_INIT(cmd, 3);
BUFFER_INIT(res, 4 * (end_page - start_page + 1));
// Append read 16B command to buffer
BUFFER_APPEND (cmd, 0x3A);
BUFFER_APPEND (cmd, start_page);
BUFFER_APPEND (cmd, end_page);
BUFFER_APPEND(cmd, 0x3A);
BUFFER_APPEND(cmd, start_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;
}
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);
int re = ntag21x_fast_read(tag,page,page,res);
memcpy(data,res,4);
BUFFER_INIT(res, 4);
int re = ntag21x_fast_read(tag, page, page, res);
memcpy(data, res, 4);
return re;
}
@ -583,19 +582,19 @@ ntag21x_fast_read4(FreefareTag tag,uint8_t page,uint8_t *data)
int
ntag21x_read_cnt(FreefareTag tag, uint8_t *data)
{
ASSERT_ACTIVE (tag);
ASSERT_ACTIVE(tag);
// Init buffers
BUFFER_INIT (cmd, 2);
BUFFER_INIT (res,3);
BUFFER_INIT(cmd, 2);
BUFFER_INIT(res, 3);
// Append read cnt command to buffer
BUFFER_APPEND (cmd, 0x39);
BUFFER_APPEND (cmd, 0x02);
BUFFER_APPEND(cmd, 0x39);
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;
}
@ -605,19 +604,19 @@ ntag21x_read_cnt(FreefareTag tag, uint8_t *data)
int
ntag21x_write(FreefareTag tag, uint8_t page, uint8_t data[4])
{
ASSERT_ACTIVE (tag);
NTAG_ASSERT_VALID_PAGE (tag, page, true);
ASSERT_ACTIVE(tag);
NTAG_ASSERT_VALID_PAGE(tag, page, true);
// Init buffera
BUFFER_INIT (cmd, 6);
BUFFER_INIT (res, 1);
BUFFER_INIT(cmd, 6);
BUFFER_INIT(res, 1);
// Append write 4B command to buffer
BUFFER_APPEND (cmd, 0xA2);
BUFFER_APPEND (cmd, page);
BUFFER_APPEND_BYTES (cmd, data, 4); // Copy data to last 4 bytes of buffer
BUFFER_APPEND(cmd, 0xA2);
BUFFER_APPEND(cmd, page);
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;
}
@ -625,22 +624,22 @@ ntag21x_write(FreefareTag tag, uint8_t page, uint8_t data[4])
int
ntag21x_compatibility_write(FreefareTag tag, uint8_t page, uint8_t data[4])
{
ASSERT_ACTIVE (tag);
NTAG_ASSERT_VALID_PAGE (tag, page, true);
ASSERT_ACTIVE(tag);
NTAG_ASSERT_VALID_PAGE(tag, page, true);
// Init buffera
BUFFER_INIT (cmd, 18);
BUFFER_INIT (res, 1);
BUFFER_INIT(cmd, 18);
BUFFER_INIT(res, 1);
// Append write 4B command to buffer
BUFFER_APPEND (cmd, 0xA0);
BUFFER_APPEND (cmd, page);
BUFFER_APPEND_BYTES (cmd, data, 4); // Copy data to last 4 bytes of buffer
for (int i=0;i<12;i++) {
BUFFER_APPEND(cmd,0x00);
BUFFER_APPEND(cmd, 0xA0);
BUFFER_APPEND(cmd, page);
BUFFER_APPEND_BYTES(cmd, data, 4); // Copy data to last 4 bytes of buffer
for (int i = 0; i < 12; i++) {
BUFFER_APPEND(cmd, 0x00);
}
NTAG_TRANSCEIVE (tag, cmd, res);
NTAG_TRANSCEIVE(tag, cmd, res);
return 0;
}
@ -650,22 +649,22 @@ ntag21x_compatibility_write(FreefareTag tag, uint8_t page, uint8_t data[4])
int
ntag21x_authenticate(FreefareTag tag, const NTAG21xKey key)
{
ASSERT_ACTIVE (tag);
BUFFER_INIT (cmd1, 5);
BUFFER_INIT (res, 2);
BUFFER_APPEND (cmd1, 0x1B);
BUFFER_APPEND_BYTES (cmd1, key->data,4); // Append key to command
ASSERT_ACTIVE(tag);
BUFFER_INIT(cmd1, 5);
BUFFER_INIT(res, 2);
BUFFER_APPEND(cmd1, 0x1B);
BUFFER_APPEND_BYTES(cmd1, key->data, 4); // Append key to command
NTAG_TRANSCEIVE_RAW(tag, cmd1, res);
//Check if authenticated (PACK must be as expected)
bool flag_auth = true;
for(int i=0;i<2;i++)
for (int i = 0; i < 2; i++)
if (res[i] != key->pack[i]) {
flag_auth = false;
break;
}
if(!flag_auth)
if (!flag_auth)
return -1;
// XXX Should we store the state "authenticated" in the tag struct??
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_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_initiator_deselect_target(device);
return ret >= 0;

View file

@ -1,11 +1,11 @@
/*-
* Copyright (C) 2010, Romain Tartiere, Romuald Conty.
*
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
@ -57,9 +57,9 @@
#define TLV_TERMINATOR 0xFE
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);
size_t tlv_sequence_length (uint8_t *stream);
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);
size_t tlv_sequence_length(uint8_t *stream);
/*
* TLV (Type Length Value) Manipulation Functions.
@ -69,7 +69,7 @@ size_t tlv_sequence_length (uint8_t *stream);
* Encode data stream into TLV.
*/
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;
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 */
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 */
res[n++] = type;
if (isize > 254) {
res[n++] = 0xff;
uint16_t size_be = htobe16 (isize);
memcpy (res + n, &size_be, sizeof (uint16_t));
uint16_t size_be = htobe16(isize);
memcpy(res + n, &size_be, sizeof(uint16_t));
n += 2;
} else {
res[n++] = (uint8_t)isize;
}
memcpy (res + n, istream, isize);
memcpy(res + n, istream, isize);
n += isize;
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.
*/
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 fvs = 0;
@ -117,14 +117,14 @@ tlv_decode (const uint8_t *istream, uint8_t *type, uint16_t *size)
if (type)
*type = istream[0];
tlv_record_length (istream, &fls, &fvs);
tlv_record_length(istream, &fls, &fvs);
if (size) {
*size = fvs;
}
if ((res = malloc (fvs))) {
memcpy (res, istream + 1 + fls, fvs);
if ((res = malloc(fvs))) {
memcpy(res, istream + 1 + fls, fvs);
}
return res;
}
@ -133,7 +133,7 @@ tlv_decode (const uint8_t *istream, uint8_t *type, uint16_t *size)
* Length of a TLV field
*/
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 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.
if (stream[1] == 0xff) {
uint16_t be_size;
memcpy (&be_size, stream + 2, sizeof (uint16_t));
memcpy(&be_size, stream + 2, sizeof(uint16_t));
fls = 3;
fvs = be16toh(be_size);
} else {
@ -176,11 +176,11 @@ tlv_record_length (const uint8_t *stream, size_t *field_length_size, size_t *fie
* Fourth call NULL
*/
uint8_t *
tlv_next (uint8_t *stream)
tlv_next(uint8_t *stream)
{
uint8_t *res = NULL;
if (stream[0] != TLV_TERMINATOR)
res = stream + tlv_record_length (stream, NULL, NULL);
res = stream + tlv_record_length(stream, NULL, NULL);
return res;
}
@ -189,13 +189,13 @@ tlv_next (uint8_t *stream)
* Full-length of all TLV fields.
*/
size_t
tlv_sequence_length (uint8_t *stream)
tlv_sequence_length(uint8_t *stream)
{
size_t res = 0;
do {
res += tlv_record_length (stream, NULL, NULL);
} while ((stream = tlv_next (stream)));
res += tlv_record_length(stream, NULL, NULL);
} while ((stream = tlv_next(stream)));
return res;
}
@ -205,14 +205,14 @@ tlv_sequence_length (uint8_t *stream)
* Append two TLV. Acts like realloc(3).
*/
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 b_size = tlv_sequence_length (b);
size_t a_size = tlv_sequence_length(a);
size_t b_size = tlv_sequence_length(b);
size_t new_size = a_size + b_size - 1;
if ((a = realloc (a, new_size))) {
memcpy (a + a_size - 1, b, b_size);
if ((a = realloc(a, new_size))) {
memcpy(a + a_size - 1, b, b_size);
}
return a;

View file

@ -1,11 +1,11 @@
/*-
* Copyright (C) 2010, Romain Tartiere.
*
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
@ -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_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,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
const uint8_t key_data_aes_version = 0x42;
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 */
uint8_t 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()"));
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()"));
MifareDESFireKey key;
switch (key_version) {
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;
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;
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;
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;
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;
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 */
switch (key_version) {
case 0x00:
case 0xAA:
case 0xC7:
res = mifare_desfire_authenticate (tag, key_no, key);
res = mifare_desfire_authenticate(tag, key_no, key);
break;
case 0x55:
res = mifare_desfire_authenticate_iso (tag, key_no, key);
res = mifare_desfire_authenticate_iso(tag, key_no, key);
break;
case 0x42:
res = mifare_desfire_authenticate_aes (tag, key_no, key);
res = mifare_desfire_authenticate_aes(tag, key_no, key);
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

@ -1,11 +1,11 @@
/*-
* Copyright (C) 2010, Romain Tartiere.
*
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
@ -25,6 +25,6 @@ extern uint8_t key_data_aes[16];
extern uint8_t key_data_3k3des[24];
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

View file

@ -1,11 +1,11 @@
/*-
* Copyright (C) 2015, Romain Tartiere
*
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
@ -26,52 +26,52 @@ static FreefareTag *tags = NULL;
FreefareTag tag = NULL;
void
cut_setup (void)
cut_setup(void)
{
int res;
nfc_connstring devices[8];
size_t device_count;
nfc_init (&context);
cut_assert_not_null (context, cut_message ("Unable to init libnfc (malloc)"));
nfc_init(&context);
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)
cut_omit ("No device found");
cut_omit("No device found");
for (size_t i = 0; i < device_count; i++) {
device = nfc_open (context, devices[i]);
if (!device)
cut_omit ("nfc_open() failed.");
device = nfc_open(context, devices[i]);
if (!device)
cut_omit("nfc_open() failed.");
tags = freefare_get_tags (device);
cut_assert_not_null (tags, cut_message ("freefare_get_tags() failed"));
tags = freefare_get_tags(device);
cut_assert_not_null(tags, cut_message("freefare_get_tags() failed"));
tag = NULL;
for (int i=0; tags[i]; i++) {
if (freefare_get_tag_type(tags[i]) == FELICA) {
tag = tags[i];
return;
}
}
nfc_close (device);
device = NULL;
freefare_free_tags (tags);
tags = NULL;
tag = NULL;
for (int i = 0; tags[i]; i++) {
if (freefare_get_tag_type(tags[i]) == FELICA) {
tag = tags[i];
return;
}
}
nfc_close(device);
device = NULL;
freefare_free_tags(tags);
tags = NULL;
}
cut_omit ("No FeliCa tag on NFC device");
cut_omit("No FeliCa tag on NFC device");
}
void
cut_teardown (void)
cut_teardown(void)
{
if (tags) {
freefare_free_tags (tags);
tags = NULL;
freefare_free_tags(tags);
tags = NULL;
}
if (device)
nfc_close (device);
nfc_close(device);
nfc_exit (context);
nfc_exit(context);
}

View file

@ -1,11 +1,11 @@
/*-
* Copyright (C) 2015, Romain Tartiere.
*
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for

View file

@ -1,12 +1,12 @@
/*-
* Copyright (C) 2010, Romain Tartiere
* Copyright (C) 2013, Romuald Conty
*
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
@ -27,59 +27,59 @@ static FreefareTag *tags = NULL;
FreefareTag tag = NULL;
void
cut_setup (void)
cut_setup(void)
{
int res;
nfc_connstring devices[8];
size_t device_count;
nfc_init (&context);
cut_assert_not_null (context, cut_message ("Unable to init libnfc (malloc)"));
nfc_init(&context);
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)
cut_omit ("No device found");
cut_omit("No device found");
for (size_t i = 0; i < device_count; i++) {
device = nfc_open (context, devices[i]);
if (!device)
cut_omit ("nfc_open() failed.");
device = nfc_open(context, devices[i]);
if (!device)
cut_omit("nfc_open() failed.");
tags = freefare_get_tags (device);
cut_assert_not_null (tags, cut_message ("freefare_get_tags() failed"));
tags = freefare_get_tags(device);
cut_assert_not_null(tags, cut_message("freefare_get_tags() failed"));
tag = NULL;
for (int i=0; tags[i]; i++) {
if ((freefare_get_tag_type(tags[i]) == MIFARE_CLASSIC_1K) ||
(freefare_get_tag_type(tags[i]) == MIFARE_CLASSIC_4K)) {
tag = tags[i];
res = mifare_classic_connect (tag);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_connect() failed"));
return;
}
}
nfc_close (device);
device = NULL;
freefare_free_tags (tags);
tags = NULL;
tag = NULL;
for (int i = 0; tags[i]; i++) {
if ((freefare_get_tag_type(tags[i]) == MIFARE_CLASSIC_1K) ||
(freefare_get_tag_type(tags[i]) == MIFARE_CLASSIC_4K)) {
tag = tags[i];
res = mifare_classic_connect(tag);
cut_assert_equal_int(0, res, cut_message("mifare_classic_connect() failed"));
return;
}
}
nfc_close(device);
device = NULL;
freefare_free_tags(tags);
tags = NULL;
}
cut_omit ("No MIFARE Classic tag on NFC device");
cut_omit("No MIFARE Classic tag on NFC device");
}
void
cut_teardown (void)
cut_teardown(void)
{
if (tag)
mifare_classic_disconnect (tag);
mifare_classic_disconnect(tag);
if (tags) {
freefare_free_tags (tags);
tags = NULL;
freefare_free_tags(tags);
tags = NULL;
}
if (device)
nfc_close (device);
nfc_close(device);
nfc_exit (context);
nfc_exit(context);
}

View file

@ -1,11 +1,11 @@
/*-
* Copyright (C) 2010, Romain Tartiere, Romuald Conty.
*
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for

View file

@ -1,12 +1,12 @@
/*-
* Copyright (C) 2010, Romain Tartiere
* Copyright (C) 2013, Romuald Conty
*
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
@ -27,73 +27,73 @@ static FreefareTag *tags = NULL;
FreefareTag tag = NULL;
void
cut_setup (void)
cut_setup(void)
{
int res;
nfc_connstring devices[8];
size_t device_count;
nfc_init (&context);
cut_assert_not_null (context, cut_message ("Unable to init libnfc (malloc)"));
nfc_init(&context);
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)
cut_omit ("No device found");
cut_omit("No device found");
for (size_t i = 0; i < device_count; i++) {
device = nfc_open (context, devices[i]);
if (!device)
cut_omit ("nfc_open() failed.");
device = nfc_open(context, devices[i]);
if (!device)
cut_omit("nfc_open() failed.");
tags = freefare_get_tags (device);
cut_assert_not_null (tags, cut_message ("freefare_get_tags() failed"));
tags = freefare_get_tags(device);
cut_assert_not_null(tags, cut_message("freefare_get_tags() failed"));
tag = NULL;
for (int i=0; tags[i]; i++) {
if (freefare_get_tag_type(tags[i]) == MIFARE_DESFIRE) {
tag = tags[i];
res = mifare_desfire_connect (tag);
cut_assert_equal_int (0, res, cut_message ("mifare_desfire_connect() failed"));
tag = NULL;
for (int i = 0; tags[i]; i++) {
if (freefare_get_tag_type(tags[i]) == MIFARE_DESFIRE) {
tag = tags[i];
res = mifare_desfire_connect(tag);
cut_assert_equal_int(0, res, cut_message("mifare_desfire_connect() failed"));
struct mifare_desfire_version_info version_info;
res = mifare_desfire_get_version (tag, &version_info);
cut_assert_equal_int (0, res, cut_message ("mifare_desfire_get_version"));
struct mifare_desfire_version_info version_info;
res = mifare_desfire_get_version(tag, &version_info);
cut_assert_equal_int(0, res, cut_message("mifare_desfire_get_version"));
if (version_info.hardware.storage_size < 0x18) {
cut_omit ("DESFire EV1 tests require at least a 4K card");
}
if (version_info.hardware.storage_size < 0x18) {
cut_omit("DESFire EV1 tests require at least a 4K card");
}
if ((version_info.hardware.version_major >= 1) &&
(version_info.software.version_major >= 1)) {
return;
}
if ((version_info.hardware.version_major >= 1) &&
(version_info.software.version_major >= 1)) {
return;
}
mifare_desfire_disconnect (tag);
}
}
nfc_close (device);
device = NULL;
freefare_free_tags (tags);
tags = NULL;
mifare_desfire_disconnect(tag);
}
}
nfc_close(device);
device = NULL;
freefare_free_tags(tags);
tags = NULL;
}
cut_omit ("No MIFARE DESFire EV1 tag on NFC device");
cut_omit("No MIFARE DESFire EV1 tag on NFC device");
}
void
cut_teardown (void)
cut_teardown(void)
{
if (tag)
mifare_desfire_disconnect (tag);
mifare_desfire_disconnect(tag);
if (tags) {
freefare_free_tags (tags);
tags = NULL;
freefare_free_tags(tags);
tags = NULL;
}
if (device)
nfc_close (device);
nfc_close(device);
nfc_exit (context);
nfc_exit(context);
}

View file

@ -1,11 +1,11 @@
/*-
* Copyright (C) 2010, Romain Tartiere.
*
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for

View file

@ -1,12 +1,12 @@
/*-
* Copyright (C) 2010, Romain Tartiere
* Copyright (C) 2013, Romuald Conty
*
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
@ -27,68 +27,68 @@ static FreefareTag *tags = NULL;
FreefareTag tag = NULL;
void
cut_setup (void)
cut_setup(void)
{
int res;
nfc_connstring devices[8];
size_t device_count;
int res;
nfc_connstring devices[8];
size_t device_count;
nfc_init (&context);
cut_assert_not_null (context, cut_message ("Unable to init libnfc (malloc)"));
nfc_init(&context);
cut_assert_not_null(context, cut_message("Unable to init libnfc (malloc)"));
device_count = nfc_list_devices (context, devices, 8);
if (device_count <= 0)
cut_omit ("No device found");
device_count = nfc_list_devices(context, devices, 8);
if (device_count <= 0)
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]);
if (!device)
cut_omit ("nfc_open() failed.");
device = nfc_open(context, devices[i]);
if (!device)
cut_omit("nfc_open() failed.");
tags = freefare_get_tags (device);
cut_assert_not_null (tags, cut_message ("freefare_get_tags() failed"));
tags = freefare_get_tags(device);
cut_assert_not_null(tags, cut_message("freefare_get_tags() failed"));
tag = NULL;
for (int i=0; tags[i]; i++) {
if (freefare_get_tag_type(tags[i]) == MIFARE_DESFIRE) {
tag = tags[i];
res = mifare_desfire_connect (tag);
cut_assert_equal_int (0, res, cut_message ("mifare_desfire_connect() failed"));
tag = NULL;
for (int i = 0; tags[i]; i++) {
if (freefare_get_tag_type(tags[i]) == MIFARE_DESFIRE) {
tag = tags[i];
res = mifare_desfire_connect(tag);
cut_assert_equal_int(0, res, cut_message("mifare_desfire_connect() failed"));
struct mifare_desfire_version_info version_info;
res = mifare_desfire_get_version (tag, &version_info);
cut_assert_equal_int (0, res, cut_message ("mifare_desfire_get_version"));
struct mifare_desfire_version_info version_info;
res = mifare_desfire_get_version(tag, &version_info);
cut_assert_equal_int(0, res, cut_message("mifare_desfire_get_version"));
if (version_info.hardware.storage_size < 0x18) {
cut_omit ("DESFire tests require at least a 4K card");
}
if (version_info.hardware.storage_size < 0x18) {
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);
device = NULL;
freefare_free_tags (tags);
tags = NULL;
}
cut_omit ("No MIFARE DESFire tag on NFC device");
cut_omit("No MIFARE DESFire tag on NFC device");
}
void
cut_teardown (void)
cut_teardown(void)
{
if (tag)
mifare_desfire_disconnect (tag);
if (tag)
mifare_desfire_disconnect(tag);
if (tags) {
freefare_free_tags (tags);
tags = NULL;
}
if (tags) {
freefare_free_tags(tags);
tags = NULL;
}
if (device)
nfc_close (device);
if (device)
nfc_close(device);
nfc_exit (context);
nfc_exit(context);
}

View file

@ -1,11 +1,11 @@
/*-
* Copyright (C) 2010, Romain Tartiere.
*
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for

View file

@ -1,12 +1,12 @@
/*-
* Copyright (C) 2010, Romain Tartiere
* Copyright (C) 2013, Romuald Conty
*
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
@ -27,61 +27,61 @@ static FreefareTag *tags = NULL;
FreefareTag tag = NULL;
void
cut_setup (void)
cut_setup(void)
{
int res;
nfc_connstring devices[8];
size_t device_count;
nfc_init (&context);
cut_assert_not_null (context, cut_message ("Unable to init libnfc (malloc)"));
nfc_init(&context);
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)
cut_omit ("No device found");
cut_omit("No device found");
for (size_t i = 0; i < device_count; i++) {
device = nfc_open (context, devices[i]);
if (!device)
cut_omit ("nfc_open() failed.");
device = nfc_open(context, devices[i]);
if (!device)
cut_omit("nfc_open() failed.");
tags = freefare_get_tags (device);
cut_assert_not_null (tags, cut_message ("freefare_get_tags() failed"));
tags = freefare_get_tags(device);
cut_assert_not_null(tags, cut_message("freefare_get_tags() failed"));
tag = NULL;
for (int i=0; tags[i]; i++) {
if ((freefare_get_tag_type(tags[i]) == MIFARE_ULTRALIGHT) ||
(freefare_get_tag_type(tags[i]) == MIFARE_ULTRALIGHT_C)) {
tag = tags[i];
res = mifare_ultralight_connect (tag);
cut_assert_equal_int (0, res, cut_message ("mifare_ultralight_connect() failed"));
return;
}
}
nfc_close (device);
device = NULL;
freefare_free_tags (tags);
tags = NULL;
tag = NULL;
for (int i = 0; tags[i]; i++) {
if ((freefare_get_tag_type(tags[i]) == MIFARE_ULTRALIGHT) ||
(freefare_get_tag_type(tags[i]) == MIFARE_ULTRALIGHT_C)) {
tag = tags[i];
res = mifare_ultralight_connect(tag);
cut_assert_equal_int(0, res, cut_message("mifare_ultralight_connect() failed"));
return;
}
}
nfc_close(device);
device = NULL;
freefare_free_tags(tags);
tags = NULL;
}
cut_omit ("No MIFARE UltraLight tag on NFC device");
cut_omit("No MIFARE UltraLight tag on NFC device");
}
void
cut_teardown (void)
cut_teardown(void)
{
if (tag)
mifare_ultralight_disconnect (tag);
mifare_ultralight_disconnect(tag);
if (tags) {
freefare_free_tags (tags);
tags = NULL;
freefare_free_tags(tags);
tags = NULL;
}
if (device)
nfc_close (device);
nfc_close(device);
nfc_exit (context);
nfc_exit(context);
}

View file

@ -1,11 +1,11 @@
/*-
* Copyright (C) 2010, Romain Tartiere.
*
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for

View file

@ -5,12 +5,12 @@
#include "felica_fixture.h"
void
test_felica_read_without_encryption (void)
test_felica_read_without_encryption(void)
{
uint8_t buffer[64];
int res = felica_read (tag, FELICA_SC_RO, 0x00, buffer, 16);
cut_assert_equal_int (16, res);
int res = felica_read(tag, FELICA_SC_RO, 0x00, buffer, 16);
cut_assert_equal_int(16, res);
uint8_t blocks[] = {
0x02,
@ -18,12 +18,12 @@ test_felica_read_without_encryption (void)
0x04,
};
res = felica_read_ex (tag, FELICA_SC_RO, 3, blocks, buffer, 3 * 16);
cut_assert_equal_int (3 * 16, res);
res = felica_read_ex(tag, FELICA_SC_RO, 3, blocks, buffer, 3 * 16);
cut_assert_equal_int(3 * 16, res);
}
void
test_felica_write_without_encryption (void)
test_felica_write_without_encryption(void)
{
uint8_t buffer[16] = {
0x00, 0x01, 0x02, 0x03,
@ -32,7 +32,7 @@ test_felica_write_without_encryption (void)
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"
void
test_is_mifare_ultralight (void)
test_is_mifare_ultralight(void)
{
FreefareTag tag;
nfc_target target;
tag = mifare_ultralight_tag_new (NULL, target);
cut_assert_true (is_mifare_ultralight (tag));
mifare_ultralight_tag_free (tag);
tag = mifare_ultralight_tag_new(NULL, target);
cut_assert_true(is_mifare_ultralight(tag));
mifare_ultralight_tag_free(tag);
}
void
test_is_mifare_ultralightc (void)
test_is_mifare_ultralightc(void)
{
FreefareTag tag;
nfc_target target;
tag = mifare_ultralightc_tag_new (NULL, target);
cut_assert_true (is_mifare_ultralightc (tag));
mifare_ultralightc_tag_free (tag);
tag = mifare_ultralightc_tag_new(NULL, target);
cut_assert_true(is_mifare_ultralightc(tag));
mifare_ultralightc_tag_free(tag);
}

View file

@ -1,11 +1,11 @@
/*-
* Copyright (C) 2009, 2010, Romain Tartiere, Romuald Conty.
*
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
@ -21,54 +21,54 @@
#include "freefare_internal.h"
void
test_mad (void)
test_mad(void)
{
int res;
Mad mad = mad_new (1);
cut_assert_not_null (mad, cut_message ("Can create a new MAD"));
Mad mad = mad_new(1);
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"));
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(1, mad_get_version(mad), cut_message("Wrong default MAD version"));
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 (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);
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"));
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(13, mad_get_card_publisher_sector(mad), cut_message("Wrong publisher sector"));
res = mad_set_card_publisher_sector (mad, 0xff);
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"));
res = mad_set_card_publisher_sector(mad, 0xff);
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"));
MadAid aid = {
.function_cluster_code = 0,
.application_code = 0
};
res = mad_get_aid (mad, 3, &aid);
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.application_code, cut_message ("Invalid default value"));
res = mad_get_aid(mad, 3, &aid);
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.application_code, cut_message("Invalid default value"));
aid.function_cluster_code = 0xc0;
aid.application_code = 0x42;
res = mad_set_aid (mad, 3, aid);
cut_assert_equal_int (0, res, cut_message ("mad_set_aid() failed"));
res = mad_set_aid(mad, 3, aid);
cut_assert_equal_int(0, res, cut_message("mad_set_aid() failed"));
res = mad_get_aid (mad, 3, &aid);
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 (0x42, aid.application_code, cut_message ("Invalid value"));
res = mad_get_aid(mad, 3, &aid);
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(0x42, aid.application_code, cut_message("Invalid value"));
mad_free (mad);
mad_free(mad);
}
#define CRC_PRESET 0xc7
void
test_mad_crc8_basic (void)
test_mad_crc8_basic(void)
{
uint8_t crc;
const uint8_t crc_value = 0x42;
@ -81,14 +81,14 @@ test_mad_crc8_basic (void)
crc = CRC_PRESET;
nxp_crc(&crc, crc_value);
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.
*/
void
test_mad_crc8_doc_example (void)
test_mad_crc8_doc_example(void)
{
/* Preset */
uint8_t crc = CRC_PRESET;
@ -134,14 +134,14 @@ test_mad_crc8_doc_example (void)
/* 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.
*/
void
test_mad_crc8_real_example_1 (void)
test_mad_crc8_real_example_1(void)
{
/* Preset */
uint8_t crc = CRC_PRESET;
@ -187,14 +187,14 @@ test_mad_crc8_real_example_1 (void)
/* 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.
*/
void
test_mad_crc8_real_example_2 (void)
test_mad_crc8_real_example_2(void)
{
/* Preset */
uint8_t crc = CRC_PRESET;
@ -240,48 +240,48 @@ test_mad_crc8_real_example_2 (void)
/* 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
test_mad_sector_0x00_crc8 (void)
test_mad_sector_0x00_crc8(void)
{
int res;
Mad mad = mad_new (1);
cut_assert_not_null (mad, cut_message ("mad_new() failed"));
Mad mad = mad_new(1);
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 */
MadAid aid1 = { 0x01, 0x08 };
mad_set_aid (mad, 1, aid1);
mad_set_aid (mad, 2, aid1);
mad_set_aid (mad, 3, aid1);
mad_set_aid(mad, 1, aid1);
mad_set_aid(mad, 2, aid1);
mad_set_aid(mad, 3, aid1);
/* Block 2 */
MadAid empty_aid = { 0x00, 0x00 };
mad_set_aid (mad, 4, empty_aid);
mad_set_aid (mad, 5, empty_aid);
mad_set_aid (mad, 6, empty_aid);
mad_set_aid(mad, 4, empty_aid);
mad_set_aid(mad, 5, empty_aid);
mad_set_aid(mad, 6, empty_aid);
MadAid aid2 = { 0x04, 0x00 };
mad_set_aid (mad, 7, aid2);
mad_set_aid(mad, 7, aid2);
/* Block 3 */
MadAid aid3 = { 0x03, 0x10 };
mad_set_aid (mad, 8, aid3);
mad_set_aid (mad, 9, aid3);
mad_set_aid(mad, 8, aid3);
mad_set_aid(mad, 9, aid3);
MadAid aid4 = { 0x02, 0x10 };
mad_set_aid (mad, 10, aid4);
mad_set_aid (mad, 11, aid4);
mad_set_aid(mad, 10, aid4);
mad_set_aid(mad, 11, aid4);
mad_set_aid (mad, 12, empty_aid);
mad_set_aid (mad, 13, empty_aid);
mad_set_aid (mad, 14, empty_aid);
mad_set_aid(mad, 12, empty_aid);
mad_set_aid(mad, 13, empty_aid);
mad_set_aid(mad, 14, empty_aid);
MadAid aid5 = { 0x11, 0x30 };
mad_set_aid (mad, 15, aid5);
mad_set_aid(mad, 15, aid5);
res = sector_0x00_crc8 (mad);
cut_assert_equal_int(0x89, res, cut_message ("Sample CRC should match"));
res = sector_0x00_crc8(mad);
cut_assert_equal_int(0x89, res, cut_message("Sample CRC should match"));
mad_free (mad);
mad_free(mad);
}

View file

@ -1,11 +1,11 @@
/*-
* Copyright (C) 2010, Romain Tartiere, Romuald Conty.
*
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
@ -19,61 +19,61 @@
#include <freefare.h>
void
test_mifare_application (void)
test_mifare_application(void)
{
/* Card publisher part */
MadAid aid = { 0x22, 0x42 };
Mad mad = mad_new (2);
Mad mad = mad_new(2);
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);
cut_assert_not_null (s_alloc, cut_message ("mifare_application_alloc() failed"));
MifareClassicSectorNumber *s_alloc = mifare_application_alloc(mad, aid, 3 * 3 * 16);
cut_assert_not_null(s_alloc, cut_message("mifare_application_alloc() failed"));
MifareClassicSectorNumber *s_found = mifare_application_find (mad, aid);
cut_assert_not_null (s_found, cut_message ("mifare_application_alloc() failed"));
MifareClassicSectorNumber *s_found = mifare_application_find(mad, aid);
cut_assert_not_null(s_found, cut_message("mifare_application_alloc() failed"));
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_found[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"));
mifare_application_free (mad, aid);
mifare_application_free(mad, aid);
free (s_alloc);
free (s_found);
free(s_alloc);
free(s_found);
s_found = mifare_application_find (mad, aid);
cut_assert_null (s_found, cut_message ("mifare_application_free() failed"));
s_found = mifare_application_find(mad, aid);
cut_assert_null(s_found, cut_message("mifare_application_free() failed"));
s_alloc = mifare_application_alloc (mad, aid, 15*16 + 1*16 + 1);
cut_assert_not_null (s_alloc, cut_message ("mifare_application_alloc() failed"));
s_alloc = mifare_application_alloc(mad, aid, 15 * 16 + 1 * 16 + 1);
cut_assert_not_null(s_alloc, cut_message("mifare_application_alloc() failed"));
s_found = mifare_application_find (mad, aid);
cut_assert_not_null (s_found, cut_message ("mifare_application_alloc() failed"));
s_found = mifare_application_find(mad, aid);
cut_assert_not_null(s_found, cut_message("mifare_application_alloc() failed"));
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_found[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"));
mifare_application_free (mad, aid);
mifare_application_free(mad, aid);
free (s_alloc);
free (s_found);
free(s_alloc);
free(s_found);
s_found = mifare_application_find (mad, aid);
cut_assert_null (s_found, cut_message ("mifare_application_free() failed"));
s_found = mifare_application_find(mad, aid);
cut_assert_null(s_found, cut_message("mifare_application_free() failed"));
mad_free (mad);
mad_free(mad);
}

View file

@ -1,11 +1,11 @@
/*-
* Copyright (C) 2010, Romain Tartiere, Romuald Conty.
*
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
@ -25,86 +25,86 @@
#include "mifare_classic_fixture.h"
void
test_mifare_classic_authenticate (void)
test_mifare_classic_authenticate(void)
{
int res;
MifareClassicKey k = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
res = mifare_classic_authenticate (tag, 0x00, k, MFC_KEY_A);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_authenticate() failed"));
res = mifare_classic_authenticate(tag, 0x00, k, MFC_KEY_A);
cut_assert_equal_int(0, res, cut_message("mifare_classic_authenticate() failed"));
}
void
test_mifare_classic_get_data_block_permission (void)
test_mifare_classic_get_data_block_permission(void)
{
int res;
MifareClassicKey k = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
res = mifare_classic_authenticate (tag, 0x04, k, MFC_KEY_A);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_authenticate() failed"));
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 (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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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"));
}
void
test_mifare_classic_get_trailer_permission (void)
test_mifare_classic_get_trailer_permission(void)
{
int res;
MifareClassicKey k = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
res = mifare_classic_authenticate (tag, 0x07, k, MFC_KEY_A);
cut_assert_equal_int (res, 0, cut_message ("mifare_classic_authenticate() failed"));
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 (-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_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_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_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_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_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_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_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 (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 (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 (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 (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 (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 (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_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(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(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(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(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(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"));
}
void
test_mifare_classic_format_first_sector (void)
test_mifare_classic_format_first_sector(void)
{
int res;
MifareClassicKey k = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
res = mifare_classic_authenticate (tag, 0x00, k, MFC_KEY_A);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_authenticate() failed"));
res = mifare_classic_authenticate(tag, 0x00, k, MFC_KEY_A);
cut_assert_equal_int(0, res, cut_message("mifare_classic_authenticate() failed"));
MifareClassicBlock data = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
@ -112,54 +112,54 @@ test_mifare_classic_format_first_sector (void)
};
MifareClassicBlock empty;
memset (empty, '\x00', sizeof (empty));
memset(empty, '\x00', sizeof(empty));
MifareClassicBlock b0;
res = mifare_classic_read (tag, 0x00, &b0);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_read() failed"));
res = mifare_classic_read(tag, 0x00, &b0);
cut_assert_equal_int(0, res, cut_message("mifare_classic_read() failed"));
res = mifare_classic_write (tag, 0x00, data);
cut_assert_equal_int (-1, res, cut_message ("mifare_classic_write() succeeded"));
res = mifare_classic_write(tag, 0x00, data);
cut_assert_equal_int(-1, res, cut_message("mifare_classic_write() succeeded"));
res = mifare_classic_disconnect (tag);
res = mifare_classic_connect (tag);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_connect() failed"));
res = mifare_classic_authenticate (tag, 0x00, k, MFC_KEY_A);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_authenticate() failed"));
res = mifare_classic_disconnect(tag);
res = mifare_classic_connect(tag);
cut_assert_equal_int(0, res, cut_message("mifare_classic_connect() failed"));
res = mifare_classic_authenticate(tag, 0x00, k, MFC_KEY_A);
cut_assert_equal_int(0, res, cut_message("mifare_classic_authenticate() failed"));
res = mifare_classic_write (tag, 0x01, data);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_write() failed"));
res = mifare_classic_write (tag, 0x02, data);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_write() failed"));
res = mifare_classic_write(tag, 0x01, data);
cut_assert_equal_int(0, res, cut_message("mifare_classic_write() failed"));
res = mifare_classic_write(tag, 0x02, data);
cut_assert_equal_int(0, res, cut_message("mifare_classic_write() failed"));
res = mifare_classic_format_sector (tag, 0x00);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_format_sector() failed"));
res = mifare_classic_format_sector(tag, 0x00);
cut_assert_equal_int(0, res, cut_message("mifare_classic_format_sector() failed"));
res = mifare_classic_read (tag, 0x00, &data);
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)"));
res = mifare_classic_read(tag, 0x00, &data);
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)"));
res = mifare_classic_read (tag, 0x01, &data);
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)"));
res = mifare_classic_read(tag, 0x01, &data);
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)"));
res = mifare_classic_read (tag, 0x02, &data);
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)"));
res = mifare_classic_read(tag, 0x02, &data);
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)"));
res = mifare_classic_read (tag, 0x03, &data);
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"));
res = mifare_classic_read(tag, 0x03, &data);
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"));
}
void
test_mifare_classic_format (void)
test_mifare_classic_format(void)
{
int res;
MifareClassicKey k = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
res = mifare_classic_authenticate (tag, 0x3c, k, MFC_KEY_A);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_authenticate() failed"));
res = mifare_classic_authenticate(tag, 0x3c, k, MFC_KEY_A);
cut_assert_equal_int(0, res, cut_message("mifare_classic_authenticate() failed"));
MifareClassicBlock data = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
@ -167,140 +167,140 @@ test_mifare_classic_format (void)
};
MifareClassicBlock empty;
memset (empty, 0, sizeof (empty));
memset(empty, 0, sizeof(empty));
res = mifare_classic_write (tag, 0x3c, data);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_write() failed"));
res = mifare_classic_write (tag, 0x3d, data);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_write() failed"));
res = mifare_classic_write (tag, 0x3e, data);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_write() failed"));
res = mifare_classic_write(tag, 0x3c, data);
cut_assert_equal_int(0, res, cut_message("mifare_classic_write() failed"));
res = mifare_classic_write(tag, 0x3d, data);
cut_assert_equal_int(0, res, cut_message("mifare_classic_write() failed"));
res = mifare_classic_write(tag, 0x3e, data);
cut_assert_equal_int(0, res, cut_message("mifare_classic_write() failed"));
res = mifare_classic_format_sector (tag, mifare_classic_block_sector (0x3c));
cut_assert_equal_int (0, res, cut_message ("mifare_classic_format_sector() failed"));
res = mifare_classic_format_sector(tag, mifare_classic_block_sector(0x3c));
cut_assert_equal_int(0, res, cut_message("mifare_classic_format_sector() failed"));
res = mifare_classic_read (tag, 0x3c, &data);
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)"));
res = mifare_classic_read(tag, 0x3c, &data);
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)"));
res = mifare_classic_read (tag, 0x3d, &data);
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)"));
res = mifare_classic_read(tag, 0x3d, &data);
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)"));
res = mifare_classic_read (tag, 0x3e, &data);
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)"));
res = mifare_classic_read(tag, 0x3e, &data);
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)"));
res = mifare_classic_read (tag, 0x3f, &data);
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"));
res = mifare_classic_read(tag, 0x3f, &data);
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"));
}
void
test_mifare_classic_value_block_increment (void)
test_mifare_classic_value_block_increment(void)
{
int res;
MifareClassicBlockNumber block = 0x04;
MifareClassicKey k = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
res = mifare_classic_authenticate (tag, block, k, MFC_KEY_A);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_authenticate() failed"));
res = mifare_classic_authenticate(tag, block, k, MFC_KEY_A);
cut_assert_equal_int(0, res, cut_message("mifare_classic_authenticate() failed"));
res = mifare_classic_init_value (tag, block, 1000, 0x00);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_init_value() failed"));
res = mifare_classic_init_value(tag, block, 1000, 0x00);
cut_assert_equal_int(0, res, cut_message("mifare_classic_init_value() failed"));
/* Initialize value block */
int32_t value;
MifareClassicBlockNumber 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 (1000, value, cut_message ("Wrong value block value"));
cut_assert_equal_int (0x00, adr, cut_message ("Wrong value block address"));
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(1000, value, cut_message("Wrong value block value"));
cut_assert_equal_int(0x00, adr, cut_message("Wrong value block address"));
/* Increment by 1 */
res = mifare_classic_increment (tag, block, 1);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_increment() failed"));
res = mifare_classic_increment(tag, block, 1);
cut_assert_equal_int(0, res, cut_message("mifare_classic_increment() failed"));
res = mifare_classic_transfer (tag, block);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_transfer() failed"));
res = mifare_classic_transfer(tag, block);
cut_assert_equal_int(0, res, cut_message("mifare_classic_transfer() failed"));
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 (1001, value, cut_message ("Wrong value block value"));
cut_assert_equal_int (0x00, adr, cut_message ("Wrong value block address"));
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(1001, value, cut_message("Wrong value block value"));
cut_assert_equal_int(0x00, adr, cut_message("Wrong value block address"));
/* Increment by 10 */
res = mifare_classic_increment (tag, block, 10);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_increment() failed"));
res = mifare_classic_increment(tag, block, 10);
cut_assert_equal_int(0, res, cut_message("mifare_classic_increment() failed"));
res = mifare_classic_transfer (tag, block);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_transfer() failed"));
res = mifare_classic_transfer(tag, block);
cut_assert_equal_int(0, res, cut_message("mifare_classic_transfer() failed"));
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 (1011, value, cut_message ("Wrong value block value"));
cut_assert_equal_int (0x00, adr, cut_message ("Wrong value block address"));
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(1011, value, cut_message("Wrong value block value"));
cut_assert_equal_int(0x00, adr, cut_message("Wrong value block address"));
}
void
test_mifare_classic_value_block_decrement (void)
test_mifare_classic_value_block_decrement(void)
{
int res;
MifareClassicBlockNumber block = 0x04;
MifareClassicKey k = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
res = mifare_classic_authenticate (tag, block, k, MFC_KEY_A);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_authenticate() failed"));
res = mifare_classic_init_value (tag, block, 1000, 0x00);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_init_value() failed"));
res = mifare_classic_authenticate(tag, block, k, MFC_KEY_A);
cut_assert_equal_int(0, res, cut_message("mifare_classic_authenticate() failed"));
res = mifare_classic_init_value(tag, block, 1000, 0x00);
cut_assert_equal_int(0, res, cut_message("mifare_classic_init_value() failed"));
/* Initialize value block */
int32_t value;
MifareClassicBlockNumber 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 (1000, value, cut_message ("Wrong value block value"));
cut_assert_equal_int (0x00, adr, cut_message ("Wrong value block address"));
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(1000, value, cut_message("Wrong value block value"));
cut_assert_equal_int(0x00, adr, cut_message("Wrong value block address"));
/* Decrement */
res = mifare_classic_decrement (tag, block, 1);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_decrement() failed"));
res = mifare_classic_decrement(tag, block, 1);
cut_assert_equal_int(0, res, cut_message("mifare_classic_decrement() failed"));
res = mifare_classic_transfer (tag, block);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_transfer() failed"));
res = mifare_classic_transfer(tag, block);
cut_assert_equal_int(0, res, cut_message("mifare_classic_transfer() failed"));
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 (999, value, cut_message ("Wrong value block value"));
cut_assert_equal_int (0x00, adr, cut_message ("Wrong value block address"));
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(999, value, cut_message("Wrong value block value"));
cut_assert_equal_int(0x00, adr, cut_message("Wrong value block address"));
res = mifare_classic_decrement (tag, block, 1000);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_decrement() failed"));
res = mifare_classic_decrement(tag, block, 1000);
cut_assert_equal_int(0, res, cut_message("mifare_classic_decrement() failed"));
res = mifare_classic_transfer (tag, block);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_transfer() failed"));
res = mifare_classic_transfer(tag, block);
cut_assert_equal_int(0, res, cut_message("mifare_classic_transfer() failed"));
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 (-1, value, cut_message ("Wrong value block value"));
cut_assert_equal_int (0x00, adr, cut_message ("Wrong value block address"));
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(-1, value, cut_message("Wrong value block value"));
cut_assert_equal_int(0x00, adr, cut_message("Wrong value block address"));
}
void
test_mifare_classic_value_block_restore (void)
test_mifare_classic_value_block_restore(void)
{
int res;
MifareClassicBlockNumber block = 0x04;
MifareClassicKey k = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
res = mifare_classic_authenticate (tag, block, k, MFC_KEY_A);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_authenticate() failed"));
res = mifare_classic_authenticate(tag, block, k, MFC_KEY_A);
cut_assert_equal_int(0, res, cut_message("mifare_classic_authenticate() failed"));
/* Restore */
@ -326,49 +326,49 @@ test_mifare_classic_value_block_restore (void)
0xff
};
res = mifare_classic_write (tag, block, sample);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_write() failed"));
res = mifare_classic_write(tag, block, sample);
cut_assert_equal_int(0, res, cut_message("mifare_classic_write() failed"));
res = mifare_classic_read (tag, block, &data);
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"));
res = mifare_classic_read(tag, block, &data);
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"));
res = mifare_classic_write (tag, block+1, nul);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_write() failed"));
res = mifare_classic_write(tag, block + 1, nul);
cut_assert_equal_int(0, res, cut_message("mifare_classic_write() failed"));
res = mifare_classic_read (tag, block+1, &data);
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"));
res = mifare_classic_read(tag, block + 1, &data);
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"));
res = mifare_classic_restore (tag, block);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_restore() failed"));
res = mifare_classic_restore(tag, block);
cut_assert_equal_int(0, res, cut_message("mifare_classic_restore() failed"));
res = mifare_classic_transfer (tag, block+1);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_transfer() failed"));
res = mifare_classic_transfer(tag, block + 1);
cut_assert_equal_int(0, res, cut_message("mifare_classic_transfer() failed"));
res = mifare_classic_read (tag, block+1, &data);
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"));
res = mifare_classic_read(tag, block + 1, &data);
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"));
}
void
test_mifare_classic_get_uid (void)
test_mifare_classic_get_uid(void)
{
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 (((strlen (uid) == 8)||(strlen (uid) == 14)), cut_message ("Wrong UID length"));
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"));
free (uid);
free(uid);
}
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

@ -1,11 +1,11 @@
/*-
* Copyright (C) 2010, Romain Tartiere, Romuald Conty.
*
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
@ -20,15 +20,15 @@
#include <freefare.h>
void
test_mifare_classic_create_trailer_block (void)
test_mifare_classic_create_trailer_block(void)
{
MifareClassicBlock data;
MifareClassicKey key_a = { 0xff, 0xff, 0xff, 0xff, 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

@ -1,11 +1,11 @@
/*-
* Copyright (C) 2010, Romain Tartiere.
*
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
@ -22,11 +22,11 @@
#include "mifare_classic_fixture.h"
void
test_mifare_classic_mad (void)
test_mifare_classic_mad(void)
{
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_10 = { 0x1a, 0x98, 0x2c, 0x7e, 0x45 ,0x9a };
MifareClassicKey key_b_sector_10 = { 0x1a, 0x98, 0x2c, 0x7e, 0x45, 0x9a };
MifareClassicBlock tb;
Mad mad;
int res;
@ -37,21 +37,21 @@ test_mifare_classic_mad (void)
* |_| |_/_/ \_\___/ \_/|_|
*/
mad = mad_new (1);
cut_assert_not_null (mad, cut_message ("mad_new() failed"));
mad = mad_new(1);
cut_assert_not_null(mad, cut_message("mad_new() failed"));
// Prepare sector 0x00 for writing a MAD.
res = mifare_classic_authenticate (tag, 0x00, key_a_transport, MFC_KEY_A);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_authenticate() failed"));
res = mifare_classic_authenticate(tag, 0x00, key_a_transport, MFC_KEY_A);
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);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_write() failed"));
res = mifare_classic_write(tag, 0x03, tb);
cut_assert_equal_int(0, res, cut_message("mifare_classic_write() failed"));
// Write the empty MAD
res = mad_write (tag, mad, key_b_sector_00, NULL);
cut_assert_equal_int (0, res, cut_message ("mad_write() failed"));
res = mad_write(tag, mad, key_b_sector_00, NULL);
cut_assert_equal_int(0, res, cut_message("mad_write() failed"));
// Check the empty MAD
@ -65,27 +65,27 @@ test_mifare_classic_mad (void)
};
MifareClassicBlock data;
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"));
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"));
res = mifare_classic_read (tag, 0x01, &data);
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"));
res = mifare_classic_read(tag, 0x01, &data);
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"));
res = mifare_classic_read (tag, 0x02, &data);
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"));
res = mifare_classic_read(tag, 0x02, &data);
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"));
Mad mad2 = mad_read (tag);
cut_assert_not_null (mad2, cut_message ("mad_read() failed"));
cut_assert_equal_memory (mad, sizeof (mad), mad2, sizeof (mad2), cut_message ("Wrong MAD"));
Mad mad2 = mad_read(tag);
cut_assert_not_null(mad2, cut_message("mad_read() failed"));
cut_assert_equal_memory(mad, sizeof(mad), mad2, sizeof(mad2), cut_message("Wrong MAD"));
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 = {
.function_cluster_code = 0x01,
@ -93,78 +93,78 @@ test_mifare_classic_mad (void)
};
// Write some data in the application
MifareClassicSectorNumber *sectors = mifare_application_alloc (mad, aid, sizeof (application_data));
cut_assert_not_null (sectors, cut_message ("mifare_application_alloc() failed"));
free (sectors);
MifareClassicSectorNumber *sectors = mifare_application_alloc(mad, aid, sizeof(application_data));
cut_assert_not_null(sectors, cut_message("mifare_application_alloc() failed"));
free(sectors);
res = mad_write (tag, mad, key_b_sector_00, NULL);
cut_assert_equal_int (0, res, cut_message ("mad_write() failed"));
res = mad_write(tag, mad, key_b_sector_00, NULL);
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);
cut_assert_equal_int (sizeof (application_data), s, cut_message ("mifare_application_write() failed"));
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"));
char read_buf[500];
// Read it again
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_memory (application_data, sizeof (application_data), read_buf, s, cut_message ("Wrong application data"));
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_memory(application_data, sizeof(application_data), read_buf, s, cut_message("Wrong application data"));
mad_free (mad);
mad_free (mad2);
mad_free(mad);
mad_free(mad2);
// Revert to the transport configuration
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"));
res = mifare_classic_format_sector (tag, 0x00);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_format_sector() failed"));
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"));
res = mifare_classic_format_sector(tag, 0x00);
cut_assert_equal_int(0, res, cut_message("mifare_classic_format_sector() failed"));
/* __ __ _ ___ ___
* | \/ | /_\ | \__ _|_ )
* | |\/| |/ _ \| |) \ V // /
* |_| |_/_/ \_\___/ \_//___|
*/
if (freefare_get_tag_type (tag) != MIFARE_CLASSIC_4K) {
cut_omit ("MADv2 requires a MIFARE Classic 4K to be tested");
if (freefare_get_tag_type(tag) != MIFARE_CLASSIC_4K) {
cut_omit("MADv2 requires a MIFARE Classic 4K to be tested");
}
mad = mad_new (2);
cut_assert_not_null (mad, cut_message ("mad_new() failed"));
mad = mad_new(2);
cut_assert_not_null(mad, cut_message("mad_new() failed"));
// Prepare sector 0x00 for writing a MAD.
res = mifare_classic_authenticate (tag, 0x00, key_a_transport, MFC_KEY_A);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_authenticate() failed"));
res = mifare_classic_authenticate(tag, 0x00, key_a_transport, MFC_KEY_A);
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);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_write() failed"));
res = mifare_classic_write(tag, 0x03, tb);
cut_assert_equal_int(0, res, cut_message("mifare_classic_write() failed"));
// Prepare sector 0x10 for writing a MAD.
res = mifare_classic_authenticate (tag, 0x40, key_a_transport, MFC_KEY_A);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_authenticate() failed"));
res = mifare_classic_authenticate(tag, 0x40, key_a_transport, MFC_KEY_A);
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);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_write() failed"));
res = mifare_classic_write(tag, 0x43, tb);
cut_assert_equal_int(0, res, cut_message("mifare_classic_write() failed"));
// Write the empty MAD
res = mad_write (tag, mad, key_b_sector_00, key_b_sector_10);
cut_assert_equal_int (0, res, cut_message ("mad_write() failed"));
res = mad_write(tag, mad, key_b_sector_00, key_b_sector_10);
cut_assert_equal_int(0, res, cut_message("mad_write() failed"));
// Check the empty MAD
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"));
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"));
res = mifare_classic_read (tag, 0x01, &data);
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"));
res = mifare_classic_read(tag, 0x01, &data);
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"));
res = mifare_classic_read (tag, 0x02, &data);
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"));
res = mifare_classic_read(tag, 0x02, &data);
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"));
MifareClassicBlock ref_40 = {
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
};
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"));
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"));
res = mifare_classic_read (tag, 0x40, &data);
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"));
res = mifare_classic_read(tag, 0x40, &data);
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"));
res = mifare_classic_read (tag, 0x41, &data);
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"));
res = mifare_classic_read(tag, 0x41, &data);
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"));
res = mifare_classic_read (tag, 0x42, &data);
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"));
res = mifare_classic_read(tag, 0x42, &data);
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"));
mad2 = mad_read (tag);
cut_assert_not_null (mad2, cut_message ("mad_read() failed"));
cut_assert_equal_memory (mad, sizeof (mad), mad2, sizeof (mad2), cut_message ("Wrong MAD"));
mad2 = mad_read(tag);
cut_assert_not_null(mad2, cut_message("mad_read() failed"));
cut_assert_equal_memory(mad, sizeof(mad), mad2, sizeof(mad2), cut_message("Wrong MAD"));
// Write some data in the application
sectors = mifare_application_alloc (mad, aid, sizeof (application_data));
cut_assert_not_null (sectors, cut_message ("mifare_application_alloc() failed"));
free (sectors);
sectors = mifare_application_alloc(mad, aid, sizeof(application_data));
cut_assert_not_null(sectors, cut_message("mifare_application_alloc() failed"));
free(sectors);
res = mad_write (tag, mad, key_b_sector_00, key_b_sector_10);
cut_assert_equal_int (0, res, cut_message ("mad_write() failed"));
res = mad_write(tag, mad, key_b_sector_00, key_b_sector_10);
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);
cut_assert_equal_int (sizeof (application_data), s, cut_message ("mifare_application_write() failed"));
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"));
// Read it again
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_memory (application_data, sizeof (application_data), read_buf, s, cut_message ("Wrong application data"));
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_memory(application_data, sizeof(application_data), read_buf, s, cut_message("Wrong application data"));
mad_free (mad);
mad_free (mad2);
mad_free(mad);
mad_free(mad2);
// Revert to the transport configuration
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"));
res = mifare_classic_format_sector (tag, 0x00);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_format_sector() failed"));
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"));
res = mifare_classic_format_sector(tag, 0x00);
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);
cut_assert_equal_int (0, res, cut_message ("mifare_classic_authenticate() failed"));
res = mifare_classic_format_sector (tag, 0x10);
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);
cut_assert_equal_int(0, res, cut_message("mifare_classic_authenticate() failed"));
res = mifare_classic_format_sector(tag, 0x10);
cut_assert_equal_int(0, res, cut_message("mifare_classic_format_sector() failed"));
}

View file

@ -1,11 +1,11 @@
/*-
* Copyright (C) 2010, Romain Tartiere, Romuald Conty.
*
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
@ -21,19 +21,19 @@
#include "freefare_internal.h"
void
test_mifare_classic_sector_boundaries (void)
test_mifare_classic_sector_boundaries(void)
{
for (int i=0; i < 32; i++) {
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 + 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 < 32; i++) {
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 + 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 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 + 15, mifare_classic_sector_last_block (mifare_classic_block_sector (128 + 16 * i + j)), cut_message ("Wrong last block number for block %d", i));
for (int i = 0; i < 8; i++) {
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 + 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

@ -1,11 +1,11 @@
/*-
* Copyright (C) 2010, Romain Tartiere, Romuald Conty.
*
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
@ -38,7 +38,7 @@ uint8_t key_data[] = {
void
test_mifare_desfire_aes_generate_subkeys (void)
test_mifare_desfire_aes_generate_subkeys(void)
{
uint8_t sk1[] = {
0xfb, 0xee, 0xd6, 0x18,
@ -54,23 +54,23 @@ test_mifare_desfire_aes_generate_subkeys (void)
0xe4, 0x6d, 0x51, 0x3b
};
MifareDESFireKey key = mifare_desfire_aes_key_new (key_data);
cmac_generate_subkeys (key);
MifareDESFireKey key = mifare_desfire_aes_key_new(key_data);
cmac_generate_subkeys(key);
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(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"));
mifare_desfire_key_free (key);
mifare_desfire_key_free(key);
}
void
test_mifare_desfire_aes_cmac_empty (void)
test_mifare_desfire_aes_cmac_empty(void)
{
MifareDESFireKey key = mifare_desfire_aes_key_new (key_data);
cmac_generate_subkeys (key);
MifareDESFireKey key = mifare_desfire_aes_key_new(key_data);
cmac_generate_subkeys(key);
uint8_t ivect[16];
memset (ivect, 0, sizeof (ivect));
memset(ivect, 0, sizeof(ivect));
uint8_t expected_cmac[] = {
0xbb, 0x1d, 0x69, 0x29,
@ -80,21 +80,21 @@ test_mifare_desfire_aes_cmac_empty (void)
};
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
test_mifare_desfire_aes_cmac_128 (void)
test_mifare_desfire_aes_cmac_128(void)
{
MifareDESFireKey key = mifare_desfire_aes_key_new (key_data);
cmac_generate_subkeys (key);
MifareDESFireKey key = mifare_desfire_aes_key_new(key_data);
cmac_generate_subkeys(key);
uint8_t ivect[16];
memset (ivect, 0, sizeof (ivect));
memset(ivect, 0, sizeof(ivect));
uint8_t message[] = {
0x6b, 0xc1, 0xbe, 0xe2,
@ -111,21 +111,21 @@ test_mifare_desfire_aes_cmac_128 (void)
};
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
test_mifare_desfire_aes_cmac_320 (void)
test_mifare_desfire_aes_cmac_320(void)
{
MifareDESFireKey key = mifare_desfire_aes_key_new (key_data);
cmac_generate_subkeys (key);
MifareDESFireKey key = mifare_desfire_aes_key_new(key_data);
cmac_generate_subkeys(key);
uint8_t ivect[16];
memset (ivect, 0, sizeof (ivect));
memset(ivect, 0, sizeof(ivect));
uint8_t message[] = {
0x6b, 0xc1, 0xbe, 0xe2,
@ -148,21 +148,21 @@ test_mifare_desfire_aes_cmac_320 (void)
};
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
test_mifare_desfire_aes_cmac_512 (void)
test_mifare_desfire_aes_cmac_512(void)
{
MifareDESFireKey key = mifare_desfire_aes_key_new (key_data);
cmac_generate_subkeys (key);
MifareDESFireKey key = mifare_desfire_aes_key_new(key_data);
cmac_generate_subkeys(key);
uint8_t ivect[16];
memset (ivect, 0, sizeof (ivect));
memset(ivect, 0, sizeof(ivect));
uint8_t message[] = {
0x6b, 0xc1, 0xbe, 0xe2,
@ -191,9 +191,9 @@ test_mifare_desfire_aes_cmac_512 (void)
};
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

@ -1,11 +1,11 @@
/*-
* Copyright (C) 2010, Romain Tartiere, Romuald Conty.
*
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
@ -21,7 +21,7 @@
#include "freefare_internal.h"
void
test_mifare_desfire_aid (void)
test_mifare_desfire_aid(void)
{
/*
* <-- LSB MSB -->
@ -33,17 +33,17 @@ test_mifare_desfire_aid (void)
*
* 0xF21438 -> 0x83412F
*/
MifareDESFireAID desfire_aid = mifare_desfire_aid_new (0x00f12ab8);
MifareDESFireAID desfire_aid = mifare_desfire_aid_new(0x00f12ab8);
MadAid mad_aid = {
.function_cluster_code = 0x12,
.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_aid2);
free(desfire_aid);
free(desfire_aid2);
}

View file

@ -1,11 +1,11 @@
/*-
* Copyright (C) 2010, Romain Tartiere.
*
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
@ -20,73 +20,73 @@
#include "freefare_internal.h"
void
test_mifare_rol (void)
test_mifare_rol(void)
{
uint8_t data[8] = "01234567";
rol (data, 8);
cut_assert_equal_memory ("12345670", 8, data, 8, cut_message ("Wrong data"));
rol(data, 8);
cut_assert_equal_memory("12345670", 8, data, 8, cut_message("Wrong data"));
uint8_t data2[16] = "0123456789abcdef";
rol (data2, 16);
cut_assert_equal_memory (data2, 16, "123456789abcdef0", 16, cut_message ("Wrong data"));
rol(data2, 16);
cut_assert_equal_memory(data2, 16, "123456789abcdef0", 16, cut_message("Wrong data"));
}
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 data[8] = { 0xd6, 0x59, 0xe1, 0x70, 0x43, 0xa8, 0x40, 0x68 };
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_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_key, 8, key->data, 8, cut_message ("Wrong key"));
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"));
mifare_desfire_key_free (key);
mifare_desfire_key_free(key);
}
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 data[8] = { 0x73, 0x0d, 0xdf, 0xad, 0xa4, 0xd2, 0x07, 0x89 };
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_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_key, 8, key->data, 8, cut_message ("Wrong key"));
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"));
mifare_desfire_key_free (key);
mifare_desfire_key_free(key);
}
void
test_mifare_desfire_padded_data_length (void)
test_mifare_desfire_padded_data_length(void)
{
size_t res;
res = padded_data_length (0, 8);
cut_assert_equal_int (res, 8, cut_message ("Invalid size"));
res = padded_data_length (1, 8);
cut_assert_equal_int (res, 8, cut_message ("Invalid size"));
res = padded_data_length (8, 8);
cut_assert_equal_int (res, 8, cut_message ("Invalid size"));
res = padded_data_length (9, 8);
cut_assert_equal_int (res, 16, cut_message ("Invalid size"));
res = padded_data_length (0, 16);
cut_assert_equal_int (res, 16, cut_message ("Invalid size"));
res = padded_data_length (33, 16);
cut_assert_equal_int (res, 48, cut_message ("Invalid size"));
res = padded_data_length(0, 8);
cut_assert_equal_int(res, 8, cut_message("Invalid size"));
res = padded_data_length(1, 8);
cut_assert_equal_int(res, 8, cut_message("Invalid size"));
res = padded_data_length(8, 8);
cut_assert_equal_int(res, 8, cut_message("Invalid size"));
res = padded_data_length(9, 8);
cut_assert_equal_int(res, 16, cut_message("Invalid size"));
res = padded_data_length(0, 16);
cut_assert_equal_int(res, 16, cut_message("Invalid size"));
res = padded_data_length(33, 16);
cut_assert_equal_int(res, 48, cut_message("Invalid size"));
}

View file

@ -1,11 +1,11 @@
/*-
* Copyright (C) 2010, Romain Tartiere.
*
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
@ -28,128 +28,128 @@
#define cut_assert_success(last_command) \
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_not_equal_int (-1, res, cut_message ("Wrong return value")); \
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")); \
} while (0)
void
test_mifare_desfire_ev1_aes2 (void)
test_mifare_desfire_ev1_aes2(void)
{
int res;
MifareDESFireKey key;
mifare_desfire_auto_authenticate (tag, 0);
mifare_desfire_auto_authenticate(tag, 0);
// Setup the AES key
key = mifare_desfire_aes_key_new_with_version (key_data_aes, key_data_aes_version);
res = mifare_desfire_change_key (tag, 0x80, key, NULL);
cut_assert_success ("mifare_desfire_change_key");
mifare_desfire_key_free (key);
key = mifare_desfire_aes_key_new_with_version(key_data_aes, key_data_aes_version);
res = mifare_desfire_change_key(tag, 0x80, key, NULL);
cut_assert_success("mifare_desfire_change_key");
mifare_desfire_key_free(key);
// Authenticate with the AES key
key = mifare_desfire_aes_key_new_with_version (key_data_aes, key_data_aes_version);
res = mifare_desfire_authenticate_aes (tag, 0, key);
cut_assert_success ("mifare_desfire_authenticate");
mifare_desfire_key_free (key);
key = mifare_desfire_aes_key_new_with_version(key_data_aes, key_data_aes_version);
res = mifare_desfire_authenticate_aes(tag, 0, key);
cut_assert_success("mifare_desfire_authenticate");
mifare_desfire_key_free(key);
res = mifare_desfire_format_picc (tag);
cut_assert_success ("mifare_desfire_format_picc()");
res = mifare_desfire_format_picc(tag);
cut_assert_success("mifare_desfire_format_picc()");
key = mifare_desfire_aes_key_new_with_version (key_data_aes, key_data_aes_version);
res = mifare_desfire_authenticate_aes (tag, 0, key);
cut_assert_success ("mifare_desfire_authenticate");
mifare_desfire_key_free (key);
key = mifare_desfire_aes_key_new_with_version(key_data_aes, key_data_aes_version);
res = mifare_desfire_authenticate_aes(tag, 0, key);
cut_assert_success("mifare_desfire_authenticate");
mifare_desfire_key_free(key);
uint32_t size;
res = mifare_desfire_free_mem (tag, &size);
cut_assert_success ("mifare_desfire_free_mem");
res = mifare_desfire_free_mem(tag, &size);
cut_assert_success("mifare_desfire_free_mem");
// Do some commands to check CMAC is properly handled
res = mifare_desfire_free_mem (tag, &size);
cut_assert_success ("mifare_desfire_free_mem");
res = mifare_desfire_free_mem(tag, &size);
cut_assert_success("mifare_desfire_free_mem");
struct mifare_desfire_version_info info;
res = mifare_desfire_get_version (tag, &info);
cut_assert_success ("mifare_desfire_get_version");
res = mifare_desfire_get_version(tag, &info);
cut_assert_success("mifare_desfire_get_version");
res = mifare_desfire_change_key_settings (tag, 0x0F);
cut_assert_success ("mifare_desfire_change_key_settings");
res = mifare_desfire_change_key_settings(tag, 0x0F);
cut_assert_success("mifare_desfire_change_key_settings");
res = mifare_desfire_free_mem (tag, &size);
cut_assert_success ("mifare_desfire_free_mem");
res = mifare_desfire_free_mem(tag, &size);
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);
cut_assert_success ("mifare_desfire_create_application");
res = mifare_desfire_create_application(tag, aid, 0xff, 0x81);
cut_assert_success("mifare_desfire_create_application");
res = mifare_desfire_select_application (tag, aid);
cut_assert_success ("mifare_desfire_select_application");
res = mifare_desfire_select_application(tag, aid);
cut_assert_success("mifare_desfire_select_application");
key = mifare_desfire_aes_key_new (key_data_aes);
res = mifare_desfire_authenticate_aes (tag, 0, key);
cut_assert_success ("mifare_desfire_authenticate");
free (key);
key = mifare_desfire_aes_key_new(key_data_aes);
res = mifare_desfire_authenticate_aes(tag, 0, key);
cut_assert_success("mifare_desfire_authenticate");
free(key);
key = mifare_desfire_aes_key_new_with_version (key_data_aes, key_data_aes_version);
res = mifare_desfire_change_key (tag, 0x00, key, NULL);
cut_assert_success ("mifare_desfire_change_key");
mifare_desfire_key_free (key);
key = mifare_desfire_aes_key_new_with_version(key_data_aes, key_data_aes_version);
res = mifare_desfire_change_key(tag, 0x00, key, NULL);
cut_assert_success("mifare_desfire_change_key");
mifare_desfire_key_free(key);
key = mifare_desfire_aes_key_new (key_data_aes);
res = mifare_desfire_authenticate_aes (tag, 0, key);
cut_assert_success ("mifare_desfire_authenticate");
free (key);
key = mifare_desfire_aes_key_new(key_data_aes);
res = mifare_desfire_authenticate_aes(tag, 0, key);
cut_assert_success("mifare_desfire_authenticate");
free(key);
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))
cut_assert_success ("mifare_desfire_create_std_data_file");
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))
cut_assert_success("mifare_desfire_create_std_data_file");
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"
"ly, some failure in the algorirthm should trigger an error in this uni"
"t test.";
res = mifare_desfire_write_data_ex (tag, 1, 0, strlen (sample_data), sample_data, MDCM_MACED);
cut_assert_success ("mifare_desfire_write_data");
"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"
"t test.";
res = mifare_desfire_write_data_ex(tag, 1, 0, strlen(sample_data), sample_data, MDCM_MACED);
cut_assert_success("mifare_desfire_write_data");
char buffer[1024];
res = mifare_desfire_read_data_ex (tag, 1, 0, 27, buffer, MDCM_MACED);
cut_assert_success ("mifare_desfire_read_data");
cut_assert_equal_memory (buffer, res, sample_data, 27, cut_message ("AES crypto failed"));
res = mifare_desfire_read_data_ex(tag, 1, 0, 27, buffer, MDCM_MACED);
cut_assert_success("mifare_desfire_read_data");
cut_assert_equal_memory(buffer, res, sample_data, 27, cut_message("AES crypto failed"));
char canaries[] = "Canaries Canaries Canaries Canaries Canaries";
res = mifare_desfire_read_data_ex (tag, 1, 0, 1, canaries, MDCM_MACED);
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_memory (canaries, 44, "Hanaries Canaries Canaries Canaries Canaries", 44, cut_message ("Canaries got smashed!"));
res = mifare_desfire_read_data_ex(tag, 1, 0, 1, canaries, MDCM_MACED);
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_memory(canaries, 44, "Hanaries Canaries Canaries Canaries Canaries", 44, cut_message("Canaries got smashed!"));
uint8_t s, c;
res = mifare_desfire_get_key_settings (tag, &s, &c);
cut_assert_success ("mifare_desfire_get__key_settings");
res = mifare_desfire_get_key_settings(tag, &s, &c);
cut_assert_success("mifare_desfire_get__key_settings");
res = mifare_desfire_read_data_ex (tag, 1, 27, 27, buffer, MDCM_MACED);
cut_assert_success ("mifare_desfire_read_data");
cut_assert_equal_memory (buffer, res, sample_data + 27, 27, cut_message ("AES crypto failed"));
res = mifare_desfire_read_data_ex(tag, 1, 27, 27, buffer, MDCM_MACED);
cut_assert_success("mifare_desfire_read_data");
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);
cut_assert_success ("mifare_desfire_read_data");
cut_assert_equal_memory (buffer, strlen (buffer), sample_data, strlen (sample_data), cut_message ("AES crypto failed"));
res = mifare_desfire_read_data_ex(tag, 1, 0, 0, buffer, MDCM_MACED);
cut_assert_success("mifare_desfire_read_data");
cut_assert_equal_memory(buffer, strlen(buffer), sample_data, strlen(sample_data), cut_message("AES crypto failed"));
// Revert to the default DES key
res = mifare_desfire_select_application (tag, NULL);
cut_assert_success ("mifare_desfire_select_application");
res = mifare_desfire_select_application(tag, NULL);
cut_assert_success("mifare_desfire_select_application");
key = mifare_desfire_aes_key_new_with_version (key_data_aes, key_data_aes_version);
res = mifare_desfire_authenticate_aes (tag, 0, key);
cut_assert_success ("mifare_desfire_authenticate");
mifare_desfire_key_free (key);
key = mifare_desfire_aes_key_new_with_version(key_data_aes, key_data_aes_version);
res = mifare_desfire_authenticate_aes(tag, 0, key);
cut_assert_success("mifare_desfire_authenticate");
mifare_desfire_key_free(key);
key = mifare_desfire_des_key_new (key_data_null);
res = mifare_desfire_change_key (tag, 0x00, key, NULL);
cut_assert_success ("mifare_desfire_change_key");
mifare_desfire_key_free (key);
key = mifare_desfire_des_key_new(key_data_null);
res = mifare_desfire_change_key(tag, 0x00, key, NULL);
cut_assert_success("mifare_desfire_change_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

@ -1,11 +1,11 @@
/*-
* Copyright (C) 2011, Romain Tartiere.
*
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
@ -25,105 +25,105 @@
#define cut_assert_success(last_command) \
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_not_equal_int (-1, res, cut_message ("Wrong return value")); \
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")); \
} while (0)
void
test_mifare_desfire_ev1_iso (void)
test_mifare_desfire_ev1_iso(void)
{
int res;
mifare_desfire_auto_authenticate (tag, 0);
mifare_desfire_auto_authenticate(tag, 0);
res = mifare_desfire_format_picc (tag);
cut_assert_equal_int (res, 0, cut_message ("mifare_desfire_format_picc()"));
res = mifare_desfire_format_picc(tag);
cut_assert_equal_int(res, 0, cut_message("mifare_desfire_format_picc()"));
MifareDESFireDF *dfs;
size_t 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 (count, 0, cut_message ("Wrong DF count"));
cut_assert_null (dfs, cut_message ("DF should be NULL"));
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(count, 0, cut_message("Wrong DF count"));
cut_assert_null(dfs, cut_message("DF should be NULL"));
MifareDESFireAID aid = mifare_desfire_aid_new (0x111110);
res = mifare_desfire_create_application_iso (tag, aid, 0xFF, 1, 0, 0x111F, NULL, 0);
cut_assert_success ("mifare_desfire_create_application_iso");
free (aid);
MifareDESFireAID aid = mifare_desfire_aid_new(0x111110);
res = mifare_desfire_create_application_iso(tag, aid, 0xFF, 1, 0, 0x111F, NULL, 0);
cut_assert_success("mifare_desfire_create_application_iso");
free(aid);
uint8_t app2[] = "App2";
aid = mifare_desfire_aid_new (0x222220);
res = mifare_desfire_create_application_iso (tag, aid, 0xFF, 1, 0, 0x222F, app2, sizeof (app2));
cut_assert_success ("mifare_desfire_create_application_iso");
free (aid);
aid = mifare_desfire_aid_new(0x222220);
res = mifare_desfire_create_application_iso(tag, aid, 0xFF, 1, 0, 0x222F, app2, sizeof(app2));
cut_assert_success("mifare_desfire_create_application_iso");
free(aid);
uint8_t app3[] = "App3";
aid = mifare_desfire_aid_new (0x333330);
res = mifare_desfire_create_application_iso (tag, aid, 0xFF, 1, 0, 0x333F, app3, sizeof (app3));
cut_assert_success ("mifare_desfire_create_application_iso");
free (aid);
aid = mifare_desfire_aid_new(0x333330);
res = mifare_desfire_create_application_iso(tag, aid, 0xFF, 1, 0, 0x333F, app3, sizeof(app3));
cut_assert_success("mifare_desfire_create_application_iso");
free(aid);
aid = mifare_desfire_aid_new (0x444440);
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 (DUPLICATE_ERROR, mifare_desfire_last_picc_error (tag), cut_message ("Should be a duplicate error"));
aid = mifare_desfire_aid_new(0x444440);
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(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));
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"));
free (aid);
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(DUPLICATE_ERROR, mifare_desfire_last_picc_error(tag), cut_message("Should be a duplicate error"));
free(aid);
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 (3, count, cut_message ("Wrong DF count"));
cut_assert_not_null (dfs, cut_message ("DF should not be NULL"));
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(3, count, cut_message("Wrong DF count"));
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 (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(0x111110, dfs[0].aid, 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 (0x222220, dfs[1].aid, 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_memory (app2, sizeof (app2), dfs[1].df_name, dfs[1].df_name_len, 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(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_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 (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"));
free (dfs);
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(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"));
free(dfs);
aid = mifare_desfire_aid_new (0x555550);
res = mifare_desfire_create_application_iso (tag, aid, 0xff, 1, 1, 0x555F, NULL, 0);
cut_assert_success ("mifare_desfire_create_application_iso");
aid = mifare_desfire_aid_new(0x555550);
res = mifare_desfire_create_application_iso(tag, aid, 0xff, 1, 1, 0x555F, NULL, 0);
cut_assert_success("mifare_desfire_create_application_iso");
res = mifare_desfire_select_application (tag, aid);
cut_assert_success ("mifare_desfire_select_application");
res = mifare_desfire_select_application(tag, aid);
cut_assert_success("mifare_desfire_select_application");
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");
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");
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");
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");
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");
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");
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");
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");
uint16_t *ids;
res = mifare_desfire_get_iso_file_ids (tag, &ids, &count);
cut_assert_success ("mifare_desfire_get_iso_file_ids");
res = mifare_desfire_get_iso_file_ids(tag, &ids, &count);
cut_assert_success("mifare_desfire_get_iso_file_ids");
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 (0x2345, ids[1], 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"));
free (ids);
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(0x2345, ids[1], 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"));
free(ids);
free (aid);
free(aid);
}

View file

@ -1,11 +1,11 @@
/*-
* Copyright (C) 2010, Romain Tartiere.
*
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
@ -21,76 +21,76 @@
void
test_mifare_desfire_key (void)
test_mifare_desfire_key(void)
{
MifareDESFireKey key;
int version;
uint8_t key1_des_data[8] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 };
key = mifare_desfire_des_key_new (key1_des_data);
version = mifare_desfire_key_get_version (key);
cut_assert_equal_int (0x00, version, cut_message ("Wrong MifareDESFireKey version"));
mifare_desfire_key_free (key);
key = mifare_desfire_des_key_new(key1_des_data);
version = mifare_desfire_key_get_version(key);
cut_assert_equal_int(0x00, version, cut_message("Wrong MifareDESFireKey version"));
mifare_desfire_key_free(key);
key = mifare_desfire_des_key_new_with_version (key1_des_data);
version = mifare_desfire_key_get_version (key);
cut_assert_equal_int (0x55, version, cut_message ("Wrong MifareDESFireKey version"));
mifare_desfire_key_set_version (key, 0xaa);
version = mifare_desfire_key_get_version (key);
cut_assert_equal_int (0xaa, version, cut_message ("Wrong MifareDESFireKey version"));
mifare_desfire_key_free (key);
key = mifare_desfire_des_key_new_with_version(key1_des_data);
version = mifare_desfire_key_get_version(key);
cut_assert_equal_int(0x55, version, cut_message("Wrong MifareDESFireKey version"));
mifare_desfire_key_set_version(key, 0xaa);
version = mifare_desfire_key_get_version(key);
cut_assert_equal_int(0xaa, version, cut_message("Wrong MifareDESFireKey version"));
mifare_desfire_key_free(key);
uint8_t key2_des_data[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
key = mifare_desfire_des_key_new (key2_des_data);
version = mifare_desfire_key_get_version (key);
cut_assert_equal_int (0x00, version, cut_message ("Wrong MifareDESFireKey version"));
mifare_desfire_key_free (key);
key = mifare_desfire_des_key_new(key2_des_data);
version = mifare_desfire_key_get_version(key);
cut_assert_equal_int(0x00, version, cut_message("Wrong MifareDESFireKey version"));
mifare_desfire_key_free(key);
key = mifare_desfire_des_key_new_with_version (key2_des_data);
version = mifare_desfire_key_get_version (key);
cut_assert_equal_int (0x00, version, cut_message ("Wrong MifareDESFireKey version"));
mifare_desfire_key_free (key);
key = mifare_desfire_des_key_new_with_version(key2_des_data);
version = mifare_desfire_key_get_version(key);
cut_assert_equal_int(0x00, version, cut_message("Wrong MifareDESFireKey version"));
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 };
key = mifare_desfire_3des_key_new (key1_3des_data);
version = mifare_desfire_key_get_version (key);
cut_assert_equal_int (0x00, version, cut_message ("Wrong MifareDESFireKey version"));
mifare_desfire_key_free (key);
key = mifare_desfire_3des_key_new(key1_3des_data);
version = mifare_desfire_key_get_version(key);
cut_assert_equal_int(0x00, version, cut_message("Wrong MifareDESFireKey version"));
mifare_desfire_key_free(key);
key = mifare_desfire_3des_key_new_with_version (key1_3des_data);
version = mifare_desfire_key_get_version (key);
cut_assert_equal_int (0x55, version, cut_message ("Wrong MifareDESFireKey version"));
mifare_desfire_key_set_version (key, 0xaa);
version = mifare_desfire_key_get_version (key);
cut_assert_equal_int (0xaa, version, cut_message ("Wrong MifareDESFireKey version"));
mifare_desfire_key_free (key);
key = mifare_desfire_3des_key_new_with_version(key1_3des_data);
version = mifare_desfire_key_get_version(key);
cut_assert_equal_int(0x55, version, cut_message("Wrong MifareDESFireKey version"));
mifare_desfire_key_set_version(key, 0xaa);
version = mifare_desfire_key_get_version(key);
cut_assert_equal_int(0xaa, version, cut_message("Wrong MifareDESFireKey version"));
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 };
key = mifare_desfire_3des_key_new (key2_3des_data);
version = mifare_desfire_key_get_version (key);
cut_assert_equal_int (0x00, version, cut_message ("Wrong MifareDESFireKey version"));
mifare_desfire_key_free (key);
key = mifare_desfire_3des_key_new(key2_3des_data);
version = mifare_desfire_key_get_version(key);
cut_assert_equal_int(0x00, version, cut_message("Wrong MifareDESFireKey version"));
mifare_desfire_key_free(key);
key = mifare_desfire_3des_key_new_with_version (key2_3des_data);
version = mifare_desfire_key_get_version (key);
cut_assert_equal_int (0x02, version, cut_message ("Wrong MifareDESFireKey version"));
mifare_desfire_key_free (key);
key = mifare_desfire_3des_key_new_with_version(key2_3des_data);
version = mifare_desfire_key_get_version(key);
cut_assert_equal_int(0x02, version, cut_message("Wrong MifareDESFireKey version"));
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 };
key = mifare_desfire_3des_key_new (key3_3des_data);
version = mifare_desfire_key_get_version (key);
cut_assert_equal_int (0x00, version, cut_message ("Wrong MifareDESFireKey version"));
mifare_desfire_key_free (key);
key = mifare_desfire_3des_key_new(key3_3des_data);
version = mifare_desfire_key_get_version(key);
cut_assert_equal_int(0x00, version, cut_message("Wrong MifareDESFireKey version"));
mifare_desfire_key_free(key);
key = mifare_desfire_3des_key_new_with_version (key3_3des_data);
version = mifare_desfire_key_get_version (key);
cut_assert_equal_int (0x10, version, cut_message ("Wrong MifareDESFireKey version"));
mifare_desfire_key_free (key);
key = mifare_desfire_3des_key_new_with_version(key3_3des_data);
version = mifare_desfire_key_get_version(key);
cut_assert_equal_int(0x10, version, cut_message("Wrong MifareDESFireKey version"));
mifare_desfire_key_free(key);
}

View file

@ -1,11 +1,11 @@
/*-
* Copyright (C) 2010, Romain Tartiere.
*
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
@ -25,7 +25,7 @@
#include "mifare_ultralight_fixture.h"
void
test_mifare_ultralight_write (void)
test_mifare_ultralight_write(void)
{
int res;
@ -37,158 +37,158 @@ test_mifare_ultralight_write (void)
MifareUltralightPageNumber n = 7;
/* Read and save current value (should be { 0x00 0x00 0x00 0x00 }) */
res = mifare_ultralight_read (tag, n, &initial);
cut_assert_equal_int (0, res, cut_message ("mifare_ultralight_read() failed"));
res = mifare_ultralight_read(tag, n, &initial);
cut_assert_equal_int(0, res, cut_message("mifare_ultralight_read() failed"));
/* Write payload1 */
res = mifare_ultralight_write (tag, n, payload1);
cut_assert_equal_int (0, res, cut_message ("mifare_ultralight_write() failed"));
res = mifare_ultralight_write(tag, n, payload1);
cut_assert_equal_int(0, res, cut_message("mifare_ultralight_write() failed"));
/* Check it */
res = mifare_ultralight_read (tag, n, &page);
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"));
res = mifare_ultralight_read(tag, n, &page);
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"));
/* Write payload2 */
res = mifare_ultralight_write (tag, n, payload2);
cut_assert_equal_int (0, res, cut_message ("mifare_ultralight_write() failed"));
res = mifare_ultralight_write(tag, n, payload2);
cut_assert_equal_int(0, res, cut_message("mifare_ultralight_write() failed"));
/* Check it */
res = mifare_ultralight_read (tag, n, &page);
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"));
res = mifare_ultralight_read(tag, n, &page);
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"));
/* Write initial data */
res = mifare_ultralight_write (tag, n, initial);
cut_assert_equal_int (0, res, cut_message ("mifare_ultralight_write() failed"));
res = mifare_ultralight_write(tag, n, initial);
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) */
res = mifare_ultralight_read (tag, n, &page);
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"));
res = mifare_ultralight_read(tag, n, &page);
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"));
}
void
test_mifare_ultralight_invalid_page (void)
test_mifare_ultralight_invalid_page(void)
{
int res;
MifareUltralightPage page = { 0x00, 0x00, 0x00, 0x00 };
int invalid_page;
if (is_mifare_ultralightc (tag)) {
invalid_page = MIFARE_ULTRALIGHT_C_PAGE_COUNT;
if (is_mifare_ultralightc(tag)) {
invalid_page = MIFARE_ULTRALIGHT_C_PAGE_COUNT;
} else {
invalid_page = MIFARE_ULTRALIGHT_PAGE_COUNT;
invalid_page = MIFARE_ULTRALIGHT_PAGE_COUNT;
}
res = mifare_ultralight_read (tag, invalid_page, &page);
cut_assert_equal_int (-1, res, cut_message ("mifare_ultralight_read() succeeded"));
cut_assert_equal_int (EINVAL, errno, cut_message ("Wrong errno value"));
res = mifare_ultralight_read(tag, invalid_page, &page);
cut_assert_equal_int(-1, res, cut_message("mifare_ultralight_read() succeeded"));
cut_assert_equal_int(EINVAL, errno, cut_message("Wrong errno value"));
res = mifare_ultralight_write (tag, invalid_page, page);
cut_assert_equal_int (-1, res, cut_message ("mifare_ultralight_write() succeeded"));
cut_assert_equal_int (EINVAL, errno, cut_message ("Wrong errno value"));
res = mifare_ultralight_write(tag, invalid_page, page);
cut_assert_equal_int(-1, res, cut_message("mifare_ultralight_write() succeeded"));
cut_assert_equal_int(EINVAL, errno, cut_message("Wrong errno value"));
}
void
test_mifare_ultralight_cache (void)
test_mifare_ultralight_cache(void)
{
int res;
MifareUltralightPage page;
res = mifare_ultralight_read (tag, 0, &page);
cut_assert_equal_int (0, res, cut_message ("mifare_ultralight_read() failed"));
res = mifare_ultralight_read(tag, 0, &page);
cut_assert_equal_int(0, res, cut_message("mifare_ultralight_read() failed"));
/* Check cached pages consistency */
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++) {
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
test_mifare_ultralight_cache_hit (void)
test_mifare_ultralight_cache_hit(void)
{
int res;
MifareUltralightPage page1;
MifareUltralightPage page2;
res = mifare_ultralight_read (tag, 0, &page1);
cut_assert_equal_int (0, res, cut_message ("mifare_ultralight_read() failed"));
res = mifare_ultralight_read(tag, 0, &page1);
cut_assert_equal_int(0, res, cut_message("mifare_ultralight_read() failed"));
res = mifare_ultralight_read (tag, 0, &page2);
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"));
res = mifare_ultralight_read(tag, 0, &page2);
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"));
}
void
test_mifare_ultralight_cache_wrap (void)
test_mifare_ultralight_cache_wrap(void)
{
int res;
MifareUltralightPage page;
int last_page;
if (is_mifare_ultralightc (tag)) {
// 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;
// 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");
if (is_mifare_ultralightc(tag)) {
// 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;
// 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");
} else {
last_page = MIFARE_ULTRALIGHT_PAGE_COUNT -1;
last_page = MIFARE_ULTRALIGHT_PAGE_COUNT - 1;
}
res = mifare_ultralight_read (tag, last_page, &page);
cut_assert_equal_int (0, res, cut_message ("mifare_ultralight_read() failed"));
res = mifare_ultralight_read(tag, last_page, &page);
cut_assert_equal_int(0, res, cut_message("mifare_ultralight_read() failed"));
/* Check cached pages consistency */
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++) {
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
test_mifare_ultralight_get_uid (void)
test_mifare_ultralight_get_uid(void)
{
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_equal_int (14, strlen (uid), cut_message ("Wrong UID length"));
cut_assert_not_null(uid, cut_message("mifare_ultralight_get_uid() failed"));
cut_assert_equal_int(14, strlen(uid), cut_message("Wrong UID length"));
free (uid);
free(uid);
}
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
test_mifare_ultralightc_authenticate (void)
test_mifare_ultralightc_authenticate(void)
{
int res;
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 };
key = mifare_desfire_3des_key_new (key1_3des_data);
res = mifare_ultralightc_authenticate (tag, key);
cut_assert_equal_int (0, res, cut_message ("mifare_ultralightc_authenticate() failed"));
mifare_desfire_key_free (key);
key = mifare_desfire_3des_key_new(key1_3des_data);
res = mifare_ultralightc_authenticate(tag, key);
cut_assert_equal_int(0, res, cut_message("mifare_ultralightc_authenticate() failed"));
mifare_desfire_key_free(key);
MifareUltralightPage page;
int last_page = MIFARE_ULTRALIGHT_C_PAGE_COUNT_READ -1;
res = mifare_ultralight_read (tag, last_page, &page);
cut_assert_equal_int (0, res, cut_message ("mifare_ultralight_read() failed"));
int last_page = MIFARE_ULTRALIGHT_C_PAGE_COUNT_READ - 1;
res = mifare_ultralight_read(tag, last_page, &page);
cut_assert_equal_int(0, res, cut_message("mifare_ultralight_read() failed"));
} else {
cut_omit("mifare_ultralightc_authenticate() skipped on Ultralight");
}

View file

@ -1,11 +1,11 @@
/*-
* Copyright (C) 2010, Romain Tartiere, Romuald Conty.
*
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
@ -28,120 +28,120 @@ const uint8_t eshortdata[11] = "\x03" "\x08" "elephant" "\xfe";
* OS / compiler does not support UTF-8 ;-)
*/
const uint8_t longdata[660] = "Dans une terre grasse et pleine d'escargots\n" \
"Je veux creuser moi-même une fosse profonde,\n" \
"Où je puisse à loisir étaler mes vieux os\n" \
"Et dormir dans l'oubli comme un requin dans l'onde.\n" \
"Je hais les testaments et je hais les tombeaux;\n" \
"Plutôt que d'implorer une larme du monde,\n" \
"Vivant, j'aimerais mieux inviter les corbeaux\n" \
"À saigner tous les bouts de ma carcasse immonde.\n" \
"Ô vers! noirs compagnons sans oreille et sans yeux,\n" \
"Voyez venir à vous un mort libre et joyeux;\n" \
"Philosophes viveurs, fils de la pourriture,\n" \
"À travers ma ruine allez donc sans remords,\n" \
"Et dites-moi s'il est encor quelque torture\n" \
"Pour ce vieux corps sans âme et mort parmi les morts!\n";
"Je veux creuser moi-même une fosse profonde,\n" \
"Où je puisse à loisir étaler mes vieux os\n" \
"Et dormir dans l'oubli comme un requin dans l'onde.\n" \
"Je hais les testaments et je hais les tombeaux;\n" \
"Plutôt que d'implorer une larme du monde,\n" \
"Vivant, j'aimerais mieux inviter les corbeaux\n" \
"À saigner tous les bouts de ma carcasse immonde.\n" \
"Ô vers! noirs compagnons sans oreille et sans yeux,\n" \
"Voyez venir à vous un mort libre et joyeux;\n" \
"Philosophes viveurs, fils de la pourriture,\n" \
"À travers ma ruine allez donc sans remords,\n" \
"Et dites-moi s'il est encor quelque torture\n" \
"Pour ce vieux corps sans âme et mort parmi les morts!\n";
const uint8_t elongdata[665] = "\x07" "\xff\x02\x94" \
"Dans une terre grasse et pleine d'escargots\n" \
"Je veux creuser moi-même une fosse profonde,\n" \
"Où je puisse à loisir étaler mes vieux os\n" \
"Et dormir dans l'oubli comme un requin dans l'onde.\n" \
"Je hais les testaments et je hais les tombeaux;\n" \
"Plutôt que d'implorer une larme du monde,\n" \
"Vivant, j'aimerais mieux inviter les corbeaux\n" \
"À saigner tous les bouts de ma carcasse immonde.\n" \
"Ô vers! noirs compagnons sans oreille et sans yeux,\n" \
"Voyez venir à vous un mort libre et joyeux;\n" \
"Philosophes viveurs, fils de la pourriture,\n" \
"À travers ma ruine allez donc sans remords,\n" \
"Et dites-moi s'il est encor quelque torture\n" \
"Pour ce vieux corps sans âme et mort parmi les morts!\n"
"\xfe";
"Dans une terre grasse et pleine d'escargots\n" \
"Je veux creuser moi-même une fosse profonde,\n" \
"Où je puisse à loisir étaler mes vieux os\n" \
"Et dormir dans l'oubli comme un requin dans l'onde.\n" \
"Je hais les testaments et je hais les tombeaux;\n" \
"Plutôt que d'implorer une larme du monde,\n" \
"Vivant, j'aimerais mieux inviter les corbeaux\n" \
"À saigner tous les bouts de ma carcasse immonde.\n" \
"Ô vers! noirs compagnons sans oreille et sans yeux,\n" \
"Voyez venir à vous un mort libre et joyeux;\n" \
"Philosophes viveurs, fils de la pourriture,\n" \
"À travers ma ruine allez donc sans remords,\n" \
"Et dites-moi s'il est encor quelque torture\n" \
"Pour ce vieux corps sans âme et mort parmi les morts!\n"
"\xfe";
void
test_tlv_encode_short (void)
test_tlv_encode_short(void)
{
uint8_t *res;
size_t 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 (3, res[0], cut_message ("Wrong type"));
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"));
free (res);
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(3, res[0], cut_message("Wrong type"));
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"));
free(res);
}
void
test_tlv_encode_long (void)
test_tlv_encode_long(void)
{
uint8_t *res;
size_t 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 (7, res[0], cut_message ("Wrong type"));
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 (0x94, res[3], cut_message ("Wrong value length"));
cut_assert_equal_memory (elongdata, sizeof (elongdata), res, osize, cut_message ("Wrong encoded value"));
free (res);
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(7, res[0], cut_message("Wrong type"));
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(0x94, res[3], cut_message("Wrong value length"));
cut_assert_equal_memory(elongdata, sizeof(elongdata), res, osize, cut_message("Wrong encoded value"));
free(res);
}
void
test_tlv_decode_short (void)
test_tlv_decode_short(void)
{
uint8_t *res;
uint16_t size;
uint8_t type;
res = tlv_decode (eshortdata, &type, &size);
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_memory (shortdata, sizeof (shortdata), res, size, cut_message ("Wrong decoded value"));
free (res);
res = tlv_decode(eshortdata, &type, &size);
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_memory(shortdata, sizeof(shortdata), res, size, cut_message("Wrong decoded value"));
free(res);
}
void
test_tlv_decode_long (void)
test_tlv_decode_long(void)
{
uint8_t *res;
uint16_t size;
uint8_t type;
res = tlv_decode (elongdata, &type, &size);
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_memory (longdata, sizeof (longdata), res, size, cut_message ("Wrong decoded value"));
free (res);
res = tlv_decode(elongdata, &type, &size);
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_memory(longdata, sizeof(longdata), res, size, cut_message("Wrong decoded value"));
free(res);
}
void
test_tlv_rfu (void)
test_tlv_rfu(void)
{
uint8_t *data = malloc (0xffff);
cut_assert_not_null (data, cut_message ("Out of memory"));
uint8_t *data = malloc(0xffff);
cut_assert_not_null(data, cut_message("Out of memory"));
uint8_t *res = tlv_encode (7, data, 0xffff, NULL);
cut_assert_null (res, cut_message ("Size reserved for future use"));
uint8_t *res = tlv_encode(7, data, 0xffff, NULL);
cut_assert_null(res, cut_message("Size reserved for future use"));
free (data);
free(data);
}
void
test_tlv_append (void)
test_tlv_append(void)
{
const uint8_t a[] = { 0xde, 0xad, 0xbe, 0xef };
const uint8_t b[] = { 0x42 };
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_b = tlv_encode (3, b, 1, NULL);
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"));
uint8_t *ndef_a = tlv_encode(3, a, 4, NULL);
uint8_t *ndef_b = tlv_encode(3, b, 1, NULL);
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"));
free (ndef_a);
free (ndef_b);
free(ndef_a);
free(ndef_b);
}