diff --git a/nfc_init.c b/nfc_init.c index 1b26f13..0356594 100644 --- a/nfc_init.c +++ b/nfc_init.c @@ -4,32 +4,32 @@ #include "poll_desfire.h" int init(nfc_context **context, nfc_device **device) { - nfc_connstring devices[8]; - size_t device_count; + nfc_connstring devices[8]; + size_t device_count; - nfc_init(context); - if (context == NULL) { - errx(EXIT_FAILURE, "Unable to init libnfc (malloc)"); - } + 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[0])); - if (device_count <= 0) { - errx(EXIT_FAILURE, "No NFC device found."); - } - - if (device_count > 1) { - printf("More than 1 device available. Using %s\n", devices[0]); - } + device_count = nfc_list_devices(*context, devices, sizeof(devices) / sizeof(devices[0])); + if (device_count <= 0) { + errx(EXIT_FAILURE, "No NFC device found."); + } - *device = nfc_open(*context, devices[0]); - if (!device) { - errx(EXIT_FAILURE, "nfc_open() failed."); - } - - if (nfc_initiator_init(*device) < 0) { - errx(EXIT_FAILURE, "Initiator failed."); - } + if (device_count > 1) { + printf("More than 1 device available. Using %s\n", devices[0]); + } - return 0; + *device = nfc_open(*context, devices[0]); + if (!device) { + errx(EXIT_FAILURE, "nfc_open() failed."); + } + + if (nfc_initiator_init(*device) < 0) { + errx(EXIT_FAILURE, "Initiator failed."); + } + + return 0; } void poll_target(nfc_device *device); diff --git a/poll_desfire.c b/poll_desfire.c index d3d7b32..705c375 100644 --- a/poll_desfire.c +++ b/poll_desfire.c @@ -7,186 +7,204 @@ #include #include "poll_desfire.h" -#define AID 0x22eaa0 +#define AID 0x22eaa0 #define RANDOM_UID_SIZE 8 void init_keys(MifareDESFireKey *null_key, MifareDESFireKey *master_key, char const *name) { - uint8_t const key_data_null[8] = {0, 0, 0, 0, 0, 0, 0, 0}; - *null_key = mifare_desfire_des_key_new_with_version(key_data_null); - - uint8_t key_data_real[16] = {0}; - { - FILE *f = fopen(name, "rb"); - if (!f) { - errx(EXIT_FAILURE, "error opening key file: %s", name); - } - if (fread(key_data_real, 1, sizeof key_data_real, f) < sizeof key_data_real) { - errx(EXIT_FAILURE, "key file too small."); - } - fclose(f); - } - *master_key = mifare_desfire_aes_key_new(key_data_real); + uint8_t const key_data_null[8] = {0, 0, 0, 0, 0, 0, 0, 0}; + *null_key = mifare_desfire_des_key_new_with_version(key_data_null); + + uint8_t key_data_real[16] = {0}; + { + FILE *f = fopen(name, "rb"); + if (!f) { + errx(EXIT_FAILURE, "error opening key file: %s", name); + } + if (fread(key_data_real, 1, sizeof key_data_real, f) < sizeof key_data_real) { + errx(EXIT_FAILURE, "key file too small."); + } + fclose(f); + } + *master_key = mifare_desfire_aes_key_new(key_data_real); } int main(int argc, char **argv) { - int error = EXIT_SUCCESS; + int error = EXIT_SUCCESS; - nfc_context *context = NULL; - nfc_device *device = NULL; - FreefareTag *tags = NULL; - MifareDESFireKey key_null, key_master; - MifareDESFireAID aid = mifare_desfire_aid_new(AID); + nfc_context *context = NULL; + nfc_device *device = NULL; + FreefareTag *tags = NULL; + MifareDESFireKey key_null, key_master; + MifareDESFireAID aid = mifare_desfire_aid_new(AID); - error = init(&context, &device); - init_keys(&key_null, &key_master, (argc > 1) ? argv[1] : "key"); + error = init(&context, &device); + init_keys(&key_null, &key_master, (argc > 1) ? argv[1] : "key"); - FILE *out = argc > 2 ? fopen(argv[2], "w") : stdout; + FILE *out = argc > 2 ? fopen(argv[2], "w") : stdout; - while (true) { - tags = freefare_get_tags(device); - if (!tags) { - nfc_close(device); - errx(EXIT_FAILURE, "Error listing tags."); - } + while (true) { + tags = freefare_get_tags(device); + if (!tags) { + nfc_close(device); + errx(EXIT_FAILURE, "Error listing tags."); + } - for (int id = 0; tags[id]; id++) { - FreefareTag tag = tags[id]; - if (MIFARE_DESFIRE != freefare_get_tag_type(tag)) - continue; - - char *tag_uid = freefare_get_tag_uid(tag); - /* Result of various operations */ - int res; - - res = mifare_desfire_connect(tag); - if (res < 0) { - warnx("Can't connect to Mifare DESFire target."); - goto next_tag; - } + for (int id = 0; tags[id]; id++) { + FreefareTag tag = tags[id]; + if (MIFARE_DESFIRE != freefare_get_tag_type(tag)) + continue; - if (mifare_desfire_select_application(tag, aid) != 0) { - // Check for old card with our key as master key - res = mifare_desfire_authenticate(tag, 0, key_master); - if (res >= 0) { - warnx("Old tag detected: %s", tag_uid); - res = mifare_desfire_change_key(tag, 0, key_master, key_null); - } - - // Card needs to have default null key as master - res = mifare_desfire_authenticate(tag, 0, key_null); - if (res < 0) { - warnx("Could not authenticate: %d", res); - goto next_tag; - } + char *tag_uid = freefare_get_tag_uid(tag); + /* Result of various operations */ + int res; - // create application - res = mifare_desfire_create_application_aes(tag, aid, MDAPP_SETTINGS(0, 1, 0, 0, 1), 1); - if (res < 0) { - warnx("Could not create application: %d", res); - goto next_tag; - } + res = mifare_desfire_connect(tag); + if (res < 0) { + warnx("Can't connect to Mifare DESFire target."); + goto next_tag; + } - // Select it - res = mifare_desfire_select_application(tag, aid); - if (res < 0) { - warnx("Application not selectable after creation: %d", res); - goto next_tag; - } + if (mifare_desfire_select_application(tag, aid) != 0) { + // Check for old card with our key as master key + res = mifare_desfire_authenticate(tag, 0, key_master); + if (res >= 0) { + warnx("Old tag detected: %s", tag_uid); + res = + mifare_desfire_change_key(tag, 0, key_null, key_master); + if (res < 0) { + warnx("Could not change key: %d", res); + goto next_tag; + } + } - // Key should be null - res = mifare_desfire_authenticate_aes(tag, 0, key_null); - if (res < 0) { - warnx("Could not authenticate new application with default key: %d", res); - goto next_tag; - } + // Card needs to have default null key as master + res = mifare_desfire_authenticate(tag, 0, key_null); + if (res < 0) { + warnx("Could not authenticate: %d", res); + goto next_tag; + } - // Update to our key - res = mifare_desfire_change_key(tag, 0, key_master, key_null); - if (res < 0) { - warnx("Could not change key of new application to master key: %d", res); - goto next_tag; - } - - // Authenticate with new key - res = mifare_desfire_authenticate_aes(tag, 0, key_master); - if (res < 0) { - warnx("Could not authenticate new application with our key: %d", res); - goto next_tag; - } + // create application + res = mifare_desfire_create_application_aes( + tag, aid, MDAPP_SETTINGS(0, 1, 0, 0, 1), 1); + if (res < 0) { + warnx("Could not create application: %d", res); + goto next_tag; + } - // Create file - res = mifare_desfire_create_std_data_file(tag, 0, 0, MDAR(0, 0, 0, 0), RANDOM_UID_SIZE); - if (res < 0) { - warnx("Could not create data file: %d", res); - goto next_tag; - } + // Select it + res = mifare_desfire_select_application(tag, aid); + if (res < 0) { + warnx("Application not selectable after creation: %d", res); + goto next_tag; + } - // Grab random data for it - unsigned char uid_data[RANDOM_UID_SIZE]; - { - int fd = open("/dev/urandom", O_RDONLY); - if (fd < 0) { - warnx("Could not open /dev/urandom"); - goto next_tag; - } + // Key should be null + res = mifare_desfire_authenticate_aes(tag, 0, key_null); + if (res < 0) { + warnx( + "Could not authenticate new application with default " + "key: %d", + res); + goto next_tag; + } - if (RANDOM_UID_SIZE != read(fd, &uid_data[0], RANDOM_UID_SIZE)) { - warnx("Could not read data from /dev/random"); - goto next_tag; - } - close(fd); - } + // Update to our key + res = mifare_desfire_change_key(tag, 0, key_master, key_null); + if (res < 0) { + warnx( + "Could not change key of new application to master " + "key: %d", + res); + goto next_tag; + } - // Write data - res = mifare_desfire_write_data(tag, 0, 0, RANDOM_UID_SIZE, &uid_data[0]); - if (res < 0) { - warnx("Could not write UID data to tag: %d", res); - goto next_tag; - } - } + // Authenticate with new key + res = mifare_desfire_authenticate_aes(tag, 0, key_master); + if (res < 0) { + warnx( + "Could not authenticate new application with our key: " + "%d", + res); + goto next_tag; + } - // Authenticate with our key - res = mifare_desfire_authenticate_aes(tag, 0, key_master); - if (res < 0) { - warnx("Authentication on application failed: %d", res); - goto next_tag; - } + // Create file + res = mifare_desfire_create_std_data_file( + tag, 0, 0, MDAR(0, 0, 0, 0), RANDOM_UID_SIZE); + if (res < 0) { + warnx("Could not create data file: %d", res); + goto next_tag; + } - // Grab UID - uint8_t data[RANDOM_UID_SIZE]; - res = mifare_desfire_read_data(tag, 0, 0, RANDOM_UID_SIZE, &data[0]); - if (res != RANDOM_UID_SIZE) { - warnx("Could not read all bytes from tag: %d", res); - goto next_tag; - } + // Grab random data for it + unsigned char uid_data[RANDOM_UID_SIZE]; + { + int fd = open("/dev/urandom", O_RDONLY); + if (fd < 0) { + warnx("Could not open /dev/urandom"); + goto next_tag; + } - // Print out key ID and UID - fprintf(out, "%s:", tag_uid); - for (int j = 0; j < RANDOM_UID_SIZE; j++) { - fprintf(out, "%02x", data[j]); - } - fprintf(out, "\n"); - fflush(out); + if (RANDOM_UID_SIZE != + read(fd, &uid_data[0], RANDOM_UID_SIZE)) { + warnx("Could not read data from /dev/random"); + goto next_tag; + } + close(fd); + } -next_tag: - free(tag_uid); - - mifare_desfire_disconnect(tag); - } + // Write data + res = mifare_desfire_write_data(tag, 0, 0, RANDOM_UID_SIZE, + &uid_data[0]); + if (res < 0) { + warnx("Could not write UID data to tag: %d", res); + goto next_tag; + } + } - while (freefare_selected_tag_is_present(device)) - ; - - freefare_free_tags(tags); - fflush(stdout); - fflush(stderr); - } + // Authenticate with our key + res = mifare_desfire_authenticate_aes(tag, 0, key_master); + if (res < 0) { + warnx("Authentication on application failed: %d", res); + goto next_tag; + } - mifare_desfire_key_free(key_null); - mifare_desfire_key_free(key_master); + // Grab UID + uint8_t data[RANDOM_UID_SIZE]; + res = mifare_desfire_read_data(tag, 0, 0, RANDOM_UID_SIZE, &data[0]); + if (res != RANDOM_UID_SIZE) { + warnx("Could not read all bytes from tag: %d", res); + goto next_tag; + } - nfc_close(device); - nfc_exit(context); + // Print out key ID and UID + fprintf(out, "%s:", tag_uid); + for (int j = 0; j < RANDOM_UID_SIZE; j++) { + fprintf(out, "%02x", data[j]); + } + fprintf(out, "\n"); + fflush(out); - exit(error); + next_tag: + free(tag_uid); + + mifare_desfire_disconnect(tag); + } + + while (freefare_selected_tag_is_present(device)) + ; + + freefare_free_tags(tags); + fflush(stdout); + fflush(stderr); + } + + mifare_desfire_key_free(key_null); + mifare_desfire_key_free(key_master); + + nfc_close(device); + nfc_exit(context); + + exit(error); } diff --git a/poll_desfire.h b/poll_desfire.h index c012eb6..6da6180 100644 --- a/poll_desfire.h +++ b/poll_desfire.h @@ -3,4 +3,3 @@ int init(nfc_context **context, nfc_device **device); void poll_target(nfc_device *device); -