How To Implement Firmware Anti-cloning Protection

Disclaimer: We can not be held responsible for any damage or loss caused by the information covered in this article which is provided "AS IS". You agree to use the information at your own risk.


The firmware running on most embedded systems resides in an external FLASH memory device which is connected to a processor over a memory interface bus (parallel or serial). Both the Flash memory device and the memory bus are exposed and can be easily tapped by a hacker to illegally copy the firmware. Preventing the firmware from being copied or cloned is really not practical. But the execution of the firmware can be practically and securely controlled such that even the firmware gets illegally cloned it will not be illegally run, effectively protecting the intellectual properties of the firmware.

To securely control the execution of the firmware, the firmware needs to be tied to a hardware device of which secret contents can not be cloned or reproduced. The firmware uses the challenge-response mechanism to ensure that the hardware on board is authentic to execute normally. Thus securing the hardware device translates to securing the firmware execution.

The firmware, which is the client, sends a question (challenge) to the hardware device, which is an authentication chipset. The client expects an answer (response) from the authentication chipset. If the answer is correct, the firmware continues normal execution. During the cause of execution, the firmware sends out many different questions to the authentication chipset and these questions are randomly generated with a Secret Key known only to the authentication chipset. The authentication chipset uses the same Secret Key to generate answers (responses) that satisfy the questions (challenges).

The response sent on a physical bus (I2C, for example) from the authentication chipset to the firmware is securely protected by hashing the response using SHA-256 cryptographic algorithm. The response is a digest computed by the authentication chipset. The physical communications bus (I2C, for example) is now a secure channel preventing it from being tapped, replayed by the hacker.

In our implementation, we use ATSHA204 authentication chipset from Atmel. Our firmware resides in a NOR SPI serial Flash memory device on board which obviously can be easily de-soldered from the board and its contents can be duplicated using a device programmer at ease.

The implementation flow consists of the following major steps:
- The firmware generates a challenge.
- The firmware sends the challenge to the authentication chipset.
- The firmware instructs the authentication chipset to compute a response and send it back.
- At the same time, the firmware calculates the expected response.
- Upon receiving the response from the authentication chipset, the firmware compares it against the expected response. If there is a mismatch, the firmware stops the execution or causes the execution to be abnormal or buggy.

The Secret Key is used by the firmware to generate the expected responses. The weakest point is the Secret Key being exposed. The firmware should store the Secret Key securely, for example, by hard coding its pieces in various places and/or use multiple secret keys spreading around in the code. Also the JTAG port on the processor should be disabled and the serial port console should not have the root login privilege, preventing the firmware execution from getting stepped through.

A. Generating Challenge

First of all, the challenge should be as random as possible. A fixed challenge completely defeats the purpose of authentication.

To generate a 256-bit random number, the firmware can use a simple linear feedback shift register (LFSR) algorithm or send out a RANDOM command to have the ATSHA204 authentication chip to generate a high quality random number for you. We name this random number as Rand4Challege.

The parameters to the RANDOM command are:

NameByte SizeValueNotes
Param1Mode10x00automatically update EEPROM seed.
Param2N/A20x0000must be zero.

The RANDOM command upon successful execution returns a 32-byte random number.

B. Sending Challenge

The challenge should be sent randomly often but not frequent so that the communications on the physical channel appears to be random, not periodic. For example the challenges can be sent in a combination of prime numbers of seconds, such as 7 seconds, 45 seconds, 23 seconds, 37 seconds.

Use the NONCE command to send out the challenge to the ATSHA204 authentication chipset. Note, NONCE command takes only 20 bytes as its input value so we will use the first 20 bytes from the 32-byte random number generated by in Step A.

The parameters for the NOCE command are:

NameByte SizeValueNotes
Param1Mode10x00combine new random number with NumIn, store in TempKey. Automatically update EEPROM seed.
Param2N/A20x0000must be zero.
DataNumIn20Rand4Challegeobtained from Step A.

Upon execution the NOCE command returns a 32-byte random number (we name it RandOut) which will be used in the next step along with the Secret Key to calculate the expected response.

C. Instructing Authentication Chipset to Send Back Response

After sending the NOCE command and receiving the random number RandOut, the firmware issues the MAC command to have the authentication chipset compute the response (a digest) and return it.

The parameters for the MAC command are:

NameByte SizeValueNotes
Param1Mode10x01use SecretKey and TempKey.
Param2KeyID20x0003the slot # where the Secret Key is stored.

The response (digest) is generated from hashing the following message (88 bytes):

