Rework tag allocation.
Split Mifare Classic 1 and 4K tag allocation. Rely on new tasting functions.
This commit is contained in:
parent
0279361873
commit
ee628f7ec5
11 changed files with 162 additions and 109 deletions
|
@ -58,9 +58,19 @@ felica_taste (nfc_device *device, nfc_target target)
|
|||
}
|
||||
|
||||
FreefareTag
|
||||
felica_tag_new (void)
|
||||
felica_tag_new (nfc_device *device, nfc_target target)
|
||||
{
|
||||
return malloc (sizeof (struct felica_tag));
|
||||
FreefareTag tag;
|
||||
|
||||
if ((tag = malloc (sizeof (struct felica_tag)))) {
|
||||
tag->type = FELICA;
|
||||
tag->free_tag = felica_tag_free;
|
||||
tag->device = device;
|
||||
tag->info = target;
|
||||
tag->active = 0;
|
||||
}
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -49,68 +49,22 @@ struct supported_tag supported_tags[] = {
|
|||
FreefareTag
|
||||
freefare_tag_new (nfc_device *device, nfc_target target)
|
||||
{
|
||||
bool found = false;
|
||||
struct supported_tag *tag_info;
|
||||
FreefareTag tag;
|
||||
FreefareTag tag = NULL;
|
||||
|
||||
/* Ensure the target is supported */
|
||||
for (size_t i = 0; i < sizeof (supported_tags) / sizeof (struct supported_tag); i++) {
|
||||
if (target.nm.nmt != supported_tags[i].modulation_type)
|
||||
continue;
|
||||
|
||||
if (target.nm.nmt == NMT_FELICA) {
|
||||
tag_info = &(supported_tags[i]);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
if ((target.nm.nmt == NMT_ISO14443A) && ((target.nti.nai.szUidLen == 4) || (target.nti.nai.abtUid[0] == NXP_MANUFACTURER_CODE)) &&
|
||||
(target.nti.nai.btSak == supported_tags[i].SAK) &&
|
||||
(!supported_tags[i].ATS_min_length || ((target.nti.nai.szAtsLen >= supported_tags[i].ATS_min_length) &&
|
||||
(0 == memcmp (target.nti.nai.abtAts, supported_tags[i].ATS, supported_tags[i].ATS_compare_length)))) &&
|
||||
((supported_tags[i].check_tag_on_reader == NULL) ||
|
||||
supported_tags[i].check_tag_on_reader(device, target.nti.nai))) {
|
||||
|
||||
tag_info = &(supported_tags[i]);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
if (felica_taste (device, target)) {
|
||||
tag = felica_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 (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 (!found)
|
||||
return NULL;
|
||||
|
||||
/* Allocate memory for the found MIFARE target */
|
||||
switch (tag_info->type) {
|
||||
case FELICA:
|
||||
tag = felica_tag_new ();
|
||||
break;
|
||||
case MIFARE_CLASSIC_1K:
|
||||
case MIFARE_CLASSIC_4K:
|
||||
tag = mifare_classic_tag_new ();
|
||||
break;
|
||||
case MIFARE_DESFIRE:
|
||||
tag = mifare_desfire_tag_new ();
|
||||
break;
|
||||
case MIFARE_ULTRALIGHT:
|
||||
tag = mifare_ultralight_tag_new ();
|
||||
break;
|
||||
case MIFARE_ULTRALIGHT_C:
|
||||
tag = mifare_ultralightc_tag_new ();
|
||||
break;
|
||||
}
|
||||
|
||||
if (!tag)
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* Initialize common fields
|
||||
* (Target specific fields are initialized in mifare_*_tag_new())
|
||||
*/
|
||||
tag->device = device;
|
||||
tag->info = target;
|
||||
tag->active = 0;
|
||||
tag->tag_info = tag_info;
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
|
@ -204,7 +158,7 @@ freefare_get_tags (nfc_device *device)
|
|||
enum freefare_tag_type
|
||||
freefare_get_tag_type (FreefareTag tag)
|
||||
{
|
||||
return tag->tag_info->type;
|
||||
return tag->type;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -213,7 +167,22 @@ freefare_get_tag_type (FreefareTag tag)
|
|||
const char *
|
||||
freefare_get_tag_friendly_name (FreefareTag tag)
|
||||
{
|
||||
return tag->tag_info->friendly_name;
|
||||
switch (tag->type) {
|
||||
case FELICA:
|
||||
return "FeliCA";
|
||||
case MIFARE_CLASSIC_1K:
|
||||
return "Mifare Classic 1k";
|
||||
case MIFARE_CLASSIC_4K:
|
||||
return "Mifare Classic 4k";
|
||||
case MIFARE_DESFIRE:
|
||||
return "Mifare DESFire";
|
||||
case MIFARE_ULTRALIGHT_C:
|
||||
return "Mifare UltraLightC";
|
||||
case MIFARE_ULTRALIGHT:
|
||||
return "Mifare UltraLight";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -262,22 +231,7 @@ void
|
|||
freefare_free_tag (FreefareTag tag)
|
||||
{
|
||||
if (tag) {
|
||||
switch (tag->tag_info->type) {
|
||||
case FELICA:
|
||||
felica_tag_free (tag);
|
||||
break;
|
||||
case MIFARE_CLASSIC_1K:
|
||||
case MIFARE_CLASSIC_4K:
|
||||
mifare_classic_tag_free (tag);
|
||||
break;
|
||||
case MIFARE_DESFIRE:
|
||||
mifare_desfire_tag_free (tag);
|
||||
break;
|
||||
case MIFARE_ULTRALIGHT:
|
||||
case MIFARE_ULTRALIGHT_C:
|
||||
mifare_ultralight_tag_free (tag);
|
||||
break;
|
||||
}
|
||||
tag->free_tag (tag);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -288,7 +242,7 @@ freefare_strerror (FreefareTag tag)
|
|||
if (nfc_device_get_last_error (tag->device) < 0) {
|
||||
p = nfc_strerror (tag->device);
|
||||
} else {
|
||||
if (tag->tag_info->type == MIFARE_DESFIRE) {
|
||||
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) {
|
||||
|
|
|
@ -97,7 +97,8 @@ bool is_mifare_ultralightc_on_reader (nfc_device *device, nfc_iso14443a_info n
|
|||
|
||||
|
||||
|
||||
bool mifare_classic_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);
|
||||
|
||||
typedef unsigned char MifareClassicBlock[16];
|
||||
|
||||
|
|
|
@ -102,15 +102,16 @@ struct mad_sector_0x00;
|
|||
struct mad_sector_0x10;
|
||||
|
||||
void nxp_crc (uint8_t *crc, const uint8_t value);
|
||||
FreefareTag felica_tag_new (void);
|
||||
FreefareTag felica_tag_new (nfc_device *device, nfc_target target);
|
||||
void felica_tag_free (FreefareTag tag);
|
||||
FreefareTag mifare_classic_tag_new (void);
|
||||
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);
|
||||
FreefareTag mifare_desfire_tag_new (void);
|
||||
FreefareTag mifare_desfire_tag_new (nfc_device *device, nfc_target target);
|
||||
void mifare_desfire_tag_free (FreefareTag tags);
|
||||
FreefareTag mifare_ultralight_tag_new (void);
|
||||
FreefareTag mifare_ultralight_tag_new (nfc_device *device, nfc_target target);
|
||||
void mifare_ultralight_tag_free (FreefareTag tag);
|
||||
FreefareTag mifare_ultralightc_tag_new (void);
|
||||
FreefareTag mifare_ultralightc_tag_new (nfc_device *device, nfc_target target);
|
||||
void mifare_ultralightc_tag_free (FreefareTag tag);
|
||||
uint8_t sector_0x00_crc8 (Mad mad);
|
||||
uint8_t sector_0x10_crc8 (Mad mad);
|
||||
|
@ -189,8 +190,9 @@ struct supported_tag {
|
|||
struct freefare_tag {
|
||||
nfc_device *device;
|
||||
nfc_target info;
|
||||
const struct supported_tag *tag_info;
|
||||
int type;
|
||||
int active;
|
||||
void (*free_tag) (FreefareTag tag);
|
||||
};
|
||||
|
||||
struct felica_tag {
|
||||
|
|
|
@ -194,7 +194,7 @@ int get_block_access_bits (FreefareTag tag, const MifareClassicBlockNumber blo
|
|||
*/
|
||||
|
||||
bool
|
||||
mifare_classic_taste (nfc_device *device, nfc_target target)
|
||||
mifare_classic1k_taste (nfc_device *device, nfc_target target)
|
||||
{
|
||||
(void) device;
|
||||
return target.nm.nmt == NMT_ISO14443A &&
|
||||
|
@ -202,8 +202,18 @@ mifare_classic_taste (nfc_device *device, nfc_target target)
|
|||
target.nti.nai.btSak == 0x08 ||
|
||||
target.nti.nai.btSak == 0x28 ||
|
||||
target.nti.nai.btSak == 0x68 ||
|
||||
target.nti.nai.btSak == 0x88 ||
|
||||
target.nti.nai.btSak == 0x18
|
||||
target.nti.nai.btSak == 0x88
|
||||
);
|
||||
}
|
||||
|
||||
bool
|
||||
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
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -211,10 +221,32 @@ mifare_classic_taste (nfc_device *device, nfc_target target)
|
|||
* Allocates and initialize a MIFARE Classic tag.
|
||||
*/
|
||||
|
||||
FreefareTag
|
||||
mifare_classic_tag_new (void)
|
||||
static FreefareTag
|
||||
_mifare_classic_tag_new (nfc_device *device, nfc_target target, int tag_type)
|
||||
{
|
||||
return malloc (sizeof (struct mifare_classic_tag));
|
||||
FreefareTag tag;
|
||||
|
||||
if ((tag = malloc (sizeof (struct mifare_classic_tag)))) {
|
||||
tag->type = tag_type;
|
||||
tag->free_tag = mifare_classic_tag_free;
|
||||
tag->device = device;
|
||||
tag->info = target;
|
||||
tag->active = 0;
|
||||
}
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
FreefareTag
|
||||
mifare_classic1k_tag_new (nfc_device *device, nfc_target target)
|
||||
{
|
||||
return _mifare_classic_tag_new (device, target, MIFARE_CLASSIC_1K);
|
||||
}
|
||||
|
||||
FreefareTag
|
||||
mifare_classic4k_tag_new (nfc_device *device, nfc_target target)
|
||||
{
|
||||
return _mifare_classic_tag_new (device, target, MIFARE_CLASSIC_4K);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -239,6 +239,16 @@ le24toh (uint8_t data[3])
|
|||
return (data[2] << 16) | (data[1] << 8) | data[0];
|
||||
}
|
||||
|
||||
bool
|
||||
mifare_desfire_taste (nfc_device *device, nfc_target target)
|
||||
{
|
||||
(void) device;
|
||||
return target.nm.nmt == NMT_ISO14443A &&
|
||||
target.nti.nai.btSak == 0x20 &&
|
||||
target.nti.nai.szAtsLen >= 5 &&
|
||||
memcmp (target.nti.nai.abtAts, "\x75\x77\x81\x02", 4) == 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Memory management functions.
|
||||
|
@ -248,7 +258,7 @@ le24toh (uint8_t data[3])
|
|||
* Allocates and initialize a MIFARE DESFire tag.
|
||||
*/
|
||||
FreefareTag
|
||||
mifare_desfire_tag_new (void)
|
||||
mifare_desfire_tag_new (nfc_device *device, nfc_target target)
|
||||
{
|
||||
FreefareTag tag;
|
||||
if ((tag= malloc (sizeof (struct mifare_desfire_tag)))) {
|
||||
|
@ -257,6 +267,11 @@ mifare_desfire_tag_new (void)
|
|||
MIFARE_DESFIRE (tag)->session_key = NULL;
|
||||
MIFARE_DESFIRE (tag)->crypto_buffer = NULL;
|
||||
MIFARE_DESFIRE (tag)->crypto_buffer_size = 0;
|
||||
tag->type = MIFARE_DESFIRE;
|
||||
tag->free_tag = mifare_desfire_tag_free;
|
||||
tag->device = device;
|
||||
tag->info = target;
|
||||
tag->active = 0;
|
||||
}
|
||||
return tag;
|
||||
}
|
||||
|
|
|
@ -72,7 +72,7 @@ mifare_desfire_error_lookup (uint8_t code)
|
|||
uint8_t
|
||||
mifare_desfire_last_pcd_error (FreefareTag tag)
|
||||
{
|
||||
if (tag->tag_info->type != MIFARE_DESFIRE)
|
||||
if (tag->type != MIFARE_DESFIRE)
|
||||
return 0;
|
||||
|
||||
return MIFARE_DESFIRE (tag)->last_pcd_error;
|
||||
|
@ -81,7 +81,7 @@ mifare_desfire_last_pcd_error (FreefareTag tag)
|
|||
uint8_t
|
||||
mifare_desfire_last_picc_error (FreefareTag tag)
|
||||
{
|
||||
if (tag->tag_info->type != MIFARE_DESFIRE)
|
||||
if (tag->type != MIFARE_DESFIRE)
|
||||
return 0;
|
||||
|
||||
return MIFARE_DESFIRE (tag)->last_picc_error;
|
||||
|
|
|
@ -115,24 +115,33 @@ mifare_ultralightc_taste (nfc_device *device, nfc_target target)
|
|||
/*
|
||||
* Allocates and initialize a MIFARE UltraLight tag.
|
||||
*/
|
||||
FreefareTag
|
||||
mifare_ultralight_tag_new (void)
|
||||
static FreefareTag
|
||||
_mifare_ultralightc_tag_new (nfc_device *device, nfc_target target, bool is_ultralightc)
|
||||
{
|
||||
FreefareTag res;
|
||||
if ((res = malloc (sizeof (struct mifare_ultralight_tag)))) {
|
||||
MIFARE_ULTRALIGHT(res)->is_ultralightc = false;
|
||||
FreefareTag tag;
|
||||
|
||||
if ((tag = malloc (sizeof (struct mifare_ultralight_tag)))) {
|
||||
MIFARE_ULTRALIGHT(tag)->is_ultralightc = is_ultralightc;
|
||||
tag->type = (is_ultralightc) ? MIFARE_ULTRALIGHT_C : MIFARE_ULTRALIGHT;
|
||||
tag->free_tag = mifare_ultralightc_tag_free;
|
||||
tag->device = device;
|
||||
tag->info = target;
|
||||
tag->active = 0;
|
||||
}
|
||||
return res;
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
FreefareTag
|
||||
mifare_ultralightc_tag_new (void)
|
||||
mifare_ultralight_tag_new (nfc_device *device, nfc_target target)
|
||||
{
|
||||
FreefareTag res;
|
||||
if ((res = malloc (sizeof (struct mifare_ultralight_tag)))) {
|
||||
MIFARE_ULTRALIGHT(res)->is_ultralightc = true;
|
||||
}
|
||||
return res;
|
||||
return _mifare_ultralightc_tag_new (device, target, false);
|
||||
}
|
||||
|
||||
FreefareTag
|
||||
mifare_ultralightc_tag_new (nfc_device *device, nfc_target target)
|
||||
{
|
||||
return _mifare_ultralightc_tag_new (device, target, true);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -12,6 +12,7 @@ TESTS_ENVIRONMENT = NO_MAKE=yes CUTTER="$(CUTTER)"
|
|||
|
||||
cutter_unit_test_libs = \
|
||||
test_felica.la \
|
||||
test_freefare.la \
|
||||
test_mad.la \
|
||||
test_mifare_application.la \
|
||||
test_mifare_classic.la \
|
||||
|
@ -39,6 +40,9 @@ test_felica_la_SOURCES = test_felica.c \
|
|||
felica_fixture.h
|
||||
test_felica_la_LIBADD = $(top_builddir)/libfreefare/libfreefare.la
|
||||
|
||||
test_freefare_la_SOURCES = test_freefare.c
|
||||
test_freefare_la_LIBADD = $(top_builddir)/libfreefare/libfreefare.la
|
||||
|
||||
test_mad_la_SOURCES = test_mad.c
|
||||
test_mad_la_LIBADD = $(top_builddir)/libfreefare/libfreefare.la
|
||||
|
||||
|
|
26
test/test_freefare.c
Normal file
26
test/test_freefare.c
Normal file
|
@ -0,0 +1,26 @@
|
|||
#include <cutter.h>
|
||||
|
||||
#include <freefare.h>
|
||||
#include "freefare_internal.h"
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
|
@ -178,7 +178,7 @@ test_mifare_ultralightc_authenticate (void)
|
|||
int res;
|
||||
MifareDESFireKey key;
|
||||
|
||||
if (tag->tag_info->type == MIFARE_ULTRALIGHT_C) {
|
||||
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);
|
||||
|
|
Loading…
Reference in a new issue