Compare commits

...

2 Commits

Author SHA1 Message Date
Valentin Ochs 14cf157b56 Formatting 2022-11-22 17:13:44 +01:00
Valentin Ochs 084866dbbc Rewrite 2022-11-22 17:13:29 +01:00
4 changed files with 215 additions and 101 deletions

View File

@ -1,8 +1,9 @@
VERSION ?= $(shell git rev-parse --short HEAD) VERSION ?= $(shell git rev-parse --short HEAD)
PKG_CONFIG ?= pkg-config
all: poll_desfire all: poll_desfire
poll_desfire: poll_desfire.o poll_desfire: poll_desfire.o nfc_init.o
$(CC) $(LDFLAGS) $(shell $(PKG_CONFIG) --libs libfreefare) $^ -o $@ $(CC) $(LDFLAGS) $(shell $(PKG_CONFIG) --libs libfreefare) $^ -o $@
%.o: %.c %.o: %.c

35
nfc_init.c Normal file
View File

@ -0,0 +1,35 @@
#include <err.h>
#include <errno.h>
#include <stdlib.h>
#include "poll_desfire.h"
int init(nfc_context **context, nfc_device **device) {
nfc_connstring devices[8];
size_t device_count;
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 = 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);

View File

@ -1,133 +1,206 @@
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <err.h> #include <err.h>
#include <errno.h> #include <errno.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "poll_desfire.h"
#include <nfc/nfc.h> #define AID 0x22eaa0
#include <freefare.h> #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);
}
int main(int argc, char **argv) { int main(int argc, char **argv) {
int error = EXIT_SUCCESS; int error = EXIT_SUCCESS;
nfc_device *device = NULL; nfc_context *context = NULL;
FreefareTag *tags = NULL; nfc_device *device = NULL;
FreefareTag *tags = NULL;
MifareDESFireKey key_null, key_master;
MifareDESFireAID aid = mifare_desfire_aid_new(AID);
nfc_connstring devices[8]; error = init(&context, &device);
size_t device_count; init_keys(&key_null, &key_master, (argc > 1) ? argv[1] : "key");
nfc_context *context; FILE *out = argc > 2 ? fopen(argv[2], "w") : stdout;
nfc_init(&context);
if (context == NULL) {
errx(EXIT_FAILURE, "Unable to init libnfc (malloc)");
}
uint8_t const key_data_null[8] = {0, 0, 0, 0, 0, 0, 0, 0}; while (true) {
MifareDESFireKey key_null = mifare_desfire_des_key_new_with_version(key_data_null); tags = freefare_get_tags(device);
if (!tags) {
nfc_close(device);
errx(EXIT_FAILURE, "Error listing tags.");
}
uint8_t key_data_real[16] = {0}; for (int id = 0; tags[id]; id++) {
{ FreefareTag tag = tags[id];
char const *name = (argc > 1) ? argv[1] : "key"; if (MIFARE_DESFIRE != freefare_get_tag_type(tag))
FILE *f = fopen(name, "rb"); continue;
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);
}
MifareDESFireKey key_real = mifare_desfire_aes_key_new(key_data_real);
FILE *out = argc > 2 ? fopen(argv[2], "w") : stdout; char *tag_uid = freefare_get_tag_uid(tag);
/* Result of various operations */
int res;
device_count = nfc_list_devices(context, devices, sizeof(devices) / sizeof(devices[0])); res = mifare_desfire_connect(tag);
if (device_count <= 0) { if (res < 0) {
errx(EXIT_FAILURE, "No NFC device found."); warnx("Can't connect to Mifare DESFire target.");
} goto next_tag;
}
if (device_count > 1) { if (mifare_desfire_select_application(tag, aid) != 0) {
printf("More than 1 device available. Using %s\n", devices[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);
}
device = nfc_open(context, devices[0]); // Card needs to have default null key as master
if (!device) { res = mifare_desfire_authenticate(tag, 0, key_null);
errx(EXIT_FAILURE, "nfc_open() failed."); if (res < 0) {
} warnx("Could not authenticate: %d", res);
goto next_tag;
}
if (nfc_initiator_init(device) < 0) { // create application
errx(EXIT_FAILURE, "Initiator failed."); 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;
}
while (true) { // Select it
/* Poll for targets */ res = mifare_desfire_select_application(tag, aid);
const nfc_modulation nmModulations = {.nmt = NMT_ISO14443A, .nbr = NBR_106}; if (res < 0) {
nfc_target target; warnx("Application not selectable after creation: %d", res);
nfc_initiator_poll_target(device, &nmModulations, 1, 10, 1, &target); goto next_tag;
}
/* Got at least one, read tag list */ // Key should be null
tags = freefare_get_tags(device); res = mifare_desfire_authenticate_aes(tag, 0, key_null);
if (!tags) { if (res < 0) {
nfc_close(device); warnx(
errx(EXIT_FAILURE, "Error listing tags."); "Could not authenticate new application with default "
} "key: %d",
res);
goto next_tag;
}
if (!tags[0]) { // Update to our key
goto free_tags; 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;
}
FreefareTag tag = tags[0]; // Authenticate with new key
if (MIFARE_DESFIRE != freefare_get_tag_type(tag)) res = mifare_desfire_authenticate_aes(tag, 0, key_master);
goto free_tags; if (res < 0) {
warnx(
"Could not authenticate new application with our key: "
"%d",
res);
goto next_tag;
}
char *tag_uid = freefare_get_tag_uid(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;
}
/* Result of various operations */ // Grab random data for it
int res; 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;
}
res = mifare_desfire_connect(tag); if (RANDOM_UID_SIZE !=
if (res < 0) { read(fd, &uid_data[0], RANDOM_UID_SIZE)) {
warnx("Can't connect to Mifare DESFire target."); warnx("Could not read data from /dev/random");
goto free_tag; goto next_tag;
} }
close(fd);
}
res = mifare_desfire_authenticate(tag, 0, key_null); // Write data
if (res >= 0) { res = mifare_desfire_write_data(tag, 0, 0, RANDOM_UID_SIZE,
// Default key still active, create new key &uid_data[0]);
res = mifare_desfire_change_key(tag, 0, key_real, key_null); if (res < 0) {
warnx("Could not write UID data to tag: %d", res);
goto next_tag;
}
}
if (res < 0) { // Authenticate with our key
warnx("Error changing key"); res = mifare_desfire_authenticate_aes(tag, 0, key_master);
goto free_tag; if (res < 0) {
} warnx("Authentication on application failed: %d", res);
} goto next_tag;
}
res = mifare_desfire_authenticate_aes(tag, 0, key_real); // Grab UID
if (res < 0) { uint8_t data[RANDOM_UID_SIZE];
warnx("Authentication on master application failed"); res = mifare_desfire_read_data(tag, 0, 0, RANDOM_UID_SIZE, &data[0]);
goto free_tag; if (res != RANDOM_UID_SIZE) {
} else { warnx("Could not read all bytes from tag: %d", res);
fprintf(out, "%s\n", tag_uid); goto next_tag;
fflush(out); }
}
wait_disconnect: // Print out key ID and UID
while (0 == nfc_initiator_target_is_present(device, 0)) fprintf(out, "%s:", tag_uid);
; for (int j = 0; j < RANDOM_UID_SIZE; j++) {
mifare_desfire_disconnect(tag); fprintf(out, "%02x", data[j]);
}
fprintf(out, "\n");
fflush(out);
free_tag: next_tag:
free(tag_uid); free(tag_uid);
free_tags:
freefare_free_tags(tags);
fflush(stdout);
fflush(stderr);
}
mifare_desfire_key_free(key_null); mifare_desfire_disconnect(tag);
mifare_desfire_key_free(key_real); }
nfc_close(device); while (freefare_selected_tag_is_present(device))
nfc_exit(context); ;
exit(error); 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);
} }

5
poll_desfire.h Normal file
View File

@ -0,0 +1,5 @@
#include <nfc/nfc.h>
#include <freefare.h>
int init(nfc_context **context, nfc_device **device);
void poll_target(nfc_device *device);