tests/puf_sram: add test application

This commit is contained in:
PeterKietzmann 2018-07-03 16:15:36 +02:00
parent 2f86d6fcd8
commit 2262a6e309
5 changed files with 180 additions and 0 deletions

7
tests/puf_sram/Makefile Normal file
View File

@ -0,0 +1,7 @@
BOARD ?= nucleo-f411re
include ../Makefile.tests_common
USEMODULE += puf_sram
include $(RIOTBASE)/Makefile.include

33
tests/puf_sram/README.md Normal file
View File

@ -0,0 +1,33 @@
# Tool Introduction
This tool is designed to interface with a test to get the random numbers generated by the using a hash of a block of uninitialized SRAM. In order to run the test a certain hardware setup is required due to the requirement to power off the DUT (device under test) for a certain time. Furthermore, the module detects button and/or software resets. If you push the reset button for example (without powering off the DUT), a warning should be printed to the console.
# Setup
## Required Tools
- DUT (a supported RIOT target board)
- USB to UART converter that supports setting the RTS pin and 5 volts (ie. FT232RL FTDI USB to TTL adapter)
- MOSFET to control power to the DUT (ie. STP36NF06L)
- Jumper cables
- Solderless breadboard
## Wiring Example
1. RTS <--> MOSFET gate pin (FT232RL RTS - STP36NF06L 1)
2. +5V <--> MOSFET drain pin (FT232RL 5V - STP36NF06L 2)
3. DUT Power <--> MOSFET source pin (E15 - STP36NF06L 3)
4. DUT UART TX <--> USB to UART RX
5. GND <--> GND
## Example Setup
![PUF SRAM test setup](https://raw.githubusercontent.com/wiki/RIOT-OS/RIOT/images/puf-sram-setup.jpg)
# Running the test
1. Plug the USB to UART converter in (it should be done first so it can autoconnect to the serial port)
2. Program the DUT with the puf_sram test
3. Connect all wires
4. change jumpers to only run on power provided by the USB to USRT converter
5. Run the example_test.py
# Running Custom Tests
Different tests can be run using the get_seed_list(self, n=10000, off_time=1, allow_print=False)
n -> the number of samples to take
off_time -> The time that the device is powered off to properly randomize the RAM

31
tests/puf_sram/main.c Normal file
View File

@ -0,0 +1,31 @@
/*
* Copyright (C) 2018 HAW Hamburg
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup tests
* @{
*
* @file
* @brief Test application for the random number generator based of SRAM
*
* @author Kevin Weiss <kevin.weiss@haw-hamburg.de>
*
* @}
*/
#include <stdio.h>
#include "puf_sram.h"
int main(void)
{
puts("Start: Test random number generator");
printf("Success: Data for puf_sram_seed: [0x%08lX]", puf_sram_seed);
puts("End: Test finished");
return 0;
}

View File

@ -0,0 +1,47 @@
#!/usr/bin/env python3
# Copyright (C) 2018 Kevin Weiss <kevin.weiss@haw-hamburg.de>
# Copyright (C) 2018 Peter Kietzmann <peter.kietzmann@haw-hamburg.de>
#
# This file is subject to the terms and conditions of the GNU Lesser
# General Public License v2.1. See the file LICENSE in the top level
# directory for more details.
import puf_sram_if
import numpy
def min_erntropy(all_meas):
p1 = numpy.zeros(len(all_meas[0]))
# number of ones for each bit
for i in range(0, len(all_meas[0])):
tmp = list(map(lambda x: int(x[i]), all_meas))
p1[i] = numpy.count_nonzero(tmp)
# probability of ones
p1 = numpy.divide(p1, float(len(all_meas)))
# probability of zeros
p0 = 1 - p1
p0_1_max = numpy.maximum(p1, p0)
log2_p0_1_max = numpy.log2(p0_1_max)
H_min = numpy.sum(-log2_p0_1_max)
H_min_rel = 100 * H_min/len(p0_1_max)
return [H_min, H_min_rel]
def main_func():
puf_sram = puf_sram_if.PufSram()
seeds = puf_sram.get_seed_list(n=500, off_time=1, allow_print=True)
seeds = [format(x, '0>32b') for x in seeds]
H_min, H_min_rel = min_erntropy(seeds)
print("Number of seeds: %i " % len(seeds))
print("Seed length : %i Bit " % len(seeds[0]))
print("Abs. Entropy : %02.02f Bit " % H_min)
print("Rel. Entropy : %02.02f perc. " % H_min_rel)
if __name__ == "__main__":
main_func()

View File

@ -0,0 +1,62 @@
#!/usr/bin/env python3
# Copyright (C) 2018 Kevin Weiss <kevin.weiss@haw-hamburg.de>
#
# This file is subject to the terms and conditions of the GNU Lesser
# General Public License v2.1. See the file LICENSE in the top level
# directory for more details.
import serial
import time
class PufSram:
def __init__(self, port='/dev/ttyUSB0', baud=115200):
self.__dev = serial.Serial(port, baud, timeout=10)
if(self.__dev.isOpen() is False):
self.__dev.open()
def repower(self, shutdown_time=1):
self.__dev.setRTS(True)
time.sleep(shutdown_time)
self.__dev.setRTS(False)
def read_data(self):
data = None
start = False
str = 'no_exit'
while (str != ''):
str = self.__dev.readline()
if (b'Start: ' in str):
start = True
if ((b'Success: ' in str) and (start is True)):
if (b'[' in str) and (b']' in str):
data_str = str[str.find(b"[")+1:str.find(b"]")]
data = int(data_str, 0)
if ((b'End: ' in str) and (data is not None)):
return data
return None
def get_seed_list(self, n=10000, off_time=1, allow_print=False):
data = list()
for i in range(0, n):
self.repower(off_time)
data.append(self.read_data())
if (allow_print):
print('Iteration %i/%i' % (i, n))
print(data[-1])
return data
def connect(self, dev):
if (dev.isOpen()):
dev.close()
self.__dev = self
if(self.__dev.isOpen() is False):
self.__dev.open()
def disconnect(self):
self.__dev.close()
def __del__(self):
self.__dev.close()