mirror of
https://github.com/revyos/th1520-vendor-uboot.git
synced 2026-10-05 01:16:04 +02:00
1442 lines
42 KiB
C
1442 lines
42 KiB
C
/*
|
|
* Copyright (C) 2017-2020 Alibaba Group Holding Limited
|
|
*/
|
|
|
|
/* eip76_test.c
|
|
*
|
|
* Module implements the EIP76 Driver Library Known-answer test (KAT) API
|
|
*/
|
|
|
|
|
|
/*----------------------------------------------------------------------------
|
|
* This module implements (provides) the following interface(s):
|
|
*/
|
|
|
|
// EIP-76 Driver Library Known-answer test (KAT) API
|
|
#include "eip76_test.h"
|
|
|
|
|
|
/*----------------------------------------------------------------------------
|
|
* This module uses (requires) the following interface(s):
|
|
*/
|
|
|
|
// Default configuration
|
|
#include "c_eip76.h"
|
|
|
|
// Driver Framework Basic Definitions API
|
|
#include "basic_defs.h" // uint32_t
|
|
|
|
// EIP-76 Driver Library Types API
|
|
#include "eip76_types.h" // EIP76_* types
|
|
|
|
// EIP-76 Driver Library Internal interfaces
|
|
#include "eip76_level0.h" // Level 0 macros
|
|
#include "eip76_internal.h" // Internal macros
|
|
#include "eip76_fsm.h" // State machine
|
|
|
|
/*----------------------------------------------------------------------------
|
|
* Definitions and macros
|
|
*/
|
|
|
|
#define START_SHA_KAT_TEST ((uint32_t)0x00008030)
|
|
#define TEST_SAMPLE_CYCLES 0x10000
|
|
|
|
|
|
/*----------------------------------------------------------------------------
|
|
* EIP76Lib_Test_Is_Ready
|
|
*
|
|
*/
|
|
static bool
|
|
EIP76Lib_Test_Is_Ready(
|
|
const Device_Handle_t Device)
|
|
{
|
|
#ifdef EIP76_CONT_POKER_TEST_READY_CDS
|
|
// Check if continuous Poker test is enabled,
|
|
if ((EIP76_TEST_RD(Device) & EIP76_TEST_CONT_POKER) != 0 )
|
|
{
|
|
volatile uint32_t RunCntRegVal1, RunCntRegVal2;
|
|
|
|
// Continuous Poker test is enabled,
|
|
// Reading twice the same value from the TRNG_RUN_CNT:run_test_count
|
|
// field means test is ready
|
|
RunCntRegVal1 = EIP76_RUNCNT_RD(Device);
|
|
RunCntRegVal2 = EIP76_RUNCNT_RD(Device);
|
|
if( RunCntRegVal1 == RunCntRegVal2 )
|
|
return true;
|
|
else
|
|
return false;
|
|
}
|
|
else
|
|
#endif // EIP76_CONT_POKER_TEST_READY_CDS
|
|
{
|
|
uint32_t Mask = EIP76_STATUS_TEST_READY;
|
|
uint32_t StatusRegVal = EIP76_STATUS_RD(Device);
|
|
|
|
#if (EIP76_POST_PROCESSOR_TYPE == EIP76_POST_PROCESSOR_BC_DF)
|
|
if ((EIP76_TEST_RD(Device) & EIP76_TEST_SP_800_90) != 0 )
|
|
{
|
|
// SP80090 BCDF test
|
|
Mask |= EIP76_STATUS_RESEED_AI;
|
|
}
|
|
#endif // EIP76_POST_PROCESSOR_BC_DF
|
|
|
|
if((StatusRegVal & Mask) == Mask)
|
|
return true;
|
|
else
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
uint32_t
|
|
Device_SwapEndian(
|
|
const uint32_t Value)
|
|
{
|
|
#ifdef DEVICE_SWAP_SAFE
|
|
return (((Value & 0x000000FFU) << 24) |
|
|
((Value & 0x0000FF00U) << 8) |
|
|
((Value & 0x00FF0000U) >> 8) |
|
|
((Value & 0xFF000000U) >> 24));
|
|
#else
|
|
// reduces typically unneeded AND operations
|
|
return ((Value << 24) |
|
|
((Value & 0x0000FF00U) << 8) |
|
|
((Value & 0x00FF0000U) >> 8) |
|
|
(Value >> 24));
|
|
#endif
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------------------------
|
|
* EIP76_Test_Start
|
|
*
|
|
*/
|
|
EIP76_Status_t
|
|
EIP76_Test_Start(
|
|
EIP76_IOArea_t * const IOArea_p,
|
|
const EIP76_Test_Type_t TestType,
|
|
EIP76_EventStatus_t * const Events_p)
|
|
{
|
|
Device_Handle_t Device;
|
|
uint32_t RegVal;
|
|
uint32_t ControlWord = 0;
|
|
uint8_t SHAVersion;
|
|
EIP76_Status_t rv;
|
|
volatile EIP76_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
|
|
|
|
EIP76_CHECK_POINTER(IOArea_p);
|
|
|
|
EIP76_CHECK_POINTER(Events_p);
|
|
|
|
Device = TrueIOArea_p->Device;
|
|
|
|
RegVal = EIP76_STATUS_RD(Device);
|
|
|
|
SHAVersion = EIP76_SHA_VERSION_RD(Device);
|
|
|
|
// Store event status
|
|
*Events_p = (RegVal & EIP76_EVENTS_MASK);
|
|
|
|
// Save TRNG_CONTROL register (internal TRNG HW state)
|
|
RegVal = EIP76_CONTROL_RD(Device);
|
|
|
|
// Check if Post Processor is enabled
|
|
if (TestType != EIP76_PRM_KAT_TYPE &&
|
|
TestType != EIP76_SHA_KAT_TYPE &&
|
|
TestType != EIP76_SHA_RANDOM &&
|
|
TestType != EIP76_ADPRO_TYPE_64 &&
|
|
TestType != EIP76_ADPRO_TYPE_4k &&
|
|
TestType != EIP76_ADPRO_TYPE_512 &&
|
|
TestType != EIP76_PRM_CONTINUOUS_KAT_TYPE &&
|
|
TestType != EIP76_SP80090_AES_CORE_KAT_TYPE &&
|
|
TestType != EIP76_REPCOUNT_TYPE &&
|
|
(RegVal & EIP76_CONTROL_POSTPROCESSOR_ENABLE) == 0)
|
|
// Post Processor KAT is requested while PP is disabled
|
|
return EIP76_ILLEGAL_IN_STATE;
|
|
|
|
TrueIOArea_p->SavedControl = RegVal;
|
|
|
|
// Transit to a new state
|
|
rv = EIP76_State_Set((volatile EIP76_State_t* const ) &TrueIOArea_p->State,
|
|
EIP76_STATE_KAT_START);
|
|
if (rv != EIP76_NO_ERROR)
|
|
return EIP76_ILLEGAL_IN_STATE; // May never occur
|
|
|
|
// set Entropy generation configuration to default
|
|
EIP76_CONFIG_WR(Device,
|
|
EIP76_NOISE_BLOCKS,
|
|
EIP76_SAMPLE_DIVIDER,
|
|
EIP76_READ_TIMEOUT,
|
|
EIP76_SAMPLE_CYCLES,
|
|
EIP76_SAMPLE_SCALE);
|
|
|
|
// Enter Test Mode and disable fatal error interrupts
|
|
RegVal |= EIP76_CONTROL_ENABLE_TEST_MODE;
|
|
RegVal &= (~(EIP76_STUCK_OUT_EVENT | EIP76_NOISE_FAIL_EVENT));
|
|
#if (EIP76_SHUTDOWN_FATAL == 1)
|
|
RegVal &= (~EIP76_SHUTDOWN_OFLO_EVENT);
|
|
#endif
|
|
EIP76_CONTROL_WR(Device, RegVal);
|
|
|
|
if (TestType == EIP76_PRM_KAT_TYPE ||
|
|
TestType == EIP76_PRM_CONTINUOUS_KAT_TYPE)
|
|
{
|
|
// Read ALARMCNT register
|
|
RegVal = EIP76_ALARMCNT_RD(Device);
|
|
|
|
// Reset counters for test
|
|
EIP76_COUNT_WR(Device, RESET_COUNTERS);
|
|
|
|
// Clear any test related bits in the INTACK register
|
|
EIP76_INTACK_WR(Device, EIP76_INTACK_CLEAR_PRM);
|
|
|
|
// PRM test is requested, set stall_run_poker in TRNG_ALARMCNT so
|
|
// that in case test fails its result can be inspected and is not
|
|
// overwritten
|
|
RegVal |= EIP76_ALARMCNT_STALL_RUN_POKER;
|
|
|
|
EIP76_ALARMCNT_WR(Device, RegVal);
|
|
|
|
}
|
|
|
|
// Start KAT
|
|
if (TestType == EIP76_PRM_KAT_TYPE)
|
|
{
|
|
// PRM test
|
|
EIP76_TEST_WR(Device, EIP76_TEST_RUN_POKER);
|
|
}
|
|
else if (TestType == EIP76_PRM_CONTINUOUS_KAT_TYPE)
|
|
{
|
|
// PRM Continuous test
|
|
EIP76_TEST_WR(Device, EIP76_TEST_RUN_POKER | EIP76_TEST_CONT_POKER);
|
|
}
|
|
else if (TestType == EIP76_SHA_KAT_TYPE)
|
|
{
|
|
TrueIOArea_p->ConfigStatus = EIP76_CONFIG_RD(Device);
|
|
|
|
// SHA test, restart hash core. This is needed to write the noise_blocks
|
|
// field
|
|
EIP76_TEST_WR(Device, EIP76_TEST_SHA);
|
|
|
|
if (SHAVersion == 2) {
|
|
// 50 512 bit blocks for SHA2 KAT test
|
|
ControlWord |= EIP76_SHA2_NOISE_BLOCKS;
|
|
} else {
|
|
// 44 512 bit blocks for SHA1 KAT test
|
|
ControlWord |= EIP76_SHA1_NOISE_BLOCKS;
|
|
}
|
|
|
|
// Configure the noise_block field for test
|
|
EIP76_CONFIG_NOISEBLK_WR(Device, ControlWord);
|
|
|
|
// Disable hash core
|
|
EIP76_TEST_WR(Device, 0);
|
|
|
|
// Enable known noise test mode, conditioner test and set cont_poker
|
|
// so that the PR module doesn't stall the test.
|
|
EIP76_TEST_WR(Device, START_SHA_KAT_TEST);
|
|
|
|
ControlWord |= TEST_SAMPLE_CYCLES;
|
|
|
|
// Configure the noise_block field for test
|
|
EIP76_CONFIG_NOISEBLK_WR(Device, ControlWord);
|
|
}
|
|
else if (TestType == EIP76_SHA_RANDOM)
|
|
{
|
|
// Ack any related events
|
|
EIP76_INTACK_WR(Device, 0x1);
|
|
|
|
TrueIOArea_p->ConfigStatus = EIP76_CONFIG_RD(Device);
|
|
|
|
// SHA test, restart hash core. This is needed to write the noise_blocks
|
|
// field
|
|
EIP76_TEST_WR(Device, EIP76_TEST_SHA);
|
|
|
|
ControlWord |= EIP76_SHA_RANDOM_NOISE_BLOCKS;
|
|
|
|
// Configure the noise_block field for test
|
|
EIP76_CONFIG_NOISEBLK_WR(Device, ControlWord);
|
|
|
|
// Disable hash core
|
|
EIP76_TEST_WR(Device, 0);
|
|
|
|
// Enable known noise test mode, conditioner test and set cont_poker
|
|
// so that the PR module doesn't stall the test.
|
|
EIP76_TEST_WR(Device, START_SHA_KAT_TEST);
|
|
|
|
ControlWord |= TEST_SAMPLE_CYCLES;
|
|
|
|
// Configure the noise_block field for test
|
|
EIP76_CONFIG_NOISEBLK_WR(Device, ControlWord);
|
|
}
|
|
else if (TestType == EIP76_REPCOUNT_TYPE)
|
|
{
|
|
TrueIOArea_p->ConfigStatus = EIP76_CONFIG_RD(Device);
|
|
|
|
// Set cont_poker, test_known_noise and test_spb
|
|
EIP76_TEST_WR(Device, EIP76_TEST_REPCOUNTORADAPTIVE);
|
|
|
|
ControlWord |= TEST_SAMPLE_CYCLES;
|
|
|
|
// Configure the noise_block field for test
|
|
EIP76_CONFIG_NOISEBLK_WR(Device, ControlWord);
|
|
|
|
// Reset the counters through INTACK register
|
|
EIP76_INTACK_WR(Device, EIP76_REPCNT_FAIL_EVENT | EIP76_APROP_FAIL_EVENT);
|
|
|
|
// Set cut-off value for repetition test
|
|
// This is the maximum value of the repetition counter 63.
|
|
EIP76_SPB_WR(Device, EIP76_CUTOFF_REP);
|
|
}
|
|
else if ((TestType == EIP76_ADPRO_TYPE_64) ||
|
|
(TestType == EIP76_ADPRO_TYPE_512) ||
|
|
(TestType == EIP76_ADPRO_TYPE_4k))
|
|
{
|
|
TrueIOArea_p->ConfigStatus = EIP76_CONFIG_RD(Device);
|
|
|
|
// Set cont_poker, test_known_noise and test_spb
|
|
EIP76_TEST_WR(Device, EIP76_TEST_REPCOUNTORADAPTIVE);
|
|
|
|
ControlWord |= TEST_SAMPLE_CYCLES;
|
|
|
|
// Configure the noise_block field for test
|
|
EIP76_CONFIG_NOISEBLK_WR(Device, ControlWord);
|
|
|
|
// Set show counters and show values to reset the counters
|
|
EIP76_SPB_WR(Device, EIP76_SHOW_COUNTERS_AND_VALUES);
|
|
|
|
if (TestType == EIP76_ADPRO_TYPE_64)
|
|
{
|
|
// Set cutoff value for adaptive proportion 64 test
|
|
// this is the maximum value of the adaptive proportion 64 counter 63.
|
|
EIP76_SPB_WR(Device, EIP76_CUTOFF_APROP_64 << 8);
|
|
}
|
|
else if (TestType == EIP76_ADPRO_TYPE_512)
|
|
{
|
|
// Set cutoff value for adaptive proportion 512 test
|
|
// this is the maximum value of the adaptive proportion 512 counter 511.
|
|
EIP76_SPB_WR(Device, EIP76_CUTOFF_APROP_512 << 16);
|
|
}
|
|
else
|
|
{
|
|
// Set cutoff value for adaptive proportion 4k test
|
|
// this is the maximum value of the adaptive proportion 4096 counter 4095.
|
|
EIP76_SPB_WR(Device, EIP76_CUTOFF_APROP_4k << 16);
|
|
}
|
|
|
|
// Reset TRNG_COUNT to keep the conditioner quit
|
|
EIP76_COUNT_WR(Device, RESET_COUNTERS);
|
|
}
|
|
else if (TestType == EIP76_SP80090_AES_CORE_KAT_TYPE)
|
|
{
|
|
// Post Processor Test
|
|
EIP76_TEST_WR(Device, EIP76_TEST_POST_PROC);
|
|
}
|
|
#if (EIP76_POST_PROCESSOR_TYPE == EIP76_POST_PROCESSOR_BC_DF)
|
|
else if (TestType == EIP76_SP80090_BC_DF_KAT_TYPE)
|
|
{
|
|
// Post Processor Test
|
|
EIP76_TEST_WR(Device, EIP76_TEST_SP_800_90 | EIP76_TEST_KNOWN_NOISE);
|
|
|
|
// Configure the noise_block field for this test
|
|
EIP76_CONFIG_WR(Device,
|
|
1, // SP80090 BCDF KAT noise blocks
|
|
EIP76_SAMPLE_DIVIDER,
|
|
EIP76_READ_TIMEOUT,
|
|
3, // SP80090 BCDF KAT sample cycles
|
|
EIP76_SAMPLE_SCALE);
|
|
}
|
|
#endif
|
|
else
|
|
{
|
|
// Post Processor Test
|
|
EIP76_TEST_WR(Device, EIP76_TEST_SP_800_90);
|
|
}
|
|
|
|
// Check if test is ready
|
|
{
|
|
uint32_t Mask = EIP76_STATUS_TEST_READY;
|
|
|
|
if (TestType == EIP76_SP80090_BC_DF_KAT_TYPE)
|
|
Mask |= EIP76_STATUS_RESEED_AI;
|
|
|
|
RegVal = EIP76_STATUS_RD(Device);
|
|
|
|
if ((RegVal & Mask) != Mask)
|
|
{
|
|
// Test is not ready, remain in EIP76_STATE_KAT_START state
|
|
return EIP76_BUSY_RETRY_LATER;
|
|
}
|
|
}
|
|
|
|
// Test is ready, transit to a new state
|
|
return EIP76_State_Set((volatile EIP76_State_t*) &TrueIOArea_p->State,
|
|
EIP76_STATE_KAT_READY);
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------------------------
|
|
* EIP76_Test_Abort
|
|
*
|
|
*/
|
|
EIP76_Status_t
|
|
EIP76_Test_Abort(
|
|
EIP76_IOArea_t * const IOArea_p,
|
|
EIP76_EventStatus_t * const Events_p)
|
|
{
|
|
Device_Handle_t Device;
|
|
uint32_t RegVal;
|
|
EIP76_Status_t rv;
|
|
volatile EIP76_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
|
|
|
|
EIP76_CHECK_POINTER(IOArea_p);
|
|
|
|
EIP76_CHECK_POINTER(Events_p);
|
|
|
|
// No events detected yet
|
|
*Events_p = 0;
|
|
|
|
Device = TrueIOArea_p->Device;
|
|
|
|
TrueIOArea_p->Flag = false;
|
|
TrueIOArea_p->Index = 0;
|
|
|
|
// Check if in test mode
|
|
RegVal = EIP76_CONTROL_RD(Device);
|
|
if( (RegVal & EIP76_CONTROL_ENABLE_TEST_MODE) == 0 )
|
|
return EIP76_ILLEGAL_IN_STATE;
|
|
|
|
// Transit to a new state
|
|
rv = EIP76_State_Set((volatile EIP76_State_t*)&TrueIOArea_p->State,
|
|
EIP76_STATE_RANDOM_GENERATING);
|
|
|
|
if(rv != EIP76_NO_ERROR)
|
|
return EIP76_ILLEGAL_IN_STATE; // May never occur
|
|
|
|
RegVal = EIP76_STATUS_RD(Device);
|
|
|
|
// Store event status
|
|
*Events_p = (RegVal & EIP76_EVENTS_MASK);
|
|
|
|
// Set to 0 number of written 64-bit words as test input
|
|
TrueIOArea_p->PRM_WordCount = 0;
|
|
|
|
// Read Test Mode
|
|
RegVal = EIP76_TEST_RD(Device);
|
|
|
|
// Reset Cutoff values as they are changed for the test
|
|
if (RegVal == EIP76_TEST_REPCOUNTORADAPTIVE)
|
|
{
|
|
if (EIP76_APROP512_RD(Device))
|
|
{
|
|
EIP76_SPB_WR(Device, EIP76_CUTOFF_512_DEFAULT);
|
|
}
|
|
else {
|
|
EIP76_SPB_WR(Device, EIP76_CUTOFF_DEFAULT);
|
|
}
|
|
}
|
|
|
|
// Clear all existing tests that could have been started
|
|
RegVal &= (~(EIP76_TEST_CONT_POKER |
|
|
EIP76_TEST_RUN_POKER |
|
|
EIP76_TEST_POST_PROC |
|
|
EIP76_TEST_SP_800_90 |
|
|
EIP76_TEST_REPCOUNTORADAPTIVE));
|
|
EIP76_TEST_WR(Device, RegVal);
|
|
|
|
// Clear stall_run_poker and fro_test_mux in TRNG_ALARMCNT
|
|
RegVal = EIP76_ALARMCNT_RD(Device);
|
|
EIP76_ALARMCNT_WR(Device, RegVal & (~(EIP76_ALARMCNT_STALL_RUN_POKER)));
|
|
|
|
#ifdef EIP76_HW_PRM_ENABLED // Check if PRM tests are enabled
|
|
// Acknowledge test events
|
|
EIP76_INTACK_WR(Device,
|
|
(EIP76_RUN_FAIL_EVENT | EIP76_LONG_RUN_FAIL_EVENT |
|
|
EIP76_POKER_FAIL_EVENT | EIP76_MONOBIT_FAIL_EVENT |
|
|
EIP76_REPCNT_FAIL_EVENT | EIP76_APROP_FAIL_EVENT |
|
|
EIP76_STUCK_NRBG_EVENT));
|
|
#else
|
|
// Acknowledge test events
|
|
EIP76_INTACK_WR(Device,
|
|
(EIP76_REPCNT_FAIL_EVENT | EIP76_APROP_FAIL_EVENT |
|
|
EIP76_STUCK_NRBG_EVENT));
|
|
#endif
|
|
|
|
// Restore TRNG_CONTROL register (internal TRNG HW state) stored
|
|
// when the test was started
|
|
EIP76_CONTROL_WR(Device, TrueIOArea_p->SavedControl);
|
|
|
|
return EIP76_NO_ERROR;
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------------------------
|
|
* EIP76_Test_Status_Get
|
|
*
|
|
*/
|
|
EIP76_Status_t
|
|
EIP76_Test_Status_Get(
|
|
EIP76_IOArea_t * const IOArea_p,
|
|
EIP76_EventStatus_t * const Events_p)
|
|
{
|
|
Device_Handle_t Device;
|
|
uint32_t StatusRegVal;
|
|
volatile EIP76_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
|
|
|
|
EIP76_CHECK_POINTER(IOArea_p);
|
|
|
|
EIP76_CHECK_POINTER(Events_p);
|
|
|
|
// No events detected yet
|
|
*Events_p = 0;
|
|
|
|
Device = TrueIOArea_p->Device;
|
|
|
|
StatusRegVal = EIP76_STATUS_RD(Device);
|
|
|
|
// Store event status
|
|
*Events_p = (StatusRegVal & EIP76_EVENTS_MASK);
|
|
|
|
if( TrueIOArea_p->PRM_WordCount < 625 )
|
|
{
|
|
if ( EIP76Lib_Test_Is_Ready(Device) )
|
|
{
|
|
return EIP76_State_Set((volatile EIP76_State_t*)&TrueIOArea_p->State,
|
|
EIP76_STATE_KAT_READY);
|
|
}
|
|
else
|
|
{
|
|
// test is not ready, stay in current state
|
|
return EIP76_BUSY_RETRY_LATER;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
uint32_t RunCntRegVal;
|
|
|
|
RunCntRegVal = EIP76_RUNCNT_RD(Device) & EIP76_RUN_CNT_TEST_COUNT_MASK;
|
|
|
|
if( RunCntRegVal < 20001 )
|
|
// Monobit test is not finished yet, stay in current state
|
|
return EIP76_BUSY_RETRY_LATER;
|
|
|
|
// Check if Monobit test failed
|
|
if( (StatusRegVal & EIP76_MONOBIT_FAIL_EVENT) != 0 )
|
|
{
|
|
EIP76_Status_t rv = EIP76_NO_ERROR;
|
|
|
|
// Monobit test is failed and thus finished,
|
|
// transit to a new state
|
|
rv = EIP76_State_Set((volatile EIP76_State_t*)&TrueIOArea_p->State,
|
|
EIP76_STATE_KAT_PRM_M_FAILED);
|
|
|
|
if(rv != EIP76_NO_ERROR)
|
|
return EIP76_ILLEGAL_IN_STATE; // May never occur
|
|
|
|
return EIP76_MONOBIT_FAIL;
|
|
}
|
|
|
|
if( RunCntRegVal < EIP76_TEST_FINISHED_RUN_COUNT )
|
|
// Poker test is not finished yet, stay in current state
|
|
return EIP76_BUSY_RETRY_LATER;
|
|
|
|
// PRM test is finished, transit to a new state
|
|
return EIP76_State_Set((volatile EIP76_State_t* const)&TrueIOArea_p->State,
|
|
EIP76_STATE_KAT_PRM_DONE);
|
|
}
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------------------------
|
|
* EIP76_Test_Block_Write
|
|
*
|
|
*/
|
|
EIP76_Status_t
|
|
EIP76_Test_CF_Block_Write(
|
|
EIP76_IOArea_t * const IOArea_p,
|
|
const uint32_t InputWord_First_p,
|
|
const uint32_t InputWord_Second_p,
|
|
EIP76_EventStatus_t * const Events_p)
|
|
{
|
|
Device_Handle_t Device;
|
|
uint32_t StatusRegVal, ControlRegVal;
|
|
EIP76_Status_t rv = EIP76_NO_ERROR;
|
|
volatile EIP76_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
|
|
|
|
EIP76_CHECK_POINTER(IOArea_p);
|
|
|
|
EIP76_CHECK_POINTER(Events_p);
|
|
|
|
// No events detected yet
|
|
*Events_p = 0;
|
|
|
|
Device = TrueIOArea_p->Device;
|
|
|
|
// Check if in test mode
|
|
ControlRegVal = EIP76_CONTROL_RD(Device);
|
|
if( (ControlRegVal & EIP76_CONTROL_ENABLE_TEST_MODE) == 0 )
|
|
return EIP76_ILLEGAL_IN_STATE;
|
|
|
|
// Transit to a new state
|
|
rv = EIP76_State_Set((volatile EIP76_State_t*)&TrueIOArea_p->State,
|
|
EIP76_STATE_KAT_CF_PROCESSING);
|
|
|
|
if(rv != EIP76_NO_ERROR)
|
|
return EIP76_ILLEGAL_IN_STATE; // May never occur
|
|
|
|
StatusRegVal = EIP76_STATUS_RD(Device);
|
|
|
|
// Store event status
|
|
*Events_p = (StatusRegVal & EIP76_EVENTS_MASK);
|
|
|
|
// Write 64-bit input word for the test
|
|
EIP76_MAINSHIFTREG_L_WR(Device, InputWord_First_p);
|
|
EIP76_MAINSHIFTREG_H_WR(Device, InputWord_Second_p);
|
|
|
|
|
|
// Check if test is ready
|
|
if ( !EIP76Lib_Test_Is_Ready(Device) )
|
|
// Test is not ready,
|
|
// remain in EIP76_STATE_KAT_START state
|
|
return EIP76_BUSY_RETRY_LATER;
|
|
|
|
|
|
return EIP76_NO_ERROR;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------
|
|
* EIP76_Test_State_Block_Write
|
|
*
|
|
*/
|
|
EIP76_Status_t
|
|
EIP76_Test_State_Block_Write(
|
|
EIP76_IOArea_t * const IOArea_p,
|
|
const uint32_t InputWord_First_p,
|
|
const uint32_t InputWord_Second_p,
|
|
const EIP76_State_t NewState,
|
|
EIP76_EventStatus_t * const Events_p)
|
|
{
|
|
Device_Handle_t Device;
|
|
uint32_t StatusRegVal, ControlRegVal;
|
|
EIP76_Status_t rv = EIP76_NO_ERROR;
|
|
volatile EIP76_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
|
|
|
|
EIP76_CHECK_POINTER(IOArea_p);
|
|
|
|
EIP76_CHECK_POINTER(Events_p);
|
|
|
|
// No events detected yet
|
|
*Events_p = 0;
|
|
|
|
Device = TrueIOArea_p->Device;
|
|
|
|
// Check if in test mode
|
|
ControlRegVal = EIP76_CONTROL_RD(Device);
|
|
if( (ControlRegVal & EIP76_CONTROL_ENABLE_TEST_MODE) == 0 )
|
|
return EIP76_ILLEGAL_IN_STATE;
|
|
|
|
// Transit to a new state
|
|
rv = EIP76_State_Set((volatile EIP76_State_t*)&TrueIOArea_p->State,
|
|
NewState);
|
|
|
|
if(rv != EIP76_NO_ERROR)
|
|
return EIP76_ILLEGAL_IN_STATE; // May never occur
|
|
|
|
StatusRegVal = EIP76_STATUS_RD(Device);
|
|
|
|
// Store event status
|
|
*Events_p = (StatusRegVal & EIP76_EVENTS_MASK);
|
|
|
|
// Write 64-bit input word for the test
|
|
EIP76_MAINSHIFTREG_L_WR(Device, InputWord_First_p);
|
|
EIP76_MAINSHIFTREG_H_WR(Device, InputWord_Second_p);
|
|
|
|
// Check if test is ready
|
|
if ( !EIP76Lib_Test_Is_Ready(Device) )
|
|
// Test is not ready,
|
|
// remain in EIP76_STATE_KAT_START state
|
|
return EIP76_BUSY_RETRY_LATER;
|
|
|
|
|
|
return EIP76_NO_ERROR;
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------------------------
|
|
* EIP76_Test_PRM_Write64
|
|
*
|
|
*/
|
|
EIP76_Status_t
|
|
EIP76_Test_PRM_Write64(
|
|
EIP76_IOArea_t * const IOArea_p,
|
|
const uint32_t InputWord_First_p,
|
|
const uint32_t InputWord_Second_p,
|
|
EIP76_EventStatus_t * const Events_p)
|
|
{
|
|
Device_Handle_t Device;
|
|
uint32_t StatusRegVal, TestRegVal, ControlRegVal;
|
|
EIP76_Status_t rv = EIP76_NO_ERROR;
|
|
volatile EIP76_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
|
|
|
|
EIP76_CHECK_POINTER(IOArea_p);
|
|
|
|
EIP76_CHECK_POINTER(Events_p);
|
|
|
|
// No events detected yet
|
|
*Events_p = 0;
|
|
|
|
Device = TrueIOArea_p->Device;
|
|
|
|
// Check if in test mode
|
|
ControlRegVal = EIP76_CONTROL_RD(Device);
|
|
if( (ControlRegVal & EIP76_CONTROL_ENABLE_TEST_MODE) == 0 )
|
|
return EIP76_ILLEGAL_IN_STATE;
|
|
|
|
// Transit to a new state
|
|
rv = EIP76_State_Set((volatile EIP76_State_t*)&TrueIOArea_p->State,
|
|
EIP76_STATE_KAT_PRM_PROCESSING);
|
|
|
|
if(rv != EIP76_NO_ERROR)
|
|
return EIP76_ILLEGAL_IN_STATE; // May never occur
|
|
|
|
StatusRegVal = EIP76_STATUS_RD(Device);
|
|
|
|
// Store event status
|
|
*Events_p = (StatusRegVal & EIP76_EVENTS_MASK);
|
|
|
|
TestRegVal = EIP76_TEST_RD(Device);
|
|
|
|
// Increase 64-bit word count only for normal Poker test
|
|
if( (TestRegVal & EIP76_TEST_RUN_POKER) != 0 &&
|
|
(TestRegVal & EIP76_TEST_CONT_POKER) == 0)
|
|
TrueIOArea_p->PRM_WordCount = TrueIOArea_p->PRM_WordCount + 2;
|
|
|
|
// Write 64-bit input word for the test
|
|
EIP76_MAINSHIFTREG_L_WR(Device, InputWord_First_p);
|
|
EIP76_MAINSHIFTREG_H_WR(Device, InputWord_Second_p);
|
|
|
|
|
|
// Check if test is ready
|
|
if ( !EIP76Lib_Test_Is_Ready(Device) )
|
|
// Test is not ready,
|
|
// remain in EIP76_STATE_KAT_START state
|
|
return EIP76_BUSY_RETRY_LATER;
|
|
|
|
if( TrueIOArea_p->PRM_WordCount < 625 )
|
|
{
|
|
// Test is ready, transit to a new state
|
|
rv = EIP76_State_Set((volatile EIP76_State_t*)&TrueIOArea_p->State,
|
|
EIP76_STATE_KAT_READY);
|
|
|
|
if(rv != EIP76_NO_ERROR)
|
|
return EIP76_ILLEGAL_IN_STATE; // May never occur
|
|
}
|
|
|
|
return EIP76_NO_ERROR;
|
|
}
|
|
|
|
|
|
#ifndef EIP76_MONOBIT_DISABLE
|
|
/*----------------------------------------------------------------------------
|
|
* EIP76_Test_M_Result_Read
|
|
*
|
|
*/
|
|
EIP76_Status_t
|
|
EIP76_Test_M_Result_Read(
|
|
EIP76_IOArea_t * const IOArea_p,
|
|
uint32_t * const MonobitCount_p,
|
|
EIP76_EventStatus_t * const Events_p)
|
|
{
|
|
Device_Handle_t Device;
|
|
uint32_t RegVal;
|
|
volatile EIP76_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
|
|
|
|
EIP76_CHECK_POINTER(IOArea_p);
|
|
|
|
EIP76_CHECK_POINTER(Events_p);
|
|
|
|
EIP76_CHECK_POINTER(MonobitCount_p);
|
|
|
|
// No events detected yet
|
|
*Events_p = 0;
|
|
|
|
Device = TrueIOArea_p->Device;
|
|
|
|
// Check if in test mode
|
|
RegVal = EIP76_CONTROL_RD(Device);
|
|
if( (RegVal & EIP76_CONTROL_ENABLE_TEST_MODE) == 0 )
|
|
return EIP76_ILLEGAL_IN_STATE;
|
|
|
|
RegVal = EIP76_STATUS_RD(Device);
|
|
|
|
// Store event status
|
|
*Events_p = (RegVal & EIP76_EVENTS_MASK);
|
|
|
|
*MonobitCount_p = EIP76_MONOBITCNT_RD(Device) & EIP76_MONOBITCNT_MASK;
|
|
|
|
// Set to 0 number of written 32-bit words as test input
|
|
TrueIOArea_p->PRM_WordCount = 0;
|
|
|
|
// Leave Test Mode
|
|
RegVal = EIP76_TEST_RD(Device);
|
|
// Clear all existing tests that could have been started
|
|
RegVal &= (~(EIP76_TEST_CONT_POKER |
|
|
EIP76_TEST_RUN_POKER |
|
|
EIP76_TEST_POST_PROC |
|
|
EIP76_TEST_SP_800_90 ));
|
|
EIP76_TEST_WR(Device, RegVal);
|
|
|
|
// Clear stall_run_poker and fro_test_mux in TRNG_ALARMCNT
|
|
RegVal = EIP76_ALARMCNT_RD(Device);
|
|
EIP76_ALARMCNT_WR(Device, RegVal & (~(EIP76_ALARMCNT_STALL_RUN_POKER)));
|
|
|
|
// Acknowledge test events
|
|
EIP76_INTACK_WR(Device,
|
|
(EIP76_RUN_FAIL_EVENT | EIP76_LONG_RUN_FAIL_EVENT |
|
|
EIP76_POKER_FAIL_EVENT | EIP76_MONOBIT_FAIL_EVENT));
|
|
|
|
// Restore TRNG_CONTROL register (internal TRNG HW state) stored
|
|
// when the test was started
|
|
EIP76_CONTROL_WR(Device, TrueIOArea_p->SavedControl);
|
|
|
|
// PRM test is finished, transit to a new state
|
|
return EIP76_State_Set((volatile EIP76_State_t*)&TrueIOArea_p->State,
|
|
EIP76_STATE_RANDOM_GENERATING);
|
|
}
|
|
#endif // not EIP76_MONOBIT_DISABLE
|
|
|
|
|
|
/*----------------------------------------------------------------------------
|
|
* EIP76_Test_PR_Result_Read
|
|
*
|
|
*/
|
|
EIP76_Status_t
|
|
EIP76_Test_PR_Result_Read(
|
|
EIP76_IOArea_t * const IOArea_p,
|
|
EIP76_RunKAT_Result_t * const RunKATResult_p,
|
|
EIP76_PokerKAT_Result_t * const PokerKATResult_p,
|
|
EIP76_EventStatus_t * const Events_p)
|
|
{
|
|
Device_Handle_t Device;
|
|
uint32_t RegVal;
|
|
volatile EIP76_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
|
|
|
|
EIP76_CHECK_POINTER(IOArea_p);
|
|
|
|
EIP76_CHECK_POINTER(Events_p);
|
|
|
|
EIP76_CHECK_POINTER(RunKATResult_p);
|
|
|
|
EIP76_CHECK_POINTER(PokerKATResult_p);
|
|
|
|
// No events detected yet
|
|
*Events_p = 0;
|
|
|
|
Device = TrueIOArea_p->Device;
|
|
|
|
// Check if in test mode
|
|
RegVal = EIP76_CONTROL_RD(Device);
|
|
if( (RegVal & EIP76_CONTROL_ENABLE_TEST_MODE) == 0 )
|
|
return EIP76_ILLEGAL_IN_STATE;
|
|
|
|
RegVal = EIP76_STATUS_RD(Device);
|
|
|
|
// Store event status
|
|
*Events_p = (RegVal & EIP76_EVENTS_MASK);
|
|
|
|
// Read Run test results
|
|
EIP76_RUN_TEST_READ(Device, RunKATResult_p);
|
|
|
|
// Read Poker test results
|
|
EIP76_POKER_TEST_READ(Device, PokerKATResult_p);
|
|
|
|
// Set to 0 number of written 32-bit words as test input
|
|
TrueIOArea_p->PRM_WordCount = 0;
|
|
|
|
// Leave Test Mode
|
|
RegVal = EIP76_TEST_RD(Device);
|
|
// Clear all existing tests that could have been started
|
|
RegVal &= (~(EIP76_TEST_CONT_POKER |
|
|
EIP76_TEST_RUN_POKER |
|
|
EIP76_TEST_POST_PROC |
|
|
EIP76_TEST_SP_800_90 ));
|
|
EIP76_TEST_WR(Device, RegVal);
|
|
|
|
// Clear stall_run_poker and fro_test_mux in TRNG_ALARMCNT
|
|
RegVal = EIP76_ALARMCNT_RD(Device);
|
|
EIP76_ALARMCNT_WR(Device, RegVal & (~(EIP76_ALARMCNT_STALL_RUN_POKER)));
|
|
|
|
// Acknowledge test events
|
|
EIP76_INTACK_WR(Device,
|
|
(EIP76_RUN_FAIL_EVENT | EIP76_LONG_RUN_FAIL_EVENT |
|
|
EIP76_POKER_FAIL_EVENT | EIP76_MONOBIT_FAIL_EVENT));
|
|
|
|
// Restore TRNG_CONTROL register (internal TRNG HW state) stored
|
|
// when the test was started
|
|
EIP76_CONTROL_WR(Device, TrueIOArea_p->SavedControl);
|
|
|
|
// PRM test is finished, transit to a new state
|
|
return EIP76_State_Set((volatile EIP76_State_t*)&TrueIOArea_p->State,
|
|
EIP76_STATE_RANDOM_GENERATING);
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------------------------
|
|
* EIP76_Test_CF_Input_Write
|
|
*
|
|
*/
|
|
EIP76_Status_t
|
|
EIP76_Test_CF_Input_Write(
|
|
EIP76_IOArea_t * const IOArea_p,
|
|
EIP76_EventStatus_t * const Events_p,
|
|
uint32_t *SHA_Input_Data,
|
|
uint8_t const SHAVersion)
|
|
{
|
|
Device_Handle_t Device;
|
|
uint32_t RegVal;
|
|
|
|
volatile EIP76_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
|
|
|
|
EIP76_CHECK_POINTER(IOArea_p);
|
|
|
|
EIP76_CHECK_POINTER(Events_p);
|
|
|
|
// No events detected yet
|
|
*Events_p = 0;
|
|
|
|
Device = TrueIOArea_p->Device;
|
|
|
|
// Check if in test mode
|
|
RegVal = EIP76_CONTROL_RD(Device);
|
|
if( (RegVal & EIP76_CONTROL_ENABLE_TEST_MODE) == 0 )
|
|
return EIP76_ILLEGAL_IN_STATE;
|
|
|
|
RegVal = EIP76_STATUS_RD(Device);
|
|
|
|
// Store event status
|
|
*Events_p = (RegVal & EIP76_EVENTS_MASK);
|
|
|
|
if(SHAVersion == 1){
|
|
// Write the CF output registers
|
|
EIP76_INPUT_CF_0_WR(Device, SHA_Input_Data[0]);
|
|
EIP76_INPUT_CF_1_WR(Device, SHA_Input_Data[1]);
|
|
EIP76_INPUT_CF_2_WR(Device, SHA_Input_Data[2]);
|
|
EIP76_INPUT_CF_3_WR(Device, SHA_Input_Data[3]);
|
|
EIP76_INPUT_CF_4_WR(Device, SHA_Input_Data[4]);
|
|
}
|
|
else
|
|
{
|
|
// Write the CF output registers
|
|
EIP76_INPUT_CF_0_WR(Device, SHA_Input_Data[0]);
|
|
EIP76_INPUT_CF_1_WR(Device, SHA_Input_Data[1]);
|
|
EIP76_INPUT_CF_2_WR(Device, SHA_Input_Data[2]);
|
|
EIP76_INPUT_CF_3_WR(Device, SHA_Input_Data[3]);
|
|
EIP76_INPUT_CF_4_WR(Device, SHA_Input_Data[4]);
|
|
EIP76_INPUT_CF_5_WR(Device, SHA_Input_Data[5]);
|
|
EIP76_INPUT_CF_6_WR(Device, SHA_Input_Data[6]);
|
|
EIP76_INPUT_CF_7_WR(Device, SHA_Input_Data[7]);
|
|
|
|
}
|
|
|
|
return EIP76_NO_ERROR;
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------------------------
|
|
* EIP76_Test_CF_Read_Result
|
|
*
|
|
*/
|
|
EIP76_Status_t EIP76_Test_CF_Read_Result(EIP76_IOArea_t * const IOArea_p,
|
|
EIP76_EventStatus_t * const Events_p, uint32_t const * SHA_MD,
|
|
uint8_t SHAVersion)
|
|
{
|
|
Device_Handle_t Device;
|
|
uint32_t Digest[8];
|
|
uint32_t RegVal;
|
|
volatile EIP76_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
|
|
|
|
EIP76_CHECK_POINTER(IOArea_p);
|
|
|
|
EIP76_CHECK_POINTER(Events_p);
|
|
|
|
// No events detected yet
|
|
*Events_p = 0;
|
|
|
|
Device = TrueIOArea_p->Device;
|
|
|
|
// Check if in test mode
|
|
RegVal = EIP76_CONTROL_RD(Device);
|
|
if ((RegVal & EIP76_CONTROL_ENABLE_TEST_MODE) == 0)
|
|
return EIP76_ILLEGAL_IN_STATE;
|
|
|
|
RegVal = EIP76_STATUS_RD(Device);
|
|
|
|
// Store event status
|
|
*Events_p = (RegVal & EIP76_EVENTS_MASK);
|
|
|
|
if (SHAVersion == 1) {
|
|
// Read result from CF output registers, read 4 bits (the actual data)
|
|
Digest[0] = Device_SwapEndian(EIP76_INPUT_CF_0_RD(Device));
|
|
Digest[1] = Device_SwapEndian(EIP76_INPUT_CF_1_RD(Device));
|
|
Digest[2] = Device_SwapEndian(EIP76_INPUT_CF_2_RD(Device));
|
|
Digest[3] = Device_SwapEndian(EIP76_INPUT_CF_3_RD(Device));
|
|
Digest[4] = Device_SwapEndian(EIP76_INPUT_CF_4_RD(Device));
|
|
Digest[5] = 0;
|
|
Digest[6] = 0;
|
|
Digest[7] = 0;
|
|
|
|
// Clear ready bit when done reading result
|
|
EIP76_INTACK_WR(Device, CLEAR_READY_BIT);
|
|
EIP76_INTACK_WR(Device, CLEAR_TEST_READY_BIT);
|
|
|
|
// Compare with digest
|
|
if ((Digest[0] == SHA_MD[0]) && (Digest[1] == SHA_MD[1]) && (Digest[2]
|
|
== SHA_MD[2]) && (Digest[3] == SHA_MD[3]) && (Digest[4]
|
|
== SHA_MD[4])) {
|
|
|
|
// Write back the config register with pre test values
|
|
EIP76_CONFIG_NOISEBLK_WR(Device, TrueIOArea_p->ConfigStatus);
|
|
|
|
// Ack any related events
|
|
EIP76_INTACK_WR(Device, CLEAR_INTACK);
|
|
|
|
// Clear test register
|
|
EIP76_TEST_WR(Device, 0);
|
|
|
|
// Restore TRNG_CONTROL register (internal TRNG HW state) stored
|
|
// when the test was started
|
|
EIP76_CONTROL_WR(Device, TrueIOArea_p->SavedControl);
|
|
|
|
// Last test done go to reset state
|
|
EIP76_State_Set((volatile EIP76_State_t*) &TrueIOArea_p->State,
|
|
EIP76_STATE_RANDOM_GENERATING);
|
|
|
|
return EIP76_NO_ERROR;
|
|
}
|
|
else
|
|
{
|
|
|
|
return EIP76_SHA_FAIL;
|
|
};
|
|
}
|
|
else
|
|
{
|
|
|
|
// Read result from CF output registers
|
|
Digest[0] = Device_SwapEndian(EIP76_INPUT_CF_0_RD(Device));
|
|
Digest[1] = Device_SwapEndian(EIP76_INPUT_CF_1_RD(Device));
|
|
Digest[2] = Device_SwapEndian(EIP76_INPUT_CF_2_RD(Device));
|
|
Digest[3] = Device_SwapEndian(EIP76_INPUT_CF_3_RD(Device));
|
|
Digest[4] = Device_SwapEndian(EIP76_INPUT_CF_4_RD(Device));
|
|
Digest[5] = Device_SwapEndian(EIP76_INPUT_CF_5_RD(Device));
|
|
Digest[6] = Device_SwapEndian(EIP76_INPUT_CF_6_RD(Device));
|
|
Digest[7] = Device_SwapEndian(EIP76_INPUT_CF_7_RD(Device));
|
|
|
|
// Clear ready bit when done reading result
|
|
EIP76_INTACK_WR(Device, CLEAR_READY_BIT);
|
|
EIP76_INTACK_WR(Device, CLEAR_TEST_READY_BIT);
|
|
|
|
// Write back the config register with pre test values
|
|
EIP76_CONFIG_NOISEBLK_WR(Device, TrueIOArea_p->ConfigStatus);
|
|
|
|
// Compare with digest
|
|
if ((Digest[0] == SHA_MD[0]) && (Digest[1] == SHA_MD[1]) && (Digest[2]
|
|
== SHA_MD[2]) && (Digest[3] == SHA_MD[3]) && (Digest[4]
|
|
== SHA_MD[4]) && (Digest[5] == SHA_MD[5]) && (Digest[6]
|
|
== SHA_MD[6]) && (Digest[7] == SHA_MD[7])) {
|
|
|
|
// Ack any related events
|
|
EIP76_INTACK_WR(Device, CLEAR_INTACK);
|
|
|
|
//Clear test register
|
|
EIP76_TEST_WR(Device, 0);
|
|
|
|
// Restore TRNG_CONTROL register (internal TRNG HW state) stored
|
|
// when the test was started
|
|
EIP76_CONTROL_WR(Device, TrueIOArea_p->SavedControl);
|
|
|
|
// Last test done go to reset state
|
|
EIP76_State_Set((volatile EIP76_State_t*) &TrueIOArea_p->State,
|
|
EIP76_STATE_RANDOM_GENERATING);
|
|
|
|
return EIP76_NO_ERROR;
|
|
}
|
|
else
|
|
{
|
|
|
|
return EIP76_SHA_FAIL;
|
|
};
|
|
}
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------
|
|
* EIP76_Test_Rep_Count_Fail_Check
|
|
*
|
|
*/
|
|
EIP76_Status_t EIP76_Test_Rep_Count_Fail_Check(EIP76_IOArea_t * const IOArea_p) {
|
|
|
|
Device_Handle_t Device;
|
|
uint32_t RegVal;
|
|
volatile EIP76_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
|
|
|
|
EIP76_CHECK_POINTER(IOArea_p);
|
|
|
|
Device = TrueIOArea_p->Device;
|
|
|
|
// Read status
|
|
RegVal = EIP76_STATUS_RD(Device);
|
|
|
|
// Write back the config register with pre test values
|
|
EIP76_CONFIG_NOISEBLK_WR(Device, TrueIOArea_p->ConfigStatus);
|
|
|
|
// Ack any related events that may have occurred
|
|
EIP76_INTACK_WR(Device, CLEAR_INTACK);
|
|
|
|
// Reset Cutoff values as they are changed for the test
|
|
if (EIP76_APROP512_RD(Device))
|
|
{
|
|
EIP76_SPB_WR(Device, EIP76_CUTOFF_512_DEFAULT);
|
|
}
|
|
else {
|
|
EIP76_SPB_WR(Device, EIP76_CUTOFF_DEFAULT);
|
|
}
|
|
|
|
// Clear test register
|
|
EIP76_TEST_WR(Device, 0);
|
|
|
|
// Restore TRNG_CONTROL register (internal TRNG HW state) stored
|
|
// when the test was started
|
|
EIP76_CONTROL_WR(Device, TrueIOArea_p->SavedControl);
|
|
|
|
// Last test done go to reset state
|
|
EIP76_State_Set((volatile EIP76_State_t*) &TrueIOArea_p->State,
|
|
EIP76_STATE_RANDOM_GENERATING);
|
|
|
|
if (RegVal & BIT_13)
|
|
{
|
|
return EIP76_REPCNT_FAIL;
|
|
}
|
|
|
|
return EIP76_NO_ERROR;
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------------------------
|
|
* EIP76_Test_CF_Status_Get
|
|
*
|
|
*/
|
|
EIP76_Status_t
|
|
EIP76_Test_CF_Status_Get(EIP76_IOArea_t * const IOArea_p,
|
|
EIP76_EventStatus_t * const Events_p)
|
|
{
|
|
Device_Handle_t Device;
|
|
uint32_t StatusRegVal;
|
|
volatile EIP76_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
|
|
|
|
EIP76_CHECK_POINTER(IOArea_p);
|
|
|
|
EIP76_CHECK_POINTER(Events_p);
|
|
|
|
// No events detected yet
|
|
*Events_p = 0;
|
|
|
|
Device = TrueIOArea_p->Device;
|
|
|
|
StatusRegVal = EIP76_STATUS_RD(Device);
|
|
|
|
// Store event status
|
|
*Events_p = (StatusRegVal & EIP76_EVENTS_MASK);
|
|
|
|
if ((StatusRegVal & EIP76_STATUS_TEST_READY) &&
|
|
(StatusRegVal & EIP76_STATUS_READY)) {
|
|
// Test and ready are ready, transit to a new state
|
|
return EIP76_State_Set((volatile EIP76_State_t*) &TrueIOArea_p->State,
|
|
EIP76_STATE_KAT_CF_DONE);
|
|
}
|
|
else {
|
|
return EIP76_BUSY_RETRY_LATER;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------------------------
|
|
* EIP76_Test_CF_NonLastChain
|
|
*
|
|
*/
|
|
EIP76_Status_t
|
|
EIP76_Test_CF_NonLastChain(EIP76_IOArea_t * const IOArea_p)
|
|
{
|
|
Device_Handle_t Device;
|
|
volatile EIP76_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
|
|
|
|
EIP76_CHECK_POINTER(IOArea_p);
|
|
|
|
Device = TrueIOArea_p->Device;
|
|
|
|
EIP76_INTACK_WR(Device, CLEAR_READY_BIT);
|
|
EIP76_INTACK_WR(Device, CLEAR_TEST_READY_BIT);
|
|
|
|
// Test is ready, transit to a new state
|
|
return EIP76_State_Set((volatile EIP76_State_t*) &TrueIOArea_p->State,
|
|
EIP76_STATE_KAT_CF_PROCESSING);
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------------------------
|
|
* EIP76_Test_Rep_Sample_Counter_Read
|
|
*
|
|
*/
|
|
bool
|
|
EIP76_Test_Rep_Sample_Counter_Read(
|
|
EIP76_IOArea_t * const IOArea_p,
|
|
uint32_t ExpRepSample, uint32_t ExpRepCounter)
|
|
{
|
|
uint32_t retVal;
|
|
Device_Handle_t Device;
|
|
|
|
volatile EIP76_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
|
|
|
|
EIP76_CHECK_POINTER(IOArea_p);
|
|
|
|
Device = TrueIOArea_p->Device;
|
|
|
|
// Read counters
|
|
retVal = EIP76_SPB_RD(Device);
|
|
|
|
// Check if show_counters bit has been set
|
|
if (((retVal >> 28)&0x3) != 0x1)
|
|
{
|
|
// Set show_counters bit
|
|
EIP76_SPB_WR(Device, EIP76_SHOW_COUNTERS);
|
|
// Read counters
|
|
retVal = EIP76_SPB_RD(Device);
|
|
}
|
|
|
|
// Check current counter value with expected value
|
|
if ((retVal & 0x3f) != (ExpRepCounter & 0x3f))
|
|
return false;
|
|
|
|
// Set show values bit
|
|
EIP76_SPB_WR(Device, EIP76_SHOW_VALUES);
|
|
|
|
// Read values
|
|
retVal = EIP76_SPB_RD(Device);
|
|
|
|
// Check if there is no match in one off the words
|
|
if (((retVal & 0xff) != (ExpRepSample & 0xff)))
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------
|
|
* EIP76_Test_Adap_Sample_Counter_Read
|
|
*
|
|
*/
|
|
bool
|
|
EIP76_Test_Adap_Sample_Counter_Read(
|
|
EIP76_IOArea_t * const IOArea_p,
|
|
uint32_t ExpAdapSample,
|
|
uint32_t ExpAdapCounter,
|
|
const EIP76_Test_Type_t TestType)
|
|
{
|
|
uint32_t retVal;
|
|
Device_Handle_t Device;
|
|
|
|
volatile EIP76_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
|
|
|
|
EIP76_CHECK_POINTER(IOArea_p);
|
|
|
|
Device = TrueIOArea_p->Device;
|
|
|
|
// Read counters
|
|
retVal = EIP76_SPB_RD(Device);
|
|
|
|
// Check if show_counters bit has been set
|
|
if(((retVal >> 28)&0x3) != 0x1)
|
|
{
|
|
// Set show_counters bit
|
|
EIP76_SPB_WR(Device, EIP76_SHOW_COUNTERS);
|
|
// Read counters
|
|
retVal = EIP76_SPB_RD(Device);
|
|
}
|
|
|
|
if (TestType == EIP76_ADPRO_TYPE_64)
|
|
{
|
|
// Check current counter value with expected value
|
|
if ((retVal >> 8 & 0x3f) != (ExpAdapCounter & 0x3f))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
else if (TestType == EIP76_ADPRO_TYPE_512)
|
|
{
|
|
// Check current counter value with expected value
|
|
if ((retVal >> 16 & 0x1ff) != (ExpAdapCounter & 0x1ff))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Check current counter value with expected value
|
|
if ((retVal >> 16 & 0xfff) != (ExpAdapCounter & 0xfff))
|
|
return false;
|
|
}
|
|
|
|
// Set show_values bit
|
|
EIP76_SPB_WR(Device, EIP76_SHOW_VALUES);
|
|
|
|
// Read values
|
|
retVal = EIP76_SPB_RD(Device);
|
|
|
|
if (TestType == EIP76_ADPRO_TYPE_64)
|
|
{
|
|
// Check if there is no match in one off the words
|
|
if (((retVal >> 8 & 0xff) != (ExpAdapSample & 0xff)))
|
|
return false;
|
|
}
|
|
else if (TestType == EIP76_ADPRO_TYPE_512)
|
|
{
|
|
// Check if there is no match in one off the words
|
|
if (((retVal >> 16 & 0xff) != (ExpAdapSample & 0xff)))
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
// Check if there is no match in one off the words
|
|
if (((retVal >> 16 & 0xff) != (ExpAdapSample & 0xff)))
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------------------------
|
|
* EIP76_Test_Adap_Fail_Check
|
|
*
|
|
*/
|
|
EIP76_Status_t
|
|
EIP76_Test_Adap_Fail_Check(
|
|
EIP76_IOArea_t * const IOArea_p)
|
|
{
|
|
Device_Handle_t Device;
|
|
uint32_t RegVal;
|
|
volatile EIP76_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
|
|
|
|
EIP76_CHECK_POINTER(IOArea_p);
|
|
|
|
Device = TrueIOArea_p->Device;
|
|
|
|
// Read status
|
|
RegVal = EIP76_STATUS_RD(Device);
|
|
|
|
// Write back the config register with pre test values
|
|
EIP76_CONFIG_NOISEBLK_WR(Device, TrueIOArea_p->ConfigStatus);
|
|
|
|
// Ack any related events that may have occurred
|
|
EIP76_INTACK_WR(Device, CLEAR_INTACK);
|
|
|
|
// Reset Cutoff values as they are changed for the test
|
|
if (EIP76_APROP512_RD(Device))
|
|
{
|
|
EIP76_SPB_WR(Device, EIP76_CUTOFF_512_DEFAULT);
|
|
}
|
|
else {
|
|
EIP76_SPB_WR(Device, EIP76_CUTOFF_DEFAULT);
|
|
}
|
|
|
|
// Clear test register
|
|
EIP76_TEST_WR(Device, 0);
|
|
|
|
// Restore TRNG_CONTROL register (internal TRNG HW state) stored
|
|
// when the test was started
|
|
EIP76_CONTROL_WR(Device, TrueIOArea_p->SavedControl);
|
|
|
|
// Last test done go to reset state
|
|
EIP76_State_Set((volatile EIP76_State_t*) &TrueIOArea_p->State,
|
|
EIP76_STATE_RANDOM_GENERATING);
|
|
|
|
// Check if error bit is set
|
|
if (RegVal & BIT_14)
|
|
{
|
|
return EIP76_ADPRO_FAIL;
|
|
}
|
|
|
|
return EIP76_NO_ERROR;
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------------------------
|
|
* EIP76_Test_Is_Ready
|
|
*
|
|
*/
|
|
EIP76_Status_t
|
|
EIP76_Test_Is_Ready(
|
|
EIP76_IOArea_t * const IOArea_p,
|
|
EIP76_EventStatus_t * const Events_p,
|
|
uint32_t * const data_buf_p)
|
|
{
|
|
Device_Handle_t Device;
|
|
uint32_t StatusRegVal;
|
|
volatile EIP76_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
|
|
|
|
|
|
EIP76_CHECK_POINTER(IOArea_p);
|
|
|
|
EIP76_CHECK_POINTER(Events_p);
|
|
|
|
Device = TrueIOArea_p->Device;
|
|
|
|
StatusRegVal = EIP76_STATUS_RD(Device);
|
|
|
|
// Store event status
|
|
*Events_p = (StatusRegVal & EIP76_EVENTS_MASK);
|
|
|
|
if (EIP76_STATUS_IS_READY(StatusRegVal))
|
|
{
|
|
|
|
data_buf_p[0] = EIP76_OUTPUT_0_RD(Device);
|
|
data_buf_p[1] = EIP76_OUTPUT_1_RD(Device);
|
|
data_buf_p[2] = EIP76_OUTPUT_2_RD(Device);
|
|
data_buf_p[3] = EIP76_OUTPUT_3_RD(Device);
|
|
|
|
// Clear ready bit when done reading result
|
|
EIP76_INTACK_WR(Device, CLEAR_READY_BIT);
|
|
return EIP76_NO_ERROR;
|
|
}
|
|
else
|
|
{
|
|
// status is not ready, stay in current state
|
|
return EIP76_BUSY_RETRY_LATER;
|
|
}
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------
|
|
* EIP76_Test_Set_Reseed
|
|
*
|
|
*/
|
|
void
|
|
EIP76_Test_Set_Reseed(
|
|
EIP76_IOArea_t * const IOArea_p,
|
|
EIP76_EventStatus_t * const Events_p)
|
|
{
|
|
Device_Handle_t Device;
|
|
|
|
volatile EIP76_True_IOArea_t * const TrueIOArea_p = IOAREA(IOArea_p);
|
|
|
|
// EIP76_CHECK_POINTER(IOArea_p);
|
|
|
|
// EIP76_CHECK_POINTER(Events_p);
|
|
|
|
Device = TrueIOArea_p->Device;
|
|
|
|
// No event found
|
|
*Events_p = 0;
|
|
|
|
EIP76_CONTROL_WR(Device, EIP76_CONTROL_ENABLE_RESEED);
|
|
}
|
|
|