Implement ISO14443-4 block numbers.
This feature was not used by the cards I initially used when coding the , but is required for (at least some) Mifare DESFire EV1 to work. IMPORTANT NOTE: The cards needing this block-number management to work out break-down when mifare_desfire_format_picc() is performed on them. The ATR change from 0x7577810280 to 0x757781028f and further communication alway result in a timeout. At the time of committing, the reason is still unknown (bogus cards, missed "Remarks" in the documentation, ...). Other commands seems to not expose additional problems.
This commit is contained in:
parent
cdac2ea340
commit
91d3ff9cc4
2 changed files with 28 additions and 0 deletions
|
@ -185,6 +185,7 @@ struct mifare_desfire_tag {
|
|||
uint8_t authenticated_key_no;
|
||||
uint8_t *crypto_buffer;
|
||||
size_t crypto_buffer_size;
|
||||
uint8_t block_number;
|
||||
};
|
||||
|
||||
MifareDESFireKey mifare_desfire_session_key_new (uint8_t rnda[8], uint8_t rndb[8], MifareDESFireKey authentication_key);
|
||||
|
|
|
@ -18,6 +18,16 @@
|
|||
*/
|
||||
|
||||
/*
|
||||
* This implementation was written based on information provided by the
|
||||
* following documents:
|
||||
*
|
||||
* Draft ISO/IEC FCD 14443-4
|
||||
* Identification cards
|
||||
* - Contactless integrated circuit(s) cards
|
||||
* - Proximity cards
|
||||
* - Part 4: Transmission protocol
|
||||
* Final Committee Draft - 2000-03-10
|
||||
*
|
||||
* http://ridrix.wordpress.com/2009/09/19/mifare-desfire-communication-example/
|
||||
*/
|
||||
|
||||
|
@ -139,6 +149,20 @@ static ssize_t read_data (MifareTag tag, uint8_t command, uint8_t file_no, off_
|
|||
uint8_t *buffer_name = &(__##buffer_name[1]); \
|
||||
size_t __##buffer_name##_n = 0
|
||||
|
||||
/*
|
||||
* Conditionnaly toogles tag->block_number depending on the last received
|
||||
* block. This is described in section "7.4.4 Block numbering rules" of
|
||||
* ISO/IEC 14443-4.
|
||||
*/
|
||||
#define ISO144443_CHAIN_BLOCK_NUMBER(tag, block) \
|
||||
do { \
|
||||
if (((__##res[0] & 0xc0) == 0x00) || (((__##res[0] & 0xa0) == 0xa0) && ((__##res[0] & 0x50) == 0x00))) { \
|
||||
if (MIFARE_DESFIRE (tag)->block_number == (block & 0x01)) { \
|
||||
MIFARE_DESFIRE (tag)->block_number ^= 0x01; \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Transmit the message msg to the NFC tag and receive the response res. The
|
||||
* response buffer's size is set according to the quantity of data received.
|
||||
|
@ -149,11 +173,13 @@ static ssize_t read_data (MifareTag tag, uint8_t command, uint8_t file_no, off_
|
|||
#define DESFIRE_TRANSCEIVE(tag, msg, res) \
|
||||
do { \
|
||||
errno = 0; \
|
||||
__##msg[0] = 0x02 | (MIFARE_DESFIRE (tag)->block_number & 0x01); \
|
||||
MIFARE_DESFIRE (tag)->last_picc_error = OPERATION_OK; \
|
||||
DEBUG_XFER (__##msg, __##msg##_n+1, "===> "); \
|
||||
if (!(nfc_initiator_transceive_bytes (tag->device, __##msg, __##msg##_n+1, __##res, &__##res##_n))) { \
|
||||
return errno = EIO, -1; \
|
||||
} \
|
||||
ISO144443_CHAIN_BLOCK_NUMBER (tag, __##res[0]); \
|
||||
DEBUG_XFER (__##res, __##res##_n, "<=== "); \
|
||||
__##res##_n -= 1; \
|
||||
while (__##res[0] == 0xf2) { \
|
||||
|
@ -282,6 +308,7 @@ mifare_desfire_connect (MifareTag tag)
|
|||
MIFARE_DESFIRE (tag)->last_picc_error = OPERATION_OK;
|
||||
MIFARE_DESFIRE (tag)->last_pcd_error = NULL;
|
||||
MIFARE_DESFIRE (tag)->authenticated_key_no = NOT_YET_AUTHENTICATED;
|
||||
MIFARE_DESFIRE (tag)->block_number = 0;
|
||||
} else {
|
||||
errno = EIO;
|
||||
return -1;
|
||||
|
|
Loading…
Reference in a new issue