tests/puf_sram: add test application
This commit is contained in:
parent
2f86d6fcd8
commit
2262a6e309
7
tests/puf_sram/Makefile
Normal file
7
tests/puf_sram/Makefile
Normal 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
33
tests/puf_sram/README.md
Normal 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
|
||||

|
||||
|
||||
|
||||
# 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
31
tests/puf_sram/main.c
Normal 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;
|
||||
}
|
||||
47
tests/puf_sram/tests/example_test.py
Normal file
47
tests/puf_sram/tests/example_test.py
Normal 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()
|
||||
62
tests/puf_sram/tests/puf_sram_if.py
Normal file
62
tests/puf_sram/tests/puf_sram_if.py
Normal 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()
|
||||
Loading…
x
Reference in New Issue
Block a user