/*
* Creation date : Tues Mar 03 09:00:00 2007
* Last modified : %modify_time%
*/
/** @file
* \brief This file contains implementation of common usage
*  low level functions for ECC 
*
* \version LLF_ECPKI_Common.c#1:csrc:1
* \author Yermalayeu Ihar
* \remarks Copyright (C) 2007 by Discretix Technologies Ltd.
* All Rights reserved
*/

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

#include "LLF_ECPKI_Common.h"

/************************ Defines *****************************/
#define LLF_PRNG_BUFFER_SIZE 16
/************************ Enums *******************************/
/************************ Typedefs ****************************/
/************************ Global Data *************************/
/************************ Private function prototype **********/
/************************ Private Functions *******************/
/************************ Public Functions ********************/

/**
****************************************************************
* Function Name: 
*  LLF_ECPKI_DomainIdToModulusSize
*
* Inputs:
* @param domainId [in] - The enumerator variable defines the current EC domain.
*
* Outputs: @returns \b
*  DxUint_t - Modulus size for current ECC domain ID.
*
* \brief \b 
* Description:
*  This function return modulus size for current ECC domain ID.
*
* \b 
* Algorithm:
*  -# Return modulus size for current ECC domain ID.
***************************************************************/
DxUint_t LLF_ECPKI_DomainIdToModulusSize(CE2_ECPKI_DomainID_t domainId)
{
  DxUint_t modulusSize;

  switch(domainId)
  {
  case CE2_ECPKI_DomainID_WMDRM10:
    modulusSize = 20;
    break;
  case CE2_ECPKI_DomainID_secp160k1:
    modulusSize = 20;
    break;
  case CE2_ECPKI_DomainID_secp160r1:
    modulusSize = 20;
    break;
  case CE2_ECPKI_DomainID_secp160r2:
    modulusSize = 20;
    break;
  case CE2_ECPKI_DomainID_secp192k1:
    modulusSize = 24;
    break;
  case CE2_ECPKI_DomainID_secp192r1:
    modulusSize = 24;
    break;
  case CE2_ECPKI_DomainID_secp224k1:
    modulusSize = 28;
    break;
  case CE2_ECPKI_DomainID_secp224r1:
    modulusSize = 28;
    break;
  case CE2_ECPKI_DomainID_secp256k1:
    modulusSize = 32;
    break;
  case CE2_ECPKI_DomainID_secp256r1:
    modulusSize = 32;
    break;
  case CE2_ECPKI_DomainID_secp384r1:
    modulusSize = 48;
    break;
  case CE2_ECPKI_DomainID_secp521r1:
    modulusSize = 66;
    break;
  default:
    modulusSize = 0;
  }
  return modulusSize;
} /* End of LLF_ECPKI_DomainIdToModulusSize */

/**
****************************************************************
* Function Name: 
*  LLF_ECPKI_DomainIdToOrderSizeInBytes
*
* Inputs:
* @param domainId [in] - The enumerator variable defines the current EC domain.
*
* Outputs: @returns \b
*  DxUint_t - Order size for current ECC domain ID in bytes.
*
* \brief \b 
* Description:
*  This function return order size for current ECC domain ID in bytes.
*
* \b 
* Algorithm:
*  -# Return order size for current ECC domain ID.
***************************************************************/
DxUint_t LLF_ECPKI_DomainIdToOrderSizeInBytes(CE2_ECPKI_DomainID_t domainId)
{
  DxUint_t orderSize;

  switch(domainId)
  {
  case CE2_ECPKI_DomainID_WMDRM10:
    orderSize = 20;
    break;
  case CE2_ECPKI_DomainID_secp160k1:
    orderSize = 21;
    break;
  case CE2_ECPKI_DomainID_secp160r1:
    orderSize = 21;
    break;
  case CE2_ECPKI_DomainID_secp160r2:
    orderSize = 21;
    break;
  case CE2_ECPKI_DomainID_secp192k1:
    orderSize = 24;
    break;
  case CE2_ECPKI_DomainID_secp192r1:
    orderSize = 24;
    break;
  case CE2_ECPKI_DomainID_secp224k1:
    orderSize = 29;
    break;
  case CE2_ECPKI_DomainID_secp224r1:
    orderSize = 28;
    break;
  case CE2_ECPKI_DomainID_secp256k1:
    orderSize = 32;
    break;
  case CE2_ECPKI_DomainID_secp256r1:
    orderSize = 32;
    break;
  case CE2_ECPKI_DomainID_secp384r1:
    orderSize = 48;
    break;
  case CE2_ECPKI_DomainID_secp521r1:
    orderSize = 66;
    break;
  default:
    orderSize = 0;
  }
  return orderSize;
} /* End of LLF_ECPKI_DomainIdToOrderSizeInBytes */

