Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CRC errors when writing a MIFARE Classic 1K using USB_PN53x #410

Open
TeeTrizZz opened this issue Apr 25, 2017 · 14 comments
Open

CRC errors when writing a MIFARE Classic 1K using USB_PN53x #410

TeeTrizZz opened this issue Apr 25, 2017 · 14 comments

Comments

@TeeTrizZz
Copy link

Hi guys,

I have problems writing data to MIFARE Classik 1K tags with a USB_PN53x device (DL533N flat/OEM) due to CRC errors. This does not happen when using a SPI_PN532 device. Writing via SPI works flawlessly.

When writing data to a MIFARE Classik 1K tag, the nfc-mfclassic tool (almost) always stopped with a "failed to write trailer block" message. Sometimes it was block 3, sometimes block 7 (or any other trailor block), sometimes it worked with no problems at all. I checked the libnfc debug messages and found the reason: the chip reported an CRC error / transmission error. I was wondering why this only happened when writing the trailer block. So I tried to write similar data to other blocks, e.g. FF FF FF FF FF FF to the second block. Surprisingly, the result was a CRC error when writing the second block.

Long story short: When writing stuff like FF FF FF or 7F 7F 7F or any other data, which, in binary, represents a lot of ones, the chip will most likely crash with a CRC error. This is of course pretty unfortunate as FF FF FF FF FF is the MIFARE default key.

I already tried to change some of the settings in the chip's source code (i.e. disabling CRC, enabling/disabling easy framing) but to be honest, I don't even know what these settings do. Before wasting time: Is this a bug with the library, the chip, or the device? Is it a timing problem? Is there any way to fix this?

Unfortunately, I cannot use the SPI device as an alternative. So, I hope you guys can help me!

Thanks!

Best,
Fabian

@smortex
Copy link
Contributor

smortex commented Apr 26, 2017

Wow!

If I understand correctly, you are using this device? I do have one and just run the Mifare Classic related tests from the libfreefare test suite with it and 2 Mifare Classic 4K:

romain@marvin ~/Projects/nfc-tools/libfreefare % ./configure --enable-debug
romain@marvin ~/Projects/nfc-tools/libfreefare % make
romain@marvin ~/Projects/nfc-tools/libfreefare % time cutter -n /classic/ test
.............

Finished in 3,158809 seconds (total: 1,759851 seconds)

13 test(s), 709 assertion(s), 0 failure(s), 0 error(s), 0 pending(s), 0 omission(s), 0 notification(s)
100% passed
cutter -n /classic/ test  0,06s user 0,03s system 2% cpu 3,177 total

So, your device look like defective. I may suggest reproducing the failure running the test suite as I did in order to confirm your problem before contacting the seller. In case the test suite does not fail, please provide a sample application that reproduces the error.

@TeeTrizZz
Copy link
Author

Hi smortex,

Thanks for your fast reply!

I have a similiar device. So, I just ran the libfreefare test suite and here are the results:

===> 0000   60 00 ff ff ff ff ff ff 41 22 24 72              |`.......A"$r    |
F
===============================================================================
Failure: test_mifare_classic_authenticate
mifare_classic_authenticate() failed
<0 == res>
expected: <0>
  actual: <-1>
test_mifare_classic.c:33: test_mifare_classic_authenticate(): cut_assert_equal_int(0, res, cut_test_context_set_current_result_user_message( cut_test_context_current_peek(), cut_test_context_take_printf(cut_test_context_current_peek(), "mifare_classic_authenticate() failed")))
===============================================================================
===> 0000   60 04 ff ff ff ff ff ff 41 22 24 72              |`.......A"$r    |
===> 0000   a0 04 e8 03 00 00 17 fc ff ff e8 03 00 00 00 ff  |................|
===> 0010   00 ff                                            |..              |
===> 0000   30 04                                            |0.              |
<=== 0000   e8 03 00 00 17 fc ff ff e8 03 00 00 00 ff 00 ff  |................|
===> 0000   c0 04 01 00 00 00                                |......          |
===> 0000   b0 04                                            |..              |
===> 0000   30 04                                            |0.              |
<=== 0000   e7 03 00 00 18 fc ff ff e7 03 00 00 00 ff 00 ff  |................|
===> 0000   c0 04 e8 03 00 00                                |......          |
===> 0000   b0 04                                            |..              |
===> 0000   30 04                                            |0.              |
<=== 0000   ff ff ff ff 00 00 00 00 ff ff ff ff 00 ff 00 ff  |................|
.===> 0000   60 04 ff ff ff ff ff ff 41 22 24 72              |`.......A"$r    |
===> 0000   30 07                                            |0.              |
<=== 0000   00 00 00 00 00 00 ff 07 80 00 ff ff ff ff ff ff  |................|
.===> 0000   60 00 ff ff ff ff ff ff 41 22 24 72              |`.......A"$r    |
F
===============================================================================
Failure: test_mifare_classic_mad
mifare_classic_authenticate() failed
<0 == res>
expected: <0>
  actual: <-1>
