Tuesday, November 23, 2010

Locking Memory on EPC RFID Tags

Locking the memory on EPC GEN 2 compliant tags is an often misunderstood process. Many think that it is simply a matter of changing the access password to a non-zero value (the default for Gen 2 tags) and then the tag is 'locked' but this is not the case. This posting will review how tag locking works for EPC RFID tags and show you how to lock the Impinj Monza tags using .NET version 1.0.0.6 of the Octane Software Development Kit (SDK).

GEN 2 TAG PASSWORDS

An EPC GEN 2 tag has two separate passwords, an access password and a kill password, each are 32 bits and are stored in the reserved bank (bank 00) of the tag memory.



STATES

When tag is singulated, enters one of two states:
Secured (if access password is all zeros, which is the factory default)
Open (if non-zero access password has been programmed to the tag)

A tag in the open state can be moved to secured by providing non-zero access password.

The key thing to remember is that assigning a non-zero access password does not, in itself, prevent anyone with a GEN 2 reader from reading or changing data on the tag. It only requires that any future users must provide the access password in order to change the lock state and is simply one step in effectively locking tag memory.

Each memory bank can be in one of four lock states:
1. Unlocked
2. Perma-unlocked (can never be locked)
3. Locked
4. Perma-locked (can never be unlocked)

This is illustrated below using intellisense options when programming the lock state of the tag.




LOCK PROCEDURE

The steps would be (for a factory default tag):
1. Lock (or perma-lock) the selected memory bank using default password of all zeros.
2. Assign a 32 bit (8 hex character) access password, this will prevent the tag lock state from being changed.
3. Lock the access password - this will prevent the password from being read or over-written. Not doing this step would allow any user to simply read the access password, then use it to unlock and over-write memory on the tag (unless it has been perma-locked).

Only reserved memory bank (access and kill passwords) can be both write and READ locked - all others (EPC, TID, and User) can be write-locked only. Typically the Tag Identification (TID) memory bank is perma-locked at the factory.

Each tag memory bank can be individually write locked as shown below.



SAMPLE CODE

Here is an example of locking user memory in C# using the Octane SDK.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Impinj.OctaneSdk;
 
namespace LockUserMemory
{
    class Program
    {
        // Create an instance of the SpeedwayReader class.
        static SpeedwayReader Reader = new SpeedwayReader();
         
        static void Main(string[] args)
        {
            try
            {
                // Connect to the reader.
                // Replace "SpeedwayR-10-25-32" with your
                // reader's host name or IP address.
                Reader.Connect("SpeedwayR-10-25-32");
                 
                // Configure the reader with the factory deafult settings.
                Reader.ApplyFactorySettings();
                 
                // Define how we want to program the access password.
                ProgramAccessPasswordParams passwordParams = 
                    new ProgramAccessPasswordParams();
                passwordParams.AccessPassword = "12345678";
                passwordParams.NewAccessPassword= "12345678";
                passwordParams.TimeoutInMs = 5000;
                passwordParams.TargetTag = null;
                 
                // Program the access password and check the results.
                ProgramAccessPasswordResult passwordResult = 
                    Reader.ProgramAccessPassword(passwordParams);
                if (passwordResult.WriteResult.Result == AccessResult.Success)
                {
                    Console.WriteLine("Successfully programmed access password.");
                }
                else
                {
                    Console.WriteLine("Error programming access password : {0}",
                    passwordResult.WriteResult.Result);
                }
                 
                // Define how we want to lock user memory.
                LockTagParams lockParams = new LockTagParams();
                lockParams.AccessPassword = "12345678";
                lockParams.LockUserMemory = LockType.Locked;
                lockParams.TimeoutInMs = 5000;
                lockParams.TargetTag = null;
                lockParams.AntennaPortNumber = 1;
                 
                // Lock user memory check the results.
                LockTagResult lockResult = Reader.LockTag(lockParams);
                if (lockResult.LockResult.Result == AccessResult.Success)
                {
                    Console.WriteLine("Tag lock successful.");
                }
                else
                {
                    Console.WriteLine("Error locking tag : {0}",
                    lockResult.LockResult.Result);
                }
                 
                // Disconnect from the reader.
                Reader.Disconnect();
            }
            catch (OctaneSdkException e)
            {
                Console.WriteLine("Octane SDK exception: {0}", e.Message);
            }
            catch (Exception e)
            {
                Console.WriteLine("Exception : {0}", e.Message);
            }
             
            // Wait for the user to press enter.
            Console.WriteLine("Press enter when done.");
            Console.ReadLine();
        }
    }
}


OTHER USEFUL NOTES

In addition to the increased memory size, the Impinj Monza 4QT tag chips offer the ability to independently lock four fixed, 128-bit sections of user memory (block permalock). This feature is particularly useful for situations such as in a supply chain, where various participants along the chain may want to record data, but not necessarily have it be openly available to all parties.

Lock status cannot be read, it can only be inferred. So there is no direct way to query a tag and have it reply if it is locked or not. However, in some cases when attempting to access a tag memory bank, it will return a pretty specific error "tag memory locked".