timmerk / libfreefare

Automatically exported from code.google.com/p/libfreefare
Other
0 stars 0 forks source link

Wrong MAX_FRAME_SIZE and error when reading larger frames #8

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
There is a bug when reading data larger than a desfire frame.
It happens e.g. with mifare-desfire-read-ndef
----
$ mifare-desfire-read-ndef -o foo
Found Mifare DESFire with UID 04376069fe1e80. Read NDEF [yN] y
Max NDEF size: 3808 bytes
NDEF size: 410 bytes
error   libnfc.chip.pn53x   Buffer size is too short: 60o available(s), 61o needed
lt-mifare-desfire-read-ndef: Read data failed
----
Desfire "max Le" is =59
freefare_internal.h:
#define MAX_FRAME_SIZE 60
which is I guess error_code + data of a pure desfire frame.

But in reality "read" is a desfire command encapsulated in ISO so ending with 2 
SW.
So max=61, not 60

Now the problem is where to do the change as cleanly as possible.
I don't want to mess up things somewhere else by just changing MAX_FRAME_SIZE
E.g. there is dependencies: FRAME_PAYLOAD_SIZE = MAX_FRAME_SIZE - 5

So I thought changing it only in DESFIRE_TRANSCEIVE2 macro.
From where comes the value in the macro giving the recv buffer size??

nfc_initiator_transceive_bytes (tag->device, __msg, __len, __res,
__##res##_size, 0)

=> where is defined __res_size? and wht not just sizeof(__res)?

Moreover __res is defined internally with MAX_FRAME_SIZE(+1) while 
__##res##_size linked to res argument rather than locale var __res?

Very dirty hack solving the issue, just to show the direction...

diff --git a/libfreefare/libfreefare/mifare_desfire.c
b/libfreefare/libfreefare/mifare_desfire.c
index cb812ea..c00eb23 100644
--- a/libfreefare/libfreefare/mifare_desfire.c
+++ b/libfreefare/libfreefare/mifare_desfire.c
@@ -157,7 +157,8 @@ static ssize_t       read_data (MifareTag tag,
uint8_t command, uint8_t file_no, off_
     do { \
        static uint8_t __msg[MAX_FRAME_SIZE] = { 0x90, 0x00, 0x00, 0x00,
0x00, /* ..., */ 0x00 }; \
        /*                                       CLA   INS   P1    P2   
Lc    PAYLOAD    LE*/ \
-       static uint8_t __res[MAX_FRAME_SIZE]; \
+       /* Max res size is one byte longer when using ISO encapsulation
(2 SW instead of one) */ \
+       static uint8_t __res[MAX_FRAME_SIZE+1]; \
        size_t __len = 5; \
        errno = 0; \
        if (!msg) return errno = EINVAL, -1; \
@@ -173,7 +174,7 @@ static ssize_t       read_data (MifareTag tag,
uint8_t command, uint8_t file_no, off_
        MIFARE_DESFIRE (tag)->last_pcd_error = OPERATION_OK; \
        DEBUG_XFER (__msg, __len, "===> "); \
        int _res; \
-       if ((_res = nfc_initiator_transceive_bytes (tag->device, __msg,
__len, __res, __##res##_size, 0)) < 0) { \
+       if ((_res = nfc_initiator_transceive_bytes (tag->device, __msg,
__len, __res, __##res##_size+1, 0)) < 0) { \
            return errno = EIO, -1; \
        } \
        __##res##_n = _res; \

Original issue reported on code.google.com by yob...@gmail.com on 15 Jan 2013 at 10:45

GoogleCodeExporter commented 9 years ago
Fixed by fbb5434f2435bd7668a46212896997191c9a076c

Original comment by yob...@gmail.com on 18 Feb 2013 at 4:22