test_mifare_classic_mad.c:45: test_mifare_classic_mad(): cut_assert_equal_int(0, res, cut_test_context_set_current_result_user_message( cut_test_context_current_peek(), cut_test_context_take_printf(cut_test_context_current_peek(), "mifare_classic_authenticate() failed")))
===============================================================================
===> 0000   60 07 ff ff ff ff ff ff 41 22 24 72              |`.......A"$r    |
===> 0000   30 07                                            |0.              |
<=== 0000   00 00 00 00 00 00 ff 07 80 00 ff ff ff ff ff ff  |................|
.===> 0000   60 3c ff ff ff ff ff ff 41 22 24 72              |`<......A"$r    |
===> 0000   a0 3c 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d  |.<..............|
===> 0010   0e 0f                                            |..              |
===> 0000   a0 3d 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d  |.=..............|
===> 0010   0e 0f                                            |..              |
===> 0000   a0 3e 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d  |.>..............|
===> 0010   0e 0f                                            |..              |
===> 0000   30 3f                                            |0?              |
<=== 0000   00 00 00 00 00 00 ff 07 80 69 ff ff ff ff ff ff  |.........i......|
===> 0000   a0 3c 00 00 00 00 00 00 00 00 00 00 00 00 00 00  |.<..............|
===> 0010   00 00                                            |..              |
===> 0000   a0 3d 00 00 00 00 00 00 00 00 00 00 00 00 00 00  |.=..............|
===> 0010   00 00                                            |..              |
===> 0000   a0 3e 00 00 00 00 00 00 00 00 00 00 00 00 00 00  |.>..............|
===> 0010   00 00                                            |..              |
===> 0000   a0 3f ff ff ff ff ff ff ff 07 80 69 ff ff ff ff  |.?.........i....|
===> 0010   ff ff                                            |..              |
===> 0000   30 3c                                            |0<              |
<=== 0000   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  |................|
===> 0000   30 3d                                            |0=              |
<=== 0000   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  |................|
===> 0000   30 3e                                            |0>              |
<=== 0000   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  |................|
===> 0000   30 3f                                            |0?              |
<=== 0000   00 00 00 00 00 00 ff 07 80 69 ff ff ff ff ff ff  |.........i......|
.===> 0000   60 04 ff ff ff ff ff ff 41 22 24 72              |`.......A"$r    |
===> 0000   a0 04 e8 03 00 00 17 fc ff ff e8 03 00 00 00 ff  |................|
===> 0010   00 ff                                            |..              |
===> 0000   30 04                                            |0.              |
<=== 0000   e8 03 00 00 17 fc ff ff e8 03 00 00 00 ff 00 ff  |................|
===> 0000   c1 04 01 00 00 00                                |......          |
===> 0000   b0 04                                            |..              |
===> 0000   30 04                                            |0.              |
<=== 0000   e9 03 00 00 16 fc ff ff e9 03 00 00 00 ff 00 ff  |................|
===> 0000   c1 04 0a 00 00 00                                |......          |
===> 0000   b0 04                                            |..              |
===> 0000   30 04                                            |0.              |
<=== 0000   f3 03 00 00 0c fc ff ff f3 03 00 00 00 ff 00 ff  |................|
..===> 0000   60 00 ff ff ff ff ff ff 41 22 24 72              |`.......A"$r    |
F
===============================================================================
Failure: test_mifare_classic_format_first_sector
mifare_classic_authenticate() failed
<0 == res>
expected: <0>
  actual: <-1>
