Protect Firmware from Counterfeiting
The intellectual property (IP) that resides in the system firmware is the most valuable and expensive to develop piece of any embedded system. Modern MCU-based systems typically use nonvolatile memory to store firmware/software. As a result, it is extremely vulnerable to theft. Stolen firmware is used to make cheap counterfeit products that steal marketshare from the original equipment manufacturer (OEM). The only way to fully protect firmware IP is to make it inaccessible for attackers to read and thus attack. Full-blown security microprocessors can provide 100% protection. At 10X the cost of a standard microcontroller, however, they’re too expensive for most embedded systems. Another option is cryptographic-authentication integrated circuits (ICs), which are available for less than a dollar. With the MCU’s help, these ICs can protect system firmware using an on-chip 256-SHA engine, unique serial number, 256-bit key, and an additional 64-bit “secret” stored permanently inside the chip (see Figure 1).

Figure 1: The CryptoAuth integrated circuit is depicted here.
Cryptographic authentication uses a challenge/response protocol to tie the firmware IP to a specific “secret” or key, which is stored in the authentication device. Challengeresponse verification can be added to any existing firmware and executed by the system MCU in a variety of ways. For example, challenges and responses coded directly into the firmware can be used to challenge the cryptoauthentication IC. For a given challenge, the device will always give the same response. It is therefore wise to code multiple challenge- response pairs in different configurations throughout the code. If the firmware is to make 10 calls to the security device, for example, one should use the second response, {PLEASE SPELL OUT XOR}XOR its value with the fifth response, and then use that calculated value as the ninth challenge. The firmware may ignore or use any of the challenges- responses in this group, thereby making it difficult to reverse-engineer the process (see Figure 2).

Figure 2: This figure shows the CryptoAuthFlow.
The following is an example of challenge-response logic coded in C. This example uses an application programming interface (API) to call the device that’s readily available online. To use this example, the connected cryptoauthentication device must have the following secret key and fuse value pre-programmed into the device.
265-bit key value
={0×3B,0×4A,0xFD,0×79,0xC4,0xC8,0×6C,0×78,0×25,0xA6,0xE9, 0xAF,0xD7,0×0F,0×2E,0xD9,0×6E,0×3C,0×15,0×24,0xD3,0xEE, 0×55, 0xF6,0xD6,0xC8,0×86,0xF2,0xA0,0×2F,0xB0,0xF6}
Secret-fuse value
={0xBE,0×8B,0×92,0×9A,0×93,0xCD,0xC8,0xFF};
/***********************************************************/
/* Prototypes */
/***********************************************************/
int xorfunc(uint8_t *xor1, uint8_t *xor2, uint8_t *result); void makeCAcalls(void);
/*================================================== =======*/
#define MODE_20 0×20 // MAC includes secret fuses,
// challenge and internal
secret key
#define KEY_INDEX
0xFFFF // Published Test key index
// for CryptoAuthentication
/***********************************************************/
/* Main function */
/* – Calls security device and blinks lights on then off */
/* – Exits program if authentication checks fail */ /***********************************************************/
int main(void)
{
Leds_init();
if(SA_init(0×00)){
// Initialize CA
library
goto failed;}
while(1)
{
makeCAcalls();
Leds_on();
_delay_ms(600);
makeCAcalls();
Leds_off();
_delay_ms(600);
}
failed:
return 0;
}
/*================================================== =======*/
/***********************************************************/
/* Security check function */
/* – Calls security device 10 times */
/* – XORs the 2nd call with the 5th call and used the*/
/* result as the 9th call. It then verifies the 9th */
/* call is correct based on a predefined result */
/***********************************************************/
void makeCAcalls()
{
uint8_t error;
// Error status from CA
uint8_t Challenge[32] ;
uint8_t Response[32];
uint8_t *pChallenge;
uint8_t *pResponse;
uint8_t FirstResponsekept[32];
uint8_t SecondResponsekept[32];
pChallenge = Challenge;
pResponse = Response;
uint8_t Challenge0[32]
={0×2B,0xC4,0×90,0×92,0xBE,0×4F,0×8E,0×23,0×9A,0×41,0xFF, 0xE4,0xC7,0×70,0×5C,0×9B,0xC3,0×41,0xC8,0×9E,0×03,0×01, 0xED,0×0D,0×9D,0xFE,0xF9,0×82,0×33,0xB8,0xBC,0xD3};
error = SA_DoMAC(MODE_20, KEY_INDEX, Challenge0, pResponse);
uint8_t Challenge1[32] ={0×41,0×46,0×6D,0×41,0×53,0×4C,0×5C,0×66,0×43,0×77,0×5A, 0×4A,0×62,0×5A,0×45,0×76,0×68,0×56,0×68,0×78,0×68,0×4E, 0×5A,0×74,0×79,0×72,0×47,0×64,0×72,0×51,0×5F,0×7A};
error = SA_DoMAC(MODE_20, KEY_INDEX, Challenge1, pResponse);
memcpy(FirstResponsekept, pResponse, 32);
uint8_t Challenge2[32]
={0×02,0xFE,0xD3,0×20,0×5F,0xEE,0×7D,0×02,0×44,0xA3,0xA6, 0×23,0×89,0×12,0×21,0xDD,0xF2,0×42,0×52,0×22,0×34,0×67, 0×44,0×37,0×25,0×26,0×99,0×10,0×30,0×78,0×01,0×96};
error = SA_DoMAC(MODE_20, KEY_INDEX, Challenge2, pResponse);
uint8_t Challenge3[32]
={0×78,0×59,0×68,0×4E,0×78,0×57,0×5F,0×6A,0×68,0×52,0×45, 0×55,0×4C,0×68,0×6A,0×5D,0×58,0×56,0×54,0×75,0×79,0×52, 0×62,0×61,0×52,0×73,0×6D,0×71,0×4A,0×66,0×73,0×69};
error = SA_DoMAC(MODE_20, KEY_INDEX, Challenge3, pResponse);
uint8_t Challenge4[32] ={0×64,0×5F,0×73,0×46,0×6F,0×6A,0×4A,0×51,0×4F,0×52,0×51, 0×6F,0×6C,0×48,0×5D,0×5C,0×75,0×6F,0×5A,0×64,0×52,0×62, 0×7A,0×4D,0×67,0×49,0×6A,0×4C,0×72,0×46,0×4A,0×4C};
error = SA_DoMAC(MODE_20, KEY_INDEX, Challenge4, pResponse); memcpy(SecondResponsekept, pResponse, 32);
uint8_t Challenge5[32] ={0×05,0xFE,0xD3,0×20,0×5F,0xEE,0×7D,0×02,0×44,0xA3,0xA6, 0×23,0×89,0×12,0×21,0xDD,0xF2,0×42,0×52,0×22,0×34,0×67, 0×44,0×37,0×25,0×26,0×99,0×10,0×30,0×78,0×01,0×96};
error = SA_DoMAC(MODE_20, KEY_INDEX, Challenge5, pResponse);
uint8_t Challenge6[32] ={0×45,0×77,0×55,0×79,0×79,0×75,0×5E,0×57,0×79,0×41 ,0×59, 0×5B,0×58,0×4E,0×68,0×5C,0×61,0×5B,0×6B,0×6B,0×6C,0×75, 0×53,0×6A,0×71,0×5D,0×64,0×49,0×50,0×74,0×4F,0×4B};
error = SA_DoMAC(MODE_20, KEY_INDEX, Challenge6, pResponse);
uint8_t Challenge7[32] ={0×3C,0×38,0xEE,0xBD,0xC6,0xEF,0xF1,0×1C,0×54,0xF1,0×07, 0×41,0xF5,0xB9,0xE6,0xDF,0×82,0xD5,0xB2,0×21,0×60,0×3C, 0xB8,0×26,0xFF,0×26,0xB3,0×9B,0xAB,0xD0,0×6E,0×9D};
error = SA_DoMAC(MODE_20, KEY_INDEX, Challenge7, pResponse);
xorfunc(FirstResponsekept, SecondResponsekept, pChallenge); error = SA_DoMAC(MODE_20, KEY_INDEX, pChallenge, pResponse);
uint8_t CheckResp[32] ={0×27,0xBF,0×34,0xC0,0×72,0×2B,0×73,0×17,0×2C,0×3 1,0×00, 0×09,0×69,0×86,0xA0,0xA4,0×6E,0×6D,0×9B,0xA8,0xFE,0xDE, 0×5D,0×82,0xF7,0×16,0xE5,0×90,0×9C,0×13,0×24,0xC7};
if( memcmp( pResponse, CheckResp, 32 )){ exit(0);}
uint8_t Challenge9[32] ={0xCC,0×8B,0×3E,0×70,0xD8,0×4F,0×92,0xCC,0×0A,0×8D,0×14, 0×67,0×1A,0xF4,0×76,0×88,0×5A,0×94,0×1F,0×7D,0xFA,0×81, 0×64,0xA0,0×17,0xC4,0xEE,0×69,0×6E,0xED,0×65,0xC1};
error = SA_DoMAC(MODE_20, KEY_INDEX, Challenge9, pResponse);
}
/*================================================== =======*/
/***********************************************************/ /* XOR utility function */ /***********************************************************/ int xorfunc(uint8_t *xor1, uint8_t *xor2, uint8_t *result)
{
uint8_t i;
for (i=0; i<32; i++){
result[i] = xor1[i] ^ xor2[i];
}
return 1;
}
/*================================================== =======*/
The firmware also can use runtime components as challenges or combine runtime components with challenge or response values prior to verification. If the system MCU has a partial locking sector, one or more challenge-response pairs could be implemented from within the locked-code sector. Obfuscating each portion of code differently and in obscure locations is the key to making cloning more difficult.
Each time an updated firmware is installed, it can change the challenge-response values and calling sequences. Changes to the security challenge in the firmware update will send any current clones back to ground zero. These updates can be as minor as replacing the challengeresponse pairs or changing the challenge/response logic described previously (see Figure 3).

Figure 3: Here is an example of how embedded firmware can be protected.
Also keep in mind that systems that connect over networks can offer greatly increased security when combined with hardware security devices at both ends. Challenges can be made and responded to remotely using the keys stored in the cryptoauthentication device. A device that doesn’t have the appropriate cryptographic authentication hardware cannot produce a correct response.
In addition, encrypted blocks of source code within the firmware can each be associated with a random-number challenge that’s sent to the cryptographic-authentication IC. The IC’s response can be used as the key to decrypt the block prior to execution. Ideally, this security method would have multiple encrypted firmware blocks including some that are rarely executed and some that are never executed. Cloners would have to watch the code at runtime to be able to reverse-engineer it. Even then, they would have great difficulty achieving operation of all of the blocks and would be forced to not address some of the code. The result would be to either not have a 100% cloned device or have to re-develop the system from the ground up.

Christopher Gorog is a crypto solutions applications engineer who has a BS in computer engineering and a masters of business administration from Colorado Technical University. He also has been certified as a project management professional (PMP) by the Project Management Institute. Gorog has more than 18 years of engineering, information-technology, and project-management experience in both the commercial and government sectors. He can be reached at Christopher.Gorog@atmel.com.














