mirror of https://github.com/ARMmbed/mbed-os.git
Add TRNG API test
parent
dc45990a58
commit
669b618ea1
|
@ -0,0 +1,133 @@
|
|||
"""
|
||||
Copyright (c) 2018 ARM Limited
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
"""
|
||||
|
||||
"""
|
||||
This script is the host script for trng test sequence, it send the
|
||||
step signaling sequence and receive and transmit data to the device after
|
||||
reset if necesarry (default lading and storing while reseting the device
|
||||
is NVstore, in case NVstore isn't enabled we'll use current infrastructure,
|
||||
for more details see main.cpp file)
|
||||
"""
|
||||
|
||||
import time
|
||||
from mbed_host_tests import BaseHostTest
|
||||
from mbed_host_tests.host_tests_runner.host_test_default import DefaultTestSelector
|
||||
|
||||
DEFAULT_CYCLE_PERIOD = 1.0
|
||||
MSG_VALUE_DUMMY = '0'
|
||||
MSG_TRNG_READY = 'ready'
|
||||
MSG_TRNG_BUFFER = 'buffer'
|
||||
MSG_TRNG_FINISH = 'finish'
|
||||
MSG_TRNG_TEST_STEP1 = 'check_step1'
|
||||
MSG_TRNG_TEST_STEP2 = 'check_step2'
|
||||
MSG_KEY_SYNC = '__sync'
|
||||
MSG_KEY_TEST_SUITE_ENDED = 'Test suite ended'
|
||||
|
||||
class TRNGResetTest(BaseHostTest):
|
||||
"""Test for the TRNG API.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
super(TRNGResetTest, self).__init__()
|
||||
self.reset = False
|
||||
self.finish = False
|
||||
self.suite_ended = False
|
||||
self.buffer = 0
|
||||
cycle_s = self.get_config_item('program_cycle_s')
|
||||
self.program_cycle_s = cycle_s if cycle_s is not None else DEFAULT_CYCLE_PERIOD
|
||||
self.test_steps_sequence = self.test_steps()
|
||||
# Advance the coroutine to it's first yield statement.
|
||||
self.test_steps_sequence.send(None)
|
||||
|
||||
#define callback functions for msg handling
|
||||
def setup(self):
|
||||
self.register_callback(MSG_TRNG_READY, self.cb_device_ready)
|
||||
self.register_callback(MSG_TRNG_BUFFER, self.cb_trng_buffer)
|
||||
self.register_callback(MSG_TRNG_FINISH, self.cb_device_finish)
|
||||
self.register_callback(MSG_KEY_TEST_SUITE_ENDED, self.cb_device_test_suit_ended)
|
||||
|
||||
#receive sent data from device before reset
|
||||
def cb_trng_buffer(self, key, value, timestamp):
|
||||
"""Acknowledge device rebooted correctly and feed the test execution
|
||||
"""
|
||||
self.buffer = value
|
||||
|
||||
def cb_device_ready(self, key, value, timestamp):
|
||||
"""Acknowledge device rebooted correctly and feed the test execution
|
||||
"""
|
||||
self.reset = True
|
||||
|
||||
try:
|
||||
if self.test_steps_sequence.send(value):
|
||||
self.notify_complete(True)
|
||||
except (StopIteration, RuntimeError) as exc:
|
||||
self.notify_complete(False)
|
||||
|
||||
def cb_device_finish(self, key, value, timestamp):
|
||||
"""Acknowledge device finished a test step correctly and feed the test execution
|
||||
"""
|
||||
self.finish = True
|
||||
|
||||
try:
|
||||
if self.test_steps_sequence.send(value):
|
||||
self.notify_complete(True)
|
||||
except (StopIteration, RuntimeError) as exc:
|
||||
self.notify_complete(False)
|
||||
|
||||
def cb_device_test_suit_ended(self, key, value, timestamp):
|
||||
"""Acknowledge device finished a test step correctly and feed the test execution
|
||||
"""
|
||||
self.suite_ended = True
|
||||
|
||||
try:
|
||||
if self.test_steps_sequence.send(value):
|
||||
self.notify_complete(True)
|
||||
except (StopIteration, RuntimeError) as exc:
|
||||
self.notify_complete(False)
|
||||
|
||||
#define test steps and actions
|
||||
def test_steps(self):
|
||||
"""Test step 1
|
||||
"""
|
||||
wait_for_communication = yield
|
||||
|
||||
self.reset = False
|
||||
self.send_kv(MSG_TRNG_TEST_STEP1, MSG_VALUE_DUMMY)
|
||||
time.sleep(self.program_cycle_s)
|
||||
self.send_kv(MSG_KEY_SYNC, MSG_VALUE_DUMMY)
|
||||
|
||||
wait_for_communication = yield
|
||||
|
||||
if self.reset == False:
|
||||
raise RuntimeError('Phase 1: Platform did not reset as expected.')
|
||||
|
||||
"""Test step 2 (After reset)
|
||||
"""
|
||||
self.finish = False
|
||||
self.send_kv(MSG_TRNG_TEST_STEP2, self.buffer)
|
||||
time.sleep(self.program_cycle_s)
|
||||
|
||||
wait_for_communication = yield
|
||||
|
||||
if self.finish == False:
|
||||
raise RuntimeError('Test failed.')
|
||||
|
||||
wait_for_communication = yield
|
||||
|
||||
if self.suite_ended == False:
|
||||
raise RuntimeError('Test failed.')
|
||||
|
||||
# The sequence is correct -- test passed.
|
||||
yield True
|
|
@ -0,0 +1,185 @@
|
|||
#include "base64b.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
static char IntToBase64Char(uint8_t intVal)
|
||||
{
|
||||
const char* base64Digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
return base64Digits[intVal & 0x3F];
|
||||
}
|
||||
|
||||
#define BASE_64_PAD 0xFF
|
||||
static base64_result_e Base64CharToInt(char base64, uint8_t* intVal)
|
||||
{
|
||||
if (NULL == intVal)
|
||||
{
|
||||
return BASE64_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if ((base64 >= 'A') && (base64 <= 'Z'))
|
||||
*intVal = base64 - 'A' ;
|
||||
else if((base64 >= 'a')&&(base64 <= 'z'))
|
||||
*intVal = base64 - 'a' + 26;
|
||||
else if ((base64 >= '0')&&(base64 <= '9'))
|
||||
*intVal = base64 - '0' + 52;
|
||||
else if (base64 == '+')
|
||||
*intVal = 62;
|
||||
else if (base64 == '/')
|
||||
*intVal = 63;
|
||||
else if (base64 == '=')
|
||||
*intVal = BASE_64_PAD;
|
||||
else
|
||||
{
|
||||
return BASE64_ERROR;
|
||||
}
|
||||
|
||||
return BASE64_SUCCESS;
|
||||
}
|
||||
|
||||
base64_result_e esfs_DecodeNBase64(const char* string,
|
||||
uint32_t stringMaxSize,
|
||||
void* buffer,
|
||||
uint32_t bufferSize,
|
||||
uint32_t* lengthWritten,
|
||||
uint32_t* charsProcessed)
|
||||
{
|
||||
base64_result_e result = BASE64_SUCCESS;
|
||||
uint32_t bitOffset =0;
|
||||
uint8_t* writePtr = (uint8_t*)buffer;
|
||||
uint8_t* bufferEnd = (uint8_t*)buffer + bufferSize;
|
||||
uint8_t tempVal = 0;
|
||||
uint32_t currPos = 0;
|
||||
uint32_t localBytesWritten = 0;
|
||||
uint32_t localCharsProcessed = 0;
|
||||
bool isEndOfString = false;
|
||||
|
||||
if ((NULL == string) || (NULL == buffer) || (bufferSize == 0))
|
||||
{
|
||||
return BASE64_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
*writePtr = 0;
|
||||
while (( string[currPos] != 0 ) &&
|
||||
( currPos < stringMaxSize ) &&
|
||||
( writePtr < bufferEnd ) &&
|
||||
( !isEndOfString ))
|
||||
{
|
||||
uint8_t val;
|
||||
|
||||
if (string[currPos] == 0 || currPos >= stringMaxSize)
|
||||
break;
|
||||
|
||||
result = Base64CharToInt(string[currPos++], &val);
|
||||
if (result != BASE64_SUCCESS)
|
||||
break;
|
||||
|
||||
if (val != BASE_64_PAD)
|
||||
{
|
||||
if(bitOffset <= 2)
|
||||
{
|
||||
tempVal |= val << (2 - bitOffset);
|
||||
if (bitOffset == 2)
|
||||
{
|
||||
*writePtr++ = tempVal;
|
||||
tempVal = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*writePtr++ = (uint8_t)(tempVal | (val >> (bitOffset - 2)));
|
||||
tempVal = (uint8_t)(val << (10 - bitOffset));
|
||||
}
|
||||
}
|
||||
else // found BASE_64_PAD
|
||||
{
|
||||
// At most two pad characters may occur at the end of the encoded stream
|
||||
if (bitOffset == 2)
|
||||
isEndOfString = true; // The last padding byte has been processed.
|
||||
else if (bitOffset != 4)
|
||||
return BASE64_ERROR; // Incorrect padding
|
||||
}
|
||||
|
||||
bitOffset = (bitOffset + 6) & 0x7;
|
||||
if (bitOffset == 0)
|
||||
{
|
||||
localBytesWritten = (uint32_t)(writePtr - (uint8_t*)buffer);
|
||||
localCharsProcessed = currPos;
|
||||
}
|
||||
}
|
||||
if (charsProcessed == NULL)
|
||||
localBytesWritten = (uint32_t)(writePtr - (uint8_t*)buffer);
|
||||
else
|
||||
*charsProcessed = localCharsProcessed;
|
||||
if (lengthWritten != NULL)
|
||||
*lengthWritten = localBytesWritten;
|
||||
else if (bufferSize != localBytesWritten)
|
||||
return BASE64_BUFFER_TOO_SMALL;
|
||||
|
||||
// Check if additional bytes should have been processed but buffer isn't sufficient.
|
||||
if (( result == BASE64_SUCCESS ) &&
|
||||
( !isEndOfString ) &&
|
||||
( string[currPos] != '=' ) &&
|
||||
( string[currPos] != 0 ) &&
|
||||
( currPos < stringMaxSize) )
|
||||
return BASE64_BUFFER_TOO_SMALL;
|
||||
|
||||
if (result != BASE64_SUCCESS)
|
||||
return result;
|
||||
|
||||
return BASE64_SUCCESS;
|
||||
}
|
||||
|
||||
base64_result_e esfs_EncodeBase64(const void* buffer, uint32_t bufferSize, char* string, uint32_t stringSize)
|
||||
{
|
||||
uint32_t bitOffset = 0;
|
||||
|
||||
const uint8_t* readPtr = (const uint8_t*)buffer;
|
||||
const uint8_t* bufferEnd = (const uint8_t*)buffer + bufferSize;
|
||||
|
||||
char* writePtr = string;
|
||||
char* stringEnd = string + stringSize - 1;
|
||||
|
||||
if ((NULL == string) || (NULL == buffer) || (stringSize == 0))
|
||||
return BASE64_INVALID_PARAMETER;
|
||||
|
||||
stringSize--;
|
||||
while(readPtr < bufferEnd && writePtr < stringEnd)
|
||||
{
|
||||
uint8_t tempVal = 0;
|
||||
switch (bitOffset)
|
||||
{
|
||||
case 0:
|
||||
*writePtr++ = IntToBase64Char(*readPtr >> 2); // take upper 6 bits
|
||||
break;
|
||||
case 6:
|
||||
tempVal = *readPtr++ << 4;
|
||||
if (readPtr < bufferEnd)
|
||||
tempVal |= *readPtr >> 4;
|
||||
*writePtr++ = IntToBase64Char(tempVal);
|
||||
break;
|
||||
case 4:
|
||||
tempVal = *readPtr++ << 2;
|
||||
if (readPtr < bufferEnd)
|
||||
tempVal |= *readPtr >> 6;
|
||||
*writePtr++ = IntToBase64Char(tempVal);
|
||||
break;
|
||||
case 2:
|
||||
*writePtr++ = IntToBase64Char(*readPtr++);
|
||||
break;
|
||||
default:
|
||||
return BASE64_ERROR; // we should never reach this code.
|
||||
}
|
||||
bitOffset = (bitOffset + 6) & 0x7;
|
||||
}
|
||||
while (bitOffset > 0 && writePtr < stringEnd)
|
||||
{
|
||||
*writePtr++ = '=';
|
||||
bitOffset = (bitOffset + 6) & 0x7;
|
||||
}
|
||||
*writePtr = 0;
|
||||
|
||||
if ((readPtr < bufferEnd) || (bitOffset != 0))
|
||||
return (BASE64_BUFFER_TOO_SMALL);
|
||||
|
||||
return(BASE64_SUCCESS);
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string>
|
||||
|
||||
typedef enum {
|
||||
BASE64_SUCCESS = 0,
|
||||
BASE64_INVALID_PARAMETER = 1,
|
||||
BASE64_BUFFER_TOO_SMALL = 2,
|
||||
BASE64_ERROR = 3,
|
||||
}base64_result_e;
|
||||
|
||||
base64_result_e esfs_EncodeBase64(const void* buffer, uint32_t bufferSize, char* string, uint32_t stringSize);
|
||||
base64_result_e esfs_DecodeNBase64(const char* string, uint32_t stringMaxSize, void* buffer, uint32_t bufferSize,
|
||||
uint32_t* lengthWritten, uint32_t* charsProcessed);
|
||||
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* Copyright (c) 2000-2008 Marc Alexander Lehmann <schmorp@schmorp.de>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modifica-
|
||||
* tion, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
|
||||
* CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
|
||||
* CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
|
||||
* ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License ("GPL") version 2 or any later version,
|
||||
* in which case the provisions of the GPL are applicable instead of
|
||||
* the above. If you wish to allow the use of your version of this file
|
||||
* only under the terms of the GPL and not to allow others to use your
|
||||
* version of this file under the BSD license, indicate your decision
|
||||
* by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL. If you do not delete the
|
||||
* provisions above, a recipient may use your version of this file under
|
||||
* either the BSD or the GPL.
|
||||
*/
|
||||
|
||||
#ifndef LZF_H
|
||||
#define LZF_H
|
||||
|
||||
/***********************************************************************
|
||||
**
|
||||
** lzf -- an extremely fast/free compression/decompression-method
|
||||
** http://liblzf.plan9.de/
|
||||
**
|
||||
** This algorithm is believed to be patent-free.
|
||||
**
|
||||
***********************************************************************/
|
||||
|
||||
#define LZF_VERSION 0x0105 /* 1.5, API version */
|
||||
|
||||
/*
|
||||
* Compress in_len bytes stored at the memory block starting at
|
||||
* in_data and write the result to out_data, up to a maximum length
|
||||
* of out_len bytes.
|
||||
*
|
||||
* If the output buffer is not large enough or any error occurs return 0,
|
||||
* otherwise return the number of bytes used, which might be considerably
|
||||
* more than in_len (but less than 104% of the original size), so it
|
||||
* makes sense to always use out_len == in_len - 1), to ensure _some_
|
||||
* compression, and store the data uncompressed otherwise (with a flag, of
|
||||
* course.
|
||||
*
|
||||
* lzf_compress might use different algorithms on different systems and
|
||||
* even different runs, thus might result in different compressed strings
|
||||
* depending on the phase of the moon or similar factors. However, all
|
||||
* these strings are architecture-independent and will result in the
|
||||
* original data when decompressed using lzf_decompress.
|
||||
*
|
||||
* The buffers must not be overlapping.
|
||||
*
|
||||
* If the option LZF_STATE_ARG is enabled, an extra argument must be
|
||||
* supplied which is not reflected in this header file. Refer to lzfP.h
|
||||
* and lzf_c.c.
|
||||
*
|
||||
*/
|
||||
unsigned int
|
||||
lzf_compress (const void *const in_data, unsigned int in_len,
|
||||
void *out_data, unsigned int out_len,
|
||||
unsigned char **htab);
|
||||
|
||||
/*
|
||||
* Decompress data compressed with some version of the lzf_compress
|
||||
* function and stored at location in_data and length in_len. The result
|
||||
* will be stored at out_data up to a maximum of out_len characters.
|
||||
*
|
||||
* If the output buffer is not large enough to hold the decompressed
|
||||
* data, a 0 is returned and errno is set to E2BIG. Otherwise the number
|
||||
* of decompressed bytes (i.e. the original length of the data) is
|
||||
* returned.
|
||||
*
|
||||
* If an error in the compressed data is detected, a zero is returned and
|
||||
* errno is set to EINVAL.
|
||||
*
|
||||
* This function is very fast, about as fast as a copying loop.
|
||||
*/
|
||||
unsigned int
|
||||
lzf_decompress (const void *const in_data, unsigned int in_len,
|
||||
void *out_data, unsigned int out_len);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,185 @@
|
|||
/*
|
||||
* Copyright (c) 2000-2007 Marc Alexander Lehmann <schmorp@schmorp.de>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modifica-
|
||||
* tion, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
|
||||
* CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
|
||||
* CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
|
||||
* ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License ("GPL") version 2 or any later version,
|
||||
* in which case the provisions of the GPL are applicable instead of
|
||||
* the above. If you wish to allow the use of your version of this file
|
||||
* only under the terms of the GPL and not to allow others to use your
|
||||
* version of this file under the BSD license, indicate your decision
|
||||
* by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL. If you do not delete the
|
||||
* provisions above, a recipient may use your version of this file under
|
||||
* either the BSD or the GPL.
|
||||
*/
|
||||
|
||||
#ifndef LZFP_h
|
||||
#define LZFP_h
|
||||
|
||||
#define STANDALONE 1 /* at the moment, this is ok. */
|
||||
|
||||
#ifndef STANDALONE
|
||||
# include "lzf.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Size of hashtable is (1 << HLOG) * sizeof (char *)
|
||||
* decompression is independent of the hash table size
|
||||
* the difference between 15 and 14 is very small
|
||||
* for small blocks (and 14 is usually a bit faster).
|
||||
* For a low-memory/faster configuration, use HLOG == 13;
|
||||
* For best compression, use 15 or 16 (or more, up to 22).
|
||||
*/
|
||||
#ifndef HLOG
|
||||
# define HLOG 14
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Sacrifice very little compression quality in favour of compression speed.
|
||||
* This gives almost the same compression as the default code, and is
|
||||
* (very roughly) 15% faster. This is the preferred mode of operation.
|
||||
*/
|
||||
#ifndef VERY_FAST
|
||||
# define VERY_FAST 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Sacrifice some more compression quality in favour of compression speed.
|
||||
* (roughly 1-2% worse compression for large blocks and
|
||||
* 9-10% for small, redundant, blocks and >>20% better speed in both cases)
|
||||
* In short: when in need for speed, enable this for binary data,
|
||||
* possibly disable this for text data.
|
||||
*/
|
||||
#ifndef ULTRA_FAST
|
||||
# define ULTRA_FAST 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Unconditionally aligning does not cost very much, so do it if unsure
|
||||
*/
|
||||
#ifndef STRICT_ALIGN
|
||||
# define STRICT_ALIGN !(defined(__i386) || defined (__amd64))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* You may choose to pre-set the hash table (might be faster on some
|
||||
* modern cpus and large (>>64k) blocks, and also makes compression
|
||||
* deterministic/repeatable when the configuration otherwise is the same).
|
||||
*/
|
||||
#ifndef INIT_HTAB
|
||||
# define INIT_HTAB 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Avoid assigning values to errno variable? for some embedding purposes
|
||||
* (linux kernel for example), this is necessary. NOTE: this breaks
|
||||
* the documentation in lzf.h. Avoiding errno has no speed impact.
|
||||
*/
|
||||
#ifndef AVOID_ERRNO
|
||||
# define AVOID_ERRNO 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Whether to pass the LZF_STATE variable as argument, or allocate it
|
||||
* on the stack. For small-stack environments, define this to 1.
|
||||
* NOTE: this breaks the prototype in lzf.h.
|
||||
*/
|
||||
#ifndef LZF_STATE_ARG
|
||||
# define LZF_STATE_ARG 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Whether to add extra checks for input validity in lzf_decompress
|
||||
* and return EINVAL if the input stream has been corrupted. This
|
||||
* only shields against overflowing the input buffer and will not
|
||||
* detect most corrupted streams.
|
||||
* This check is not normally noticeable on modern hardware
|
||||
* (<1% slowdown), but might slow down older cpus considerably.
|
||||
*/
|
||||
#ifndef CHECK_INPUT
|
||||
# define CHECK_INPUT 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Whether to store pointers or offsets inside the hash table. On
|
||||
* 64 bit architetcures, pointers take up twice as much space,
|
||||
* and might also be slower. Default is to autodetect.
|
||||
*/
|
||||
/*#define LZF_USER_OFFSETS autodetect */
|
||||
|
||||
/*****************************************************************************/
|
||||
/* nothing should be changed below */
|
||||
|
||||
#ifdef __cplusplus
|
||||
# include <cstring>
|
||||
# include <climits>
|
||||
using namespace std;
|
||||
#else
|
||||
# include <string.h>
|
||||
# include <limits.h>
|
||||
#endif
|
||||
|
||||
#ifndef LZF_USE_OFFSETS
|
||||
# if defined (WIN32)
|
||||
# define LZF_USE_OFFSETS defined(_M_X64)
|
||||
# else
|
||||
# if __cplusplus > 199711L
|
||||
# include <cstdint>
|
||||
# else
|
||||
# include <stdint.h>
|
||||
# endif
|
||||
# define LZF_USE_OFFSETS (UINTPTR_MAX > 0xffffffffU)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
typedef unsigned char u8;
|
||||
|
||||
#if LZF_USE_OFFSETS
|
||||
# define LZF_HSLOT_BIAS ((const u8 *)in_data)
|
||||
typedef unsigned int LZF_HSLOT;
|
||||
#else
|
||||
# define LZF_HSLOT_BIAS 0
|
||||
typedef const u8 *LZF_HSLOT;
|
||||
#endif
|
||||
|
||||
typedef LZF_HSLOT LZF_STATE[1 << (HLOG)];
|
||||
|
||||
#if !STRICT_ALIGN
|
||||
/* for unaligned accesses we need a 16 bit datatype. */
|
||||
# if USHRT_MAX == 65535
|
||||
typedef unsigned short u16;
|
||||
# elif UINT_MAX == 65535
|
||||
typedef unsigned int u16;
|
||||
# else
|
||||
# undef STRICT_ALIGN
|
||||
# define STRICT_ALIGN 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if ULTRA_FAST
|
||||
# undef VERY_FAST
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,291 @@
|
|||
/*
|
||||
* Copyright (c) 2000-2010 Marc Alexander Lehmann <schmorp@schmorp.de>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modifica-
|
||||
* tion, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
|
||||
* CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
|
||||
* CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
|
||||
* ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License ("GPL") version 2 or any later version,
|
||||
* in which case the provisions of the GPL are applicable instead of
|
||||
* the above. If you wish to allow the use of your version of this file
|
||||
* only under the terms of the GPL and not to allow others to use your
|
||||
* version of this file under the BSD license, indicate your decision
|
||||
* by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL. If you do not delete the
|
||||
* provisions above, a recipient may use your version of this file under
|
||||
* either the BSD or the GPL.
|
||||
*/
|
||||
|
||||
#include "lzfP.h"
|
||||
|
||||
#define HSIZE (1 << (HLOG))
|
||||
|
||||
/*
|
||||
* don't play with this unless you benchmark!
|
||||
* the data format is not dependent on the hash function.
|
||||
* the hash function might seem strange, just believe me,
|
||||
* it works ;)
|
||||
*/
|
||||
#ifndef FRST
|
||||
# define FRST(p) (((p[0]) << 8) | p[1])
|
||||
# define NEXT(v,p) (((v) << 8) | p[2])
|
||||
# if ULTRA_FAST
|
||||
# define IDX(h) ((( h >> (3*8 - HLOG)) - h ) & (HSIZE - 1))
|
||||
# elif VERY_FAST
|
||||
# define IDX(h) ((( h >> (3*8 - HLOG)) - h*5) & (HSIZE - 1))
|
||||
# else
|
||||
# define IDX(h) ((((h ^ (h << 5)) >> (3*8 - HLOG)) - h*5) & (HSIZE - 1))
|
||||
# endif
|
||||
#endif
|
||||
/*
|
||||
* IDX works because it is very similar to a multiplicative hash, e.g.
|
||||
* ((h * 57321 >> (3*8 - HLOG)) & (HSIZE - 1))
|
||||
* the latter is also quite fast on newer CPUs, and compresses similarly.
|
||||
*
|
||||
* the next one is also quite good, albeit slow ;)
|
||||
* (int)(cos(h & 0xffffff) * 1e6)
|
||||
*/
|
||||
|
||||
#if 0
|
||||
/* original lzv-like hash function, much worse and thus slower */
|
||||
# define FRST(p) (p[0] << 5) ^ p[1]
|
||||
# define NEXT(v,p) ((v) << 5) ^ p[2]
|
||||
# define IDX(h) ((h) & (HSIZE - 1))
|
||||
#endif
|
||||
|
||||
#define MAX_LIT (1 << 5)
|
||||
#define MAX_OFF (1 << 13)
|
||||
#define MAX_REF ((1 << 8) + (1 << 3))
|
||||
|
||||
#if __GNUC__ >= 3
|
||||
# define expect(expr,value) __builtin_expect ((expr),(value))
|
||||
# define inline inline
|
||||
#else
|
||||
# define expect(expr,value) (expr)
|
||||
# define inline static
|
||||
#endif
|
||||
|
||||
#define expect_false(expr) expect ((expr) != 0, 0)
|
||||
#define expect_true(expr) expect ((expr) != 0, 1)
|
||||
|
||||
/*
|
||||
* compressed format
|
||||
*
|
||||
* 000LLLLL <L+1> ; literal, L+1=1..33 octets
|
||||
* LLLooooo oooooooo ; backref L+1=1..7 octets, o+1=1..4096 offset
|
||||
* 111ooooo LLLLLLLL oooooooo ; backref L+8 octets, o+1=1..4096 offset
|
||||
*
|
||||
*/
|
||||
|
||||
unsigned int
|
||||
lzf_compress (const void *const in_data, unsigned int in_len,
|
||||
void *out_data, unsigned int out_len
|
||||
#if LZF_STATE_ARG
|
||||
, LZF_STATE htab
|
||||
#endif
|
||||
)
|
||||
{
|
||||
#if !LZF_STATE_ARG
|
||||
LZF_STATE htab;
|
||||
#endif
|
||||
const u8 *ip = (const u8 *)in_data;
|
||||
u8 *op = (u8 *)out_data;
|
||||
const u8 *in_end = ip + in_len;
|
||||
u8 *out_end = op + out_len;
|
||||
const u8 *ref;
|
||||
|
||||
/* off requires a type wide enough to hold a general pointer difference.
|
||||
* ISO C doesn't have that (size_t might not be enough and ptrdiff_t only
|
||||
* works for differences within a single object). We also assume that no
|
||||
* no bit pattern traps. Since the only platform that is both non-POSIX
|
||||
* and fails to support both assumptions is windows 64 bit, we make a
|
||||
* special workaround for it.
|
||||
*/
|
||||
#if defined (WIN32) && defined (_M_X64)
|
||||
unsigned _int64 off; /* workaround for missing POSIX compliance */
|
||||
#else
|
||||
unsigned long off;
|
||||
#endif
|
||||
unsigned int hval;
|
||||
int lit;
|
||||
|
||||
if (!in_len || !out_len)
|
||||
return 0;
|
||||
|
||||
#if INIT_HTAB
|
||||
memset (htab, 0, sizeof (htab));
|
||||
#endif
|
||||
|
||||
lit = 0; op++; /* start run */
|
||||
|
||||
hval = FRST (ip);
|
||||
while (ip < in_end - 2)
|
||||
{
|
||||
LZF_HSLOT *hslot;
|
||||
|
||||
hval = NEXT (hval, ip);
|
||||
hslot = htab + IDX (hval);
|
||||
ref = *hslot + LZF_HSLOT_BIAS; *hslot = ip - LZF_HSLOT_BIAS;
|
||||
|
||||
if (1
|
||||
#if INIT_HTAB
|
||||
&& ref < ip /* the next test will actually take care of this, but this is faster */
|
||||
#endif
|
||||
&& (off = (unsigned long)(uintptr_t)(ip - ref - 1)) < MAX_OFF
|
||||
&& ref > (u8 *)in_data
|
||||
&& ref[2] == ip[2]
|
||||
#if STRICT_ALIGN
|
||||
&& ((ref[1] << 8) | ref[0]) == ((ip[1] << 8) | ip[0])
|
||||
#else
|
||||
&& *(u16 *)ref == *(u16 *)ip
|
||||
#endif
|
||||
)
|
||||
{
|
||||
/* match found at *ref++ */
|
||||
unsigned int len = 2;
|
||||
unsigned int maxlen = (unsigned int)((uintptr_t)in_end - (uintptr_t)ip) - len;
|
||||
maxlen = maxlen > MAX_REF ? MAX_REF : maxlen;
|
||||
|
||||
if (expect_false (op + 3 + 1 >= out_end)) /* first a faster conservative test */
|
||||
if (op - !lit + 3 + 1 >= out_end) /* second the exact but rare test */
|
||||
return 0;
|
||||
|
||||
op [- lit - 1] = lit - 1; /* stop run */
|
||||
op -= !lit; /* undo run if length is zero */
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (expect_true (maxlen > 16))
|
||||
{
|
||||
len++; if (ref [len] != ip [len]) break;
|
||||
len++; if (ref [len] != ip [len]) break;
|
||||
len++; if (ref [len] != ip [len]) break;
|
||||
len++; if (ref [len] != ip [len]) break;
|
||||
|
||||
len++; if (ref [len] != ip [len]) break;
|
||||
len++; if (ref [len] != ip [len]) break;
|
||||
len++; if (ref [len] != ip [len]) break;
|
||||
len++; if (ref [len] != ip [len]) break;
|
||||
|
||||
len++; if (ref [len] != ip [len]) break;
|
||||
len++; if (ref [len] != ip [len]) break;
|
||||
len++; if (ref [len] != ip [len]) break;
|
||||
len++; if (ref [len] != ip [len]) break;
|
||||
|
||||
len++; if (ref [len] != ip [len]) break;
|
||||
len++; if (ref [len] != ip [len]) break;
|
||||
len++; if (ref [len] != ip [len]) break;
|
||||
len++; if (ref [len] != ip [len]) break;
|
||||
}
|
||||
|
||||
do
|
||||
len++;
|
||||
while (len < maxlen && ref[len] == ip[len]);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
len -= 2; /* len is now #octets - 1 */
|
||||
ip++;
|
||||
|
||||
if (len < 7)
|
||||
{
|
||||
*op++ = (u8)((off >> 8) + (len << 5));
|
||||
}
|
||||
else
|
||||
{
|
||||
*op++ = (u8)((off >> 8) + ( 7 << 5));
|
||||
*op++ = len - 7;
|
||||
}
|
||||
|
||||
*op++ = (u8)off;
|
||||
|
||||
lit = 0; op++; /* start run */
|
||||
|
||||
ip += len + 1;
|
||||
|
||||
if (expect_false (ip >= in_end - 2))
|
||||
break;
|
||||
|
||||
#if ULTRA_FAST || VERY_FAST
|
||||
--ip;
|
||||
# if VERY_FAST && !ULTRA_FAST
|
||||
--ip;
|
||||
# endif
|
||||
hval = FRST (ip);
|
||||
|
||||
hval = NEXT (hval, ip);
|
||||
htab[IDX (hval)] = ip - LZF_HSLOT_BIAS;
|
||||
ip++;
|
||||
|
||||
# if VERY_FAST && !ULTRA_FAST
|
||||
hval = NEXT (hval, ip);
|
||||
htab[IDX (hval)] = ip - LZF_HSLOT_BIAS;
|
||||
ip++;
|
||||
# endif
|
||||
#else
|
||||
ip -= len + 1;
|
||||
|
||||
do
|
||||
{
|
||||
hval = NEXT (hval, ip);
|
||||
htab[IDX (hval)] = ip - LZF_HSLOT_BIAS;
|
||||
ip++;
|
||||
}
|
||||
while (len--);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
/* one more literal byte we must copy */
|
||||
if (expect_false (op >= out_end))
|
||||
return 0;
|
||||
|
||||
lit++; *op++ = *ip++;
|
||||
|
||||
if (expect_false (lit == MAX_LIT))
|
||||
{
|
||||
op [- lit - 1] = lit - 1; /* stop run */
|
||||
lit = 0; op++; /* start run */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (op + 3 > out_end) /* at most 3 bytes can be missing here */
|
||||
return 0;
|
||||
|
||||
while (ip < in_end)
|
||||
{
|
||||
lit++; *op++ = *ip++;
|
||||
|
||||
if (expect_false (lit == MAX_LIT))
|
||||
{
|
||||
op [- lit - 1] = lit - 1; /* stop run */
|
||||
lit = 0; op++; /* start run */
|
||||
}
|
||||
}
|
||||
|
||||
op [- lit - 1] = lit - 1; /* end run */
|
||||
op -= !lit; /* undo run if length is zero */
|
||||
|
||||
return (unsigned int)((uintptr_t)op - (uintptr_t)out_data);
|
||||
}
|
||||
|
|
@ -0,0 +1,276 @@
|
|||
/*
|
||||
* Copyright (c) 2018 ARM Limited. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The test is based on the assumption that trng will generate random data, random so
|
||||
* there will not be any similar patterns in it, that kind of data will be impossible to
|
||||
* compress, if compression will acuur the test will result in failure.
|
||||
*
|
||||
* The test is composed out of three parts:
|
||||
* the first, generate a trng buffer and try to compress it, at the end of first part
|
||||
* we will reset the device.
|
||||
* In second part we will generate a trng buffer with a different buffer size and try to
|
||||
* compress it.
|
||||
* In the third part we will again generate a trng buffer to see that the same trng output
|
||||
* is not generated as the stored trng buffer from part one (before reseting), the new trng data will
|
||||
* be concatenated to the trng data from the first part and then try to compress it
|
||||
* together, if there are similar patterns the compression will succeed.
|
||||
*
|
||||
* We need to store and load the first part data before and after reset, the mechanism
|
||||
* we chose is NVstore, mainly because its simplicity and the fact it is not platform
|
||||
* dependent, in case a specific board does not support NVstore we will use the
|
||||
* mbed greentea platform for sending and receving the data from the device to the
|
||||
* host running the test and back, the problem with this mechanism is that it doesn't handle
|
||||
* well certain characters, especially non ASCII ones, so we used the base64 algorithm
|
||||
* to ensure all characters will be transmitted correctly.
|
||||
*/
|
||||
|
||||
#include "greentea-client/test_env.h"
|
||||
#include "unity/unity.h"
|
||||
#include "utest/utest.h"
|
||||
#include "hal/trng_api.h"
|
||||
#include "base64b.h"
|
||||
#include "nvstore.h"
|
||||
#include <stdio.h>
|
||||
|
||||
/*Include LZF Compressor librart */
|
||||
extern "C" {
|
||||
#include "lzf.h"
|
||||
}
|
||||
|
||||
#if !DEVICE_TRNG
|
||||
#error [NOT_SUPPORTED] TRNG API not supported for this target
|
||||
#endif
|
||||
|
||||
#define MSG_VALUE_DUMMY "0"
|
||||
#define MSG_VALUE_LEN 64
|
||||
#define MSG_KEY_LEN 32
|
||||
|
||||
#define BUFFER_LEN (MSG_VALUE_LEN/2) //size of first step data, and half of the second step data
|
||||
|
||||
#define MSG_TRNG_READY "ready"
|
||||
#define MSG_TRNG_BUFFER "buffer"
|
||||
|
||||
#define MSG_TRNG_TEST_STEP1 "check_step1"
|
||||
#define MSG_TRNG_TEST_STEP2 "check_step2"
|
||||
#define MSG_TRNG_TEST_SUITE_ENDED "Test_suite_ended"
|
||||
|
||||
#define NVKEY 1 //NVstore key for storing and loading data
|
||||
|
||||
/*there are some issues with nvstore and greentea reset, so for now nvstore is disabled,
|
||||
*When solved delete current define and replace all NVSTORE_RESET with NVSTORE_ENABLED*/
|
||||
#define NVSTORE_RESET (NVSTORE_ENABLED & 0)
|
||||
|
||||
using namespace utest::v1;
|
||||
|
||||
static int fill_buffer_trng(uint8_t *buffer, trng_t *trng_obj, size_t trng_len)
|
||||
{
|
||||
size_t temp_size = 0, output_length = 0;
|
||||
int trng_res = 0;
|
||||
uint8_t *temp_in_buf = buffer;
|
||||
|
||||
trng_init(trng_obj);
|
||||
memset(buffer, 0, BUFFER_LEN);
|
||||
|
||||
while (true)
|
||||
{
|
||||
trng_res = trng_get_bytes(trng_obj, temp_in_buf, trng_len, &output_length);
|
||||
TEST_ASSERT_EQUAL_INT_MESSAGE(0, trng_res, "trng_get_bytes error!");
|
||||
temp_size += output_length;
|
||||
temp_in_buf += output_length;
|
||||
trng_len -= output_length;
|
||||
if (temp_size >= trng_len)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
temp_in_buf = NULL;
|
||||
trng_free(trng_obj);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void compress_and_compare(char *key, char *value)
|
||||
{
|
||||
trng_t trng_obj;
|
||||
uint8_t out_comp_buf[BUFFER_LEN * 2] = {0}, buffer[BUFFER_LEN] = {0};
|
||||
uint8_t input_buf[BUFFER_LEN * 2] = {0}, temp_buff[BUFFER_LEN * 2] = {0};
|
||||
size_t out_comp_buf_len = 0;
|
||||
unsigned int comp_res = 0, result = 0;
|
||||
unsigned char htab[32][32] = {0};
|
||||
|
||||
#if NVSTORE_RESET
|
||||
NVStore &nvstore = NVStore::get_instance();
|
||||
#endif
|
||||
|
||||
/*At the begining of step 2 load trng buffer from step 1*/
|
||||
if (strcmp(key, MSG_TRNG_TEST_STEP2) == 0)
|
||||
{
|
||||
#if NVSTORE_RESET
|
||||
uint16_t actual = 0;
|
||||
result = nvstore.get(NVKEY, sizeof(buffer), buffer, actual);
|
||||
TEST_ASSERT_EQUAL(NVSTORE_SUCCESS, result);
|
||||
#else
|
||||
/*Using base64 to decode data sent from host*/
|
||||
uint32_t lengthWritten = 0;
|
||||
uint32_t charsProcessed = 0;
|
||||
result = esfs_DecodeNBase64((const char*)value, MSG_VALUE_LEN, buffer, BUFFER_LEN, &lengthWritten, &charsProcessed);
|
||||
TEST_ASSERT_EQUAL(0, result);
|
||||
#endif
|
||||
memcpy(input_buf, buffer, BUFFER_LEN);
|
||||
}
|
||||
|
||||
/*Fill buffer with trng values*/
|
||||
result = fill_buffer_trng(buffer, &trng_obj, sizeof(buffer));
|
||||
TEST_ASSERT_EQUAL(0, result);
|
||||
|
||||
/*lzf_compress will try to compress the random data, if it succeeded it means the data is not really random*/
|
||||
if (strcmp(key, MSG_TRNG_TEST_STEP1) == 0)
|
||||
{
|
||||
printf("\n******TRNG_TEST_STEP1*****\n");
|
||||
out_comp_buf_len = BUFFER_LEN + (BUFFER_LEN / 4);
|
||||
comp_res = lzf_compress((const void *)buffer,
|
||||
(unsigned int)sizeof(buffer),
|
||||
(void *)out_comp_buf,
|
||||
out_comp_buf_len,
|
||||
(unsigned char **)htab);
|
||||
if (comp_res >= BUFFER_LEN)
|
||||
{
|
||||
printf("trng_get_bytes for buffer size %d was successful", sizeof(buffer));
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("trng_get_bytes for buffer size %d was unsuccessful", sizeof(buffer));
|
||||
TEST_ASSERT(false);
|
||||
}
|
||||
printf("\n******FINISHED_TRNG_TEST_STEP1*****\n\n");
|
||||
}
|
||||
else if (strcmp(key, MSG_TRNG_TEST_STEP2) == 0)
|
||||
{
|
||||
printf("\n******TRNG_TEST_STEP2*****\n");
|
||||
result = fill_buffer_trng(temp_buff, &trng_obj, sizeof(temp_buff));
|
||||
TEST_ASSERT_EQUAL(0, result);
|
||||
|
||||
out_comp_buf_len = 2 * BUFFER_LEN + (BUFFER_LEN / 2);
|
||||
comp_res = lzf_compress((const void *)temp_buff,
|
||||
(unsigned int)sizeof(temp_buff),
|
||||
(void *)out_comp_buf,
|
||||
out_comp_buf_len,
|
||||
(unsigned char **)htab);
|
||||
|
||||
if (comp_res >= BUFFER_LEN)
|
||||
{
|
||||
printf("trng_get_bytes for buffer size %d was successful", sizeof(temp_buff));
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("trng_get_bytes for buffer size %d was unsuccessful", sizeof(temp_buff));
|
||||
TEST_ASSERT(false);
|
||||
}
|
||||
printf("\n******FINISHED_TRNG_TEST_STEP2*****\n\n");
|
||||
|
||||
printf("******TRNG_TEST_STEP3*****\n");
|
||||
|
||||
memcpy(input_buf + BUFFER_LEN, buffer, BUFFER_LEN);
|
||||
comp_res = lzf_compress((const void *)input_buf,
|
||||
(unsigned int)sizeof(input_buf),
|
||||
(void *)out_comp_buf,
|
||||
out_comp_buf_len,
|
||||
(unsigned char **)htab);
|
||||
|
||||
if (comp_res >= BUFFER_LEN)
|
||||
{
|
||||
printf("compression for concatenated buffer after reset was successful");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("compression for concatenated buffer after reset was unsuccessful");
|
||||
TEST_ASSERT(false);
|
||||
}
|
||||
printf("\n******FINISHED_TRNG_TEST_STEP3*****\n\n");
|
||||
}
|
||||
|
||||
/*At the end of step 1 store trng buffer and reset the device*/
|
||||
if (strcmp(key, MSG_TRNG_TEST_STEP1) == 0)
|
||||
{
|
||||
int result = 0;
|
||||
#if NVSTORE_RESET
|
||||
result = nvstore.set(NVKEY, sizeof(buffer), buffer);
|
||||
TEST_ASSERT_EQUAL(NVSTORE_SUCCESS, result);
|
||||
#else
|
||||
/*Using base64 to encode data sending from host*/
|
||||
result = esfs_EncodeBase64(buffer, BUFFER_LEN, (char*)out_comp_buf, sizeof(out_comp_buf));
|
||||
TEST_ASSERT_EQUAL(NVSTORE_SUCCESS, result);
|
||||
greentea_send_kv(MSG_TRNG_BUFFER, (const char *)out_comp_buf);
|
||||
#endif
|
||||
system_reset();
|
||||
TEST_ASSERT_MESSAGE(false, "system_reset() did not reset the device as expected.");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*This method call first and second steps, it directs by the key received from the host*/
|
||||
void trng_test()
|
||||
{
|
||||
greentea_send_kv(MSG_TRNG_READY, MSG_VALUE_DUMMY);
|
||||
|
||||
static char key[MSG_KEY_LEN + 1] = { };
|
||||
static char value[MSG_VALUE_LEN + 1] = { };
|
||||
memset(key, 0, MSG_KEY_LEN + 1);
|
||||
memset(value, 0, MSG_VALUE_LEN + 1);
|
||||
|
||||
greentea_parse_kv(key, value, MSG_KEY_LEN, MSG_VALUE_LEN);
|
||||
|
||||
if (strcmp(key, MSG_TRNG_TEST_STEP1) == 0)
|
||||
{
|
||||
/*create trng data buffer and try to compress it, store it for later checks*/
|
||||
compress_and_compare(key, value);
|
||||
return trng_test();
|
||||
}
|
||||
|
||||
if (strcmp(key, MSG_TRNG_TEST_STEP2) == 0)
|
||||
{
|
||||
/*create another trng data buffer and concatenate it to the stored trng data buffer
|
||||
try to compress them both*/
|
||||
compress_and_compare(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
utest::v1::status_t greentea_failure_handler(const Case *const source, const failure_t reason) {
|
||||
greentea_case_failure_abort_handler(source, reason);
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
|
||||
Case cases[] = {
|
||||
Case("TRNG: trng_test", trng_test, greentea_failure_handler),
|
||||
};
|
||||
|
||||
utest::v1::status_t greentea_test_setup(const size_t number_of_cases)
|
||||
{
|
||||
GREENTEA_SETUP(100, "trng_reset");
|
||||
return greentea_test_setup_handler(number_of_cases);
|
||||
}
|
||||
|
||||
Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler);
|
||||
|
||||
int main()
|
||||
{
|
||||
bool ret = !Harness::run(specification);
|
||||
greentea_send_kv(MSG_TRNG_TEST_SUITE_ENDED, MSG_VALUE_DUMMY);
|
||||
|
||||
return ret;
|
||||
}
|
Loading…
Reference in New Issue