test_mifare_classic.c:107: test_mifare_classic_format_first_sector(): cut_assert_equal_int(0, res, cut_test_context_set_current_result_user_message( cut_test_context_current_peek(), cut_test_context_take_printf(cut_test_context_current_peek(), "mifare_classic_authenticate() failed")))
===============================================================================
.===> 0000   60 04 ff ff ff ff ff ff 41 22 24 72              |`.......A"$r    |
===> 0000   a0 04 e8 03 00 00 17 fc ff ff e8 03 00 00 00 ff  |................|
===> 0010   00 ff                                            |..              |
===> 0000   30 04                                            |0.              |
<=== 0000   e8 03 00 00 17 fc ff ff e8 03 00 00 00 ff 00 ff  |................|
===> 0000   a0 05 00 00 00 00 ff ff ff ff 00 00 00 00 00 ff  |................|
===> 0010   00 ff                                            |..              |
===> 0000   30 05                                            |0.              |
<=== 0000   00 00 00 00 ff ff ff ff 00 00 00 00 00 ff 00 ff  |................|
===> 0000   c2 04 00 00 00 00                                |......          |
===> 0000   b0 05                                            |..              |
===> 0000   30 05                                            |0.              |
<=== 0000   e8 03 00 00 17 fc ff ff e8 03 00 00 00 ff 00 ff  |................|
...

Finished in 2,502360 seconds (total: 0,532183 seconds)

13 test(s), 646 assertion(s), 3 failure(s), 0 error(s), 0 pending(s), 0 omission(s), 0 notification(s)
76,9231% passed

I tested only one device so far. However, I know the problem exists with at least one other device. I can try up to 10 devices tomorrow, but I guess it's not just a single defective device.

Any ideas?

Best,
Fabian

@smortex
Copy link
Contributor

smortex commented Apr 26, 2017

I just run the test suite a few time successfully with the device you used…

If the problem persist with multiple devices and multiple cards you try, maybe the environment is prone to errors (some kind of interference)?

@TeeTrizZz
Copy link
Author

TeeTrizZz commented Apr 26, 2017

So, it looks like the tags (1k, round, 47mm) are the main problem. I just tried different 1k tags (blue keyfobs, as well as black keyfobs and cards by Digital Logic). Absolutely no problem! Your test suite does not throw any errors. On the other hand, surprisingly, running the test suite with my round tags and the SPI device results in errors, too. Maybe it's their shape, maybe they're just garbage.

I have other round 1k tags in the storage room (other manufacturer, 45mm). I will try these tags tomorrow to see if they are better!

Thanks for the idea with your test suite. This will help to prevent such problems!

@doegox
Copy link
Member

doegox commented Apr 26, 2017

Note that some MFC clones are of poor quality and errors are more frequent with them.
Try scanning them e.g. with a smartphone and "NFC TagInfo by NXP", it will tell if it thinks it's a clone (not all smartphones are capable of reading MFC, the application will tell you)

@smortex
Copy link
Contributor

smortex commented Apr 26, 2017

Ah, cool @TeeTrizZz ! I'm happy you found out what was going wrong.

Maybe everything is not lost with your tags: if the use case is compatible with this, checking that all operations succeed and restarting on failure may have an acceptable time penality?

@doegox, do you know how NXP's applications guess tags origin? Response-time based?

@doegox
Copy link
Member

doegox commented Apr 26, 2017

@smortex several indicators are used for fingerprinting, I don't know all details.
Personally I like using response-time of Auth command, it doesn't require knowing any key and it's already quite discriminating.
But on Android it's clear you can't measure response time precisely.
Another approach is to try their RFIDDiscover but you need one of the supported readers.

@TeeTrizZz
Copy link
Author

@doegox Thanks for the advice! My Galaxy S7 can't read MFC but I have a HTC in my office which can. I will check if the app detects if the tag is a clone.

@TeeTrizZz
Copy link
Author

TeeTrizZz commented Apr 27, 2017

So, I tested my new tags, my old tags, different keyfobs and plastic cards.

The thing is: They are actually all okay (i.e. your test suite reports no failures!), but I can "brick" them with your test suite (-> the test suite always reports 2 or more failures after that). The smaller the tag, the harder it is to brick the tag (45mm round tag, easy. 20mm keyfob, not so easy). And this is also the reason why the test with the SPI reported failures, too. The tag was already bricked.

I guess if an error is raised while writing data / formating the tag, the tag is not failure-free anymore. It also looks like the rotation and/or the position of the tag is important. And this might be the reason why smaller tags are harder to brick: It's easier to "misplace" a larger tag.

Now this makes it a bit harder to find the "real" issue. Breaking the tag probably doesn't say too much about my problems writing FF FF FF etc. Maybe the device (in combination with my tags) is still the real issue here (or nfc-mfclassic? or the driver? etc.) . What kind of tags did you use, @smortex? Shape, size?

I'm going to rerun the test with the SPI device to see if I can brick the tags with this device, too. The only problem is that they are not really comparable. Their antenna is totally different, it's a different chip, etc. I will also test if my new tags have the FF FF FF problem (or if its less frequent).

Any ideas?

@TeeTrizZz
Copy link
Author

One more information: The two keyfobs are bricked because writing their trailor failed, so that the authentication now fails. Using nfc-mfclassic, I can't read all blocks. This is totally understandable.

The card, however, is a totally different case. I can read all blocks with nfc-mfclassic. No problems. But this is the result from your test suite:

===> 0000   60 00 ff ff ff ff ff ff fb 86 96 a4              |`...........    |
.===> 0000   60 04 ff ff ff ff ff ff fb 86 96 a4              |`...........    |
===> 0000   a0 04 e8 03 00 00 17 fc ff ff e8 03 00 00 00 ff  |................|
===> 0010   00 ff                                            |..              |
F
===============================================================================
Failure: test_mifare_classic_value_block_decrement
mifare_classic_init_value() failed
<0 == res>
expected: <0>
  actual: <-1>
test_mifare_classic.c:259: test_mifare_classic_value_block_decrement(): cut_assert_equal_int(0, res, cut_test_context_set_current_result_user_message( cut_test_context_current_peek(), cut_test_context_take_printf(cut_test_context_current_peek(), "mifare_classic_init_value() failed")))
===============================================================================
===> 0000   60 04 ff ff ff ff ff ff fb 86 96 a4              |`...........    |
===> 0000   30 07                                            |0.              |
<=== 0000   00 00 00 00 00 00 ff 07 80 69 ff ff ff ff ff ff  |.........i......|
.===> 0000   60 00 ff ff ff ff ff ff fb 86 96 a4              |`...........    |
===> 0000   a0 03 ff ff ff ff ff ff 7f 07 88 00 aa bb cc dd  |................|
===> 0010   ee ff                                            |..              |
F
===============================================================================
Failure: test_mifare_classic_mad
mifare_classic_write() failed
<0 == res>
expected: <0>
  actual: <-1>
test_mifare_classic_mad.c:50: test_mifare_classic_mad(): cut_assert_equal_int(0, res, cut_test_context_set_current_result_user_message( cut_test_context_current_peek(), cut_test_context_take_printf(cut_test_context_current_peek(), "mifare_classic_write() failed")))
===============================================================================
===> 0000   60 07 ff ff ff ff ff ff fb 86 96 a4              |`...........    |
===> 0000   30 07                                            |0.              |
<=== 0000   00 00 00 00 00 00 ff 07 80 69 ff ff ff ff ff ff  |.........i......|
.===> 0000   60 3c ff ff ff ff ff ff fb 86 96 a4              |`<..........    |
===> 0000   a0 3c 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d  |.<..............|
===> 0010   0e 0f                                            |..              |
===> 0000   a0 3d 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d  |.=..............|
===> 0010   0e 0f                                            |..              |
===> 0000   a0 3e 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d  |.>..............|
===> 0010   0e 0f                                            |..              |
===> 0000   30 3f                                            |0?              |
<=== 0000   00 00 00 00 00 00 ff 07 80 69 ff ff ff ff ff ff  |.........i......|
===> 0000   a0 3c 00 00 00 00 00 00 00 00 00 00 00 00 00 00  |.<..............|
===> 0010   00 00                                            |..              |
===> 0000   a0 3d 00 00 00 00 00 00 00 00 00 00 00 00 00 00  |.=..............|
===> 0010   00 00                                            |..              |
===> 0000   a0 3e 00 00 00 00 00 00 00 00 00 00 00 00 00 00  |.>..............|
===> 0010   00 00                                            |..              |
===> 0000   a0 3f ff ff ff ff ff ff ff 07 80 69 ff ff ff ff  |.?.........i....|
===> 0010   ff ff                                            |..              |
F
===============================================================================
Failure: test_mifare_classic_format
mifare_classic_format_sector() failed
<0 == res>
expected: <0>
  actual: <-1>
test_mifare_classic.c:180: test_mifare_classic_format(): cut_assert_equal_int(0, res, cut_test_context_set_current_result_user_message( cut_test_context_current_peek(), cut_test_context_take_printf(cut_test_context_current_peek(), "mifare_classic_format_sector() failed")))
===============================================================================
===> 0000   60 04 ff ff ff ff ff ff fb 86 96 a4              |`...........    |
===> 0000   a0 04 e8 03 00 00 17 fc ff ff e8 03 00 00 00 ff  |................|
===> 0010   00 ff                                            |..              |
===> 0000   30 04                                            |0.              |
<=== 0000   e8 03 00 00 17 fc ff ff e8 03 00 00 00 ff 00 ff  |................|
===> 0000   c1 04 01 00 00 00                                |......          |
===> 0000   b0 04                                            |..              |
F
===============================================================================
Failure: test_mifare_classic_value_block_increment
mifare_classic_transfer() failed
<0 == res>
expected: <0>
  actual: <-1>
