parent
36d44bdc90
commit
0279361873
8 changed files with 101 additions and 67 deletions
|
@ -50,6 +50,13 @@ ssize_t felica_transceive (FreefareTag tag, uint8_t *data_in, uint8_t *data_out,
|
|||
return res;
|
||||
}
|
||||
|
||||
bool
|
||||
felica_taste (nfc_device *device, nfc_target target)
|
||||
{
|
||||
(void) device;
|
||||
return target.nm.nmt == NMT_FELICA;
|
||||
}
|
||||
|
||||
FreefareTag
|
||||
felica_tag_new (void)
|
||||
{
|
||||
|
@ -67,8 +74,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 +125,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);
|
||||
|
|
|
@ -92,9 +92,11 @@ freefare_tag_new (nfc_device *device, nfc_target target)
|
|||
tag = mifare_desfire_tag_new ();
|
||||
break;
|
||||
case MIFARE_ULTRALIGHT:
|
||||
case MIFARE_ULTRALIGHT_C:
|
||||
tag = mifare_ultralight_tag_new ();
|
||||
break;
|
||||
case MIFARE_ULTRALIGHT_C:
|
||||
tag = mifare_ultralightc_tag_new ();
|
||||
break;
|
||||
}
|
||||
|
||||
if (!tag)
|
||||
|
|
|
@ -67,6 +67,10 @@ 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
|
||||
|
||||
|
@ -75,6 +79,11 @@ ssize_t felica_read_ex (FreefareTag tag, uint16_t service, uint8_t block_count
|
|||
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);
|
||||
|
||||
int mifare_ultralight_connect (FreefareTag tag);
|
||||
int mifare_ultralight_disconnect (FreefareTag tag);
|
||||
|
||||
|
@ -82,8 +91,14 @@ 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_classic_taste (nfc_device *device, nfc_target target);
|
||||
|
||||
typedef unsigned char MifareClassicBlock[16];
|
||||
|
||||
typedef uint8_t MifareClassicSectorNumber;
|
||||
|
@ -185,6 +200,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 {
|
||||
|
|
|
@ -110,6 +110,8 @@ 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);
|
||||
FreefareTag mifare_ultralightc_tag_new (void);
|
||||
void mifare_ultralightc_tag_free (FreefareTag tag);
|
||||
uint8_t sector_0x00_crc8 (Mad mad);
|
||||
uint8_t sector_0x10_crc8 (Mad mad);
|
||||
|
||||
|
@ -257,6 +259,7 @@ struct mifare_ultralight_tag {
|
|||
/* mifare_ultralight_read() reads 4 pages at a time (wrapping) */
|
||||
MifareUltralightPage cache[MIFARE_ULTRALIGHT_MAX_PAGE_COUNT + 3];
|
||||
uint8_t cached_pages[MIFARE_ULTRALIGHT_MAX_PAGE_COUNT];
|
||||
bool is_ultralightc;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -268,13 +271,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,6 +193,20 @@ int get_block_access_bits (FreefareTag tag, const MifareClassicBlockNumber blo
|
|||
* Memory management functions.
|
||||
*/
|
||||
|
||||
bool
|
||||
mifare_classic_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 == 0x18
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocates and initialize a MIFARE Classic tag.
|
||||
*/
|
||||
|
@ -228,7 +242,6 @@ int
|
|||
mifare_classic_connect (FreefareTag tag)
|
||||
{
|
||||
ASSERT_INACTIVE (tag);
|
||||
ASSERT_MIFARE_CLASSIC (tag);
|
||||
|
||||
nfc_target pnti;
|
||||
nfc_modulation modulation = {
|
||||
|
@ -251,7 +264,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 +289,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 +319,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 +387,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 +408,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 +429,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 +449,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 +477,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);
|
||||
|
|
|
@ -288,7 +288,6 @@ int
|
|||
mifare_desfire_connect (FreefareTag tag)
|
||||
{
|
||||
ASSERT_INACTIVE (tag);
|
||||
ASSERT_MIFARE_DESFIRE (tag);
|
||||
|
||||
nfc_target pnti;
|
||||
nfc_modulation modulation = {
|
||||
|
@ -332,7 +331,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 +351,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 +468,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 +493,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 +521,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 +634,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 +664,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 +735,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 +769,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 +823,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 +871,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 +909,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 +940,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 +977,6 @@ int
|
|||
mifare_desfire_free_mem (FreefareTag tag, uint32_t *size)
|
||||
{
|
||||
ASSERT_ACTIVE (tag);
|
||||
ASSERT_MIFARE_DESFIRE (tag);
|
||||
|
||||
ASSERT_NOT_NULL (size);
|
||||
|
||||
|
@ -1019,7 +1004,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 +1029,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 +1068,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 +1104,6 @@ int
|
|||
mifare_desfire_get_card_uid (FreefareTag tag, char **uid)
|
||||
{
|
||||
ASSERT_ACTIVE (tag);
|
||||
ASSERT_MIFARE_DESFIRE (tag);
|
||||
|
||||
ASSERT_NOT_NULL (uid);
|
||||
|
||||
|
@ -1160,7 +1141,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 +1173,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 +1220,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 +1278,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 +1330,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 +1385,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 +1417,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 +1473,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 +1504,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 +1626,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 +1705,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 +1738,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 +1770,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 +1802,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 +1852,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 +1878,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 +1901,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);
|
||||
|
|
|
@ -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.
|
||||
|
@ -100,7 +118,21 @@
|
|||
FreefareTag
|
||||
mifare_ultralight_tag_new (void)
|
||||
{
|
||||
return malloc (sizeof (struct mifare_ultralight_tag));
|
||||
FreefareTag res;
|
||||
if ((res = malloc (sizeof (struct mifare_ultralight_tag)))) {
|
||||
MIFARE_ULTRALIGHT(res)->is_ultralightc = false;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
FreefareTag
|
||||
mifare_ultralightc_tag_new (void)
|
||||
{
|
||||
FreefareTag res;
|
||||
if ((res = malloc (sizeof (struct mifare_ultralight_tag)))) {
|
||||
MIFARE_ULTRALIGHT(res)->is_ultralightc = true;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -112,6 +144,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 +167,6 @@ int
|
|||
mifare_ultralight_connect (FreefareTag tag)
|
||||
{
|
||||
ASSERT_INACTIVE (tag);
|
||||
ASSERT_MIFARE_ULTRALIGHT (tag);
|
||||
|
||||
nfc_target pnti;
|
||||
nfc_modulation modulation = {
|
||||
|
@ -154,7 +191,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 +216,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 +229,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 +255,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 +279,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 +339,18 @@ mifare_ultralightc_authenticate (FreefareTag tag, const MifareDESFireKey key)
|
|||
return 0;
|
||||
}
|
||||
|
||||
bool
|
||||
is_mifare_ultralight (FreefareTag tag)
|
||||
{
|
||||
return !MIFARE_ULTRALIGHT(tag)->is_ultralightc;
|
||||
}
|
||||
|
||||
bool
|
||||
is_mifare_ultralightc (FreefareTag tag)
|
||||
{
|
||||
return MIFARE_ULTRALIGHT(tag)->is_ultralightc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Callback for freefare_tag_new to test presence of a MIFARE UltralightC on the reader.
|
||||
*/
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue