/*
* Creation date : Tues May 29 09:00:00 2007
* Last modified : %modify_time%
*/
/** @file
* \brief This file contains implementation of 
* RND functions. 
*
* \version CE2_RND.c#1:csrc:1
* \author Yermalayeu Ihar
* \remarks Copyright (C) 2007 by Discretix Technologies Ltd.
* All Rights reserved
*/

/************************ Include Files ***********************/

#include "CE2_RND.h"
#include "LLF_RND.h"

#ifdef RND_FIPS_PUB_186_2

/************************ Defines *****************************/
/************************ Enums *******************************/
/************************ Typedefs ****************************/
/************************ Global Data *************************/
/************************ Private Functions *******************/
/************************ Public Functions ********************/

/**
****************************************************************
* Function Name: 
*  CE2_RND_GenerateVector
*
*  @param[in] RndSize - The size of random vector that is required.
*  @param[in/out] Output_ptr - The output vector.
*
* @returns \b
*  CE2Error_t 
*  - CE2_OK - on success
*  - Otherwise - on failure a value from CE2_error.h:
*
* \brief \b 
* Description:
*  The CE2_RND_GenerateVector function generates a random vector using
*  the FIPS-PUB 186-2 standard, Appendix 3.
*  The random function is based on the HASH SHA1 and works as follows:
*  1. Loads the secret key stored internally into a global variable.
*  2. Executes the following steps according to the number of hash result 
*     blocks required (RndSize/20).
*    a. Executes a SHA1 hash on the current key
*       (if the key is less than 512 bytes, adds zeros to it).
*    b. Stores the result to the data 
*    c. The next key is 1 ^ key ^ result. This is the new key.
*
*  \b 
* Algorithm:
*  -# Verify input parameters for validity;
*  -# Call low level function LLF_RND_GenerateVector; 
***************************************************************/
CE2CIMPORT_C CE2Error_t CE2_RND_GenerateVector(DxUint16_t  RndSize,
                                            DxUint8_t  *Output_ptr)
{
  if (Output_ptr == DX_NULL)
    return CE2_RND_GENERATE_VECTOR_OUTPUT_PTR_ERROR;

  return LLF_RND_GenerateVector(RndSize, Output_ptr);
} /* End of CE2_RND_GenerateVector */

/**
****************************************************************
* Function Name: 
*  CE2_RND_ResetSeed
*
* @returns \b
*  CE2Error_t 
*  - CE2_OK - on success
*  - Otherwise - on failure a value from CE2_error.h:
*
* \brief \b 
* Description:
*  The CE2_RND_ResetSeed resets the SEED generated by the low level
*  (the hardware or operating system service on software).
*
*  \b 
* Algorithm:
*  -# Call low level function LLF_RND_ResetSeed; 
***************************************************************/
CE2CIMPORT_C CE2Error_t CE2_RND_ResetSeed(void)
{
  return LLF_RND_ResetSeed();
} /* End of CE2_RND_ResetSeed */

/**
****************************************************************
* Function Name: 
*  CE2_RND_GenerateVectorInRange
*
*  @RndSize[in] - The size of random vectore that is required.
*  @MaxVect_ptr[in]  - The pointer to vector defines high limit of random vector.
*  @RndVect_ptr[in/out] The output vector.
*
* @returns \b
*  CE2Error_t 
*  - CE2_OK - on success
*  - Otherwise - on failure a value from CE2_error.h:
*
* \brief \b 
* Description:
*  This function generates a random vector RndVect in range:
*  1 < RndVect < MaxVect,   using the FIPS-PUB 186-2 standard appendex 3 :
*  The function performs the following:
*    1. Calls the CE2_RND_GenerateVector() function for generating random vector 
*       RndVect of size in bytes.
*    2. Zeroes extra bits of RndVect.
*    3. Compares RndVect with 1 and MaxVect. If condition  1 < RandVect < MaxVect
*       is not satisfied goues to step 1.
*
*  \b 
* Algorithm:
*  -# Verify input parameters for validity;
*  -# Call low level function CE2_RND_GenerateVectorInRange; 
***************************************************************/
CE2CIMPORT_C CE2Error_t CE2_RND_GenerateVectorInRange(DxUint32_t RndSizeInBits, 
                                                   DxUint8_t *MaxVect_ptr, 
                                                   DxUint8_t *RndVect_ptr)
{
  if (MaxVect_ptr == DX_NULL)
    return CE2_RND_GENERATE_VECTOR_IN_RANGE_MAXVECT_PTR_ERROR;

  if (RndVect_ptr == DX_NULL)
    return CE2_RND_GENERATE_VECTOR_IN_RANGE_RNDVECT_PTR_ERROR;

  return LLF_RND_GenerateVectorInRange(RndSizeInBits, MaxVect_ptr, RndVect_ptr);
} /* End of CE2_RND_GenerateVectorInRange */

#elif RND_FIPS_SP_800_90