test_mifare_classic.c:228: test_mifare_classic_value_block_increment(): cut_assert_equal_int(0, res, cut_test_context_set_current_result_user_message( cut_test_context_current_peek(), cut_test_context_take_printf(cut_test_context_current_peek(), "mifare_classic_transfer() failed")))
===============================================================================
.===> 0000   60 00 ff ff ff ff ff ff fb 86 96 a4              |`...........    |
===> 0000   30 00                                            |0.              |
<=== 0000   fb 86 96 a4 4f 08 04 00 01 0b fa 1c c6 d9 89 1d  |....O...........|
===> 0000   a0 00 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d  |................|
===> 0010   0e 0f                                            |..              |
===> 0000   60 00 ff ff ff ff ff ff fb 86 96 a4              |`...........    |
===> 0000   a0 01 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d  |................|
===> 0010   0e 0f                                            |..              |
===> 0000   a0 02 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d  |................|
===> 0010   0e 0f                                            |..              |
===> 0000   30 03                                            |0.              |
<=== 0000   00 00 00 00 00 00 7f 07 88 00 00 00 00 00 00 00  |................|
F
===============================================================================
Failure: test_mifare_classic_format_first_sector
mifare_classic_format_sector() failed
<0 == res>
expected: <0>
  actual: <-1>
