nfc-tools / libfreefare Goto Github PK
View Code? Open in Web Editor NEWA convenience API for NFC cards manipulations on top of libnfc.
License: Other
A convenience API for NFC cards manipulations on top of libnfc.
License: Other
What steps will reproduce the problem?
1. Compile libfreefare against libnfc-1.7.0-rc7
2. Run mifare-classic-read-ndef
What is the expected output? What do you see instead?
Expected output : Some data
What I see : Segfault
What version of the product are you using? On what operating system?
libfreefare-0.3.4 from distributed tarball
Debian 7.0
Please provide any additional information below.
Segfault is easy to track :
mifare-classic-read-ndef.c:108: nfc_init(NULL);
In nfc.c:183 :
void
nfc_init(nfc_context **context)
{
*context = nfc_context_new();
if (!*context) {
perror("malloc");
return;
}
if (!nfc_drivers)
nfc_drivers_init();
}
Clearly here, sending NULL to nfc_init will result in trying to write a new
context at adresse 0, in the first line.
I think previous libnfc versions were compatible with sending them NULL, albeit
I didn't checked.
Original issue reported on code.google.com by [email protected]
on 30 Jun 2013 at 6:58
Many libfreefare examples have common portions of code that have been copied/pasted and only have sparse differences and inconsistencies (tag acquisition, arguments parsing, etc.).
The test suite had to cope with a similar need, and builds a libtestcommon.a archive that is added to the test libraries that use the helper functions it defines. A similar approach for the examples may be appropriate.
Hi, when I call mifare_classic_authenticate for Classic 1k (sak 0x88)
everything is fine. But when I do same for Dual interface card i'm getting
"-1" error code and error:
"error libnfc.chip.pn53x Buffer size is too short: 1 available(s), 2 needed"
What can be wrong?
I'm using libnfc 1.7.0 with ACR-122U-A9
Original issue reported on code.google.com by [email protected]
on 20 Dec 2013 at 11:38
Reported by [email protected], Jun 7, 2012
Mifare Classic uses two types of diversification, old and new. The new type is
very very similar to DESFire diversification, actually it is 100% the same, but
the for DESFire the final key is taken from the last 16 bytes, for the classic
it is first 6 bytes of the last 16 bytes. Will there be a fn that simply
returns Classic type keys?
----
Comment 1 by project member [email protected], Jun 7, 2012
Thanks for reporting issue.
Could you provide a patch for this feature ?
If not, we will try to take care at this issue ASAP.
----
Comment 2 by [email protected], Jun 8, 2012
No, unfortunately not due to the time constraints. Perhaps sometime in the fall
i might get the time, for now i can only provide specifications for
diversification.
----
Comment 3 by project member [email protected], Jun 8, 2012
Yes, feel free to let us some references to implement it.
Thanks
----
Comment 4 by [email protected], Jun 8, 2012
Please find the file attached
----
Spec.pdf
3.5 MB Download
----
Comment 6 by project member [email protected], Jun 8, 2012
Thanks for attachement.
As we are quite busy with libnfc and ifdnfc right, I don't think we will
improve libfreefare next days.
ASAP may be not enough for some users, so if any volunteer want to take this
issue, feel free to attach patches.
----
Comment 7 by olifozzy, Aug 13, 2012
I have been trying to understand the algorithm but I am having some trouble
understanding key diversification.
If I understand correctly we need to know the master key and the 3des key to
compute diversified keys for a card ?
Signature should be something like :
- GetKey(masterKey, 3desKey, uid, blockNumber);
I have some tags that looks like mifare classic but the KeyA from the first
sector is always the same , the other keys are diversified.
Do you know if the first sector behave differently of maybe my set of tags
doesn't use that diversification algorithm...
----
Comment 8 by [email protected], Aug 13, 2012 via email
what 3des key? No 3des key is needed. Take a look at the first post and take a
look at DESFire diversification implementation in the project. You have to have
master key and diversification input (which is card UID and sector number) from
the output of desfire diversification take the first 6 bytes of last 16
bytes(because classic keys are smaller).
Marko
----
Comment 9 by olifozzy, Aug 13, 2012
I was talking about the first part of the document (old 2ktdes based key
diversification).
Anyway I also looked at the second part of the document and the way it is done
for desfire in libfreefare.
According to the document there is some padding so that diversification input
is always 32 bytes but in libfreefare, in cmac method it use key block size
that is only 16 bytes.
I've made some slight modification to make it work as in the document.
It still doesn't explain why i have always the same key for all my tags but
only for the first block (sector 0x03). Maybe they used a custom key
diversification :/
----
Comment 10 by [email protected], Aug 13, 2012 via email
could be custom diversification.
sorry, i cannot help you with older diversification.
Marko
Original issue reported on code.google.com by [email protected]
on 15 Jan 2013 at 8:01
Reported by project member [email protected], Sep 30, 2012
If you are authenticated on a sector but the requested MIFARE cmd (read, write)
is not permitted by current access bytes, libfreefare should return "permission
denied" error.
http://www.libnfc.org/community/topic/760/scl3711-mfclassic-dump-problem-chip-er
ror-invalid-received-frame/
Original issue reported on code.google.com by [email protected]
on 15 Jan 2013 at 8:09
Hello,
I was wondering if anybody builds with CMake? I'm having troubles when calling cmake with "-DDLIBNFC_INSTALL_DIR=<...path>".
When I change the find_library call in cmake/modules/FindLIBNFC.cmake to "nfc" (instead of "libnfc") - everything works out fine...
Thanks in advance,
stefan
diff --git a/cmake/modules/FindLIBNFC.cmake b/cmake/modules/FindLIBNFC.cmake
index f2b1b75..0c5d6ac 100644
--- a/cmake/modules/FindLIBNFC.cmake
+++ b/cmake/modules/FindLIBNFC.cmake
@@ -9,7 +9,7 @@ message("libnfc install dir: " ${LIBNFC_INSTALL_DIR})
find_path(LIBNFC_INCLUDE_DIRS NAMES nfc/nfc.h PATHS ${LIBNFC_INSTALL_DIR}/include)
message("libnfc include dir found: " ${LIBNFC_INCLUDE_DIRS})
-find_library(LIBNFC_LIBRARIES libnfc PATHS ${LIBNFC_INSTALL_DIR}/lib)
+find_library(LIBNFC_LIBRARIES nfc PATHS ${LIBNFC_INSTALL_DIR}/lib)
In commit f6c7f76, code was introduced that calls abort()
when malloc()
fails in mifare_desfire_crypto.c
. This is absolutely unacceptable. A library should under no circumstances terminate the program for such a minor problem as being out of memory. Please redesign the code so an error is reported by the library instead when malloc()
fails to allocate memory.
As far as i understand it, the INTEGRITY_ERROR is either a CRC or a padding Bytes issue.
Code which result in the error:
#if defined(HAVE_CONFIG_H)
#include "config.h"
#endif
#include <err.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <nfc/nfc.h>
#include <freefare.h>
uint8_t masterKey_data[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t oldAppKey_data[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t newAppKey_data[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint32_t appID_data = 0x112233;
#define MASTER_KEY_VERSION 0x00
#define APP_KEY_VERSION 0x00
struct {
bool interactive;
} configure_options = {
.interactive = true
};
static void
usage(char *progname)
{
fprintf(stderr, "usage: %s [-y]\n", progname);
fprintf(stderr, "\nOptions:\n");
fprintf(stderr, " -y Do not ask for confirmation\n");
}
int
main(int argc, char *argv[])
{
int ch;
int error = EXIT_SUCCESS;
nfc_device *device = NULL;
FreefareTag *tags = NULL;
while ((ch = getopt(argc, argv, "hy")) != -1) {
switch (ch) {
case 'h':
usage(argv[0]);
exit(EXIT_SUCCESS);
break;
case 'y':
configure_options.interactive = false;
break;
default:
usage(argv[0]);
exit(EXIT_FAILURE);
}
}
// Remaining args, if any, are in argv[optind .. (argc-1)]
nfc_connstring devices[8];
size_t device_count;
nfc_context *context;
nfc_init(&context);
if (context == NULL)
errx(EXIT_FAILURE, "Unable to init libnfc (malloc)");
device_count = nfc_list_devices(context, devices, 8);
if (device_count <= 0)
errx(EXIT_FAILURE, "No NFC device found.");
for (size_t d = 0; (!error) && (d < device_count); d++) {
device = nfc_open(context, devices[d]);
if (!device) {
warnx("nfc_open() failed.");
error = EXIT_FAILURE;
continue;
}
tags = freefare_get_tags(device);
if (!tags) {
nfc_close(device);
errx(EXIT_FAILURE, "Error listing Mifare DESFire tags.");
}
for (int i = 0; (!error) && tags[i]; i++) {
if (MIFARE_DESFIRE != freefare_get_tag_type(tags[i]))
continue;
char *tag_uid = freefare_get_tag_uid(tags[i]);
char buffer[BUFSIZ];
int res;
res = mifare_desfire_connect(tags[i]);
if (res < 0) {
warnx("Can't connect to Mifare DESFire target.");
error = EXIT_FAILURE;
break;
}
// Make sure we've at least an EV1 version
struct mifare_desfire_version_info info;
res = mifare_desfire_get_version(tags[i], &info);
if (res < 0) {
freefare_perror(tags[i], "mifare_desfire_get_version");
error = 1;
break;
}
if (info.software.version_major < 1) {
warnx("Found old DESFire, skipping");
continue;
}
printf("Found %s with UID %s. ", freefare_get_tag_friendly_name(tags[i]), tag_uid);
bool do_it = true;
if (configure_options.interactive) {
printf("Change default key? [yN] ");
fgets(buffer, BUFSIZ, stdin);
do_it = ((buffer[0] == 'y') || (buffer[0] == 'Y'));
} else {
printf("\n");
}
if (do_it) {
printf("1. Authenticate with Master key...\n");
MifareDESFireKey default_key = mifare_desfire_aes_key_new(masterKey_data);
res = mifare_desfire_authenticate(tags[i], 0, default_key);
if (res < 0) {
freefare_perror(tags[i], "mifare_desfire_authenticate");
error = EXIT_FAILURE;
break;
}
mifare_desfire_key_free(default_key);
MifareDESFireKey oldAppKey = mifare_desfire_des_key_new_with_version(oldAppKey_data);
MifareDESFireKey newAppKey = mifare_desfire_aes_key_new(newAppKey_data);
printf("Set app key as default key...\n");
mifare_desfire_key_set_version(oldAppKey, APP_KEY_VERSION);
res = mifare_desfire_set_default_key(tags[i], oldAppKey);
if (res < 0) {
freefare_perror(tags[i], "mifare_desfire_set_default_key");
error = EXIT_FAILURE;
break;
}
printf("Create application...\n");
MifareDESFireAID aid = mifare_desfire_aid_new(appID_data);
res = mifare_desfire_create_application(tags[i], aid, 0x0F, 1);
if (res < 0) {
freefare_perror(tags[i], "mifare_desfire_create_application");
error = EXIT_FAILURE;
break;
}
printf("Select application...\n");
res = mifare_desfire_select_application(tags[i], aid);
if (res < 0) {
freefare_perror(tags[i], "mifare_desfire_select_application");
error = EXIT_FAILURE;
break;
}
printf("Authenticate with old app key...\n");
res = mifare_desfire_authenticate(tags[i], 0, oldAppKey);
if (res < 0) {
freefare_perror(tags[i], "mifare_desfire_authenticate");
error = EXIT_FAILURE;
break;
}
printf("Change APP Key settings...\n");
res = mifare_desfire_change_key_settings(tags[i], 0x0F);
if (res < 0)
{
errx(EXIT_FAILURE, "ChangeKeySettings failed");
}
printf("Change App master Key DES to AES...\n");
mifare_desfire_key_set_version(newAppKey, APP_KEY_VERSION);
res = mifare_desfire_change_key(tags[i], 0, newAppKey, oldAppKey);
if (res < 0) {
freefare_perror(tags[i], "mifare_desfire_change_key");
error = EXIT_FAILURE;
break;
}
printf("Authenticate with New app key...\n");
res = mifare_desfire_authenticate(tags[i], 0, newAppKey);
if (res < 0) {
freefare_perror(tags[i], "mifare_desfire_authenticate");
error = EXIT_FAILURE;
break;
}
mifare_desfire_key_free(oldAppKey);
mifare_desfire_key_free(newAppKey);
}
mifare_desfire_disconnect(tags[i]);
free(tag_uid);
}
freefare_free_tags(tags);
nfc_close(device);
}
nfc_exit(context);
exit(error);
}
Console Output:
1. Authenticate with Master key...
Set app key as default key...
Create application...
Select application...
Authenticate with old app key...
Change APP Key settings...
Change App master Key DES to AES...
mifare_desfire_change_key: INTEGRITY_ERROR
So I think there is a library problem
I am useing the PN7120 with jgeslin/libnfc Lib.
When using mifare_desfire_change_key
without authenticating first, parts of the new key is (according to the debug log) transmitted in plaintext and then rejected by the card with an "invalid length" response. I don't know if this is intended behaviour, but it seems potentially unsafe.
Here is a log when attempting to set the key to the AES key {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77}
*** mifare_desfire_get_version ***
===> 0000 90 60 00 00 00 |.`... |
<=== 0000 04 01 01 01 00 18 05 91 af |......... |
*** mifare_desfire_get_version ***
===> 0000 90 af 00 00 00 |..... |
<=== 0000 04 01 01 01 04 18 05 91 af |......... |
*** mifare_desfire_get_version ***
===> 0000 90 af 00 00 00 |..... |
<=== 0000 04 5c 22 1a 12 4e 80 b9 0c 16 4d 40 34 16 91 00 |.\"..N....M@4...|
Found Mifare DESFire with UID 045c221a124e80.
*** mifare_desfire_change_key ***
===> 0000 90 c4 00 00 14 80 00 10 23 33 44 55 66 76 ff ff |........#3DUfv..|
===> 0010 fe fe ff fe ff ff 00 ad 98 00 |.......... |
<=== 0000 91 7e |.~ |
mifare_desfire_set_default_key: LENGTH_ERROR
Same when using mifare_desfire_set_default_key
instead of mifare_desfire_change_key
:
*** mifare_desfire_get_version ***
===> 0000 90 60 00 00 00 |.`... |
<=== 0000 04 01 01 01 00 18 05 91 af |......... |
*** mifare_desfire_get_version ***
===> 0000 90 af 00 00 00 |..... |
<=== 0000 04 01 01 01 04 18 05 91 af |......... |
*** mifare_desfire_get_version ***
===> 0000 90 af 00 00 00 |..... |
<=== 0000 04 5c 22 1a 12 4e 80 b9 0c 16 4d 40 34 16 91 00 |.\"..N....M@4...|
Found Mifare DESFire with UID 045c221a124e80.
*** mifare_desfire_set_default_key ***
===> 0000 90 5c 00 00 1a 01 00 10 23 33 44 55 66 76 ff ff |.\......#3DUfv..|
===> 0010 fe fe ff fe ff ff 00 00 00 00 00 00 00 00 34 00 |..............4.|
<=== 0000 91 7e |.~ |
mifare_desfire_set_default_key: LENGTH_ERROR
Proposed fix (unless this is intended behaviour): Check if authentication session exists before attempting to change the key, and abort locally if no authentication is active.
I tested the library with a mifare 1k card and noticed that the following call took around 20 seconds to finally grab all ndef data.
mifare-classic-read-ndef -y -o data.mdf
Is this the normal behaviour or is there a way to speed things up?
I'm running the library on Raspbian.
I got a :
autoreconf: running: /usr/bin/autoconf
configure.ac:46: error: possibly undefined macro: AC_MSG_ERROR
If this token and others are legitimate, please use m4_pattern_allow.
See the Autoconf documentation.
autoreconf: /usr/bin/autoconf failed with exit status: 1
What steps will reproduce the problem?
1. git clone
2. autoreconf -vis
3. read error message on your screen
What version of the product are you using? On what operating system?
Version ea496c4 on Debian 7.0.
Original issue reported on code.google.com by [email protected]
on 30 Jun 2013 at 5:20
If size_t length is greater than 52 and is dividable by 4 but not by 8 (e.g. 60,68,...,876,...) enciphered_data_length()
results in wrong padded data length and the read_buffer is to small to keep the content.
Here is a quick and dirty printf debug output for your convenience with 60 as length
+++++++++++++++ ENTER read_data command 189 file_no 7 offset 0 lenght 60 cs 1
############### ENTER padded_data_length: nbytes 8 block_size 16 nbytes % block_size)
############### IF branch : (nbytes / block_size) 0
############### IF branch : ((nbytes / block_size) + 1) 1
############### ((nbytes / block_size) + 1) * block_size 16
=============== ENTER enciphered_data_length
=============== nbytes 60, crc_length 4, block_size 16
############### ENTER padded_data_length: nbytes 64 block_size 16 nbytes % block_size)
############### ELSE: nbytes 64
=============== padded_data_length 64
=============== EXIT enciphered_data_length
+++++++++++++++ enciphered_data_length (tag, length, 0) = 64 rember the + 1 later
+++++++++++++++ bytes_received before memcpy = 0
+++++++++++++++ bytes_received after memcpy = 48
+++++++++++++++ bytes_received before memcpy = 48
+++++++++++++++ bytes_received after memcpy = 68
+++++++++++++++ bytes_received after transfer 68 remvember the ++ later on
+++++++++++++++ sr = 69
############### ENTER padded_data_length: nbytes 61 block_size 16 nbytes % block_size)
############### IF branch : (nbytes / block_size) 3
############### IF branch : ((nbytes / block_size) + 1) 4
############### ((nbytes / block_size) + 1) * block_size 64
*** Error in `/test': malloc(): memory corruption: 0x00e2e238 ***
Increasing the padding by one at
enciphered_data_length (padded_data_length (nbytes + crc_length +1, block_size)
instead of
enciphered_data_length (padded_data_length (nbytes + crc_length, block_size))
solves the problem for me. And I attached a patch for it. But I am not sure if this patch will be right in every case. In the case above the resulting buffer size is 80 which is enough to store the data.
While reading the source I also came along that malloc is not checked for errors.
Also this part makes me wonder
uint8_t ocs = cs;
if ((MIFARE_DESFIRE (tag)->session_key) && (cs | MDCM_MACED)) {
switch (MIFARE_DESFIRE (tag)->authentication_scheme) {
case AS_LEGACY:
break;
case AS_NEW:
cs = MDCM_PLAIN;
break;
}
}
uint8_t *p = mifare_cryto_preprocess_data (tag, cmd, &__cmd_n, 8, MDCM_PLAIN | CMAC_COMMAND);
cs = ocs;
did you wanted to use :
mifare_cryto_preprocess_data (tag, cmd, &__cmd_n, 8, cs | CMAC_COMMAND)
instead of
mifare_cryto_preprocess_data (tag, cmd, &__cmd_n, 8, MDCM_PLAIN | CMAC_COMMAND)
Thanks in advance,
Bernhard
Original issue reported on code.google.com by [email protected]
on 4 Nov 2014 at 3:41
Attachments:
Hey guys,
I use a pn532 board with arduino as a nfc reader. So I played with it a bit and found the little tool: mifare-desfire-analyze.
Now my problem, sometimes I get an error, so here is the debug log:
[...]
debug libnfc.chip.pn53x InDataExchange
debug libnfc.chip.pn53x No timeout
debug libnfc.bus.uart TX: 00 00 ff 0a f6 d4 40 01 90 aa 00 00 01 00 00 b0 00
debug libnfc.bus.uart RX: 00 00 ff 00 ff 00
debug libnfc.chip.pn53x PN53x ACKed
debug libnfc.bus.uart RX: 00 00 ff 15 eb
debug libnfc.bus.uart RX: d5 41
debug libnfc.bus.uart RX: 00 8d b1 f0 47 07 5d 45 23 80 6a 42 13 90 43 11 80 91
af
debug libnfc.bus.uart RX: c6 00
debug libnfc.chip.pn53x InDataExchange
debug libnfc.chip.pn53x No timeout
debug libnfc.bus.uart TX: 00 00 ff 29 d7 d4 40 01 90 af 00 00 20 6a c1 fd 0c 47
9b ea a3 0e e8 b3 cd 0e 8c 0d 46 a0 27 48 01 ce 60 9c 4e f0 85 4a 47 9e c1 ea
6f 00 a0 00
debug libnfc.bus.uart RX: 00 00 00 00 00 00
error libnfc.chip.pn53x Unexpected PN53x reply!
debug libnfc.chip.pn53x InDataExchange
debug libnfc.chip.pn53x No timeout
[...]
And after this one long command, I only get "unexpected pn53x reply"s. so I checked the source code of the tool. The command is generated in "mifare_desfire.c" in static int authenticate (...)
because of authenticate with AES.
Any idea why this is happening?
greeting
Tobi
Original issue reported on code.google.com by [email protected]
on 9 Aug 2014 at 4:30
Reported by [https://code.google.com/u/114415527994645740894/ kev.y.wang], Jan
1, 2012
*What steps will reproduce the problem?*
1. inside libfreefare-0.3.2 dir, run ./configure --prefix=/usr
2. make
*What is the expected output? What do you see instead?*
The expected output should not have the warnings that I see:
Smooth-Lightning:libfreefare-0.3.2 kevin$ make
make all-recursive
Making all in contrib
Making all in libutil
make[3]: Nothing to be done for `all'.
make[3]: Nothing to be done for `all-am'.
Making all in libfreefare
CC freefare.lo
CC mifare_classic.lo
mifare_classic.c: In function ‘mifare_classic_init_value’:
mifare_classic.c:326: warning: implicit declaration of function ‘htole32’
mifare_classic.c: In function ‘mifare_classic_read_value’:
mifare_classic.c:364: warning: implicit declaration of function ‘le32toh’
CC mifare_ultralight.lo
mifare_ultralight.c: In function ‘mifare_ultralightc_authenticate’:
mifare_ultralight.c:265: warning: ‘DES_random_key’ is deprecated (declared
at /usr/include/openssl/des.h:218)
CC mifare_desfire.lo
mifare_desfire.c: In function ‘authenticate’:
mifare_desfire.c:355: warning: ‘RAND_bytes’ is deprecated (declared at
/usr/include/openssl/rand.h:104)
mifare_desfire.c: In function ‘mifare_desfire_get_df_names’:
mifare_desfire.c:826: warning: implicit declaration of function ‘le16toh’
mifare_desfire.c: In function ‘mifare_desfire_get_file_settings’:
mifare_desfire.c:1249: warning: implicit declaration of function ‘le32toh’
CC mifare_desfire_aid.lo
...
Basically, some of the endian macros defined in freefare_internal.h are not
working. The compilation succeeds, but when trying to run some of the examples
(like mifare-classic-write-ndef), I get the following:
dyld: lazy symbol binding failed: Symbol not found: _htole32
Referenced from: /Users/kevin/dev/libfreefare-0.3.2/libfreefare/.libs/libfreefare.0.dylib
Expected in: flat namespace
dyld: Symbol not found: _htole32
Referenced from: /Users/kevin/dev/libfreefare-0.3.2/libfreefare/.libs/libfreefare.0.dylib
Expected in: flat namespace
Which makes sense, since during compilation, those were never defined.
*What version of the product are you using? On what operating system?*
OS: Mac OS X 10.7.
Version: libfreefare-0.3.2
Looking at it some more, would #ifdef macros in freefare_internal.h that use
<libkern/OSByteOrder.h> work?
----
Comment 2 by project member ludovic.rousseau, May 19, 2012
Maybe the solution is to use _standard_ C functions like:
NAME
htonl, htons, ntohl, ntohs -- convert values between host and network
byte order
LIBRARY
Standard C Library (libc, -lc)
SYNOPSIS
#include <arpa/inet.h>
uint32_t
htonl(uint32_t hostlong);
uint16_t
htons(uint16_t hostshort);
uint32_t
ntohl(uint32_t netlong);
uint16_t
ntohs(uint16_t netshort);
Original issue reported on code.google.com by [email protected]
on 15 Jan 2013 at 7:39
http://code.google.com/r/dheidler-libfreefare/source/detail?r=cc36619f132e973a3c
c82a6cedc6a03146d24f7d
Original issue reported on code.google.com by [email protected]
on 3 May 2013 at 8:08
Attachments:
What steps will reproduce the problem?
1. brew install libnfc
2. brew install libfreefare (or compile from source)
3. format and write a tag
mifare-classic-read-ndef and mifare-classic-format work OK,
but mifare-classic-write-ndef fails with Symbol not found: _htole32
What is the expected output? What do you see instead?
$ ./examples/mifare-classic-write-ndef -y -i hello.dmp
NDEF file is 19 bytes long.
Found Mifare Classic 1k with UID fa4360e6.
dyld: lazy symbol binding failed: Symbol not found: _htole32
Referenced from: /Users/don/Downloads/libfreefare-0.4.0/libfreefare/.libs/libfreefare.0.dylib
Expected in: flat namespace
dyld: Symbol not found: _htole32
Referenced from: /Users/don/Downloads/libfreefare-0.4.0/libfreefare/.libs/libfreefare.0.dylib
Expected in: flat namespace
Trace/BPT trap: 5
What version of the product are you using? On what operating system?
libnfc 1.7.0
libfreefare 0.4.0
OS X 10.9.4
Please provide any additional information below.
I get the same results from brew or compiling from source
for compiling, brew install automake and libtool
Original issue reported on code.google.com by [email protected]
on 28 Jul 2014 at 3:30
Am cross compiling libfreefare for arm architecture and took source from
git clone https://code.google.com/p/libfreefare/
while executing autoreconf -vis getting some warning, see
http://pastebin.com/FNQpYdFv
while configuring http://pastebin.com/wSn4xQY1
while compiling am getting errors, see http://pastebin.com/A220HGBC
Is there patch to fix this?
how to fix this?
Original issue reported on code.google.com by [email protected]
on 9 Apr 2014 at 2:10
Currently, mifare_ultralightc_authenticate() returns -1 and does not touch
errno when authentication fails. This is very strange and probably errorneous
behavior and makes it difficult to do proper error handling.
I suggest to change libfreefare to set errno to EACCES (access denied) if
authentication fails. Attached is a patch that implements this change.
Original issue reported on code.google.com by [email protected]
on 25 Feb 2014 at 12:33
Attachments:
Most functions in mifare_classic.c contain a little prelude to check the input
data for sanity:
ASSERT_ACTIVE (tag);
ASSERT_MIFARE_CLASSIC (tag);
Some other functions don't do this. I found that at least the following
functions don't check the state of tag:
mifare_classic_get_trailer_block_permission
mifare_classic_get_data_block_permission
mifare_classic_format_sector
Perhaps I am in err about this, but if the libfreefare really does not perform
any checks here, this might be a bug. Perhaps the problem also affects other
tag types.
Original issue reported on code.google.com by [email protected]
on 18 Mar 2014 at 1:59
What steps will reproduce the problem?
Fresh Arch Linux on RPI SD Card as root
wget https://libfreefare.googlecode.com/files/libfreefare-0.4.0.tar.bz2
wget https://libnfc.googlecode.com/files/libnfc-1.7.0.tar.bz2
tar xvjf libnfc-1.7.0.tar.bz2
tar xvjf libfreefare-0.4.0.tar.bz2
cd libnfc-1.7.0
./configure --prefix=/usr
make
make install
cd ..
cd libfreefare-0.4.0
./configure --prefix=/usr
What is the expected output? What do you see instead?
I see: libnfc >= 1.7.0 is mandatory
but libnfc is correctly installed!
I expect to see successful ./configure
What version of the product are you using? On what operating system?
Raspberry Pi version B 512MB RAM, Arch Linux
Linux alarmpi 3.12.23-1-ARCH #1 PREEMPT Fri Jun 27 01:32:04 MDT 2014 armv6l
GNU/Linux
Please provide any additional information below.
The error is caused by PKG_CHECK_MODULES macro in configure.ac which returns
invalid output.
PKG_CHECK_MODULES returns correct output when pkg-config is installed.
i.e. pacman -S pkg-config
This is really annoying error, it took me a few hours to figure out what's
wrong.
Original issue reported on code.google.com by [email protected]
on 3 Jul 2014 at 5:45
nfc_initiator_select_passive_target will block a whole thread, at least for me on a RaspberryPi B+ with standard but up-to-date configuration. Why is that so? Why does it wait infinitely until I hold a card in front of the sensor?
What steps will reproduce the problem?
1. Attempt to read page 0x2b
2. mifare_ultralight_read will return -1
Reading other pages seem to be fine.
What is the expected output? What do you see instead?
The expected output is a proper read of page 0x2b. Instead, 0x2b cannot be read.
What version of the product are you using? On what operating system?
Latest libfreefare from git compiled with Ubuntu 12.04 and libnfc-1.7.0-rc7.
Please provide any additional information below.
Using Smartcard Commander in Windows, I am able to read the tag with no
problems, including page 0x2b.
Original issue reported on code.google.com by [email protected]
on 10 Jun 2013 at 8:04
The following issues were found by me when I developed my Go wrapper. These issues can be found in the file BUGS, the content of which is replicated below. I do not know how many of these issues are still open as the old bug tracker is no longer available.
Bugs in the libfreefare that affect this project.
mifare_ultralight.c
* function mifare_ultralightc_authenticate does not set errno on encryption
failure. This could make finding what kind of error happened a little bit
more difficult. Anyway, cgo clears errno before any C call so this should not
affect us in most circumstances. (Reported as issue #20, fixed)
mifare_desfire_key.c
* Objects of type MifareDESFireKey are opaque and allocated by the libfreefare.
This makes it more difficult than it could be to wrap the library. These
objects are not tied to any ressources and should therefore be treatable like
any other "disposable" object. But because Go cannot track their allocation,
the user of the Go wrapper has to manually keep track of MifareDESFireKeys.
This is a huge inconvenience which could be entirely avoided by adding a
callback to the libfreefare that allows a user to provide its own allocation
function. (Reported as issue #21)
mifare_classic.c
* Some functions that assume a MifareTag is a Mifare Classic Tag don't check if
that assumption holds. The wrapper has to perform extra checks to avoid memory
corruption from invalid input data. (Reported as issue #23)
mifare_application.c
* The function mifare_application_free does not check for the possibility that
mifare_application_find returned a NULL pointer. The libfreefare crashes when
you try to delete a nonexisting application or when malloc returned NULL in
mifare_application_find (Reported as issue #24 with patch). A similar issue
exists with mifare_application_write. Even though the function checks the
return valueo of mifare_application_find, it does not check if the NULL result
came from malloc-failure and unconditionally returns EBADF instead of ENOMEM.
(Reported as additional patch to issue #23)
mifare_desfire.c
* The function mifare_desfire_get_file_ids() has an argument files of type
uint8_t *files[] (array of pointers to uint8_t). This should probably have
been uint8_t (*files)[] (pointer to array of uint8_t). The same issue appears
in mifare_desfire_get_iso_file_ids(): parameter uint16_t *files[] should have
type uint16_t (*files)[]. (filed as issue #26)
* The function mifare_desfire_read_data() writes more than length bytes into the
data buffer. This is undocumented and I was unable to deduct how long the
buffer is supposed to be. (filed as issue #28)
freefare.c
* The function freefare_get_tag_uid() does not check the return value of
malloc, potentially causing crashes or memory corruption. (filed as issue #25,
fixed)
What steps will reproduce the problem?
1. Use the function mifare_desfire_debit/credit
2.
3.
What is the expected output? What do you see instead?
the value of the value file gets changed when i get a 0 as return from the
function
What version of the product are you using? On what operating system?
version 0.4.0 of libfreefare on OS X 10.10 and Ubuntu 14.04.
Using an ACR122U and a DESFire EV1 4k card
Please provide any additional information below.
All other functions seem to work as expected.
Original issue reported on code.google.com by [email protected]
on 10 Feb 2015 at 3:21
I'm attempting to use nfc_initiator_poll_target to poll for a card, and then connect using the libfreefare function corresponding to the card type.
The following works fine for mifare_classic:
nfc_initiator_poll_target(..., candidate)
tag = freefare_tag_new(candidate)
mifare_classic_connect(tag)
mifare_classic_authenticate(tag)
mifare_classic_read(tag)
If I attempt the same for desfire, the call to mifare_desfire_connect hangs until I remove and replace the desfire card:
nfc_initiator_poll_target(..., candidate)
tag = freefare_tag_new(candidate)
mifare_desfire_connect(tag) // hangs here
It actually hangs on line 298 in mifare_desfire.c:
if (nfc_initiator_select_passive_target (tag->device, modulation, tag->info.nti.nai.abtUid, tag->info.nti.nai.szUidLen, &pnti) >= 0) {
I tried setting all parameters in this call to the same ones as used for mifare_classic, but to no avail.
I made an example by editing examples/nfc-poll.c from libnfc, add the following after line 153:
printf("Attempting desfire_connect..\n");
FreefareTag tag = freefare_tag_new(pnd, nt);
if (!tag) {
printf("freefare_tag_new failed");
}
res = mifare_desfire_connect(tag);
printf("Desfire_connect done.\n");
If you place a mifare classic card on the reader, the program will immediately continue until after printf("Desfire_connect done.\n")
If you place a desfire card on the reader, it will hang, and only continue after removing the card and replacing it.
What does work is the following:
nfc_initiator_poll_target(...) // ignore result
tags = freefare_get_tags (device);
mifare_desfire_connect (tags[0]);
mifare_desfire_select_application
mifare_desfire_authenticate
mifare_desfire_read_data
But this is quite inefficient.
best regards,
Tom
PS: I originally reported this on the forum: http://forums.nfc-tools.org/post/5717/#p5717
Reported by vishnuocv, Aug 16, 2012
What steps will reproduce the problem?
1. cross compiled for ARM ./configure CC=arm-none-linux-gnueabi-gcc-4.1.2
--host=arm-none-linux
2.
3.
What is the expected output? What do you see instead?
Mifare-desfire-info should show the tag information...
it is not showing anything
What version of the product are you using? On what operating system?
linux, latest one (libfreefare-0.3.4)
Please provide any additional information below.
Libnfc things are working fine. but mifare-DESFire is not
I compiled for PC and it is working Fine. I am able to read the tag information
also
what could be the reason
----
Comment 1 by harishakumara.k, Aug 29, 2012
I also face the same issue. mifare-desfire- functions do not work in arm, but
mifare-classic examples are working fine.
At the same time, linux compilation is working fine for both the cards.
Is it because of endianness problem in libfreefare for desfire card?
Original issue reported on code.google.com by [email protected]
on 15 Jan 2013 at 8:06
Hi,
I dig into libfreefare for the PCSC integration, and it seems that the lib will have troubles on machines with big-endian architectures. I'm lacking of real hardware to test extensively this affirmation.
Definition of le24toh() is clearly not BE-aware and it's used to decode Mifaire DESFire file size.
Regards,
Ludovic
What steps will reproduce the problem?
1. Create an application with AES encryption on DESFIRE EV1 4k card and
authenticate afterwords.
2. Create a file with AES encryption inside the application.
3. Write data into this file by using mifare_desfire_create_std_data_file().
Expected output of the method mifare_desfire-create_std_data_file is simply the
amount of data written to the card. Instead the corresponding function "
returns -1. I also tried mifare_desfire_create_std_data_file_ex with parameter
cs set to MDCM_ENCYPHERED, which had the same effect.
I'm using libfreefare 1.3.4 and libnfc 1.7.0 under Windows 7 64 Bit, both
compiled using MINGW64. The executables and libraries are 32 Bit versions. The
error occurs with libusb as well as using the PC/SC interface. As reader I'm
using several ACR122U-A9. Devices with firmware 2.13 are affected by the
described issue, while devices with firmware 2.10 are working properly (file is
written without any problems). I will invest more time in further
investigations. Does somebody have this problem too? I could also provide a
code snippet if needed.
If I write a file without encryption (MDCM_PLAIN), it also works with firmware
2.13. So it seems to depend on the communcation settings.
Bye, Eike
Original issue reported on code.google.com by [email protected]
on 7 Nov 2013 at 1:30
I'm using libfreefare for multiple DESfire projects (as of yet:
https://github.com/henryk/libopenkey and
https://github.com/henryk/desfire-tools). One issue that's come up multiple
times is handling a "card removed" error.
From the PC/SC environment I'm used to having the framework handle that: Once a
card connection is lost, all further attempts to submit commands will
immediately return with an error. libfreefare doesn't do that. Calling for
example mifare_desfire_select_application() on a card that's been removed will
actually try to transmit the command (as seen in DEBUG_XFER output) and return
after a timeout.
libnfc provides nfc_device_get_last_error() which will return NFC_ERFTRANS in
this case, but it can't be accessed properly from libfreefare. I've discovered
that MifareTag can be cast to nfc_device** and then dereferenced to call libnfc
functions (see
https://github.com/henryk/desfire-tools/blob/64dbb9d51c3feecd1aa99da8556273ebc7c
7db84/src/mifare-desfire-analyze.c#L45) and am using this as a workaround, but
that's hardly proper methodology.
Could libfreefare either:
a) Provide a defined way to access the nfc_device pointer and call libnfc
functions (even just defining the above cast as proper and promising to always
keep the structure to allow it would suffice for this)
b) Track permanent errors and not carry out any timeout-inducing actions
afterwards. Or at least give a defined feedback to the caller that he may not
attempt any further action on the tag. (Currently you could do something like
"if mifare_desfire_select_application() fails but both
mifare_desfire_last_picc_error() and mifare_desfire_last_pcd_error() return 0
then maybe the tag is gone" but that's only a heuristic and not easily
universally used.)
Actually it would be best if both happen. The point where I initially
discovered the cast is for
https://github.com/henryk/desfire-tools/blob/64dbb9d51c3feecd1aa99da8556273ebc7c
7db84/src/mifare-desfire-analyze.c#L296 where I want to find out if an AES or
DES authentication is directly answered with an authentication error (meaning
that the authentication mode is not supported) or an additional frame status
(meaning that the authentication mode is supported).
mifare_desfire_authenticate() handles these internally and
mifare_desfire_last_picc_error() doesn't distinguish between "authentication
mode not supported" and "key wrong". So I still need the ability to issue raw
libnfc commands, or maybe a status flag that I can interrogate that shows
whether the authentication failed after the first or second command.
Original issue reported on code.google.com by [email protected]
on 17 May 2013 at 11:43
I'm currently writing Go bindings for the libfreefare.
Go provides garbage collection, Go programmers expect that objects which aren't tied to external resources do not need explicit deinitialization. A MifareDESFireKey is such an object. It contains a key used for initialization. As far as I am concerned, a MifareDESFireKey does not allocate any resources and can be free'd at any time.
Right now, MifareDESFireKeys are allocated by the libfreefare using malloc() and free(). This makes it very hard to give control over allocation to a garbage collector: You need two layers of wrapping which causes performance loss and an unneccessary amount of extra garbage to be allocated. Library support is needed to be able to control the allocation of MifareDESFireKeys.
I request to implement one of the following things:
void *(*alloc)(size_t size)
to pass a custom memory allocation routine. Albeit not perfect, this would already simplify allocation control by a big deal. What is missing is the ability to embed a MifareDESFireKey into a custom Go struct to save even more space.Original issue reported on code.google.com by [email protected]
on 25 Feb 2014 at 12:58
Set of default keys has been provided in mifare-classic-format.c and
mifare-classic-write-ndef.c such as
MifareClassicKey default_keys_int[] = {
{ 0xff,0xff,0xff,0xff,0xff,0xff },
{ 0xd3,0xf7,0xd3,0xf7,0xd3,0xf7 },
....
I have 1k mifare classic tag,
instead of using that default set of keys, can i able to use keys dynamically
that is user defined key while formatting and writing. Using the -k option. Is
there any patch?
And after writing data's to the tag default access bit is changed. how can i
set it to default access bit.
Original issue reported on code.google.com by [email protected]
on 25 Apr 2014 at 11:52
It should better do so.
At the same time, it would perhaps make sense to rewrite the function to be a
little bit more efficient than calling snprintf() in a loop.
Original issue reported on code.google.com by [email protected]
on 4 Apr 2014 at 10:17
when I run auroreconf -vis on RasPi, I get the following output:
autoreconf -vis
autoreconf: Entering directory `.'
autoreconf: configure.ac: not using Gettext
autoreconf: running: aclocal -I m4
autoreconf: configure.ac: tracing
autoreconf: configure.ac: not using Libtool
autoreconf: running: /usr/bin/autoconf
autoreconf: running: /usr/bin/autoheader
autoreconf: running: automake --add-missing --no-force
configure.ac:8: installing `./ar-lib'
configure.ac:13: installing `./install-sh'
configure.ac:13: installing `./missing'
contrib/libutil/Makefile.am:5: Libtool library used but `LIBTOOL' is undefined
contrib/libutil/Makefile.am:5: The usual way to define `LIBTOOL' is to add
`LT_INIT'
contrib/libutil/Makefile.am:5: to `configure.ac' and run `aclocal' and
`autoconf' again.
contrib/libutil/Makefile.am:5: If `LT_INIT' is in `configure.ac', make sure
contrib/libutil/Makefile.am:5: its definition is in aclocal's search path.
contrib/libutil/Makefile.am: installing `./depcomp'
libfreefare/Makefile.am:6: Libtool library used but `LIBTOOL' is undefined
libfreefare/Makefile.am:6: The usual way to define `LIBTOOL' is to add
`LT_INIT'
libfreefare/Makefile.am:6: to `configure.ac' and run `aclocal' and `autoconf'
again.
libfreefare/Makefile.am:6: If `LT_INIT' is in `configure.ac', make sure
libfreefare/Makefile.am:6: its definition is in aclocal's search path.
test/Makefile.am:33: Libtool library used but `LIBTOOL' is undefined
test/Makefile.am:33: The usual way to define `LIBTOOL' is to add `LT_INIT'
test/Makefile.am:33: to `configure.ac' and run `aclocal' and `autoconf' again.
test/Makefile.am:33: If `LT_INIT' is in `configure.ac', make sure
test/Makefile.am:33: its definition is in aclocal's search path.
test/common/Makefile.am:14: Libtool library used but `LIBTOOL' is undefined
test/common/Makefile.am:14: The usual way to define `LIBTOOL' is to add
`LT_INIT'
test/common/Makefile.am:14: to `configure.ac' and run `aclocal' and
`autoconf' again.
test/common/Makefile.am:14: If `LT_INIT' is in `configure.ac', make sure
test/common/Makefile.am:14: its definition is in aclocal's search path.
Makefile.am: installing `./INSTALL'
autoreconf: automake failed with exit status: 1
Original issue reported on code.google.com by [email protected]
on 14 Jan 2015 at 5:24
The commit 1ce3db3 completely breaks the libfreefare API. This is a bad thing. Please either revert it or make a new major release to underline that the new version has a completely incompatible API.
Add last_pcd_error value for some crypto errors. Also enable the
warning even if WITH_DEBUG is not set, so that we have a clue of
why it failed.
The function mifare_desfire_get_file_ids() has a parameter uint8_t *files[].
The type describes an array of pointers to uint8_t. This is probably not the
type that was meant to be used, as the argument clearly should be a pointer to
an array of uint8_t, denoted as uint8_t (*files)[].
I suggest to change the type of files in the signature of
mifare_desfire_get_file_ids() to uint8_t (*files)[]. As the array decays to a
pointer in a function declaration, these two types should not make any
difference in a regard to the calling convention.
A similar issue exists in mifare_desfire_get_iso_file_ids() where the parameter
uint16_t *files[] should probably be type uint16_t (*files)[].
Original issue reported on code.google.com by [email protected]
on 5 Apr 2014 at 11:07
With ultralightC we could be in situations where read() is called without prior
authentication and AUTH0 < MIFARE_ULTRALIGHT_C_PAGE_COUNT_READ + 1
Several situations may occur:
Let's put auth0 = value of AUTH0 at 0x2A
read(x) with x <= auth0 - 4:
read done properly
read(x) with auth0 - 4 < x < auth0
read result is wrapped
bug in libfreefare: cached pages are not wrapped
e.g. auth0=3, read(0) returns page0|page1|page2|page0
and libfreefare caches wrongly page4 with page0 content
read(x) with x >= auth0
read fails properly
The difficulty to handle those cases, especially the early wrapping, is that
0x2A cannot be read in such situations and must be deduced by trial & error.
E.g. by trying to access the latest cached page, we can see if we get an error
or not and if cache is valid or not.
And probably we need to keep track of two other state values in the cache to
avoid this extra check whenever it's possible:
* latest known valid page
* if we reach 0x2A we can remember its actual value
* if we're authenticated we don't need to check page validity
My proposal:
* use another temp buffer to hold read data
* reduce tag cache buffer to actual max size (today it's hacked =+3 to cope
with wrapped read of last page)
* if (UL or (ULC and AUTHENTICATED)), copy data to cache with proper wrapping
if required
* if (ULC and not AUTHENTICATED), copy one single page in cache and ignore rest
of data
It's less efficient when reading without being authenticated but it keeps the
code much clearer.
What do you think?
Original issue reported on code.google.com by [email protected]
on 15 Jan 2013 at 8:18
I was having some trouble with compiling the felica-read-ndef example when I ran make
, and I also was getting some missing symbol errors [1] when executing mifare-desfire-info
after adding a mifare_desfire_read_data
call to the example. After a bit of debugging, I think I've found the answer.
Uses be32toh
, but only has conditional includes for sys/endian.h
and endian.h
. I can't speak to if the examples should be cross platform, but I figure if they're in the repo, probably?
diff --git a/examples/felica-read-ndef.c b/examples/felica-read-ndef.c
index 55483d7..60a9593 100644
--- a/examples/felica-read-ndef.c
+++ b/examples/felica-read-ndef.c
@@ -30,9 +30,14 @@
# include <endian.h>
#endif
+#if defined(HAVE_COREFOUNDATION_COREFOUNDATION_H)
+# include <CoreFoundation/CoreFoundation.h>
+#endif
+
#include <nfc/nfc.h>
#include <freefare.h>
+#include "../libfreefare/freefare_internal.h"
#define NDEF_BUFFER_SIZE 512
This is a lot like #31 .
freefare_internal.h
uses if !defined(le32toh) && defined(CFSwapInt32LittleToHost)
to determine if it needs to define the le32toh
macro, but I was checking "/System/Library/Frameworks/CoreFoundation.framework/Versions/A/Headers/CFByteOrder.h" and (on macOS Sierra) it has CF_INLINE uint32_t CFSwapInt32BigToHost(uint32_t arg) {
, which appears to be inlining as a function, instead of a macro, and I think that means defined
doesn't work on it[2]. I say "appears", "think", etc because I do not know C or libfreefare very well, so there may be gaping holes in my logic or understanding.
I just reused the same macro that was used to determine if the CoreFoundation header would be included in the first place.
diff --git a/libfreefare/freefare_internal.h b/libfreefare/freefare_internal.h
index b792ced..f7f8568 100644
--- a/libfreefare/freefare_internal.h
+++ b/libfreefare/freefare_internal.h
@@ -49,14 +49,14 @@
# define be16toh(x) betoh16(x)
#endif
-#if !defined(le32toh) && defined(CFSwapInt32LittleToHost)
+#if !defined(le32toh) && defined(HAVE_COREFOUNDATION_COREFOUNDATION_H)
# define be32toh(x) CFSwapInt32BigToHost(x)
# define htobe32(x) CFSwapInt32HostToBig(x)
# define le32toh(x) CFSwapInt32LittleToHost(x)
# define htole32(x) CFSwapInt32HostToLittle(x)
#endif
-#if !defined(le16toh) && defined(CFSwapInt16LittleToHost)
+#if !defined(le16toh) && defined(HAVE_COREFOUNDATION_COREFOUNDATION_H)
# define be16toh(x) CFSwapInt16BigToHost(x)
# define htobe16(x) CFSwapInt16HostToBig(x)
# define le16toh(x) CFSwapInt16LittleToHost(x)
[1]
dyld: lazy symbol binding failed: Symbol not found: _le16toh
Referenced from: /usr/local/opt/libfreefare/lib/libfreefare.0.dylib
Expected in: flat namespace
dyld: Symbol not found: _le16toh
Referenced from: /usr/local/opt/libfreefare/lib/libfreefare.0.dylib
Expected in: flat namespace
[2]https://gcc.gnu.org/onlinedocs/cpp/Defined.html
test whether a certain name is defined as a macro
Hi, can you please take a look at my commit
https://code.google.com/r/maximchick-1k-emulated/source/detail?r=9ee3687280fdb37
fedb3d5e2bac54c414acbbb09
It adds support for SmartMX based card emulation like eSE/dual interface
cards/UICC based cards and so on.
I tested it on ACR-122U-A9
Original issue reported on code.google.com by [email protected]
on 18 Dec 2013 at 3:19
Reported by emanuele.bertoldi, Apr 11, 2011
Currently, there are equivalent examples for MIFARE classic and desfire.
It would be great to add an example for MIFARE ultralight too.
Original issue reported on code.google.com by [email protected]
on 15 Jan 2013 at 7:34
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 [email protected]
on 15 Jan 2013 at 10:45
Thanks to time set apart for this purpose by my employer, I've been working in the month of January on enhancing libfreefare and solving a couple of the existing issues (some of which I previously opened myself :).
The primary goal was decoupling libfreefare from libnfc and allowing other reader subsystems to be used. I implemented that for PC/SC as a first step, other projects that one could think of would be librfid and the new "Linux NFC" stack (https://01.org/linux-nfc).
A secondary goal was making the API easier to use and removing unnecessary -- and libnfc-version specific -- boilerplate code. To this end the new API that I built is reader subsystem agnostic and I spent some effort into making it future-compatible with no API or ABI changes.
I have looked at the work that has been done on the "pcsc" branch and decided that that is not the way to go forward. Creating "-pcsc" versions of everything and replicating a second flurry of boilerplate code among the code examples is exactly what I strive to avoid.
The new API is centered around a new FreefareContext object that holds a library context and references to either automatically acquired or externally provided reader subsystem contexts (e.g. nfc_context) or devices (e.g. nfc_device) and provides an easy to use and unified way to retrieve MifareTag objects. The freefare_get_tags() and freefare_tag_new() methods are still there but marked deprecated (since they are libnfc specific). The latter is superseded by a new freefare_tag_new_ex() function that works with all supported reader subsystems using unions as a way to allow it to accept both libnfc or PC/SC arguments.
The new freefare_init() takes a flags argument that can be a combination of FREEFARE_FLAG_READER_LIBNFC or FREEFARE_FLAG_READER_PCSC to automatically establish a context to the given reader subsystems, or the special value FREEFARE_FLAG_READER_ALL to establish a context with all supported subsystems, even future ones. The latter is the recommended value, which means that a program using the library needs not to be updated to gain access to a future reader subsystem support by the library. The flags can also include FREEFARE_FLAG_DISABLE_ISO14443_4 to disable 14443-4 support where possible (currently only libnfc) to select the -3 version on hybrid cards.
Alternatively, freefare_context/device_add/remove are available to manually manage associating or dissociating reader subsystem contexts or devices with the libfreefare library. A FREEFARE_FLAG_AUTOCLOSE in _add will have libfreefare take over responsibility of the passed in object and automatically call the respective close function (nfc_close()/nfc_exit()) when it is no longer needed.
Once a library context has been retrieved, the freefare_tags_get() method enumerates all supported tags on all on readers on all contexts and returns a list. Alternatively freefare_tag_first() and freefare_tag_next() can be used to iterate over the same set without creating the entire list at once. Both accept an enum mifare_tag_type argument to limit the type of tags eligible (the new type NO_TAG_TYPE means no limit).
The boilerplate code can thus (without error checking) be reduced to:
FreefareContext ctx = freefare_init(FREEFARE_FLAG_READER_ALL);
for(MifareTag tag = freefare_tag_first(ctx, NO_TAG_TYPE); tag; tag = freefare_tag_next(ctx)) {
/* Actual code here... */
}
freefare_exit(ctx);
The PC/SC support currently is not complete, only DESfire is working. No functional changes to libnfc support should be present (I even added a working FREEFARE_FLAG_DISABLE_ISO14443_4).
Late in the process I added freefare_tag_wait_* which allows non-busy polling for tags (e.g. like the pcsc_scan tool does). This is only implemented for PC/SC and only works on a single context. libnfc has a similar function in nfc_initiator_poll_target() which only works for a single device, implementing support for that is possible. Anything further (waiting for multiple devices/contexts) would require a new threaded approach.
Before I could prepare my code for publication, freefare_selected_tag_is_present() was added in the main libfreefare branch. This was another libnfc specific function, which I choose not to continue supporting (it hasn't been out long, there should be minimal code breakage). Instead I added freefare_tag_is_present() as a reader subsystem agnostic alternative.
I pushed all the code changes to https://code.google.com/r/henryk-libfreefare-extended-reader-support for easy pulling and request inclusion in libfreefare (sadly Google has no pull request support).
Original issue reported on code.google.com by [email protected]
on 27 Feb 2014 at 3:19
When making checks:
make check-TESTS
make[2]: Entering directory `.../nfc-tools/git-svn/libfreefare/test'
OOOOOOO/usr/bin/cutter: symbol lookup error: ./.libs/test_mad.so: undefined
symbol: nxp_crc
FAIL: run-test.sh
This is because nxp_crc() is defined as static in libfreefare/mad.c
Same for sector_0x00_crc8() and sector_0x10_crc8()
Issue is solved by removing the keyword "static" in front of those three
functions but I'm not sure it's the right thing to expose those internal
functions.
If they are meant to be internal, why test_mad is calling them?
Original issue reported on code.google.com by [email protected]
on 15 Jan 2013 at 8:12
Implemented on noprompt branch of my fork
https://code.google.com/r/doncoleman-libfreefare/source/detail?r=070f1a71669778d
11b788183e55230bd7ac07ff3&name=noprompt
Is there a way to issue a github style pull request?
Original issue reported on code.google.com by [email protected]
on 14 Jul 2013 at 8:31
The internal function read_data()
in mifare_desfire.c contains the following comment:
/*
* FIXME: This is bogus: the user has to provide a data buffer with enougth
* room to store CRC + padding or MAC. If the user wants to read 1 byte,
* there is no reason to provide a 16 bytes buffer.
*/
It is absolutely inacceptable that read_data() reads bytes from data beyond length. Please either document how long the buffer behind data has to be or rework the function to write at most length bytes into data. As is, this is a huge security hole and makes writing a library wrapper extremely difficult as I cannot make any assumptions about extra memory I must allocate beyond what is documented. Please fix this issue ASAP.
Original issue reported on code.google.com by [email protected]
on 9 Apr 2014 at 6:24
In the source for mifare_application_free(), a call to
mifare_application_find() is done. This call could return NULL if malloc()
fails, but mifare_application_free() doesn't check for this condition.
I suggest applying the attached patch.
Original issue reported on code.google.com by [email protected]
on 19 Mar 2014 at 4:09
Attachments:
Hello,
The lastest release was on 4th, December, 2013. Do you guys plan on publishing another release?
Regards,
Alfredo Palhares
I'm using libfreefare for multiple projects in order to isolate myself from a
DESfire implementation (I'm under an NXP NDA). Currently it's entirely bound to
libnfc, which is a pity since libnfc only handles a very small fraction of all
available RFID readers. Most of them come with an PC/SC IFD handler, even for
Linux!
The DESfire functions specifically would be a great match for T=CL handling
through PC/SC, but part 3 section 3.2.2.1 of the specification
(http://www.pcscworkgroup.com/specifications/specdownload.php) also details
operations on storage cards like Mifare Classic which are implemented by at
least some devices (all Omnikey devices do this in the IFD handler, some other,
I think SCM, do it in the reader firmware).
Implementing libfreefare support for PC/SC would greatly increase the
usefulness and range of supported devices.
Original issue reported on code.google.com by [email protected]
on 17 May 2013 at 11:56
Looks like there was something forgotten in felica.c:47, felica_transceive
DEBUG_XFER (data_in, data_in_length, "===> ");
data_in_length is not passed as an argument and thus unknown to the compiler when enabling WITH_DEBUG. I changed this to sizeof (data_in) and now all works well.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.