Merge pull request #17 from nfc-tools/tag-detection
Get some flexibility in the tag type detection
This commit is contained in:
commit
48c9383ce1
11 changed files with 250 additions and 189 deletions
|
@ -50,10 +50,27 @@ ssize_t felica_transceive (FreefareTag tag, uint8_t *data_in, uint8_t *data_out,
|
|||
return res;
|
||||
}
|
||||
|
||||
FreefareTag
|
||||
felica_tag_new (void)
|
||||
bool
|
||||
felica_taste (nfc_device *device, nfc_target target)
|
||||
{
|
||||
return malloc (sizeof (struct felica_tag));
|
||||
(void) device;
|
||||
return target.nm.nmt == NMT_FELICA;
|
||||
}
|
||||
|
||||
FreefareTag
|
||||
felica_tag_new (nfc_device *device, nfc_target target)
|
||||
{
|
||||
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
|
||||
|
@ -67,8 +84,6 @@ felica_tag_free (FreefareTag tag)
|
|||
ssize_t
|
||||
felica_read_ex (FreefareTag tag, uint16_t service, uint8_t block_count, uint8_t blocks[], uint8_t *data, size_t length)
|
||||
{
|
||||
ASSERT_FELICA (tag);
|
||||
|
||||
assert (block_count <= MAX_BLOCK_COUNT);
|
||||
assert (length == 16 * block_count);
|
||||
|
||||
|
@ -120,8 +135,6 @@ felica_read (FreefareTag tag, uint16_t service, uint8_t block, uint8_t *data, si
|
|||
ssize_t
|
||||
felica_write_ex (FreefareTag tag, uint16_t service, uint8_t block_count, uint8_t blocks[], uint8_t *data, size_t length)
|
||||
{
|
||||
ASSERT_FELICA (tag);
|
||||
|
||||
DEBUG_FUNCTION();
|
||||
|
||||
assert (block_count <= MAX_BLOCK_COUNT);
|
||||
|
|
|
@ -28,86 +28,27 @@
|
|||
|
||||
#define NXP_MANUFACTURER_CODE 0x04
|
||||
|
||||
struct supported_tag supported_tags[] = {
|
||||
{ FELICA, "FeliCA", NMT_FELICA, 0x00, 0, 0, { 0x00 }, NULL },
|
||||
{ MIFARE_CLASSIC_1K, "Mifare Classic 1k", NMT_ISO14443A, 0x08, 0, 0, { 0x00 }, NULL },
|
||||
{ MIFARE_CLASSIC_1K, "Mifare Classic 1k (Emulated)", NMT_ISO14443A, 0x28, 0, 0, { 0x00 }, NULL },
|
||||
{ MIFARE_CLASSIC_1K, "Mifare Classic 1k (Emulated)", NMT_ISO14443A, 0x68, 0, 0, { 0x00 }, NULL },
|
||||
{ MIFARE_CLASSIC_1K, "Infineon Mifare Classic 1k", NMT_ISO14443A, 0x88, 0, 0, { 0x00 }, NULL },
|
||||
{ MIFARE_CLASSIC_4K, "Mifare Classic 4k", NMT_ISO14443A, 0x18, 0, 0, { 0x00 }, NULL },
|
||||
{ MIFARE_CLASSIC_4K, "Mifare Classic 4k (Emulated)", NMT_ISO14443A, 0x38, 0, 0, { 0x00 }, NULL },
|
||||
{ MIFARE_DESFIRE, "Mifare DESFire", NMT_ISO14443A, 0x20, 5, 4, { 0x75, 0x77, 0x81, 0x02 /*, 0xXX */ }, NULL},
|
||||
{ MIFARE_DESFIRE, "Cyanogenmod card emulation", NMT_ISO14443A, 0x60, 4, 3, { 0x78, 0x33, 0x88 /*, 0xXX */ }, NULL},
|
||||
{ MIFARE_DESFIRE, "Android HCE", NMT_ISO14443A, 0x60, 4, 3, { 0x78, 0x80, 0x70 /*, 0xXX */ }, NULL},
|
||||
{ MIFARE_ULTRALIGHT_C, "Mifare UltraLightC", NMT_ISO14443A, 0x00, 0, 0, { 0x00 }, is_mifare_ultralightc_on_reader },
|
||||
{ MIFARE_ULTRALIGHT, "Mifare UltraLight", NMT_ISO14443A, 0x00, 0, 0, { 0x00 }, NULL },
|
||||
};
|
||||
|
||||
/*
|
||||
* Automagically allocate a FreefareTag given a device and target info.
|
||||
*/
|
||||
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 (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 ((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 (!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:
|
||||
case MIFARE_ULTRALIGHT_C:
|
||||
tag = mifare_ultralight_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;
|
||||
}
|
||||
|
@ -202,7 +143,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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -211,7 +152,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";
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -260,22 +216,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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -286,7 +227,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) {
|
||||
|
|
|
@ -67,14 +67,30 @@ 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);
|
||||
|
||||
#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);
|
||||
|
||||
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);
|
||||
|
||||
int mifare_ultralight_connect (FreefareTag tag);
|
||||
int mifare_ultralight_disconnect (FreefareTag tag);
|
||||
|
||||
|
@ -82,8 +98,18 @@ int mifare_ultralight_read (FreefareTag tag, const MifareUltralightPageNumber
|
|||
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);
|
||||
|
||||
|
||||
|
||||
bool mifare_classic1k_taste (nfc_device *device, nfc_target target);
|
||||
bool mifare_classic4k_taste (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];
|
||||
|
||||
typedef uint8_t MifareClassicSectorNumber;
|
||||
|
@ -185,6 +211,10 @@ int mifare_application_free (Mad mad, const MadAid aid);
|
|||
|
||||
MifareClassicSectorNumber *mifare_application_find (Mad mad, const MadAid aid);
|
||||
|
||||
|
||||
|
||||
bool mifare_desfire_taste (nfc_device *device, nfc_target target);
|
||||
|
||||
/* File types */
|
||||
|
||||
enum mifare_desfire_file_types {
|
||||
|
@ -334,6 +364,9 @@ struct mifare_desfire_file_settings {
|
|||
} settings;
|
||||
};
|
||||
|
||||
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);
|
||||
|
||||
|
|
|
@ -102,14 +102,6 @@ struct mad_sector_0x00;
|
|||
struct mad_sector_0x10;
|
||||
|
||||
void nxp_crc (uint8_t *crc, const uint8_t value);
|
||||
FreefareTag felica_tag_new (void);
|
||||
void felica_tag_free (FreefareTag tag);
|
||||
FreefareTag mifare_classic_tag_new (void);
|
||||
void mifare_classic_tag_free (FreefareTag tag);
|
||||
FreefareTag mifare_desfire_tag_new (void);
|
||||
void mifare_desfire_tag_free (FreefareTag tags);
|
||||
FreefareTag mifare_ultralight_tag_new (void);
|
||||
void mifare_ultralight_tag_free (FreefareTag tag);
|
||||
uint8_t sector_0x00_crc8 (Mad mad);
|
||||
uint8_t sector_0x10_crc8 (Mad mad);
|
||||
|
||||
|
@ -165,17 +157,6 @@ void *assert_crypto_buffer_size (FreefareTag tag, size_t nbytes);
|
|||
// Max PAGE_COUNT of the Ultralight Family:
|
||||
#define MIFARE_ULTRALIGHT_MAX_PAGE_COUNT 0x30
|
||||
|
||||
struct supported_tag {
|
||||
enum freefare_tag_type type;
|
||||
const char *friendly_name;
|
||||
uint8_t modulation_type;
|
||||
uint8_t SAK;
|
||||
uint8_t ATS_min_length;
|
||||
uint8_t ATS_compare_length;
|
||||
uint8_t ATS[5];
|
||||
bool (*check_tag_on_reader) (nfc_device *, nfc_iso14443a_info);
|
||||
};
|
||||
|
||||
/*
|
||||
* This structure is common to all supported MIFARE targets but shall not be
|
||||
* used directly (it's some kind of abstract class). All members in this
|
||||
|
@ -187,8 +168,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 {
|
||||
|
@ -268,13 +250,6 @@ struct mifare_ultralight_tag {
|
|||
#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)
|
||||
|
||||
#define ASSERT_FELICA(tag) do { if (tag->tag_info->type != FELICA) return errno = ENODEV, -1; } while (0)
|
||||
#define ASSERT_MIFARE_CLASSIC(tag) do { if ((tag->tag_info->type != MIFARE_CLASSIC_1K) && (tag->tag_info->type != MIFARE_CLASSIC_4K)) return errno = ENODEV, -1; } while (0)
|
||||
#define ASSERT_MIFARE_DESFIRE(tag) do { if (tag->tag_info->type != MIFARE_DESFIRE) return errno = ENODEV, -1; } while (0)
|
||||
#define IS_MIFARE_ULTRALIGHT_C(tag) (tag->tag_info->type == MIFARE_ULTRALIGHT_C)
|
||||
#define ASSERT_MIFARE_ULTRALIGHT(tag) do { if ((tag->tag_info->type != MIFARE_ULTRALIGHT) && (! IS_MIFARE_ULTRALIGHT_C(tag))) return errno = ENODEV, -1; } while (0)
|
||||
#define ASSERT_MIFARE_ULTRALIGHT_C(tag) do { if (! IS_MIFARE_ULTRALIGHT_C(tag)) return errno = ENODEV, -1; } while (0)
|
||||
|
||||
/*
|
||||
* FreefareTag cast macros
|
||||
*
|
||||
|
|
|
@ -193,14 +193,60 @@ int get_block_access_bits (FreefareTag tag, const MifareClassicBlockNumber blo
|
|||
* Memory management functions.
|
||||
*/
|
||||
|
||||
bool
|
||||
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
|
||||
);
|
||||
}
|
||||
|
||||
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
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -228,7 +274,6 @@ int
|
|||
mifare_classic_connect (FreefareTag tag)
|
||||
{
|
||||
ASSERT_INACTIVE (tag);
|
||||
ASSERT_MIFARE_CLASSIC (tag);
|
||||
|
||||
nfc_target pnti;
|
||||
nfc_modulation modulation = {
|
||||
|
@ -251,7 +296,6 @@ int
|
|||
mifare_classic_disconnect (FreefareTag tag)
|
||||
{
|
||||
ASSERT_ACTIVE (tag);
|
||||
ASSERT_MIFARE_CLASSIC (tag);
|
||||
|
||||
if (nfc_initiator_deselect_target (tag->device) >= 0) {
|
||||
tag->active = 0;
|
||||
|
@ -277,7 +321,6 @@ int
|
|||
mifare_classic_authenticate (FreefareTag tag, const MifareClassicBlockNumber block, const MifareClassicKey key, const MifareClassicKeyType key_type)
|
||||
{
|
||||
ASSERT_ACTIVE (tag);
|
||||
ASSERT_MIFARE_CLASSIC (tag);
|
||||
|
||||
BUFFER_INIT (cmd, 12);
|
||||
BUFFER_INIT (res, 1);
|
||||
|
@ -308,7 +351,6 @@ int
|
|||
mifare_classic_read (FreefareTag tag, const MifareClassicBlockNumber block, MifareClassicBlock *data)
|
||||
{
|
||||
ASSERT_ACTIVE (tag);
|
||||
ASSERT_MIFARE_CLASSIC (tag);
|
||||
|
||||
BUFFER_INIT (cmd, 2);
|
||||
BUFFER_ALIAS (res, data, sizeof(MifareClassicBlock));
|
||||
|
@ -377,7 +419,6 @@ int
|
|||
mifare_classic_write (FreefareTag tag, const MifareClassicBlockNumber block, const MifareClassicBlock data)
|
||||
{
|
||||
ASSERT_ACTIVE (tag);
|
||||
ASSERT_MIFARE_CLASSIC (tag);
|
||||
|
||||
BUFFER_INIT (cmd, 2 + sizeof (MifareClassicBlock));
|
||||
BUFFER_INIT (res, 1);
|
||||
|
@ -399,7 +440,6 @@ int
|
|||
mifare_classic_increment (FreefareTag tag, const MifareClassicBlockNumber block, const uint32_t amount)
|
||||
{
|
||||
ASSERT_ACTIVE (tag);
|
||||
ASSERT_MIFARE_CLASSIC (tag);
|
||||
|
||||
BUFFER_INIT (cmd, 6);
|
||||
BUFFER_INIT (res, 1);
|
||||
|
@ -421,7 +461,6 @@ int
|
|||
mifare_classic_decrement (FreefareTag tag, const MifareClassicBlockNumber block, const uint32_t amount)
|
||||
{
|
||||
ASSERT_ACTIVE (tag);
|
||||
ASSERT_MIFARE_CLASSIC (tag);
|
||||
|
||||
BUFFER_INIT (cmd, 6);
|
||||
BUFFER_INIT (res, 1);
|
||||
|
@ -442,7 +481,6 @@ int
|
|||
mifare_classic_restore (FreefareTag tag, const MifareClassicBlockNumber block)
|
||||
{
|
||||
ASSERT_ACTIVE (tag);
|
||||
ASSERT_MIFARE_CLASSIC (tag);
|
||||
|
||||
/*
|
||||
* Same length as the increment and decrement commands but only the first
|
||||
|
@ -471,7 +509,6 @@ int
|
|||
mifare_classic_transfer (FreefareTag tag, const MifareClassicBlockNumber block)
|
||||
{
|
||||
ASSERT_ACTIVE (tag);
|
||||
ASSERT_MIFARE_CLASSIC (tag);
|
||||
|
||||
BUFFER_INIT (cmd, 2);
|
||||
BUFFER_INIT (res, 1);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
@ -288,7 +303,6 @@ int
|
|||
mifare_desfire_connect (FreefareTag tag)
|
||||
{
|
||||
ASSERT_INACTIVE (tag);
|
||||
ASSERT_MIFARE_DESFIRE (tag);
|
||||
|
||||
nfc_target pnti;
|
||||
nfc_modulation modulation = {
|
||||
|
@ -332,7 +346,6 @@ int
|
|||
mifare_desfire_disconnect (FreefareTag tag)
|
||||
{
|
||||
ASSERT_ACTIVE (tag);
|
||||
ASSERT_MIFARE_DESFIRE (tag);
|
||||
|
||||
free (MIFARE_DESFIRE (tag)->session_key);
|
||||
MIFARE_DESFIRE(tag)->session_key = NULL;
|
||||
|
@ -353,7 +366,6 @@ static int
|
|||
authenticate (FreefareTag tag, uint8_t cmd, uint8_t key_no, MifareDESFireKey key)
|
||||
{
|
||||
ASSERT_ACTIVE (tag);
|
||||
ASSERT_MIFARE_DESFIRE (tag);
|
||||
|
||||
memset (MIFARE_DESFIRE (tag)->ivect, 0, MAX_CRYPTO_BLOCK_SIZE);
|
||||
|
||||
|
@ -471,7 +483,6 @@ int
|
|||
mifare_desfire_change_key_settings (FreefareTag tag, uint8_t settings)
|
||||
{
|
||||
ASSERT_ACTIVE (tag);
|
||||
ASSERT_MIFARE_DESFIRE (tag);
|
||||
ASSERT_AUTHENTICATED (tag);
|
||||
|
||||
BUFFER_INIT (cmd, 9 + CMAC_LENGTH);
|
||||
|
@ -497,7 +508,6 @@ int
|
|||
mifare_desfire_get_key_settings (FreefareTag tag, uint8_t *settings, uint8_t *max_keys)
|
||||
{
|
||||
ASSERT_ACTIVE (tag);
|
||||
ASSERT_MIFARE_DESFIRE (tag);
|
||||
|
||||
BUFFER_INIT (cmd, 1);
|
||||
BUFFER_INIT (res, 3 + CMAC_LENGTH);
|
||||
|
@ -526,7 +536,6 @@ int
|
|||
mifare_desfire_change_key (FreefareTag tag, uint8_t key_no, MifareDESFireKey new_key, MifareDESFireKey old_key)
|
||||
{
|
||||
ASSERT_ACTIVE (tag);
|
||||
ASSERT_MIFARE_DESFIRE (tag);
|
||||
ASSERT_AUTHENTICATED (tag);
|
||||
|
||||
BUFFER_INIT (cmd, 42);
|
||||
|
@ -640,7 +649,6 @@ int
|
|||
mifare_desfire_get_key_version (FreefareTag tag, uint8_t key_no, uint8_t *version)
|
||||
{
|
||||
ASSERT_ACTIVE (tag);
|
||||
ASSERT_MIFARE_DESFIRE (tag);
|
||||
|
||||
ASSERT_NOT_NULL (version);
|
||||
|
||||
|
@ -671,7 +679,6 @@ static int
|
|||
create_application (FreefareTag tag, MifareDESFireAID aid, uint8_t settings1, uint8_t settings2, int want_iso_application, int want_iso_file_identifiers, uint16_t iso_file_id, uint8_t *iso_file_name, size_t iso_file_name_len)
|
||||
{
|
||||
ASSERT_ACTIVE (tag);
|
||||
ASSERT_MIFARE_DESFIRE (tag);
|
||||
|
||||
BUFFER_INIT (cmd, 22);
|
||||
BUFFER_INIT (res, 1 + CMAC_LENGTH);
|
||||
|
@ -743,7 +750,6 @@ int
|
|||
mifare_desfire_delete_application (FreefareTag tag, MifareDESFireAID aid)
|
||||
{
|
||||
ASSERT_ACTIVE (tag);
|
||||
ASSERT_MIFARE_DESFIRE (tag);
|
||||
|
||||
BUFFER_INIT (cmd, 4 + CMAC_LENGTH);
|
||||
BUFFER_INIT (res, 1 + CMAC_LENGTH);
|
||||
|
@ -778,7 +784,6 @@ int
|
|||
mifare_desfire_get_application_ids (FreefareTag tag, MifareDESFireAID *aids[], size_t *count)
|
||||
{
|
||||
ASSERT_ACTIVE (tag);
|
||||
ASSERT_MIFARE_DESFIRE (tag);
|
||||
|
||||
BUFFER_INIT (cmd, 1);
|
||||
BUFFER_INIT (res, MAX_RAPDU_SIZE);
|
||||
|
@ -833,7 +838,6 @@ int
|
|||
mifare_desfire_get_df_names (FreefareTag tag, MifareDESFireDF *dfs[], size_t *count)
|
||||
{
|
||||
ASSERT_ACTIVE (tag);
|
||||
ASSERT_MIFARE_DESFIRE (tag);
|
||||
|
||||
*count = 0;
|
||||
*dfs = NULL;
|
||||
|
@ -882,7 +886,6 @@ int
|
|||
mifare_desfire_select_application (FreefareTag tag, MifareDESFireAID aid)
|
||||
{
|
||||
ASSERT_ACTIVE (tag);
|
||||
ASSERT_MIFARE_DESFIRE (tag);
|
||||
|
||||
struct mifare_desfire_aid null_aid = { .data = { 0x00, 0x00, 0x00 } };
|
||||
|
||||
|
@ -921,7 +924,6 @@ int
|
|||
mifare_desfire_format_picc (FreefareTag tag)
|
||||
{
|
||||
ASSERT_ACTIVE (tag);
|
||||
ASSERT_MIFARE_DESFIRE (tag);
|
||||
ASSERT_AUTHENTICATED (tag);
|
||||
|
||||
BUFFER_INIT (cmd, 1 + CMAC_LENGTH);
|
||||
|
@ -953,7 +955,6 @@ int
|
|||
mifare_desfire_get_version (FreefareTag tag, struct mifare_desfire_version_info *version_info)
|
||||
{
|
||||
ASSERT_ACTIVE (tag);
|
||||
ASSERT_MIFARE_DESFIRE (tag);
|
||||
|
||||
ASSERT_NOT_NULL (version_info);
|
||||
|
||||
|
@ -991,7 +992,6 @@ int
|
|||
mifare_desfire_free_mem (FreefareTag tag, uint32_t *size)
|
||||
{
|
||||
ASSERT_ACTIVE (tag);
|
||||
ASSERT_MIFARE_DESFIRE (tag);
|
||||
|
||||
ASSERT_NOT_NULL (size);
|
||||
|
||||
|
@ -1019,7 +1019,6 @@ int
|
|||
mifare_desfire_set_configuration (FreefareTag tag, bool disable_format, bool enable_random_uid)
|
||||
{
|
||||
ASSERT_ACTIVE (tag);
|
||||
ASSERT_MIFARE_DESFIRE (tag);
|
||||
|
||||
BUFFER_INIT (cmd, 10);
|
||||
BUFFER_INIT (res, 1 + CMAC_LENGTH);
|
||||
|
@ -1045,7 +1044,6 @@ int
|
|||
mifare_desfire_set_default_key (FreefareTag tag, MifareDESFireKey key)
|
||||
{
|
||||
ASSERT_ACTIVE (tag);
|
||||
ASSERT_MIFARE_DESFIRE (tag);
|
||||
|
||||
BUFFER_INIT (cmd, 34);
|
||||
BUFFER_INIT (res, 1 + CMAC_LENGTH);
|
||||
|
@ -1085,7 +1083,6 @@ int
|
|||
mifare_desfire_set_ats (FreefareTag tag, uint8_t *ats)
|
||||
{
|
||||
ASSERT_ACTIVE (tag);
|
||||
ASSERT_MIFARE_DESFIRE (tag);
|
||||
|
||||
BUFFER_INIT (cmd, 34);
|
||||
BUFFER_INIT (res, 1 + CMAC_LENGTH);
|
||||
|
@ -1122,7 +1119,6 @@ int
|
|||
mifare_desfire_get_card_uid (FreefareTag tag, char **uid)
|
||||
{
|
||||
ASSERT_ACTIVE (tag);
|
||||
ASSERT_MIFARE_DESFIRE (tag);
|
||||
|
||||
ASSERT_NOT_NULL (uid);
|
||||
|
||||
|
@ -1160,7 +1156,6 @@ int
|
|||
mifare_desfire_get_file_ids (FreefareTag tag, uint8_t **files, size_t *count)
|
||||
{
|
||||
ASSERT_ACTIVE (tag);
|
||||
ASSERT_MIFARE_DESFIRE (tag);
|
||||
|
||||
BUFFER_INIT (cmd, 1 + CMAC_LENGTH);
|
||||
BUFFER_INIT (res, 16 + CMAC_LENGTH);
|
||||
|
@ -1193,7 +1188,6 @@ int
|
|||
mifare_desfire_get_iso_file_ids (FreefareTag tag, uint16_t **files, size_t *count)
|
||||
{
|
||||
ASSERT_ACTIVE (tag);
|
||||
ASSERT_MIFARE_DESFIRE (tag);
|
||||
|
||||
BUFFER_INIT (cmd, 1);
|
||||
BUFFER_INIT (res, 2*27 + 1);
|
||||
|
@ -1241,7 +1235,6 @@ int
|
|||
mifare_desfire_get_file_settings (FreefareTag tag, uint8_t file_no, struct mifare_desfire_file_settings *settings)
|
||||
{
|
||||
ASSERT_ACTIVE (tag);
|
||||
ASSERT_MIFARE_DESFIRE (tag);
|
||||
|
||||
if (cached_file_settings_current[file_no]) {
|
||||
*settings = cached_file_settings[file_no];
|
||||
|
@ -1300,7 +1293,6 @@ int
|
|||
mifare_desfire_change_file_settings (FreefareTag tag, uint8_t file_no, uint8_t communication_settings, uint16_t access_rights)
|
||||
{
|
||||
ASSERT_ACTIVE (tag);
|
||||
ASSERT_MIFARE_DESFIRE (tag);
|
||||
|
||||
struct mifare_desfire_file_settings settings;
|
||||
int res = mifare_desfire_get_file_settings (tag, file_no, &settings);
|
||||
|
@ -1353,7 +1345,6 @@ static int
|
|||
create_file1 (FreefareTag tag, uint8_t command, uint8_t file_no, int has_iso_file_id, uint16_t iso_file_id, uint8_t communication_settings, uint16_t access_rights, uint32_t file_size)
|
||||
{
|
||||
ASSERT_ACTIVE (tag);
|
||||
ASSERT_MIFARE_DESFIRE (tag);
|
||||
|
||||
BUFFER_INIT (cmd, 10 + CMAC_LENGTH);
|
||||
BUFFER_INIT (res, 1 + CMAC_LENGTH);
|
||||
|
@ -1409,7 +1400,6 @@ 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)
|
||||
{
|
||||
ASSERT_ACTIVE (tag);
|
||||
ASSERT_MIFARE_DESFIRE (tag);
|
||||
|
||||
BUFFER_INIT (cmd, 18 + CMAC_LENGTH);
|
||||
BUFFER_INIT (res, 1 + CMAC_LENGTH);
|
||||
|
@ -1442,7 +1432,6 @@ static int
|
|||
create_file2 (FreefareTag tag, uint8_t command, uint8_t file_no, int has_iso_file_id, uint16_t iso_file_id, uint8_t communication_settings, uint16_t access_rights, uint32_t record_size, uint32_t max_number_of_records)
|
||||
{
|
||||
ASSERT_ACTIVE (tag);
|
||||
ASSERT_MIFARE_DESFIRE (tag);
|
||||
|
||||
BUFFER_INIT (cmd, 11 + CMAC_LENGTH);
|
||||
BUFFER_INIT (res, 1 + CMAC_LENGTH);
|
||||
|
@ -1499,7 +1488,6 @@ int
|
|||
mifare_desfire_delete_file (FreefareTag tag, uint8_t file_no)
|
||||
{
|
||||
ASSERT_ACTIVE (tag);
|
||||
ASSERT_MIFARE_DESFIRE (tag);
|
||||
|
||||
BUFFER_INIT (cmd, 2 + CMAC_LENGTH);
|
||||
BUFFER_INIT (res, 1 + CMAC_LENGTH);
|
||||
|
@ -1531,7 +1519,6 @@ read_data (FreefareTag tag, uint8_t command, uint8_t file_no, off_t offset, size
|
|||
size_t bytes_received = 0;
|
||||
|
||||
ASSERT_ACTIVE (tag);
|
||||
ASSERT_MIFARE_DESFIRE (tag);
|
||||
ASSERT_CS (cs);
|
||||
|
||||
BUFFER_INIT (cmd, 8);
|
||||
|
@ -1654,7 +1641,6 @@ write_data (FreefareTag tag, uint8_t command, uint8_t file_no, off_t offset, siz
|
|||
size_t bytes_send = 0;
|
||||
|
||||
ASSERT_ACTIVE (tag);
|
||||
ASSERT_MIFARE_DESFIRE (tag);
|
||||
ASSERT_CS (cs);
|
||||
|
||||
BUFFER_INIT (cmd, 8 + length + CMAC_LENGTH);
|
||||
|
@ -1734,7 +1720,6 @@ mifare_desfire_get_value_ex (FreefareTag tag, uint8_t file_no, int32_t *value, i
|
|||
return errno = EINVAL, -1;
|
||||
|
||||
ASSERT_ACTIVE (tag);
|
||||
ASSERT_MIFARE_DESFIRE (tag);
|
||||
ASSERT_CS (cs);
|
||||
|
||||
BUFFER_INIT (cmd, 2 + CMAC_LENGTH);
|
||||
|
@ -1768,7 +1753,6 @@ int
|
|||
mifare_desfire_credit_ex (FreefareTag tag, uint8_t file_no, int32_t amount, int cs)
|
||||
{
|
||||
ASSERT_ACTIVE (tag);
|
||||
ASSERT_MIFARE_DESFIRE (tag);
|
||||
ASSERT_CS (cs);
|
||||
|
||||
BUFFER_INIT (cmd, 10 + CMAC_LENGTH);
|
||||
|
@ -1801,7 +1785,6 @@ int
|
|||
mifare_desfire_debit_ex (FreefareTag tag, uint8_t file_no, int32_t amount, int cs)
|
||||
{
|
||||
ASSERT_ACTIVE (tag);
|
||||
ASSERT_MIFARE_DESFIRE (tag);
|
||||
ASSERT_CS (cs);
|
||||
|
||||
BUFFER_INIT (cmd, 10 + CMAC_LENGTH);
|
||||
|
@ -1834,7 +1817,6 @@ int
|
|||
mifare_desfire_limited_credit_ex (FreefareTag tag, uint8_t file_no, int32_t amount, int cs)
|
||||
{
|
||||
ASSERT_ACTIVE (tag);
|
||||
ASSERT_MIFARE_DESFIRE (tag);
|
||||
ASSERT_CS (cs);
|
||||
|
||||
BUFFER_INIT (cmd, 10 + CMAC_LENGTH);
|
||||
|
@ -1885,7 +1867,6 @@ int
|
|||
mifare_desfire_clear_record_file (FreefareTag tag, uint8_t file_no)
|
||||
{
|
||||
ASSERT_ACTIVE (tag);
|
||||
ASSERT_MIFARE_DESFIRE (tag);
|
||||
|
||||
BUFFER_INIT (cmd, 2 + CMAC_LENGTH);
|
||||
BUFFER_INIT (res, 1 + CMAC_LENGTH);
|
||||
|
@ -1912,7 +1893,6 @@ int
|
|||
mifare_desfire_commit_transaction (FreefareTag tag)
|
||||
{
|
||||
ASSERT_ACTIVE (tag);
|
||||
ASSERT_MIFARE_DESFIRE (tag);
|
||||
|
||||
BUFFER_INIT (cmd, 1 + CMAC_LENGTH);
|
||||
BUFFER_INIT (res, 1 + CMAC_LENGTH);
|
||||
|
@ -1936,7 +1916,6 @@ int
|
|||
mifare_desfire_abort_transaction (FreefareTag tag)
|
||||
{
|
||||
ASSERT_ACTIVE (tag);
|
||||
ASSERT_MIFARE_DESFIRE (tag);
|
||||
|
||||
BUFFER_INIT (cmd, 1 + CMAC_LENGTH);
|
||||
BUFFER_INIT (res, 1 + CMAC_LENGTH);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
|
||||
#define ASSERT_VALID_PAGE(tag, page, mode_write) \
|
||||
do { \
|
||||
if (IS_MIFARE_ULTRALIGHT_C(tag)) { \
|
||||
if (is_mifare_ultralightc (tag)) { \
|
||||
if (mode_write) { \
|
||||
if (page >= MIFARE_ULTRALIGHT_C_PAGE_COUNT) return errno = EINVAL, -1; \
|
||||
} else { \
|
||||
|
@ -89,6 +89,24 @@
|
|||
} \
|
||||
} while (0)
|
||||
|
||||
static bool
|
||||
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)
|
||||
{
|
||||
return taste (target) && !is_mifare_ultralightc_on_reader (device, target.nti.nai);
|
||||
}
|
||||
|
||||
bool
|
||||
mifare_ultralightc_taste (nfc_device *device, nfc_target target)
|
||||
{
|
||||
return taste (target) && is_mifare_ultralightc_on_reader (device, target.nti.nai);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Memory management functions.
|
||||
|
@ -97,10 +115,32 @@
|
|||
/*
|
||||
* 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)
|
||||
{
|
||||
return malloc (sizeof (struct mifare_ultralight_tag));
|
||||
FreefareTag 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;
|
||||
tag->info = target;
|
||||
tag->active = 0;
|
||||
}
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
FreefareTag
|
||||
mifare_ultralight_tag_new (nfc_device *device, nfc_target target)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -112,6 +152,12 @@ mifare_ultralight_tag_free (FreefareTag tag)
|
|||
free (tag);
|
||||
}
|
||||
|
||||
void
|
||||
mifare_ultralightc_tag_free (FreefareTag tag)
|
||||
{
|
||||
mifare_ultralight_tag_free (tag);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* MIFARE card communication preparation functions
|
||||
|
@ -129,7 +175,6 @@ int
|
|||
mifare_ultralight_connect (FreefareTag tag)
|
||||
{
|
||||
ASSERT_INACTIVE (tag);
|
||||
ASSERT_MIFARE_ULTRALIGHT (tag);
|
||||
|
||||
nfc_target pnti;
|
||||
nfc_modulation modulation = {
|
||||
|
@ -154,7 +199,6 @@ int
|
|||
mifare_ultralight_disconnect (FreefareTag tag)
|
||||
{
|
||||
ASSERT_ACTIVE (tag);
|
||||
ASSERT_MIFARE_ULTRALIGHT (tag);
|
||||
|
||||
if (nfc_initiator_deselect_target (tag->device) >= 0) {
|
||||
tag->active = 0;
|
||||
|
@ -180,7 +224,6 @@ int
|
|||
mifare_ultralight_read (FreefareTag tag, MifareUltralightPageNumber page, MifareUltralightPage *data)
|
||||
{
|
||||
ASSERT_ACTIVE (tag);
|
||||
ASSERT_MIFARE_ULTRALIGHT (tag);
|
||||
ASSERT_VALID_PAGE (tag, page, false);
|
||||
|
||||
if (!MIFARE_ULTRALIGHT(tag)->cached_pages[page]) {
|
||||
|
@ -194,7 +237,7 @@ mifare_ultralight_read (FreefareTag tag, MifareUltralightPageNumber page, Mifare
|
|||
|
||||
/* Handle wrapped pages */
|
||||
int iPageCount;
|
||||
if (IS_MIFARE_ULTRALIGHT_C(tag)) {
|
||||
if (is_mifare_ultralightc (tag)) {
|
||||
iPageCount = MIFARE_ULTRALIGHT_C_PAGE_COUNT_READ;
|
||||
} else {
|
||||
iPageCount = MIFARE_ULTRALIGHT_PAGE_COUNT;
|
||||
|
@ -220,7 +263,6 @@ int
|
|||
mifare_ultralight_write (FreefareTag tag, const MifareUltralightPageNumber page, const MifareUltralightPage data)
|
||||
{
|
||||
ASSERT_ACTIVE (tag);
|
||||
ASSERT_MIFARE_ULTRALIGHT (tag);
|
||||
ASSERT_VALID_PAGE (tag, page, true);
|
||||
|
||||
BUFFER_INIT (cmd, 6);
|
||||
|
@ -245,7 +287,6 @@ int
|
|||
mifare_ultralightc_authenticate (FreefareTag tag, const MifareDESFireKey key)
|
||||
{
|
||||
ASSERT_ACTIVE (tag);
|
||||
ASSERT_MIFARE_ULTRALIGHT_C (tag);
|
||||
|
||||
BUFFER_INIT (cmd1, 2);
|
||||
BUFFER_INIT (res, 9);
|
||||
|
@ -306,6 +347,18 @@ mifare_ultralightc_authenticate (FreefareTag tag, const MifareDESFireKey key)
|
|||
return 0;
|
||||
}
|
||||
|
||||
bool
|
||||
is_mifare_ultralight (FreefareTag tag)
|
||||
{
|
||||
return tag->type == MIFARE_ULTRALIGHT;
|
||||
}
|
||||
|
||||
bool
|
||||
is_mifare_ultralightc (FreefareTag tag)
|
||||
{
|
||||
return tag->type == MIFARE_ULTRALIGHT_C;
|
||||
}
|
||||
|
||||
/*
|
||||
* Callback for freefare_tag_new to test presence of a MIFARE UltralightC on the reader.
|
||||
*/
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -75,7 +75,7 @@ test_mifare_ultralight_invalid_page (void)
|
|||
MifareUltralightPage page = { 0x00, 0x00, 0x00, 0x00 };
|
||||
|
||||
int invalid_page;
|
||||
if (IS_MIFARE_ULTRALIGHT_C (tag)) {
|
||||
if (is_mifare_ultralightc (tag)) {
|
||||
invalid_page = MIFARE_ULTRALIGHT_C_PAGE_COUNT;
|
||||
} else {
|
||||
invalid_page = MIFARE_ULTRALIGHT_PAGE_COUNT;
|
||||
|
@ -130,7 +130,7 @@ test_mifare_ultralight_cache_wrap (void)
|
|||
int res;
|
||||
MifareUltralightPage page;
|
||||
int last_page;
|
||||
if (IS_MIFARE_ULTRALIGHT_C (tag)) {
|
||||
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
|
||||
|
@ -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