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

NDEF Lock Control TLV not according to specification #34

tinue opened this Issue Jun 27, 2017 · 3 comments


None yet
2 participants
Copy link

tinue commented Jun 27, 2017

Line 1405 of Adafruit_PN532.cpp sets the NDEF Lock Control TLV element. It writes the bytes 0x0103A01044. When looking at page 17 of then NTAG213 chips are factory-delivered with 0x0103A00C34. This is in sync with the samples found on page 22.

Is it possible that the Adafruit-written NDEF Lock Control TLV element is faulty?

Does it even matter? The NTAG215 and NTAG216 don't even contain a factory-installed NDEF Lock Control TLV element (again page 17 of the PDF). Is the field really necessary / mandatory? I have tried both with and without this element, and the iPhone can read both tags equally fine (with the iOS 11 CoreNFC API).


This comment has been minimized.

Copy link

conoror commented Jul 21, 2017

For the NTAG213, that is completely incorrect. The lock bytes are saying "Lock at page 0x28, 16 bytes per lock bit, 16 lock bits". The lock is at page 0x28 but there are 8 bytes per lock bit and 12 lock bits. No NTAG has 16 bytes per lock bit - The 215/216 are 64 bytes per lock bit.

Lock control TLV section 2.2.2 says "can be present" not "shall be present". But I believe it does matter, at least for the NTAGS. The spec says that the lock area starts from the first byte after the data area. Also it has a default view for the number of lock bits (103 by default for NTAG216!)

However for some bizarre reason, the CC for the NTAG215 indicates a space that is 8 bytes short. The NTAG216 is 16 bytes short. If you used the CC to find the size of the data area and thus the dynamic lock area and, beyond that, the cfg pages, well... you'd be pretty wrong!

Eg: NTAG216: The CC has the value "0x6D". Multiply that by 8 = 872 bytes or DA blocks. Which means the lock area should be at 0xDE. Which is wrong because the NTAG216 data area is 888 bytes placing the lock area at 0xE2.

PS: The NTAG "get version" call returns the stupidest values imaginable. It returns a memory size as a range 2^n to 2^n + 1. In tandem with the incorrect default CC values you need a lookup table to determine the type of NTAG, it's actual memory size and thus the location of the config area! What are NXP smoking!?


This comment has been minimized.

Copy link

tinue commented Jul 23, 2017

I wonder what the purpose of the NDEF Lock Control TLV element is. To make any sense, it would have to provide information that is not otherwise present (e.g. via GET_VERSION). The information must also be "useful" in the sense that e.g. a future new NTAG chip can be used without updating the reader/writer software.

I don't see this with the NTAG2xx chips. If a new one comes to market (say one with more memory), the presence of an NDEF Lock Control TLV element would not help at all to avoid updating a tag writing software. For reading an NDEF message, the lock bytes are irrelevant, so the Lock Control in not needed anyway.

IMHO, the NDEF Lock Control TLV element should not be written at all when an NTAG2xx is used for NDEF purposes. This gives you five more bytes of user data to use, without sacrificing anything.

I sill don't know what the correct value would be. NXP themselves say that you can only determine the number of lock bits, and the start address of the lock bytes. They claim "Note that it is not possible to retrieve the locking structure of the dynamic lock bits i.e. location of the block-locking bits and the lock bit – locked area association."

So all the more: How does it help me as a programmer when I only know half of the information I need in order to lock? In order to lock, I need to know the used chip in detail, and program this information into my application. I guess I would never rely on the NDEF Lock Control TLV element, and thus is seems superfluous.


This comment has been minimized.

Copy link

conoror commented Jul 23, 2017

Hmm. Yes, what you say is absolutely true as I'm finding out myself (I'm writing NTAG/NFC code now. In Pic assembly for some reason). Get version (indirectly) tells me which NTAG I have. Which I need to know in order to "format" it to use it for NDEF messages. Even if the CC was right (which it isn't) by default, it can be changed so that doesn't help. And a TLV is totally pointless in this regard because some NTAGs have them and some don't.

The tag 2 specification does indeed tells you about the locking bits not, as you say, other structure - ie: the block-locking bits. I did assume that the lock-bit to locked area association was linear. I can't find an NTAG which isn't - ie: doesn't run LSBbit to MSbit, byte 0 to byte 1. The size of the lock area is dictated (in the tag 2 spec) by a default (which is 8) or by the Lock TLV.

BTW, the dynamic lock area is one time programmable (0->1 only) even though the datasheet doesn't tell you.

Ok. So the only device a lock TLV would help is one that is reading an pre-created properly formatted tag and would like to lock it to read-only. In which case it could read the Lock TLV to find out where the dynamic lock area starts and then just write 0xFF to both bytes. Which would do the job because the block-locking bits don't matter then.

Er. Does anyone actually do this? Or care? I can't imagine someone has an Android app that has a "lock this tag permanently" button. So I'm conflicted at the moment as to whether I'll bother writing them. For the NTAG212,213,215,216 I work them out as:

  • NTAG212 = 90 0A 34
  • NTAG213 = A0 0C 34
  • NTAG215 = 88 08 66
  • NTAG216 = E8 0E 66
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.