How to Add Memory Protection to NFC Tags For Copy Protection

Project Source Code

Get the project source code below, and follow along with the lesson material.

Download Project Source Code

To set up the project on your local machine, please follow the directions provided in the README.md file. If you run into any issues with running the project source code, then feel free to reach out to the author in the course's Discord channel.

This lesson preview is part of the The newline Guide to NFCs with React Native course and can be unlocked immediately with a \newline Pro subscription or a single-time purchase. Already have access to this course? Log in here.

This video is available to students only
Unlock This Course

Get unlimited access to The newline Guide to NFCs with React Native, plus 70+ \newline books, guides and courses with the \newline Pro subscription.

Thumbnail for the \newline course The newline Guide to NFCs with React Native
  • [00:00 - 00:16] Hello, in this lesson we will discuss how to enable memory protection for our NFC Pokemon tags. We will review the concept of the NFC tag memory protection mechanisms.

    [00:17 - 00:26] Then we explain how to use the password protection commands. Then we implement a password protection feature for our app.

    [00:27 - 00:37] Let's get started. Before we dive in, let's first consider why we need this memory protection feature.

    [00:38 - 00:51] In the previous lesson, we already started using digital signatures to protect our NFC tags. So you might wonder, why do we need extra memory protection?

    [00:52 - 01:08] Actually, these two mechanisms handle different security issues. The digital signature mechanism is useful against the case when people try to fake or clone our NFC tags.

    [01:09 - 01:25] Because we can verify the signature to find out if it is legitimate, as mentioned before. However, what if people simply want to load the tag with bad content?

    [01:26 - 01:42] To be more precise, you have seen that we can use the write command to write data into NFC tags. What if others also do write commands to override the data in our tags?

    [01:43 - 02:03] Without a memory protection mechanism, our NFC tags will easily have tempered with bad content. Let's first discuss our options regarding NFC tag memory protection.

    [02:04 - 02:14] There are three levels of protection. In-depth level, type 2 platform level and tag specific level.

    [02:15 - 02:33] Let's discuss the first end-depth level. Recall from the previous lesson that NFC tags have a special block called CC block, which is used to indicate whether this NFC tag is end-depth compatible.

    [02:34 - 02:54] The last byte of the CC block can be used to enable read-only protection for NFC tags. This operation is irreversible, which means that once you set it to read-only, you won't be able to write it again.

    [02:55 - 03:16] You can turn on this protection by calling NFCManager.end-depth-handler.make ReadOnly. Since we are not using end-depth in this app, this option won't be our final choice.

    [03:17 - 03:35] The second approach is for type 2 platform. The NFC Type 2 platform has defined a lock control feature, which has the ability to control the write access for each block or page.

    [03:36 - 03:47] However, this feature has two drawbacks. First, this feature is pretty complex and hard to use.

    [03:48 - 04:03] Second, this operation is irreversible, just like the end-depth one. Once you turn on these protection bits, you cannot turn them off.

    [04:04 - 04:24] For our NFC Pokemon app, we actually want to disable unauthorized write operations, not lock the tag data forever. So this approach doesn't suit our use case either.

    [04:25 - 04:46] The final approach is to use the tag-specific password protection feature. This feature is available for NXP, N-Tag to 13 and to 15 families, which are the most widely used NFC tags on the market.

    [04:47 - 05:09] The password protection feature for N-Tag family is configured by the blocks in the following diagram. The off-bite indicates the block index to start our memory protection.

    [05:10 - 05:31] For example, if we want our user blocks to be protected, we can set this byte to 3. The default value for this byte is 255, indicating that the protection is not enabled.

    [05:32 - 05:42] Then comes the access byte. Each bit of this byte indicates a different meaning, which we only discuss the most significant bit here.

    [05:43 - 05:56] The MSP for access byte controls the memory protection strategy. Value zero means we only protect the write operation.

    [05:57 - 06:09] Value one means we want to protect both read and write operations. For our use case, we should set the value to be zero.

    [06:10 - 06:21] Next is the password itself. It is a single 32 bits or 4 byte block.

    [06:22 - 06:45] Finally is the password act or pack in short. This is a two byte value, which will be used as the response to indicate that you have sent the correct password to the NFC tag.

    [06:46 - 07:04] Once we have configured the password related blocks, password protection will be enabled for the next power cycle. Recall that NFC tag relies on the NFC reader to supply their power.

    [07:05 - 07:22] So the next power cycle basically means the next time we scan the NFC tag. This once the NFC tag leaves the field generated by the NFC reader, it will lose power.

    [07:23 - 07:39] When password protection is enabled, we must send a special pwd auth in order to do the following write operations. It looks like this.

    [07:40 - 07:58] The command code is 1b in hex, followed by the 4 byte password. When the password is correct, the NFC tag will respond the pack value we configured earlier.

    [07:59 - 08:13] By the way, please remember that in our configuration, password protection doesn't affect the read operation. It's time to write some code.

    [08:14 - 08:35] Let's open src NFC Uteals in short password protection.js. First, let's define two constants, the password and the pact or pack.

    [08:36 - 08:51] You can define whatever value you want for these two values. Just remember the former one is 4 bytes and the later one is 2 bytes.

    [08:52 - 09:23] Then we also define some local variables inside our function body. The first thing we'd like to do is to check whether our NFC tag is n tag 213 or n tag 215 by examining the NFC tag size.

    [09:24 - 09:39] We will use the cc block to accomplish this. The third byte in cc block indicates the size of the NFC tag divided by 8.

    [09:40 - 09:55] If the value is greater than 256, we know that we are dealing with n tag 215. Otherwise, we consider it to be n tag 213.

    [09:56 - 10:14] So we can set the off page index accordingly. Next, we'd like to check if the password authentication is already activated.

    [10:15 - 10:49] We'll call from the previous discussion that we should read the off byte. When the off byte value is 255, it means the protection is not activated.

    [10:50 - 11:06] We should configure our NFC tag to enable it. Let's perform the configuration from the last page.

    [11:07 - 11:14] The last page is used to configure the pack value. So issue a write command.

    [11:15 - 11:28] Remember, the write command is per page. So even though we only need to configure the first 2 bytes for this page, we still need to pass the other 2 bytes into it.

    [11:29 - 11:46] Next, let's configure our password. Let's do that.

    [11:47 - 11:54] We're going to use the first 1 byte. And that's the first 1 byte.

    [11:55 - 12:02] And that's the first 1 byte. So we'll call from the first 1 byte.

    [12:03 - 12:08] And we'll call from the first 2 byte. And we'll call from the first 2 byte.

    [12:09 - 12:45] After the password, let's configure our access byte. We should only set the MSB, or the most significant byte to 0, which indicates we'd like to have password protection for the write operation, not for the read operation.

    [12:46 - 13:09] To achieve that, we can use the bit mask value 7F and bitwise end operator. This way, we can turn off the MSB without modifying other bits.

    [13:10 - 13:30] Finally, we can configure our auth byte. This value indicates the block or page index to start our password protection.

    [13:31 - 14:03] Let's protect all the user memory starting from index 4. On the other hand, when the password protection is activated, we should perform the PWD auth operation.

    [14:04 - 14:31] The command code is 1B in hex, followed by the 4 byte password. If the password is correct, the NSC tag will respond to us with the 2 byte pack value we set before.

    [14:32 - 14:39] That's it. Now we successfully protect our NSC tags from unauthorized write operation with passwords.

    [14:40 - 14:46] We'll see you in the next one.