Merge de libfreefare-ultralight branch into trunk (Mifare UltraLightC support).
This commit is contained in:
parent
e4057ef163
commit
82a7b8df66
8 changed files with 210 additions and 32 deletions
|
@ -151,6 +151,7 @@ linkedman = \
|
|||
mifare_ultralight.3 mifare_ultralight_get_uid.3 \
|
||||
mifare_ultralight.3 mifare_ultralight_read.3 \
|
||||
mifare_ultralight.3 mifare_ultralight_write.3 \
|
||||
mifare_ultralight.3 mifare_ultralightc_authenticate.3 \
|
||||
tlv.3 tlv_decode.3 \
|
||||
tlv.3 tlv_encode.3
|
||||
|
||||
|
|
|
@ -29,11 +29,12 @@
|
|||
#define NXP_MANUFACTURER_CODE 0x04
|
||||
|
||||
struct supported_tag supported_tags[] = {
|
||||
{ CLASSIC_1K, "Mifare Classic 1k", 0x08, 0, 0, { 0x00 } },
|
||||
{ CLASSIC_4K, "Mifare Classic 4k", 0x18, 0, 0, { 0x00 } },
|
||||
{ CLASSIC_4K, "Mifare Classic 4k (Emulated)", 0x38, 0, 0, { 0x00 } },
|
||||
{ DESFIRE, "Mifare DESFire", 0x20, 5, 4, { 0x75, 0x77, 0x81, 0x02 /*, 0xXX */ }},
|
||||
{ ULTRALIGHT, "Mifare UltraLight", 0x00, 0, 0, { 0x00 } },
|
||||
{ CLASSIC_1K, "Mifare Classic 1k", 0x08, 0, 0, { 0x00 }, NULL },
|
||||
{ CLASSIC_4K, "Mifare Classic 4k", 0x18, 0, 0, { 0x00 }, NULL },
|
||||
{ CLASSIC_4K, "Mifare Classic 4k (Emulated)", 0x38, 0, 0, { 0x00 }, NULL },
|
||||
{ DESFIRE, "Mifare DESFire", 0x20, 5, 4, { 0x75, 0x77, 0x81, 0x02 /*, 0xXX */ }, NULL},
|
||||
{ ULTRALIGHT_C, "Mifare UltraLightC", 0x00, 0, 0, { 0x00 }, is_mifare_ultralightc_on_reader },
|
||||
{ ULTRALIGHT, "Mifare UltraLight", 0x00, 0, 0, { 0x00 }, NULL },
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -51,7 +52,9 @@ freefare_tag_new (nfc_device_t *device, nfc_iso14443a_info_t nai)
|
|||
if (((nai.szUidLen == 4) || (nai.abtUid[0] == NXP_MANUFACTURER_CODE)) &&
|
||||
(nai.btSak == supported_tags[i].SAK) &&
|
||||
(!supported_tags[i].ATS_min_length || ((nai.szAtsLen >= supported_tags[i].ATS_min_length) &&
|
||||
(0 == memcmp (nai.abtAts, supported_tags[i].ATS, supported_tags[i].ATS_compare_length))))) {
|
||||
(0 == memcmp (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, nai))))) {
|
||||
|
||||
tag_info = &(supported_tags[i]);
|
||||
found = true;
|
||||
|
@ -72,6 +75,7 @@ freefare_tag_new (nfc_device_t *device, nfc_iso14443a_info_t nai)
|
|||
tag = mifare_desfire_tag_new ();
|
||||
break;
|
||||
case ULTRALIGHT:
|
||||
case ULTRALIGHT_C:
|
||||
tag = mifare_ultralight_tag_new ();
|
||||
break;
|
||||
}
|
||||
|
@ -201,6 +205,7 @@ freefare_free_tag (MifareTag tag)
|
|||
mifare_desfire_tag_free (tag);
|
||||
break;
|
||||
case ULTRALIGHT:
|
||||
case ULTRALIGHT_C:
|
||||
mifare_ultralight_tag_free (tag);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
enum mifare_tag_type {
|
||||
ULTRALIGHT,
|
||||
// ULTRALIGHT_C,
|
||||
ULTRALIGHT_C,
|
||||
// MINI,
|
||||
CLASSIC_1K,
|
||||
CLASSIC_4K,
|
||||
|
@ -46,6 +46,9 @@ enum mifare_tag_type {
|
|||
struct mifare_tag;
|
||||
typedef struct mifare_tag *MifareTag;
|
||||
|
||||
struct mifare_desfire_key;
|
||||
typedef struct mifare_desfire_key *MifareDESFireKey;
|
||||
|
||||
typedef uint8_t MifareUltralightPageNumber;
|
||||
typedef unsigned char MifareUltralightPage[4];
|
||||
|
||||
|
@ -66,6 +69,9 @@ int mifare_ultralight_disconnect (MifareTag tag);
|
|||
int mifare_ultralight_read (MifareTag tag, const MifareUltralightPageNumber page, MifareUltralightPage *data);
|
||||
int mifare_ultralight_write (MifareTag tag, const MifareUltralightPageNumber page, const MifareUltralightPage data);
|
||||
|
||||
int mifare_ultralightc_authenticate (MifareTag tag, const MifareDESFireKey key);
|
||||
bool is_mifare_ultralightc_on_reader (nfc_device_t *device, nfc_iso14443a_info_t nai);
|
||||
|
||||
typedef unsigned char MifareClassicBlock[16];
|
||||
|
||||
typedef uint8_t MifareClassicSectorNumber;
|
||||
|
@ -247,9 +253,6 @@ uint32_t mifare_desfire_aid_get_aid (MifareDESFireAID aid);
|
|||
|
||||
uint8_t mifare_desfire_last_picc_error (MifareTag tag);
|
||||
|
||||
struct mifare_desfire_key;
|
||||
typedef struct mifare_desfire_key *MifareDESFireKey;
|
||||
|
||||
#pragma pack (push)
|
||||
#pragma pack (1)
|
||||
struct mifare_desfire_version_info {
|
||||
|
|
|
@ -146,6 +146,7 @@ typedef enum {
|
|||
|
||||
void *mifare_cryto_preprocess_data (MifareTag tag, void *data, size_t *nbytes, off_t offset, int communication_settings);
|
||||
void *mifare_cryto_postprocess_data (MifareTag tag, void *data, ssize_t *nbytes, int communication_settings);
|
||||
void mifare_cypher_single_block (MifareDESFireKey key, uint8_t *data, uint8_t *ivect, MifareCryptoDirection direction, MifareCryptoOperation operation, size_t block_size);
|
||||
void mifare_cypher_blocks_chained (MifareTag tag, MifareDESFireKey key, uint8_t *ivect, uint8_t *data, size_t data_size, MifareCryptoDirection direction, MifareCryptoOperation operation);
|
||||
void rol (uint8_t *data, const size_t len);
|
||||
void desfire_crc32 (const uint8_t *data, const size_t len, uint8_t *crc);
|
||||
|
@ -159,7 +160,11 @@ void cmac_generate_subkeys (MifareDESFireKey key);
|
|||
void cmac (const MifareDESFireKey key, uint8_t *ivect, const uint8_t *data, size_t len, uint8_t *cmac);
|
||||
void *assert_crypto_buffer_size (MifareTag tag, size_t nbytes);
|
||||
|
||||
#define MIFARE_ULTRALIGHT_PAGE_COUNT 16
|
||||
#define MIFARE_ULTRALIGHT_PAGE_COUNT 0x10
|
||||
#define MIFARE_ULTRALIGHT_C_PAGE_COUNT 0x30
|
||||
#define MIFARE_ULTRALIGHT_C_PAGE_COUNT_READ 0x2B
|
||||
// Max PAGE_COUNT of the Ultralight Family:
|
||||
#define MIFARE_ULTRALIGHT_MAX_PAGE_COUNT 0x30
|
||||
|
||||
struct supported_tag {
|
||||
enum mifare_tag_type type;
|
||||
|
@ -168,6 +173,7 @@ struct supported_tag {
|
|||
uint8_t ATS_min_length;
|
||||
uint8_t ATS_compare_length;
|
||||
uint8_t ATS[5];
|
||||
bool (*check_tag_on_reader) (nfc_device_t *, nfc_iso14443a_info_t);
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -245,8 +251,8 @@ struct mifare_ultralight_tag {
|
|||
struct mifare_tag __tag;
|
||||
|
||||
/* mifare_ultralight_read() reads 4 pages at a time (wrapping) */
|
||||
MifareUltralightPage cache[MIFARE_ULTRALIGHT_PAGE_COUNT + 3];
|
||||
uint8_t cached_pages[MIFARE_ULTRALIGHT_PAGE_COUNT];
|
||||
MifareUltralightPage cache[MIFARE_ULTRALIGHT_MAX_PAGE_COUNT + 3];
|
||||
uint8_t cached_pages[MIFARE_ULTRALIGHT_MAX_PAGE_COUNT];
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -260,7 +266,9 @@ struct mifare_ultralight_tag {
|
|||
|
||||
#define ASSERT_MIFARE_CLASSIC(tag) do { if ((tag->tag_info->type != CLASSIC_1K) && (tag->tag_info->type != CLASSIC_4K)) return errno = ENODEV, -1; } while (0)
|
||||
#define ASSERT_MIFARE_DESFIRE(tag) do { if (tag->tag_info->type != DESFIRE) return errno = ENODEV, -1; } while (0)
|
||||
#define ASSERT_MIFARE_ULTRALIGHT(tag) do { if (tag->tag_info->type != ULTRALIGHT) return errno = ENODEV, -1; } while (0)
|
||||
#define IS_MIFARE_ULTRALIGHT_C(tag) (tag->tag_info->type == ULTRALIGHT_C)
|
||||
#define ASSERT_MIFARE_ULTRALIGHT(tag) do { if ((tag->tag_info->type != 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)
|
||||
|
||||
/*
|
||||
* MifareTag cast macros
|
||||
|
|
|
@ -71,7 +71,6 @@
|
|||
#define CMAC_LENGTH 8
|
||||
|
||||
static void xor (const uint8_t *ivect, uint8_t *data, const size_t len);
|
||||
static void mifare_cypher_single_block (MifareDESFireKey key, uint8_t *data, uint8_t *ivect, MifareCryptoDirection direction, MifareCryptoOperation operation, size_t block_size);
|
||||
static void desfire_crc32_byte (uint32_t *crc, const uint8_t value);
|
||||
static size_t key_macing_length (MifareDESFireKey key);
|
||||
|
||||
|
@ -608,7 +607,7 @@ mifare_cryto_postprocess_data (MifareTag tag, void *data, ssize_t *nbytes, int c
|
|||
return res;
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
mifare_cypher_single_block (MifareDESFireKey key, uint8_t *data, uint8_t *ivect, MifareCryptoDirection direction, MifareCryptoOperation operation, size_t block_size)
|
||||
{
|
||||
AES_KEY k;
|
||||
|
|
|
@ -45,7 +45,18 @@
|
|||
#include <freefare.h>
|
||||
#include "freefare_internal.h"
|
||||
|
||||
#define ASSERT_VALID_PAGE(page) do { if (page >= MIFARE_ULTRALIGHT_PAGE_COUNT) return errno = EINVAL, -1; } while (0)
|
||||
#define ASSERT_VALID_PAGE(tag, page, mode_write) \
|
||||
do { \
|
||||
if (IS_MIFARE_ULTRALIGHT_C(tag)) { \
|
||||
if (mode_write) { \
|
||||
if (page >= MIFARE_ULTRALIGHT_C_PAGE_COUNT) return errno = EINVAL, -1; \
|
||||
} else { \
|
||||
if (page >= MIFARE_ULTRALIGHT_C_PAGE_COUNT_READ) return errno = EINVAL, -1; \
|
||||
} \
|
||||
} else { \
|
||||
if (page >= MIFARE_ULTRALIGHT_PAGE_COUNT) return errno = EINVAL, -1; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define ULTRALIGHT_TRANSCEIVE(tag, msg, res) \
|
||||
do { \
|
||||
|
@ -57,6 +68,25 @@
|
|||
DEBUG_XFER (res, __##res##_n, "<=== "); \
|
||||
} while (0)
|
||||
|
||||
#define ULTRALIGHT_TRANSCEIVE_RAW(tag, msg, res) \
|
||||
do { \
|
||||
errno = 0; \
|
||||
if (!nfc_configure (tag->device, NDO_EASY_FRAMING, false)) { \
|
||||
errno = EIO; \
|
||||
return -1; \
|
||||
} \
|
||||
DEBUG_XFER (msg, __##msg##_n, "===> "); \
|
||||
if (!(nfc_initiator_transceive_bytes (tag->device, msg, __##msg##_n, res, &__##res##_n))) { \
|
||||
nfc_configure (tag->device, NDO_EASY_FRAMING, true); \
|
||||
return errno = EIO, -1; \
|
||||
} \
|
||||
DEBUG_XFER (res, __##res##_n, "<=== "); \
|
||||
if (!nfc_configure (tag->device, NDO_EASY_FRAMING, true)) { \
|
||||
errno = EIO; \
|
||||
return -1; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
/*
|
||||
* Memory management functions.
|
||||
|
@ -106,7 +136,7 @@ mifare_ultralight_connect (MifareTag tag)
|
|||
};
|
||||
if (nfc_initiator_select_passive_target (tag->device, modulation, tag->info.abtUid, tag->info.szUidLen, &pnti)) {
|
||||
tag->active = 1;
|
||||
for (int i = 0; i < MIFARE_ULTRALIGHT_PAGE_COUNT; i++)
|
||||
for (int i = 0; i < MIFARE_ULTRALIGHT_MAX_PAGE_COUNT; i++)
|
||||
MIFARE_ULTRALIGHT(tag)->cached_pages[i] = 0;
|
||||
} else {
|
||||
errno = EIO;
|
||||
|
@ -149,7 +179,7 @@ mifare_ultralight_read (MifareTag tag, MifareUltralightPageNumber page, MifareUl
|
|||
{
|
||||
ASSERT_ACTIVE (tag);
|
||||
ASSERT_MIFARE_ULTRALIGHT (tag);
|
||||
ASSERT_VALID_PAGE (page);
|
||||
ASSERT_VALID_PAGE (tag, page, false);
|
||||
|
||||
if (!MIFARE_ULTRALIGHT(tag)->cached_pages[page]) {
|
||||
BUFFER_INIT (cmd, 2);
|
||||
|
@ -161,13 +191,19 @@ mifare_ultralight_read (MifareTag tag, MifareUltralightPageNumber page, MifareUl
|
|||
ULTRALIGHT_TRANSCEIVE (tag, cmd, res);
|
||||
|
||||
/* Handle wrapped pages */
|
||||
for (int i = MIFARE_ULTRALIGHT_PAGE_COUNT; i <= page + 3; i++) {
|
||||
memcpy (MIFARE_ULTRALIGHT(tag)->cache[i % MIFARE_ULTRALIGHT_PAGE_COUNT], MIFARE_ULTRALIGHT(tag)->cache[i], sizeof (MifareUltralightPage));
|
||||
int iPageCount;
|
||||
if (IS_MIFARE_ULTRALIGHT_C(tag)) {
|
||||
iPageCount = MIFARE_ULTRALIGHT_C_PAGE_COUNT_READ;
|
||||
} else {
|
||||
iPageCount = MIFARE_ULTRALIGHT_PAGE_COUNT;
|
||||
}
|
||||
for (int i = iPageCount; i <= page + 3; i++) {
|
||||
memcpy (MIFARE_ULTRALIGHT(tag)->cache[i % iPageCount], MIFARE_ULTRALIGHT(tag)->cache[i], sizeof (MifareUltralightPage));
|
||||
}
|
||||
|
||||
/* Mark pages as cached */
|
||||
for (int i = page; i <= page + 3; i++) {
|
||||
MIFARE_ULTRALIGHT(tag)->cached_pages[i % MIFARE_ULTRALIGHT_PAGE_COUNT] = 1;
|
||||
MIFARE_ULTRALIGHT(tag)->cached_pages[i % iPageCount] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -183,7 +219,7 @@ mifare_ultralight_write (MifareTag tag, const MifareUltralightPageNumber page, c
|
|||
{
|
||||
ASSERT_ACTIVE (tag);
|
||||
ASSERT_MIFARE_ULTRALIGHT (tag);
|
||||
ASSERT_VALID_PAGE (page);
|
||||
ASSERT_VALID_PAGE (tag, page, true);
|
||||
|
||||
uint8_t cmd[6];
|
||||
cmd[0] = 0xA2;
|
||||
|
@ -201,3 +237,96 @@ mifare_ultralight_write (MifareTag tag, const MifareUltralightPageNumber page, c
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Authenticate to the provided MIFARE tag.
|
||||
*/
|
||||
int
|
||||
mifare_ultralightc_authenticate (MifareTag tag, const MifareDESFireKey key)
|
||||
{
|
||||
ASSERT_ACTIVE (tag);
|
||||
ASSERT_MIFARE_ULTRALIGHT_C (tag);
|
||||
|
||||
BUFFER_INIT (cmd1, 2);
|
||||
BUFFER_INIT (res, 9);
|
||||
BUFFER_APPEND (cmd1, 0x1A);
|
||||
BUFFER_APPEND (cmd1, 0x00);
|
||||
|
||||
ULTRALIGHT_TRANSCEIVE_RAW(tag, cmd1, res);
|
||||
|
||||
uint8_t PICC_E_RndB[8];
|
||||
memcpy (PICC_E_RndB, res+1, 8);
|
||||
|
||||
uint8_t PICC_RndB[8];
|
||||
memcpy (PICC_RndB, PICC_E_RndB, 8);
|
||||
uint8_t ivect[8];
|
||||
memset (ivect, '\0', sizeof (ivect));
|
||||
mifare_cypher_single_block (key, PICC_RndB, ivect, MCD_RECEIVE, MCO_DECYPHER, 8);
|
||||
|
||||
uint8_t PCD_RndA[8];
|
||||
DES_random_key ((DES_cblock*)&PCD_RndA);
|
||||
|
||||
uint8_t PCD_r_RndB[8];
|
||||
memcpy (PCD_r_RndB, PICC_RndB, 8);
|
||||
rol (PCD_r_RndB, 8);
|
||||
|
||||
uint8_t token[16];
|
||||
memcpy (token, PCD_RndA, 8);
|
||||
memcpy (token+8, PCD_r_RndB, 8);
|
||||
size_t offset = 0;
|
||||
|
||||
while (offset < 16) {
|
||||
mifare_cypher_single_block (key, token + offset, ivect, MCD_SEND, MCO_ENCYPHER, 8);
|
||||
offset += 8;
|
||||
}
|
||||
|
||||
BUFFER_INIT (cmd2, 17);
|
||||
|
||||
BUFFER_APPEND (cmd2, 0xAF);
|
||||
BUFFER_APPEND_BYTES (cmd2, token, 16);
|
||||
|
||||
ULTRALIGHT_TRANSCEIVE_RAW(tag, cmd2, res);
|
||||
|
||||
uint8_t PICC_E_RndA_s[8];
|
||||
memcpy (PICC_E_RndA_s, res+1, 8);
|
||||
|
||||
uint8_t PICC_RndA_s[8];
|
||||
memcpy (PICC_RndA_s, PICC_E_RndA_s, 8);
|
||||
mifare_cypher_single_block (key, PICC_RndA_s, ivect, MCD_RECEIVE, MCO_DECYPHER, 8);
|
||||
|
||||
uint8_t PCD_RndA_s[8];
|
||||
memcpy (PCD_RndA_s, PCD_RndA, 8);
|
||||
rol (PCD_RndA_s, 8);
|
||||
|
||||
if (0 != memcmp (PCD_RndA_s, PICC_RndA_s, 8)) {
|
||||
return -1;
|
||||
}
|
||||
// XXX Should we store the state "authenticated" in the tag struct??
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Callback for freefare_tag_new to test presence of a MIFARE UltralightC on the reader.
|
||||
*/
|
||||
bool
|
||||
is_mifare_ultralightc_on_reader (nfc_device_t *device, nfc_iso14443a_info_t nai)
|
||||
{
|
||||
bool ret;
|
||||
uint8_t cmd_step1[2];
|
||||
uint8_t res_step1[9];
|
||||
cmd_step1[0] = 0x1A;
|
||||
cmd_step1[1] = 0x00;
|
||||
|
||||
nfc_target_t pnti;
|
||||
nfc_modulation_t modulation = {
|
||||
.nmt = NMT_ISO14443A,
|
||||
.nbr = NBR_106
|
||||
};
|
||||
nfc_initiator_select_passive_target (device, modulation, nai.abtUid, nai.szUidLen, &pnti);
|
||||
nfc_configure (device, NDO_EASY_FRAMING, false);
|
||||
size_t n;
|
||||
ret = nfc_initiator_transceive_bytes (device, cmd_step1, sizeof (cmd_step1), res_step1, &n);
|
||||
nfc_configure (device, NDO_EASY_FRAMING, true);
|
||||
nfc_initiator_deselect_target (device);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -48,7 +48,8 @@ cut_setup ()
|
|||
|
||||
tag = NULL;
|
||||
for (int i=0; tags[i]; i++) {
|
||||
if (freefare_get_tag_type(tags[i]) == ULTRALIGHT) {
|
||||
if ((freefare_get_tag_type(tags[i]) == ULTRALIGHT) ||
|
||||
(freefare_get_tag_type(tags[i]) == ULTRALIGHT_C)) {
|
||||
tag = tags[i];
|
||||
res = mifare_ultralight_connect (tag);
|
||||
cut_assert_equal_int (0, res, cut_message ("mifare_ultralight_connect() failed"));
|
||||
|
|
|
@ -76,11 +76,17 @@ test_mifare_ultralight_invalid_page (void)
|
|||
int res;
|
||||
MifareUltralightPage page = { 0x00, 0x00, 0x00, 0x00 };
|
||||
|
||||
res = mifare_ultralight_read (tag, 16, &page);
|
||||
int invalid_page;
|
||||
if (IS_MIFARE_ULTRALIGHT_C (tag)) {
|
||||
invalid_page = MIFARE_ULTRALIGHT_C_PAGE_COUNT;
|
||||
} else {
|
||||
invalid_page = MIFARE_ULTRALIGHT_PAGE_COUNT;
|
||||
}
|
||||
res = mifare_ultralight_read (tag, invalid_page, &page);
|
||||
cut_assert_equal_int (-1, res, cut_message ("mifare_ultralight_read() succeeded"));
|
||||
cut_assert_equal_int (EINVAL, errno, cut_message ("Wrong errno value"));
|
||||
|
||||
res = mifare_ultralight_write (tag, 16, page);
|
||||
res = mifare_ultralight_write (tag, invalid_page, page);
|
||||
cut_assert_equal_int (-1, res, cut_message ("mifare_ultralight_write() succeeded"));
|
||||
cut_assert_equal_int (EINVAL, errno, cut_message ("Wrong errno value"));
|
||||
}
|
||||
|
@ -125,20 +131,26 @@ test_mifare_ultralight_cache_wrap (void)
|
|||
{
|
||||
int res;
|
||||
MifareUltralightPage page;
|
||||
|
||||
res = mifare_ultralight_read (tag, 15, &page);
|
||||
int last_page;
|
||||
if (IS_MIFARE_ULTRALIGHT_C (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
|
||||
cut_omit("mifare_ultralight_read() on last page skipped on UltralightC");
|
||||
} else {
|
||||
last_page = MIFARE_ULTRALIGHT_PAGE_COUNT -1;
|
||||
}
|
||||
res = mifare_ultralight_read (tag, last_page, &page);
|
||||
cut_assert_equal_int (0, res, cut_message ("mifare_ultralight_read() failed"));
|
||||
|
||||
/* Check cached pages consistency */
|
||||
for (int i = 0; i <= 2; i++) {
|
||||
cut_assert_equal_int (1, MIFARE_ULTRALIGHT(tag)->cached_pages[i], cut_message ("Wrong page cache value for tag->cached_pages[%d]", i));
|
||||
}
|
||||
for (int i = 3; i <= 14; i++) {
|
||||
for (int i = 3; i < last_page; i++) {
|
||||
cut_assert_equal_int (0, MIFARE_ULTRALIGHT(tag)->cached_pages[i], cut_message ("Wrong page cache value for tag->cached_pages[%d]", i));
|
||||
}
|
||||
for (int i = 15; i < MIFARE_ULTRALIGHT_PAGE_COUNT; i++) {
|
||||
cut_assert_equal_int (1, MIFARE_ULTRALIGHT(tag)->cached_pages[i], cut_message ("Wrong page cache value for tag->cached_pages[%d]", i));
|
||||
}
|
||||
cut_assert_equal_int (1, MIFARE_ULTRALIGHT(tag)->cached_pages[last_page], cut_message ("Wrong page cache value for tag->cached_pages[%d]", last_page));
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -162,4 +174,24 @@ test_mifare_ultralight_tag_friendly_name (void)
|
|||
cut_assert_not_null (name, cut_message ("freefare_get_tag_friendly_name() failed"));
|
||||
}
|
||||
|
||||
void
|
||||
test_mifare_ultralightc_authenticate (void)
|
||||
{
|
||||
int res;
|
||||
MifareDESFireKey key;
|
||||
|
||||
if (tag->tag_info->type == ULTRALIGHT_C) {
|
||||
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);
|
||||
cut_assert_equal_int (0, res, cut_message ("mifare_ultralightc_authenticate() failed"));
|
||||
mifare_desfire_key_free (key);
|
||||
|
||||
MifareUltralightPage page;
|
||||
int last_page = MIFARE_ULTRALIGHT_C_PAGE_COUNT_READ -1;
|
||||
res = mifare_ultralight_read (tag, last_page, &page);
|
||||
cut_assert_equal_int (0, res, cut_message ("mifare_ultralight_read() failed"));
|
||||
} else {
|
||||
cut_omit("mifare_ultralightc_authenticate() skipped on Ultralight");
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue