Table of Contents
Preliminary
Physical Unclonable Functions (PUFs)
A physical unclonable function (PUF) is a potential security primitive for generating volatile secret keys in cryptographic applications. A PUF is described as unclonable due to its uniqueness being derived from the uncontrollable variations introduced during the manufacturing process. PUFs offer a high level of protection in cryptographic applications with strong volatile key storage. PUFs are issued a challenge and (ideally) produce a unique and reliable response in return. Since this response is unique to the device, it can, therefore, be used as a device ID or key.
SRAM-based PUFs
The usage of SRAM as the PUF medium is appealing for a variety of reasons. Most notably, SRAM is commonly available in most systems and therefore does not require additional hardware. For a standard 6T SRAM (shown below), every memory cell is composed of six transistors that are two cross-coupled CMOS inverters and two access transistors.
The inverters are designed to be symmetric, match in size, etc., but random variations incurred during manufacturing will result in random mismatches. SRAM PUFs exploit the mismatch which results in each SRAM cell being biased (or skewed) toward a 0
or 1
at power-up. Due to uncontrollable variations in the manufacturing process, different CMOS devices have different physical parameters (e.g., doping-levels, transistor oxide thickness, etc.). When an SRAM is powered-up, these variations affect the power-up state of their associated cells. It has been observed that certain cells have a strong preference to power-up to a 1
or 0
state. Cells that have no preference are deemed neutral and power up at random depending upon the influences of system noise. The more useful cells for PUF output are the ones that strongly prefer 0
or 1
.
For at SRAM-based PUF, the challenge provided to the PUF would be a specific set of bit addresses, and the response would be the corresponding power-up states of those bits.
PUF Evaluation
Reliability: The Reliability of a PUF determines how often a PUF can generate the same response to a given challenge. A PUF must generate the same response at all operating conditions.
Uniqueness: Uniqueness measures how well a single PUF is differentiated from other PUFs based on its challenge-response pair. Different PUFs must generate different responses for a given challenge in order to separate one from another. The average inter-chip fractional hamming distance for an ideal PUF must be 0.5. If a PUF circuit is instantiated on several different chips, then each of the PUF instantiations is expected to produce unique responses when supplied with the same challenge C.
Randomness: Entropy can be used to measure the randomness of a PUF. It’s the reflection of the amount of 1s and 0s in a sequence.
True Random Number Generators (TRNGs)
A random number generator (RNG) is an important security block widely used in most cryptographic applications such as one-time pads, session, and temporary keys, nonce, seeds, challenges for authentication, zero-knowledge protocols, hardware metering, generation of primes, secure communications, secured servers and processors, VPN access, and customer-facing web access. A quality RNG generates statistically independent and unpredictable sequences of random numbers. Compromising an RNG often means compromising an entire system. A true RNG (TRNG) translates random physical phenomena such as thermal noise, atmospheric noise, shot noise, radio noise, flicker noise, clock jitter, phase noise, noise in a compact memory etc. into random digits. A TRNG must have uniform statistics; non-uniform statistics due to biased random sequences help attackers to guess the random numbers. Generally, random numbers are generated by comparing two symmetric devices which possess some process variation (PV) and random inner noise. TRNG consists of a source of randomness (entropy) and a randomness extractor. Metastability of logic cells and timing jitter of Ring Oscillators (ROs) are the most common sources of entropy for a TRNG. The simplicity of implementation and entropy collection have made the RO-based TRNG most popular.
TRNG Evaluation
Unlike the PUF output, the TRNG output has to be different from measurement to measurement so that attacker cannot guess future output from previous TRNG output. NIST test is used to measure the randomness of a TRNG output [4]. NIST’s statistical test suite is popularly used to evaluate the quality of randomness for random and pseudorandom number generators designed for cryptographic applications and can also be used for PUF [9-11]. There is a total of 15 NIST tests and different tests require a different minimum length of bitstreams. For example, rank test, linear complexity test, and overlapping template matching test require at least 38912, 106, and 106 bits long bitstreams respectively. On the other hand, frequency test, block frequency test, and runs test require a minimum of 100-bit long bitstream
Application of PUFs in Supply Chain Integrity
PUFs can serve as a root of trust and can provide a key which cannot be easily reverse engineered. One of the biggest issues in any supply chain management is being able to verify that the product ordered is the product received. The electronics industry makes great strides to verify the integrity of their product lines. For example, the distributor your group used to complete the Bill of Materials for the previous experiment, Digi- Key, is a member of the trade association Electronic Component Industry Association, or ECIA, which strives to ensure that no counterfeit devices enter the supply chain. However, one can’t always order from verified suppliers. In this case, it is necessary to order components from unauthorized resellers, increasing the risk of acquiring counterfeit goods. One emerging research area to counteract this problem is in the area of Physically Unclonable Functions. The gist of the idea of a PUF is that the manufacture of the goods will use some sort of intrinsic process variation to generate a unique signature for every device. This signature is entered into a database so that the end user can, using the same signature generation process, generate and verify the signature of their device. Applications of PUF includes cryptographic key generation memoryless key storage, device authentication, PUF-based RFID for anti- counterfeiting, Intellectual Property (IP) protection etc.
Instructions
Part I SRAM PUF
In this part, you will implement an SRAM PUF on the HAHA V3.0 Board. Read 64 bytes of the SRAM power-up states from the Microcontroller to generate a signature. Program the Microcontroller. It needs to do two things: read and send. Refer to the website to find the address range for the SRAM inside the Microcontroller. In this range, read 64 bytes power-up states. Note that when the Microcontroller is running, some SRAM addresses will be occupied, and these addresses will no longer hold their power-up states. Therefore, chose the addresses for your 64 bytes carefully and make sure they won’t be occupied by running your program. Print the values to the terminal over UART. Process your data with a custom script (eg. Python, etc.), according to the requirements given below and answer questions. 1) Refer to the datasheet of the Microcontroller, what is the size of the SRAM in it? 2) You should read the power-up states of the SRAM cells, i.e., the values are not changed by the program after power up. Can you tell what addresses will be occupied by your program? Find an address to use for your 64-byte signature? (Hint: for affected addresses, their contents will look “much less random” than the power-up values.) 3) Indicate the address you used in your report. 4) Commit your code for the Microcontroller (should be in lab2/part1/main.c). 5) Copy the terminal output to your analysis script and perform analysis as described next. 6) The first 64-byte value you collect is called signature S1. Include your S1 in the report in hex format. 7) For S1, how many of the bits are 0 and how many are 1? What is the mean value? (eg. what percentage of bits are high?
Power OFF the whole board when taking different readings. Leave the board off for 30 seconds between readings. Power ON the board and read out the signature again. Repeat this two more times. These will be your signature S2, S3, and S4. Include thse in the report in hexadecimal format. 9) Are S2, S3, and S4 the same with S1? For each new sample, how many bits are different? What is the fractional intra hamming distance? [6] (ie. percentage of bits that flipped) 10) Use the compressed air to change the temperature of the microcontroller. Take another sample, S5. (Make sure to cool the microcontroller while powered off by blowing air for ~10-15 seconds, then turn it on). 11) Again report how many bits are different than S1, and the fracitional intra hamming distance. 12) Turn in your code for calculating the mean value and the intra hamming distance for this part. Part II SRAM as a TRNG In this part, you will modify your design for Part I so that it can work as a TRNG instead of a PUF. You can repeat your steps in Part I to collect multiple S1’s. See if all the bits of S1 will stay the same whenever you collect them and find if there are bits that act more randomly than others. Use these bits to generate an 8-bit TRNG. 1) What type of SRAM cells is a good candidate for TRNG? Select 8 bits from them. Include their addresses in your report and explain the procedure that you used to find them. 2) Write code to generate an 8-bit random number with your SRAM in the Microcontroller. Turn in your code.
What to Submit
Make sure your submission tag on Github includes the following files:
- Your lab report (lab2/report.pdf).
- Your code to print your SRAM PUF (lab2/part1/main.c).
- Your analysis of the SRAM PUF (some Python or other code in lab2/part1/)
- Your code to print your TRNG output (lab2/part2/main.c).
Helpful Tips
Compiling Code for the Microcontroller
A Makefile is provided in your repository that you can use for any of the labs. Copy this Makefile to the directory where you want to develop your code (eg. lab2/part1/), and update the first line to correctly point to the location of the common software files in the sw_resources directory.
For example, if you copy the Makefile to lab2/part1/, the line
SW_RESOURCES=../sw_resources
should be changed to
SW_RESOURCES=../../sw_resources
You can then compile your code by running make
in the directory where your code is located. This will compile your code and generate a hex file that you can load onto the microcontroller. Use make program
to load the hex file onto the microcontroller. You no longer need to directly invoke the avrdude
command.
Software Library Code for the Microcontroller
The sw_resources directory contains common code for the HaHa board that you can use across multiple labs. The haha.h file is probably the most useful file to look over. It contains several haha_uart_*
functions that you can use to print to the UART.
You will notice that haha.h has this line:
#include <avr/io.h>
which imports the various AVR definitions for the microcontroller. You should be able to right-click on avr/io.h
in VS Code and select “Go to Definition” (or press F12) to open this file. VS Code knows where to look for this file because I have configured it here. If “Go to Definition” doesn’t work, make sure you have opened your lab directory correctly in VS Code.
If you look through the <avr/io.h> file, you will see that it has support for hundreds of different microcontrollers, and includes the appropriate header file for the microcontroller you are using. You should see all of the #include statements greyed out, except for the # include <avr/iox16a4.h>
statement. Again, VS Code can show you this information because I have configured the defines here. When you actually run make
, this definition will be automatically set during compilation because of the -mmcu=atxmega16a4u
flag we provide to the compiler here.
You should look through the <avr/iox16a4.h> file (press F12 on the include statement), as it has helpful definitions you can use in the lab, such as the location of the SRAM memory.
UART
When the boards are plugged into the lab computers, two device files, /dev/ttyUSB0
and /dev/ttyUSB1
, are created. In my testing the /dev/ttyUSB1
file was the one that worked for the UART, although it’s possible that could change for you based on what other boards are plugged into the computer. If these files are not showing up, try unplugging and replugging the board, or restarting the computer.
You can use the screen
command to connect to the UART. For example, to connect to the UART on the HaHa board, you can run:
screen /dev/ttyUSB1 9600
When you want to exit the screen session, you can press Ctrl-a
followed by k
, and then y
to confirm.
Acknowledgement
These instructions were originally from Dr. Swarup Bhunia, University of Florida, and were modified for this class.