/************************ Defines *****************************/
/************************ Enums *******************************/
/************************ Typedefs ****************************/
/************************ Global Data *************************/
/************************ Private Functions *******************/
/************************ Public Functions ********************/

/**
****************************************************************
* Function Name: 
*  CE2_RND_Instantiation
*
* Input:
*  None
*
* @returns \b
*  CE2Error_t 
*  - CE2_OK - on success
*  - Otherwise - on failure a value from CE2_error.h:
*
* \brief \b 
* Description:
*  Initializes RND engine according to FIPS-SP 800-90:
*  - CCSystemSpec_RNG v1.2 [2.3.2.2 Instantiation];
*  - RNG_SW_SDDv0.3.
*
*  \b 
* Algorithm:
*  -# Call low level function LLF_RND_Instantiation;
***************************************************************/
CE2CIMPORT_C CE2Error_t CE2_RND_Instantiation(void)
{
  /* Call LLF */
  return
    LLF_RND_Instantiation();
} /* End of CE2_RND_Instantiation */

/**
****************************************************************
* Function Name: 
*  CE2_RND_GenerateVector
*
* Input:
*  @param[in]     RndSize    - The size of random vector that is required;
*  @param[in/out] Output_ptr - The output vector.
*
* @returns \b
*  CE2Error_t 
*  - CE2_OK - on success
*  - Otherwise - on failure a value from CE2_error.h:
*
* \brief \b 
* Description:
*  Generates pseudo random data vector according to FIPS-SP 800-90:
*  - CCSystemSpec_RNG v1.2 [2.3.2.4 Random Number Generation];
*  - RNG_SW_SDDv0.3.
*
*  \b 
* Algorithm:
*  -# Verify input parameters for validity;
*  -# Call low level function LLF_RND_GenerateVector;
***************************************************************/
CE2CIMPORT_C CE2Error_t CE2_RND_GenerateVector(DxUint16_t RndSize,		/* in */
											   DxUint8_t  *Output_ptr)	/* in/out */
{
  /* Validate output pointer */
  if (Output_ptr == DX_NULL)
    return CE2_RND_DATA_OUT_POINTER_INVALID_ERROR;

  /*
  RNG_SW_SDDv0.3
  
  2.2 Assumptions and Constraints
  CRYS_RND_GenerateVector function is limited to generate up to
  2^12 chunks of 128 bits per each calling. 
  */

  if (RndSize > 4096 * LLF_RND_DEFAULT_DATA_SIZE)
    return CE2_RND_MODULE_ERROR_BASE;

  return LLF_RND_GenerateVector(RndSize, Output_ptr);
} /* End of CE2_RND_GenerateVector */

/**
****************************************************************
* Function Name: 
*  CE2_RND_Reseeding
*
* Input:
*  None
*
* @returns \b
*  CE2Error_t 
*  - CE2_OK - on success
*  - Otherwise - on failure a value from CE2_error.h:
*
* \brief \b 
* Description:
*  Preforms RND engine reseeding according to FIPS-SP 800-90:
*  - CCSystemSpec_RNG v1.2 [2.3.2.3 Reseeding];
*  - RNG_SW_SDDv0.3.
*
*  \b 
* Algorithm:
*  -# Call low level function LLF_RND_Reseeding;
***************************************************************/
CE2CIMPORT_C CE2Error_t CE2_RND_Reseeding(void)
{
  /* Call LLF */
  return
    LLF_RND_Reseeding();
} /* End of CE2_RND_Reseeding */

/**
****************************************************************
* Function Name: 
*  CE2_RND_AddAdditionalInput
*
* Input:
*  @param[in] AdditionalInput     - Additional input data;
*  @param[in] AdditionalInputSize - Additional input data size.
*
* @returns \b
*  CE2Error_t 
*  - CE2_OK - on success
*  - Otherwise - on failure a value from CE2_error.h:
*
* \brief \b 
* Description:
*  Adds additional info vector to RND engine according to:
*  - CCSystemSpec_RNG v1.2;
*  - RNG_SW_SDDv0.3.
*
*  \b 
* Algorithm:
*  -# Verify input parameters for validity;
*  -# Call low level function LLF_RND_AddAdditionalInput;
***************************************************************/
CE2CIMPORT_C CE2Error_t CE2_RND_AddAdditionalInput(DxUint8_t  *AdditionalInput,		/* in */
												   DxUint16_t AdditionalInputSize)	/* in */
{
  /* Validate input pointer */
  if (AdditionalInput == DX_NULL)
    return CE2_RND_ADDITIONAL_INPUT_BUFFER_NULL;

  if (AdditionalInputSize != 16 && AdditionalInputSize != 32)
    return CE2_RND_ADDITIONAL_INPUT_SIZE_ERROR;

  /* Call LLF */
  return
    LLF_RND_AddAdditionalInput(AdditionalInput, AdditionalInputSize);
} /* End of CE2_RND_AddAdditionalInput */

#endif