/**
****************************************************************
* Function Name: 
*  LLF_ECPKI_DomainIdToOrderSizeInBits
*
* Inputs:
* @param domainId [in] - The enumerator variable defines the current EC domain.
*
* Outputs: @returns \b
*  DxUint_t - Order size for current ECC domain ID in bits.
*
* \brief \b 
* Description:
*  This function return order size for current ECC domain ID in bits.
*
* \b 
* Algorithm:
*  -# Return order size for current ECC domain ID.
***************************************************************/
DxUint_t LLF_ECPKI_DomainIdToOrderSizeInBits(CE2_ECPKI_DomainID_t domainId)
{
  DxUint_t orderSize;

  switch(domainId)
  {
  case CE2_ECPKI_DomainID_WMDRM10:
    orderSize = 160;
    break;
  case CE2_ECPKI_DomainID_secp160k1:
    orderSize = 161;
    break;
  case CE2_ECPKI_DomainID_secp160r1:
    orderSize = 161;
    break;
  case CE2_ECPKI_DomainID_secp160r2:
    orderSize = 161;
    break;
  case CE2_ECPKI_DomainID_secp192k1:
    orderSize = 192;
    break;
  case CE2_ECPKI_DomainID_secp192r1:
    orderSize = 192;
    break;
  case CE2_ECPKI_DomainID_secp224k1:
    orderSize = 225;
    break;
  case CE2_ECPKI_DomainID_secp224r1:
    orderSize = 224;
    break;
  case CE2_ECPKI_DomainID_secp256k1:
    orderSize = 256;
    break;
  case CE2_ECPKI_DomainID_secp256r1:
    orderSize = 256;
    break;
  case CE2_ECPKI_DomainID_secp384r1:
    orderSize = 384;
    break;
  case CE2_ECPKI_DomainID_secp521r1:
    orderSize = 521;
    break;
  default:
    orderSize = 0;
  }
  return orderSize;
} /* End of LLF_ECPKI_DomainIdToOrderSizeInBits */

/**
****************************************************************
* Function Name: 
*  LLF_ECPKI_PRNG_Init
*
* Inputs:
* @param prng [in] - The pointer to PRNG structure.
* @param wprng [in] - The pointer to index of the PRNG.
*
* Outputs: @returns \b
*  CE2Error_t - On success returns CE2_OK; else return error code.
*
* \brief \b 
* Description:
*  This function initialize Pseudo-Random Number Generator  
* ("fortuna" generator is used). 
*  
* \b 
* Algorithm:
*  -# Create and initialize Pseudo-Random Number Generators
***************************************************************/
CE2Error_t LLF_ECPKI_PRNG_Init(prng_state *prng, int *wprng)
{
  unsigned char buffer[LLF_PRNG_BUFFER_SIZE];
  int error_code;

  /* Create and initialize Pseudo-Random Number Generators */
  error_code = register_prng(&fortuna_desc);
  if (error_code == -1) 
    return CE2_LLF_ECPKI_MODULE_ERROR_BASE;

  error_code = fortuna_start(prng);
  if (error_code != CRYPT_OK) 
    return CE2_LLF_ECPKI_MODULE_ERROR_BASE;

  error_code = sprng_read(buffer, LLF_PRNG_BUFFER_SIZE, NULL);
  if (error_code == 0) 
    return CE2_LLF_ECPKI_MODULE_ERROR_BASE;

  error_code = fortuna_add_entropy(buffer, LLF_PRNG_BUFFER_SIZE, prng);
  if (error_code != CRYPT_OK) 
    return CE2_LLF_ECPKI_MODULE_ERROR_BASE;

  error_code = fortuna_ready(prng);
  if(error_code != CRYPT_OK) 
    return CE2_LLF_ECPKI_MODULE_ERROR_BASE;

  *wprng = find_prng("fortuna");
  if(*wprng == -1) 
    return CE2_LLF_ECPKI_MODULE_ERROR_BASE;

  return CE2_OK;
} /* End of LLF_ECPKI_PRNG_Init */