1byteOpcode (0x08)
1byteMode (0x01)
2bytesParams (0x0003)
11bytesall zeros
1byteSN[8], 8th byte of the authentication ship's serial number
4bytesall zeros
2bytesSN[0:1], 1st two bytes of the authentication ship's serial number
2bytesall zeros

Multiple Secret Keys can be used to enhance the protection. For each Challenge-Response, the MAC command can take a randomly selected Secret Key (ATSHA204 supports up to 16 key slots).

D. Calculating Expected Response

The authentication chipset upon execution of NONCE command generates a 32-byte random number RandOut and returns it to the firmware. In the meantime, it uses RandOut along with the Challenge it receives from the firmware to generate a digest to be stored in the TempKey.

The digest is generated from hashing following the SHA-256 message (55 bytes):

20bytesNumIn, which is the 20-byte challenge from the firmware
1byteOpcode (0x16)
1byteMode (0x00)
1byteLSB of Param2 (0x00)

In order to calculate the same response as the authentication chip does in Step D below, the firmware needs to compute the TempKey value as well.

ExpectedTempKey = SHA256(RandOut . NumIn . 0x16 . 0x00 . 0x00, 55);
1) We use the PHP scripting language notation '.' (period) to concatenate bytes to form the SHA message to be hashed.
2) SHA256() is a function that takes a message and its length (number of bytes) to calculate a SHA-256 digest. The function prototype is
uint32 SHA256(uint8 *message, int len);

To calculate the expected response to the challenge, the firmware simply mimics what the MAC command does by the authentication chipset.

ExpectedResponse = SHA256(SecretKey . ExpectedTempKey . 0x16 . 0x01 . 0x0003 . 11 bytes of 0x00, SN[8], 4 bytes of 0x00, SN[0:1], 2 bytes of 0x00, 88);
Note: SN is the serial number of the authentication chipset and it is obtained by sending READ command to the authentication chipset during initialization.

E. Actions to Protect

Now the firmware compares the received response from the authentication chipset in Step C and the expected response it calculates in Step D. If it is a match, the firmware continues normal execution. Otherwise the firmware can simply quits itself (the decision making).

Having a match decision making at one central place can be vulnerable to a hacker stepping through the code to bypass it. In order to confuse the hacker during his code step-through hacking and to make the hacking life miserable, the decision makings should be distributed all over many places to make the firmware go 'crazy' more effectively and easily.

In a typical embedded system running an operating system (RTOS), there are tasks or threads that run in iterations. We can deploy a 'watchcat' counter in each of the tasks/threads. Each iteration decrements the watchcat counter. When the watchcat expires, the task will do the crazy thing.

The authentication process can run as a separate task/thread, it sends out challenges, receives and validates responses as described in Steps A ~ D above. However whenever there is a match, the authentication process posts a special message to the tasks/threads to have the watchcat reloaded, keeping the firmware running normally. In case the hacker is able to step through the code and bypass the section of the code comparing the received response and the expected response, any of the watchcats is still able to cause the firmware go crazy.

Appendix A. How to Read Device's Serial Number

Use the READ command (32) to read out the device's serial number. The parameters to the command are:

 NameByte SizeValueNotes
Param1Mode10x8032-byte read of ConfigZone.
Param2Address20x0000read the first 32 bytes off the ConfigZone

The READ Command returns a 32-byte array. The serial numbers are stored at [0:3] and [8:12] locations.

Appendix B. Pico's AUTHEN engine API

In a real embedded system, there are tasks that implement your IPs and you are really interested in protecting them. For each of these tasks, you can add a counter and register an autehcb callback with the authen engine. The authencb callback function acts like a watchdog to reload the counter. The task decrements the counter and if the counter reaches zero, the task can decide to sleep forever, for instance.

In general, steps are: 1. initialize authen engine, 2. add a counter in each task and register an authencb with the authen engine for each task. 3. run the authen engine. 4. enjoy and have peace of mind.

  typedef struct
      int (*registerCb)(	/* register a watchcat callback to be called back where there is a c-r match */
      void *self,					// pointer to the instance created by user
      void *UserData,				// user data pointer to be passed through the callback
      void (*watchcatCb)(void *UserData)		// user-supplied callback function
      void (*release)(	/* function called by user to release all resources allocated to the current instance */
      void *self					// pointer to the instance created by user
      void *inst;		/* internal use by the instance */
  } AUTHEN_t;
  // Authentication service (firmware anti-cloning protection) API functions. See AUTHEN_t for details.
  AUTHEN_t *
      char *devI2c		// I2C bus where the authentication IC is attached to

We offer a complete firmware anti-copy protection reference design and a standalone ATSHA204 USB programmer (USD$199). If you are interested in licensing the reference design or purchase a programmer, feel free to contact us or drop a message to us below.