test_mifare_classic.c:136: test_mifare_classic_format_first_sector(): cut_assert_equal_int(0, res, cut_test_context_set_current_result_user_message( cut_test_context_current_peek(), cut_test_context_take_printf(cut_test_context_current_peek(), "mifare_classic_format_sector() failed")))
===============================================================================
.===> 0000   60 04 ff ff ff ff ff ff fb 86 96 a4              |`...........    |
===> 0000   a0 04 e8 03 00 00 17 fc ff ff e8 03 00 00 00 ff  |................|
===> 0010   00 ff                                            |..              |
===> 0000   30 04                                            |0.              |
<=== 0000   e8 03 00 00 17 fc ff ff e8 03 00 00 00 ff 00 ff  |................|
===> 0000   a0 05 00 00 00 00 ff ff ff ff 00 00 00 00 00 ff  |................|
===> 0010   00 ff                                            |..              |
===> 0000   30 05                                            |0.              |
<=== 0000   00 00 00 00 ff ff ff ff 00 00 00 00 00 ff 00 ff  |................|
===> 0000   c2 04 00 00 00 00                                |......          |
===> 0000   b0 05                                            |..              |
===> 0000   30 05                                            |0.              |
<=== 0000   e8 03 00 00 17 fc ff ff e8 03 00 00 00 ff 00 ff  |................|
...

Finished in 1,934677 seconds (total: 0,469188 seconds)

13 test(s), 623 assertion(s), 5 failure(s), 0 error(s), 0 pending(s), 0 omission(s), 0 notification(s)
61,5385% passed

Sometimes I even get 7 failures! What is going on here?

@smortex
Copy link
Contributor

smortex commented Apr 27, 2017

One more information: The two keyfobs are bricked because writing their trailor failed, so that the authentication now fails. Using nfc-mfclassic, I can't read all blocks. This is totally understandable.

Maybe I am confused, but isn't the card integrity supposed to be guaranteed? As far as I am concerned, I would expect a write failure on a trailer block to have no impact on it's content, that is the sector is still accessible with the same keys as before. And if the CRC error is detected in the response by the PCD, then the command may have succeeded and using the old or new keys is supposed to act as expected.

@TeeTrizZz
Copy link
Author

Interesting! In this case, this seems even stranger. I'm especially surprised about the different situations: readable but non-writable (?) plastic card (although the access bits are still standard), non-readable but somehow writable key fobs, strangly-behaving stickers...

@TeeTrizZz
Copy link
Author

So, I finally found a solution. Placing a ferrite sheet directly below the antenna of the DL533N, decreases the error rate significantly. Writing the tag is now successfully, even if the tag isn't place properly. I read through a lot of different antenna and NFC documents and it seems that feritte below the antenna focuses the magnetic field above the antenna. Maybe this helps if someone has similiar problems as I had.

@anthonyraymond
Copy link

So, I finally found a solution. Placing a ferrite sheet directly below the antenna of the DL533N, decreases the error rate significantly. Writing the tag is now successfully, even if the tag isn't place properly. I read through a lot of different antenna and NFC documents and it seems that feritte below the antenna focuses the magnetic field above the antenna. Maybe this helps if someone has similiar problems as I had.

Indeed ! Lifting the tag just a bit finaly allowed me to write it.
I personally slide four or five sheets of paper betwwen the reader/writer and the tag.
Thanks for your answer !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants