/*
   *  Object %name    : KMNG.c
   *  State           :  %state%
   *  Creation date   :  Wed Nov 17 17:39:24 2004
   *  Last modified   :  %modify_time%
   */
  /** @file
   *  \brief Secure Boot implemtation of hash queues
   *
   *  \version 
   *  \author yevgenys
   *  \remarks Copyright (C) 2004 by Discretix Technologies Ltd.
   *           All Rights reserved
   */


#include "DX_VOS_BaseTypes.h"
#include "DX_VOS_Mem.h"
#include "DX_VOS_Sem.h"
#include "CRYS.h"
#include "KMNG_error.h"
#include "CRYS_RSA_Types.h"
#include "KMNG_Defs.h"
#include "KMNG_API.h"
#include "LLF_KMNG_DEF.h"
#ifdef KMNG_SEP_SIMULATOR
#include "llf_kmng_wrapper.h"
#endif
#include "LLF_KMNG.h"
#include "CRYS_AES.h"

/*-------------------------
  INTERNAL ENUMERATORS
--------------------------*/

typedef enum
{
	KMNG_SymmetricKey,
	KMNG_RsaKey,
	KMNG_DhKey,
	
	KMNG_OffModeKey,
    
    KMNG_KeyTypeGroupLast = 0x7FFFFFFF,
    
}KMNG_KeyTypeGroup_t;


/*-------------------------
  DEFINES
--------------------------*/

/* canceling the lint warning:
   Use of goto is deprecated */
/*lint --e{774} */


#define DX_KMNG_VALID_FLAG_VALUE 1
#define DX_KMNG_CALC_AND_VERIFY_WITHOUT_DELETE 0
#define DX_KMNG_CALC_AND_VERIFY_WITH_DELETE 1

/* the KMNG release definitions */

#define KMNG_RELEASE_TYPE         'A'
#define KMNG_MAJOR_VERSION_NUM     1
#define KMNG_MINOR_VERSION_NUM     2
#define KMNG_SUB_VERSION_NUM       0
#define KMNG_INTERNAL_VERSION_NUM  0

KMNG_BufferData_t        KeyGenData;
static DxVosSem          SemaphoreKeyGenDataAccess = DX_NULL;

/**
 * @brief     This function converts type of key to group of key types     
 *
 * @param[in] keyType - key type (enumerator)
 * @param[in] keyTypeGroup_ptr - pointer to key type group enum variable (symmetric, RSA. DH)
 * 
 * @return     DxError_t:  
 *                        
 */
static DxError_t KMNG_ConvertKeyTypeToGroup(
                                         KMNG_KeyType_t        keyType,
                                         KMNG_KeyTypeGroup_t*  keyTypeGroup_ptr);
 

/**
 * @brief     This function find the next empty slot for user key in key ring
 *			  according to the type of key
 *
 * @param[in] keyRing_ptr - key ring
 * @param[in] keyTypeGroup - key type group (symmetric, RSA. DH)
 * @param[out] emptySlot_ptr - pointer to empty slot (virtual)
 * @param[out] emptySlotId_ptr - Id (index of empty slot
 * 
 * @return     DxError_t:  
 *                        
 */
static DxError_t KMNG_FindUserKeyEmptySlot(DxUint8_t*         keyRing_ptr,
                                         KMNG_KeyTypeGroup_t  keyTypeGroup,
                                         DxUint8_t**          emptySlot_ptr,
                                         DxUint32_t*          emptySlotId_ptr);
                                  
                                  
/**
 * @brief     This function finds the slot of the key defined by the key id
 *
 * @param[in]  keyRing_ptr - key ring
 * @param[in]  keyId - key id of the key to find
 * @param[out] keySlot_ptr - pointer to the found key slot
 * @param[out] keyTypeGroup - defining the group of types of keys (symmetric, RSA. DH)
 * @param[out] keyDataSize_ptr - pointer to the key data size (for the found group) 
 *
 * @return     DxError_t:  
 * 
 *  NOTE: If the user is not needed to recieve the keyTypeGroup or keyGroupSize, then he can set 
 *        appropriate pointers as NULL, or to use special macros KMNG_FindKeyInKeyRing() .
 *                        
 */
static DxError_t KMNG_FindKeyAndItsGroupInKeyRing(
                                     DxUint8_t*                 keyRing_ptr,
                                     DxUint32_t                 keyId,
                                     DxUint8_t**                keySlot_ptr,
                                     KMNG_KeyTypeGroup_t*       keyTypeGroup_ptr,
                                     DxUint32_t*                keyDataSize_ptr );
                                     
/**
 * @brief     This macros is intended for calling the FindKeyInRing function with KeyType pointer NULL
 *
 * @param[in]  keyRing_ptr - key ring
 * @param[in]  keyId - key id of the key to find
 * @param[out] keySlot_ptr - pointer to the found key slot
 * 
 * @return     DxError_t:  
 *                        
 */
 #define KMNG_FindKeyInKeyRing( keyRing_ptr, keyId, keySlot_ptr )  KMNG_FindKeyAndItsGroupInKeyRing( (keyRing_ptr), (keyId), (keySlot_ptr), DX_NULL, DX_NULL )
                                                    
                                     


/*---------------------
    FUNCTIONS
-----------------------*/

/**
 * @brief     This function converts type of key to group of key types     
 *
 * @param[in] keyType - key type (enumerator)
 * @param[in] keyTypeGroup_ptr - pointer to key type group enum variable (symmetric, RSA. DH)
 * 
 * @return     DxError_t:  
 *                        
 */
static DxError_t KMNG_ConvertKeyTypeToGroup(
                                         KMNG_KeyType_t        keyType,
                                         KMNG_KeyTypeGroup_t*  keyTypeGroup_ptr)
{
	 /* error */
     DxError_t    error = KMNG_OK;
     
  /*--------------------------
      CODE
  ---------------------------*/
  
  switch( keyType )
  {
  	case KMNG_KeyTypeAES:
  	case KMNG_KeyTypeDES:
  	case KMNG_KeyTypeHMAC:
  	
  	    *keyTypeGroup_ptr = 	KMNG_SymmetricKey;
  	    break;
  	    
  	case KMNG_KeyTypeRSAPriv:
    case KMNG_KeyTypeRSAPub:
    case KMNG_KeyTypeRSAPair:
    
  	    *keyTypeGroup_ptr = 	KMNG_RsaKey;
  	    break;
  	        
    case KMNG_KeyTypeDH:  
    
  	    *keyTypeGroup_ptr = 	KMNG_DhKey;  
  	    break;
    
  	default:
  	
  		error = DX_KMNG_INVALID_KEY_TYPE_ERR;  
  }
    
  return error;     	
}

/**
 * @brief     This function initializes the KMNG component
 * 
 * @return     DxError_t:  
 *                        
 */
DxError_t KMNG_Init()
{
  DxError_t error;
  
  /*----------------------------
      CODE
  ---------------------------------*/
  
  error = KMNG_OK;

  if (SemaphoreKeyGenDataAccess == DX_NULL)
  {
      error = DX_VOS_SemCreate(&SemaphoreKeyGenDataAccess, DX_VOS_SEM_FREE, DX_NULL);
      if (DX_SUCCESS != error)
      {
          return error;
      }
  }
  
  /* init LLF module */
  error = LLF_KMNG_Init();
  
  return error;
}


/**
 * @brief     This function returns the size of buffer in bytes,
 *			  that needs to be allocated for the KeyRing with specific paramaters
 *
 *
 * @param[in] numSymKeys - number of symmetric keys to be kept in the key ring
 * @param[in] numRSAKey - number of RSA keys to be kept in the key ring
 * @param[in] numDHKeys - number of DH keys to be kept in the key ring
 * @param[out] bufferSize_ptr - buffer size needed for key ring
 * 
 * @return     DxError_t:  
 *                        
 */
DxError_t KMNG_GetKeyRingBufferSize(DxUint32_t   numSymKeys , 
                                    DxUint32_t   numRSAKeys,
                                    DxUint32_t   numDHKeys,
                                    DxUint32_t*  bufferSize_ptr)
{
  
  /*--------------------------
      CODE
  ---------------------------*/
  
  if(bufferSize_ptr == DX_NULL)
  {
    return DX_KMNG_INPUT_ARG_NULL_POINTER_ERROR;
  }
  
  /* calculate size of the buffer for key ring */
  *bufferSize_ptr = sizeof(KMNG_SYMKeyData_t) * (numSymKeys) +
                    sizeof(KMNG_RSAKeyData_t) * (numRSAKeys) +
                    sizeof(KMNG_DHKeyData_t) * (numDHKeys) +
                    sizeof(KMNG_KeyRing_t);
                
  return KMNG_OK;
  
}
                                           

/**
 * @brief     This function initializes the key ring. It creates key ring key, initializes it with given password
 *            and initializes the key ring data with given keys information
 *
 * @param[in] passwordLength - length of the password
 * @param[in] password_ptr - password pointer
 * @param[in] numSymKeys - number of symmetric keys to be kept in the key ring
 * @param[in] numRSAKeys - number of RSA keys to be kept in the key ring
 * @param[in] numDHKeys - number of DH keys to be kept in the key ring
 * @param[out] keyRing_ptr - key ring structure to be initialized
 * 
 * @return     DxError_t:  
 *                        
 */
DxError_t KMNG_KeyRingInit(DxUint32_t    passwordLength,
                         DxUint8_t*    password_ptr,
                         DxUint32_t    numSymKeys,
                         DxUint32_t    numRSAKeys,
                         DxUint32_t    numDHKeys, 
                         DxUint8_t*    keyRing_ptr)
{
  /* paramaters for create key */
  KMNG_KeyDataParameter_t   keyDataParam;
  
  /* configuration parameters */
  KMNG_KeyConfiguration_t   keyConfiguration;
  
  /* pointer to the space for the LLF use */
  KMNG_KeyRing_t*           keyRingStc_ptr;
  
  /* error */
  DxError_t                   error;
  
  /*------------------
      CODE
  ---------------------*/
  
  error = KMNG_OK;
  
  /* check input paramaters */
  if (passwordLength > KMNG_KEY_PASSWORD_MAX_LENGTH_IN_BYTES)
	  return DX_KMNG_KEY_PASSWORD_LENGTH_ERR;
  
  if( (password_ptr == DX_NULL) || (keyRing_ptr == DX_NULL) )
  {
    return DX_KMNG_INPUT_ARG_NULL_POINTER_ERROR;
  }

  /* allocate memory for the entry to be used by the LLF layer */
  keyRingStc_ptr = (KMNG_KeyRing_t*)keyRing_ptr;
  
  /* set key paramaters */
  keyDataParam.keyPassword_ptr = password_ptr;
  keyDataParam.keyPasswordLen = passwordLength;
  keyDataParam.encryptedKeyData_ptr = (DxUint8_t*)(keyRingStc_ptr->protectionKey.encryptedKeyBuffer);
  keyDataParam.encryptedKeyDataLength = KMNG_SYM_ENCR_KEY_BUFF_SIZE_IN_BYTES;

  /* set key configuration */
  keyConfiguration.type = KMNG_KeyTypeAES; 
  keyConfiguration.keySizeBytes = KMNG_AES_MAX_KEY_SIZE_IN_BYTES; /*256 Bits Key*/
  keyConfiguration.usage = KMNG_KEY_USAGE_STORAGE;
  keyConfiguration.restriction = KMNG_KEY_RESTRICTION_NON_EXPORTABLE;  /* instead PROTECTED.  May be other?? */
  
  /* create key */
  error = LLF_KMNG_CreateKeyRingKey(&keyDataParam , &keyConfiguration);
  if(error != KMNG_OK)
  {
    goto end_function;
  }
  
  /* set maximum keys */
  keyRingStc_ptr->maxSymKeysNum = numSymKeys;
  keyRingStc_ptr->maxRSAKeysNum = numRSAKeys;
  keyRingStc_ptr->maxDHKeysNum = numDHKeys;
  
  /* set active keys */
  keyRingStc_ptr->numActiveSymKeys = 0;
  keyRingStc_ptr->numActiveRSAKeys = 0;
  keyRingStc_ptr->numActiveDHKeys = 0;
  
  /* set start addresses of the keys */
  keyRingStc_ptr->startSymKeysAddr = (DxUint32_t)keyRing_ptr + sizeof(KMNG_KeyRing_t);
  keyRingStc_ptr->startRSAKeysAddr = keyRingStc_ptr->startSymKeysAddr + sizeof(KMNG_SYMKeyData_t) * numSymKeys;
  keyRingStc_ptr->startDHKeysAddr = keyRingStc_ptr->startRSAKeysAddr + sizeof(KMNG_RSAKeyData_t) * numRSAKeys;
  
  
  /* set key data */
  keyRingStc_ptr->protectionKey.generalData.validFlag = DX_KMNG_VALID_FLAG_VALUE;
  keyRingStc_ptr->protectionKey.generalData.keyDataLen =keyDataParam.encryptedKeyDataLength ;
  
  /* All pass ok -> update the Key Ring token to valid value */
  keyRingStc_ptr->ValidTag = KMNG_VALID_KEY_RING_TOKEN;

end_function:

  return error;
}



/**
 * @brief     This function returns the number of symmetric, RSA and DH keys in the key ring
 *
 *
 * @param[out] numSymKeys_ptr - number of symmetric keys  in the key ring
 * @param[out] numRSAKey_ptr - number of RSA keys  in the key ring
 * @param[out] numDHKeys_ptr - number of DH keys  in the key ring
 * @param[in] keyRing_ptr - key ring 
 * 
 * @return     DxError_t:  
 *                        
 */
DxError_t KMNG_GetKeyRingSize(DxUint32_t*  numSymKeys_ptr , 
                            DxUint32_t*  numRSAKeys_ptr,
                            DxUint32_t*  numDHKeys_ptr,
                            DxUint8_t*   keyRing_ptr)
{
  /* pointer to key ring struct */
  KMNG_KeyRing_t*           keyRingStc_ptr;
  
  /*------------------
      CODE
  ---------------------*/
  
  /* check parameters */
  if( (numSymKeys_ptr == DX_NULL) ||
      (numRSAKeys_ptr == DX_NULL) ||
      (numDHKeys_ptr == DX_NULL)  ||
      (keyRing_ptr == DX_NULL) )
  {
    return DX_KMNG_INPUT_ARG_NULL_POINTER_ERROR;
  }
  
  keyRingStc_ptr = (KMNG_KeyRing_t*)keyRing_ptr;
  
  /* check if the Key Ring is valid - check the ValidTag */
  if (keyRingStc_ptr->ValidTag != KMNG_VALID_KEY_RING_TOKEN)
  {
	return KMNG_KEY_RING_CORRUPTED_ERR;
  }

  /* set the data */
  *numSymKeys_ptr = keyRingStc_ptr->numActiveSymKeys;
  *numRSAKeys_ptr = keyRingStc_ptr->numActiveRSAKeys;
  *numDHKeys_ptr = keyRingStc_ptr->numActiveDHKeys;
  
  return KMNG_OK;
}
                                     

/**
 * @brief     This function returns the number of available entires symmetric, RSA and DH keys in the key ring
 *
 *
 * @param[out] numSymKeys_ptr - number of symmetric keys available entries in the key ring
 * @param[out] numRSAKey_ptr - number of RSA keys available entries in the key ring
 * @param[out] numDHKeys_ptr - number of DH keys available entries in the key ring
 * @param[in] keyRing_ptr - key ring 
 * 
 * @return     DxError_t:  
 *                        
 */
DxError_t KMNG_GetKeyRingCapacity(DxUint32_t*  numSymKeys_ptr , 
                                DxUint32_t*  numRSAKeys_ptr,
                                DxUint32_t*  numDHKeys_ptr,
                                DxUint8_t*   keyRing_ptr)
{
  /* pointer to key ring struct */
  KMNG_KeyRing_t*           keyRingStc_ptr;
  
  /*------------------
      CODE
  ---------------------*/
  
  /* check parameters */
  if( (numSymKeys_ptr == DX_NULL) ||
      (numRSAKeys_ptr == DX_NULL) ||
      (numDHKeys_ptr == DX_NULL)  ||
      (keyRing_ptr == DX_NULL) )
  {
    return DX_KMNG_INPUT_ARG_NULL_POINTER_ERROR;
  }
  
  keyRingStc_ptr = (KMNG_KeyRing_t*)keyRing_ptr;
  
  /* check if the Key Ring is valid - check the ValidTag */
  if (keyRingStc_ptr->ValidTag != KMNG_VALID_KEY_RING_TOKEN)
  {
	return KMNG_KEY_RING_CORRUPTED_ERR;
  }

  /* set the data */
  *numSymKeys_ptr = keyRingStc_ptr->maxSymKeysNum - keyRingStc_ptr->numActiveSymKeys;
  *numRSAKeys_ptr = keyRingStc_ptr->maxRSAKeysNum - keyRingStc_ptr->numActiveRSAKeys;
  *numDHKeys_ptr = keyRingStc_ptr->maxDHKeysNum - keyRingStc_ptr->numActiveDHKeys;
  
  return KMNG_OK;
}
   
/**
 * @brief     This function returns the ids of the  symmetric, RSA and DH keys in the key ring
 *
 *
 * @param[out] symKeyIds_ptr - number of symmetric keys available entries in the key ring
 * @param[out] rsaKeyIds_ptr - number of RSA keys available entries in the key ring
 * @param[out] dhKeyIds_ptr - number of DH keys available entries in the key ring
 * @param[in] keyRing_ptr - key ring 
 * 
 * @return     DxError_t:  
 *                        
 */
DxError_t KMNG_ListKeyIDs(DxUint32_t*  symKeyIds_ptr , 
                        DxUint32_t*  rsaKeyIds_ptr,
                        DxUint32_t*  dhKeyIds_ptr,
                        DxUint8_t*   keyRing_ptr)
{
  /* pointer to key ring struct */
  KMNG_KeyRing_t*           keyRingStc_ptr;
  
  /* counter */
  DxUint32_t                counter,index=0,Total=0;
  
  /* current pointer into the virtual key ring */
  DxUint32_t                *current_ptr;
  
  /*------------------
      CODE
  ---------------------*/
  
  /* check parameters */
  if( (symKeyIds_ptr == DX_NULL) ||
      (rsaKeyIds_ptr == DX_NULL) ||
      (dhKeyIds_ptr == DX_NULL)  ||
      (keyRing_ptr == DX_NULL) )
  {
    return DX_KMNG_INPUT_ARG_NULL_POINTER_ERROR;
  }
  
  keyRingStc_ptr = (KMNG_KeyRing_t*)keyRing_ptr;
  
  /* check if the Key Ring is valid - check the ValidTag */
  if (keyRingStc_ptr->ValidTag != KMNG_VALID_KEY_RING_TOKEN)
  {
	return KMNG_KEY_RING_CORRUPTED_ERR;
  }

  /* set current pointer */
  current_ptr = (DxUint32_t*)keyRingStc_ptr->startSymKeysAddr;
  
  /* get sym keys id */
  for(counter = 0; counter < keyRingStc_ptr->maxSymKeysNum; counter++)
  {
    
    if( ((KMNG_SYMKeyData_t*)current_ptr)->generalData.validFlag )
    {
      /* entry is valid get the id */
      symKeyIds_ptr[index++] = counter; 
	 
    } 

    current_ptr += (sizeof(KMNG_SYMKeyData_t)/sizeof(DxUint32_t));
  }
  Total=counter;
  index=0;
  
  /* set current pointer */
  current_ptr = (DxUint32_t*)keyRingStc_ptr->startRSAKeysAddr;
  
  /* get RSA keys id  */
  for(counter = 0; counter < keyRingStc_ptr->maxRSAKeysNum; counter++)
  {
    if( ((KMNG_RSAKeyData_t*)current_ptr)->generalData.validFlag )
    {
      /* entry is valid get the id */
      rsaKeyIds_ptr[index++] = Total+counter;
      
    }
    current_ptr += (sizeof(KMNG_RSAKeyData_t)/sizeof(DxUint32_t));
  }
  Total+=counter; 
  index=0;
  
  /* set current pointer */
  current_ptr = (DxUint32_t*)keyRingStc_ptr->startDHKeysAddr;
  
  /* get DH keys id  */
  for(counter = 0; counter < keyRingStc_ptr->maxDHKeysNum; counter++)
  {
    if( ((KMNG_DHKeyData_t*)current_ptr)->generalData.validFlag )
    {
      /* entry is valid get the id */
      dhKeyIds_ptr[index++] = Total+counter;      
    }
    
    current_ptr += (sizeof(KMNG_DHKeyData_t)/sizeof(DxUint32_t));
  }

  return KMNG_OK;
  
}
/**
 * @brief     This function creates a user key and inserts it into the keyRing
 *
 *
 * @param[in] keyRingPasswordAddr - address of the key ring password string
 * @param[in] keyRingPasswordLen - length of the key ring password
 * @param[in] userPasswordAddr - address of the new key password string
 * @param[in] userPasswordLen - length of the new key password
 * @param[in] keyType - type of the key
 * @param[in] keySize - size of the key in bytes
 * @param[in] keyUsage - usage of the key
 * @param[in] keyRestriction - restriction of the key
 * @param[in] UserSpecificKeyData - user specific data for key
 * @param[out] keyId_ptr - the returned id of the new key in the key ring
 * @param[in] keyRing_ptr - key ring 
 * 
 * @return     DxError_t:  
 *                        
 */
DxError_t KMNG_CreateUserKey(
                           DxUint8_t*                   keyRingPassword_ptr , 
                           DxUint32_t                   keyRingPasswordLen,
                           DxUint8_t*                   newKeyPassword_ptr , 
                           DxUint32_t                   newKeyPasswordLen,
                           KMNG_KeyType_t               keyType,
                           DxUint32_t                   keySize,
                           DxUint32_t                   keyUsage,
                           DxUint32_t                   keyRestriction,
                           KMNG_UserSpecificKeyData_t   UserSpecificKeyData,
                           DxUint32_t*                  keyId_ptr,
                           DxUint8_t*                   keyRing_ptr)
{
  /* paramaters for create key */
  KMNG_KeyDataParameter_t   keyRingDataParam;
  
  /* paramaters for create key */
  KMNG_KeyDataParameter_t   userKeyDataParam;
  
  /* configuration parameters */
  KMNG_KeyConfiguration_t   keyConfiguration;
  
  /* pointer to key ring key for the LLF use */
  KMNG_KeyRing_t*           keyRingStc_ptr;
  
  /* virtual slot pointer */
  DxUint8_t*                emptySlot_ptr;
  
  /* error */
  DxError_t                 error;
  
  DxUint32_t                encryptedKeyDataSize=0;

  /* key types group */
  KMNG_KeyTypeGroup_t       keyTypeGroup;

  /*------------------
      CODE
  ---------------------*/
  
  error = KMNG_OK;
  
  /* check paramaters */
  if( (keyRing_ptr == DX_NULL) ||
      (keyRingPassword_ptr == DX_NULL) ||
      (newKeyPassword_ptr == DX_NULL)  || 
      (keyId_ptr == DX_NULL)  )
  {
    return DX_KMNG_INPUT_ARG_NULL_POINTER_ERROR;
  }
  
  if( (keyRingPasswordLen > KMNG_KEY_PASSWORD_MAX_LENGTH_IN_BYTES) ||
      (newKeyPasswordLen > KMNG_KEY_PASSWORD_MAX_LENGTH_IN_BYTES) )
  {
    return DX_KMNG_KEY_PASSWORD_LENGTH_ERR;
  }
	  
  
  keyRingStc_ptr = (KMNG_KeyRing_t*)keyRing_ptr;
  
  /* check if the Key Ring is valid - check the ValidTag */
  if (keyRingStc_ptr->ValidTag != KMNG_VALID_KEY_RING_TOKEN)
  {
	return KMNG_KEY_RING_CORRUPTED_ERR;
  }
  

  /* set key group, check key type, usage and size */
  switch( keyType ) 
  {
  	case KMNG_KeyTypeAES:
  	    /* allowed sizes 16, 24, 32 bytes only */ 
  	    if( (keySize != 16) && (keySize != 24) && (keySize != 32) )  	    	
  	    	return DX_KMNG_INVALID_KEY_SIZE_ERR;
  	    
  	    /* set key group */
  	    keyTypeGroup = 	KMNG_SymmetricKey;  	    
  	    break;

  	    	
  	case KMNG_KeyTypeDES:
  	    /* allowed sizes 8, 16, 24 bytes only */
  	    if( (keySize != 8) && (keySize != 16) && (keySize != 24) )  	    	
  	    	return DX_KMNG_INVALID_KEY_SIZE_ERR;
 
  	    /* set key group  */
  	    keyTypeGroup = 	KMNG_SymmetricKey;  	    
  	    break;  	    
  	
  	case KMNG_KeyTypeHMAC:

 	    /* allowed size  < 64 bytes */
  	    if( keySize > 64 )  	    	
  	    	return DX_KMNG_INVALID_KEY_SIZE_ERR;
  	    
  	    /* restriction: allowed storage */
  	    
  	
  	    /* set key group */
  	    keyTypeGroup = 	KMNG_SymmetricKey;  	    
  	    break;
  	    
  	case KMNG_KeyTypeRSAPriv:
    case KMNG_KeyTypeRSAPub:
    case KMNG_KeyTypeRSAPair:
    
 	    /* allowed sizes  128, 256 bytes */
  	    if((keySize != 128) && (keySize != 256) )  	    	
  	    	return DX_KMNG_INVALID_KEY_SIZE_ERR;    
 
  	    keyTypeGroup = 	KMNG_RsaKey;
  	    break;
  	        
    case KMNG_KeyTypeDH:  

 	    /* allowed sizes  128, 256 bytes */
  	    if( (keySize != 128) && (keySize != 256) )  	    	
  	    	return DX_KMNG_INVALID_KEY_SIZE_ERR;    
    
        /* set key group  */
  	    keyTypeGroup = 	KMNG_DhKey;
  	    break; 
  	     
  	default:
  	
  		return  DX_KMNG_INVALID_KEY_TYPE_ERR;  	    
  }
  
  /* find empty slot for the key */
  error = KMNG_FindUserKeyEmptySlot(keyRing_ptr , keyTypeGroup , &emptySlot_ptr , keyId_ptr);
  if(error != KMNG_OK)
  {
    goto end_function;
  }
  
  /****** Update the Ring **********/
  
  /* set encryptedKeyDataSize */
  switch(keyTypeGroup)
  {
	case KMNG_SymmetricKey:/* symmetric key */
    
	  encryptedKeyDataSize = KMNG_SYM_ENCR_KEY_BUFF_SIZE_IN_BYTES;
      break;
      
    case KMNG_RsaKey:
      
	  encryptedKeyDataSize = KMNG_RSA_ENCR_KEY_BUFF_SIZE_IN_BYTES;
      break;
      
    case KMNG_DhKey:
      encryptedKeyDataSize = KMNG_DH_ENCR_KEY_BUFF_SIZE_IN_BYTES;
      break;
    default:
      break;
  }
  
  /* set key ring key paramaters */
  keyRingDataParam.keyPassword_ptr = keyRingPassword_ptr;
  keyRingDataParam.keyPasswordLen = keyRingPasswordLen;
  keyRingDataParam.encryptedKeyData_ptr = keyRingStc_ptr->protectionKey.encryptedKeyBuffer;
  keyRingDataParam.encryptedKeyDataLength = keyRingStc_ptr->protectionKey.generalData.keyDataLen;
  
  /* set user key paramaters */
  userKeyDataParam.keyPassword_ptr = newKeyPassword_ptr;
  userKeyDataParam.keyPasswordLen = newKeyPasswordLen;
  userKeyDataParam.encryptedKeyData_ptr = emptySlot_ptr + sizeof(KMNG_UserKeyGeneralData_t);
  userKeyDataParam.encryptedKeyDataLength = encryptedKeyDataSize;
  
  /* set key configuration */
  keyConfiguration.type = keyType;
  keyConfiguration.keySizeBytes = keySize;
  keyConfiguration.usage = keyUsage;
  keyConfiguration.restriction = keyRestriction;
  /* if UserSpecificKeyData is not NULL, then copy user specific data into configuration structure,
     else set it to 0  */
  if(UserSpecificKeyData != DX_NULL)
  {
	  keyConfiguration.UserSpecificKeyData[0] = UserSpecificKeyData[0];
	  keyConfiguration.UserSpecificKeyData[1] = UserSpecificKeyData[1];  	
  }
  
  else
  {
	  keyConfiguration.UserSpecificKeyData[0] = 0;
	  keyConfiguration.UserSpecificKeyData[1] = 0;  	
  	
  }
  
  /* create key */

	if(keyTypeGroup == KMNG_SymmetricKey)
	{
		error = LLF_KMNG_CreateUserSymKey(&keyRingDataParam , &userKeyDataParam ,
										&keyConfiguration);
	}

	else if( keyTypeGroup == KMNG_RsaKey ||
	         keyTypeGroup == KMNG_DhKey )
	{
		/* obtain the semaphore for the KeyGenData */
		error = DX_VOS_SemWait(SemaphoreKeyGenDataAccess, DX_INFINITE);
        if (error != DX_SUCCESS)
        {
            goto end_function;
        }
		error = LLF_KMNG_CreateUserAsymKey(&keyRingDataParam , &userKeyDataParam ,
											&keyConfiguration, &KeyGenData);
		
		/* release the semaphore */
		DX_VOS_SemGive(SemaphoreKeyGenDataAccess);
	}
	
  if(error != KMNG_OK)
  {
    goto end_function;
  }
   
  if (keyTypeGroup == KMNG_SymmetricKey)
      keyRingStc_ptr->numActiveSymKeys++;
  
  else if (keyTypeGroup == KMNG_RsaKey)
      keyRingStc_ptr->numActiveRSAKeys++;
  
  else if (keyTypeGroup == KMNG_DhKey)
      keyRingStc_ptr->numActiveDHKeys++;

/* error checked already */
  
  /* set key data */
  ((KMNG_UserKeyGeneralData_t*)emptySlot_ptr)->validFlag = DX_KMNG_VALID_FLAG_VALUE;
  ((KMNG_UserKeyGeneralData_t*)emptySlot_ptr)->keyDataLen = userKeyDataParam.encryptedKeyDataLength ;

end_function:

  return error;
}
                                    
                                    
/**
 * @brief     This function imports a symmetric key into key ring
 *
 *
 * @param[in] keyRingPasswordAddr - address of the key ring password string
 * @param[in] keyRingPasswordLen - length of the key ring password
 * @param[in] userPasswordAddr - address of the new key password string
 * @param[in] userPasswordLen - length of the new key password
 * @param[in] keyType - type of the key
 * @param[in] keySize - size of the key in bytes
 * @param[in] keyUsage - usage of the key
 * @param[in] keyRestriction - restriction of the key
 * @param[in] UserSpecificKeyData - user specific data for key 
 * @param[in] key - symmetric key itself
 * @param[out] keyId - the returned id of the new key in the key ring
 * @param[in] keyRing_ptr - key ring 
 * 
 * @return     DxError_t:  
 *                        
 */
DxError_t KMNG_ImportSymUserKey(DxUint8_t*                keyRingPassword_ptr , 
                              DxUint32_t                  keyRingPasswordLen,
                              DxUint8_t*                  newKeyPassword_ptr , 
                              DxUint32_t                  newKeyPasswordLen,
                              KMNG_KeyType_t              keyType,
                              DxUint32_t                  keySize,
                              DxUint32_t                  keyUsage,
                              DxUint32_t                  keyRestriction,
                              KMNG_UserSpecificKeyData_t  UserSpecificKeyData,
                              DxUint8_t*                  key_ptr,
                              DxUint32_t*                 keyId_ptr,
                              DxUint8_t*                  keyRing_ptr)
{
  /* paramaters for create key */
  KMNG_KeyDataParameter_t   keyRingDataParam;
  
  /* paramaters for create key */
  KMNG_KeyDataParameter_t   userKeyDataParam;
  
  /* configuration parameters */
  KMNG_KeyConfiguration_t   keyConfiguration;
  
  /* pointer to key ring key for the LLF use */
  KMNG_KeyRing_t*           keyRingStc_ptr;
  
  /* virtual slot pointer */
  DxUint8_t*                emptySlot_ptr;

  /* key types group */
  KMNG_KeyTypeGroup_t       keyTypeGroup;
  
  /* error */
  DxError_t                 error;
  
  /*------------------
      CODE
  ---------------------*/
  
  error = KMNG_OK;
  
  /* check paramaters */
  if( (keyRing_ptr == DX_NULL) ||
      (keyRingPassword_ptr == DX_NULL) ||
      (newKeyPassword_ptr == DX_NULL) || 
      (keyId_ptr == DX_NULL) ||
      (key_ptr == DX_NULL) )
  {
    return DX_KMNG_INPUT_ARG_NULL_POINTER_ERROR;
  }
  
    keyRingStc_ptr = (KMNG_KeyRing_t*)keyRing_ptr;
 
  /* check if the Key Ring is valid - check the ValidTag */
  if (keyRingStc_ptr->ValidTag != KMNG_VALID_KEY_RING_TOKEN)
  {
	return KMNG_KEY_RING_CORRUPTED_ERR;
  }

  if( (keyRingPasswordLen > KMNG_KEY_PASSWORD_MAX_LENGTH_IN_BYTES) ||
      (newKeyPasswordLen > KMNG_KEY_PASSWORD_MAX_LENGTH_IN_BYTES) )
  {
    return DX_KMNG_KEY_PASSWORD_LENGTH_ERR;
  }
  
  /* set key group, check key type, usage and size */
  switch( keyType ) 
  {
  	case KMNG_KeyTypeAES:
  	    /* allowed sizes 16, 24, 32 bytes only */ 
  	    if( (keySize != 16) && (keySize != 24) && (keySize != 32) )  	    	
  	    	return DX_KMNG_INVALID_KEY_SIZE_ERR;
  	    
  	    /* set key group */
  	    keyTypeGroup = 	KMNG_SymmetricKey;  	    
  	    break;

  	    	
  	case KMNG_KeyTypeDES:
  	    /* allowed sizes 8, 16, 24 bytes only */
  	    if( (keySize != 8) && (keySize != 16) && (keySize != 24) )  	    	
  	    	return DX_KMNG_INVALID_KEY_SIZE_ERR;
        
  	    /* set key group  */
  	    keyTypeGroup = 	KMNG_SymmetricKey;  	    
  	    break;  	    
  	
  	case KMNG_KeyTypeHMAC:

 	    /* allowed size  < 64 bytes */
  	    if( keySize > 64 )  	    	
  	    	return DX_KMNG_INVALID_KEY_SIZE_ERR;
  	    
 	    /* set key group */
  	    keyTypeGroup = 	KMNG_SymmetricKey;  	    
  	    break;
   	     
  	default:
  	
  		return  DX_KMNG_INVALID_KEY_TYPE_ERR;  	    
  }
  
 
   
  /* find empty slot */
  error = KMNG_FindUserKeyEmptySlot(keyRing_ptr , keyTypeGroup , &emptySlot_ptr , keyId_ptr);
  if(error != KMNG_OK)
  {
    goto end_function;
  }
  
  /* set key ring key paramaters */
  keyRingDataParam.keyPassword_ptr = keyRingPassword_ptr;
  keyRingDataParam.keyPasswordLen = keyRingPasswordLen;
  keyRingDataParam.encryptedKeyData_ptr = keyRingStc_ptr->protectionKey.encryptedKeyBuffer;

  /* key ring only Symmetric key - put the maximim length */
  keyRingDataParam.encryptedKeyDataLength = keyRingStc_ptr->protectionKey.generalData.keyDataLen;
  

  /* set user key paramaters */
  userKeyDataParam.keyPassword_ptr = newKeyPassword_ptr;
  userKeyDataParam.keyPasswordLen = newKeyPasswordLen;
  /* userKeyDataParam.keyId - will return from LLF layer */
  userKeyDataParam.encryptedKeyData_ptr = ((KMNG_SYMKeyData_t*)emptySlot_ptr)->encryptedKeyBuffer;
  userKeyDataParam.encryptedKeyDataLength = KMNG_SYM_ENCR_KEY_BUFF_SIZE_IN_BYTES;


  /* set key configuration */
  keyConfiguration.type = keyType;
  keyConfiguration.usage = keyUsage;
  keyConfiguration.keySizeBytes = keySize;  
  keyConfiguration.restriction = keyRestriction;
 
  /* if UserSpecificKeyData is not NULL, then copy user specific data into configuration structure,
     else set it to 0  */
  if(UserSpecificKeyData != DX_NULL)
  {
	  keyConfiguration.UserSpecificKeyData[0] = UserSpecificKeyData[0];
	  keyConfiguration.UserSpecificKeyData[1] = UserSpecificKeyData[1];  	
  }
  
  else
  {
	  keyConfiguration.UserSpecificKeyData[0] = 0;
	  keyConfiguration.UserSpecificKeyData[1] = 0;  	
  	
  }

  
  /* create key */
  error = LLF_KMNG_ImportSymUserKey(&keyRingDataParam ,
									&keyConfiguration ,
									&userKeyDataParam ,
									key_ptr);
  
  if(error != KMNG_OK)
  {
    goto end_function;
  }
  
  /* set key data */
  ((KMNG_SYMKeyData_t*)emptySlot_ptr)->generalData.validFlag = DX_KMNG_VALID_FLAG_VALUE;
  ((KMNG_SYMKeyData_t*)emptySlot_ptr)->generalData.keyDataLen =userKeyDataParam.encryptedKeyDataLength ;

 
  /* update the key ring data */
  keyRingStc_ptr->numActiveSymKeys++;
  
end_function:

  return error;
}
                                       
                                       
/**
 * @brief     This function imports a RSA key into key ring
 *
 *
 * @param[in] keyRingPassword_ptr - address of the key ring password string
 * @param[in] keyRingPasswordLen - length of the key ring password
 * @param[in] userPassword_ptr - address of the new key password string
 * @param[in] userPasswordLen - length of the new key password
 * @param[in] keyType - type of the key
 * @param[in] keySize - size of the key in bytes
 * @param[in] keyUsage - usage of the key
 * @param[in] keyRestriction - restriction of the key
 * @param[in] UserSpecificKeyData - user specific data for key  
 * @param[in] modulus_ptr - modulus pointer
 * @param[in] modulusSize - modulus size in bytes
 * @param[in] E_ptr - E pointer to public exponent
 * @param[in] E_Size - E size in bytes
 * @param[in] D_ptr - D pointer to private key
 * @param[in] D_Size - D size in bytes
 * @param[out] keyId - the returned id of the new key in the key ring
 * @param[in] keyRing_ptr - key ring 
 * 
 * @return     DxError_t:  
 *                        
 */
DxError_t KMNG_ImportRsaUserKey(DxUint8_t*               keyRingPassword_ptr , 
                             DxUint32_t                  keyRingPasswordLen,
                             DxUint8_t*                  newKeyPassword_ptr ,
                             DxUint32_t                  newKeyPasswordLen,
                             KMNG_KeyType_t              keyType,
                             DxUint32_t                  keySize,
                             DxUint32_t                  keyUsage,
                             DxUint32_t                  keyRestriction,
                             KMNG_UserSpecificKeyData_t  UserSpecificKeyData,
                             DxUint8_t*                  modulus_ptr,
                             DxUint32_t                  modulusSize,
                             DxUint8_t*                  E_ptr,
                             DxUint32_t                  E_Size,
                             DxUint8_t*                  D_ptr,
                             DxUint32_t                  D_Size,
                             DxUint32_t*                 keyId_ptr,
                             DxUint8_t*                  keyRing_ptr)
{
  /* paramaters for create key */
  KMNG_KeyDataParameter_t   keyRingDataParam;
  
  /* paramaters for create key */
  KMNG_KeyDataParameter_t   userKeyDataParam;
  
  /* configuration parameters */
  KMNG_KeyConfiguration_t   keyConfiguration;
  
  /* pointer to key ring key for the LLF use */
  KMNG_KeyRing_t*           keyRingStc_ptr;
  
  /* virtual slot pointer */
  DxUint8_t*                emptySlot_ptr;

  /* key types group */
  KMNG_KeyTypeGroup_t       keyTypeGroup;
  
  /* error */
  DxError_t                   error;
  
  /*------------------
      CODE
  ---------------------*/
  
  error = KMNG_OK;
  
  /* check paramaters */
  if( (keyRing_ptr == DX_NULL) ||
      (keyRingPassword_ptr == DX_NULL) ||
      (newKeyPassword_ptr == DX_NULL) || 
      (keyId_ptr == DX_NULL) ||
      (modulus_ptr == DX_NULL) || 
      (E_ptr == DX_NULL) ||
      (D_ptr == DX_NULL) )
  {
    return DX_KMNG_INPUT_ARG_NULL_POINTER_ERROR;
  }
  
   keyRingStc_ptr = (KMNG_KeyRing_t*)keyRing_ptr;  

   /* check if the Key Ring is valid - check the ValidTag */
  if (keyRingStc_ptr->ValidTag != KMNG_VALID_KEY_RING_TOKEN)
  {
	return KMNG_KEY_RING_CORRUPTED_ERR;
  }

  if( (keyRingPasswordLen > KMNG_KEY_PASSWORD_MAX_LENGTH_IN_BYTES) ||
      (newKeyPasswordLen > KMNG_KEY_PASSWORD_MAX_LENGTH_IN_BYTES) )
  {
    return DX_KMNG_KEY_PASSWORD_LENGTH_ERR;
  }
  
  /* check RSA key size:  allowed key sizes 128, 256 bytes */
  if( (keySize != 128) && (keySize != 256) )
  {
	return DX_KMNG_INVALID_KEY_SIZE_ERR;   	
  } 
  
  /* check RSA key modulus, D and E sizes */
  if( (modulusSize != keySize) ||
      (E_Size > modulusSize) ||
      (D_Size > modulusSize) )
  {
  	return DX_KMNG_INVALID_ASYM_KEY_COMPONENT_SIZE_ERR;  	
  }
  
  
  /* find key group for key type with its checking */
  error = KMNG_ConvertKeyTypeToGroup( keyType, &keyTypeGroup);  
  if(error != KMNG_OK)
  {
    goto end_function;
  }
  
  if(keyTypeGroup != KMNG_RsaKey)
  {
    return DX_KMNG_INVALID_KEY_TYPE_ERR;
  }
    

  
  /* find empty spot */
  error = KMNG_FindUserKeyEmptySlot(keyRing_ptr , keyTypeGroup , &emptySlot_ptr , keyId_ptr);  
  if(error != KMNG_OK)
  {
    goto end_function;
  }

  /* set key ring key paramaters */
  keyRingDataParam.keyPassword_ptr = keyRingPassword_ptr;
  keyRingDataParam.keyPasswordLen = keyRingPasswordLen;
  keyRingDataParam.encryptedKeyData_ptr = keyRingStc_ptr->protectionKey.encryptedKeyBuffer;
  /* key ring only Symmetric key - put the maximim length */
  keyRingDataParam.encryptedKeyDataLength = keyRingStc_ptr->protectionKey.generalData.keyDataLen;
  
  /* set user key paramaters */
  userKeyDataParam.keyPassword_ptr = newKeyPassword_ptr;
  userKeyDataParam.keyPasswordLen = newKeyPasswordLen;
  userKeyDataParam.encryptedKeyData_ptr = ((KMNG_RSAKeyData_t*)emptySlot_ptr)->encryptedKeyBuffer;
  userKeyDataParam.encryptedKeyDataLength = KMNG_RSA_ENCR_KEY_BUFF_SIZE_IN_BYTES;
  
  /* set key configuration */
  keyConfiguration.type = keyType;
  keyConfiguration.usage = keyUsage;
  keyConfiguration.keySizeBytes = keySize;  
  keyConfiguration.restriction = keyRestriction;
 
  /* if UserSpecificKeyData is not NULL, then copy user specific data into configuration structure,
     else set it to 0  */
  if(UserSpecificKeyData != DX_NULL)
  {
	  keyConfiguration.UserSpecificKeyData[0] = UserSpecificKeyData[0];
	  keyConfiguration.UserSpecificKeyData[1] = UserSpecificKeyData[1];  	
  }
  
  else
  {
	  keyConfiguration.UserSpecificKeyData[0] = 0;
	  keyConfiguration.UserSpecificKeyData[1] = 0;  	
  	
  }
  
  /* create key */
  error = LLF_KMNG_ImportRSAUserKey(&keyRingDataParam , 
                                    &keyConfiguration , 
                                    &userKeyDataParam , 
                                    modulus_ptr,
                                    modulusSize,
                                    E_ptr,
                                    E_Size,
                                    D_ptr,
                                    D_Size);
  if(error != KMNG_OK)
  {
    goto end_function;
  } 
  
  /* set user key general data */
  ((KMNG_RSAKeyData_t*)emptySlot_ptr)->generalData.validFlag = DX_KMNG_VALID_FLAG_VALUE;
  ((KMNG_RSAKeyData_t*)emptySlot_ptr)->generalData.keyDataLen =userKeyDataParam.encryptedKeyDataLength ;

  /* update the key ring data */
  keyRingStc_ptr->numActiveRSAKeys++;
  
end_function:

  return error;
}
                                       

/**
 * @brief     This function imports a DH key into key ring
 *
 *
 * @param[in] keyRingPassword_ptr - address of the key ring password string
 * @param[in] keyRingPasswordLen - length of the key ring password
 * @param[in] userPassword_ptr - address of the new key password string
 * @param[in] userPasswordLen - length of the new key password
 * @param[in] keyType - type of the key
 * @param[in] keySize - size of the key in bytes
 * @param[in] keySize - size of the key in bytes
 * @param[in] keyUsage - usage of the key
 * @param[in] keyRestriction - restriction of the key
 * @param[in] UserSpecificKeyData - user specific data for key  
 * @param[in] modulus_ptr - modulus pointer
 * @param[in] modulusSize - modulus size in bytes
 * @param[in] generator_ptr - generator pointer
 * @param[in] generatorSize - generator size in bytes
 * @param[in] E_ptr - pointer to public exponent E
 * @param[in] E_Size - E size in bytes
 * @param[in] D_ptr - D pointer to private key
 * @param[in] D_Size - D size in bytes
 * @param[out] keyId - the returned id of the new key in the key ring
 * @param[in] keyRing_ptr - key ring 
 * 
 * @return     DxError_t:  
 *                        
 */                                       
DxError_t KMNG_ImportDHUserKey(DxUint8_t*                keyRingPassword_ptr , 
                            DxUint32_t                   keyRingPasswordLen,
                            DxUint8_t*                   newKeyPassword_ptr ,
                            DxUint32_t                   newKeyPasswordLen,
                            KMNG_KeyType_t               keyType,
                            DxUint32_t                   keySize,
                            DxUint32_t                   keyUsage,
                            DxUint32_t                   keyRestriction,
                            KMNG_UserSpecificKeyData_t   UserSpecificKeyData,
                            DxUint8_t*                   prime_ptr,
                            DxUint32_t                   primeSize,
                            DxUint8_t*                   generator_ptr,
                            DxUint32_t                   generatorSize,
                            DxUint8_t*                   public_ptr,
                            DxUint32_t                   publicSize,
                            DxUint8_t*                   private_ptr,
                            DxUint32_t                   privateSize,
                            DxUint32_t*                  keyId_ptr,
                            DxUint8_t*                   keyRing_ptr)
{
  /* paramaters for create key */
  KMNG_KeyDataParameter_t   keyRingDataParam;
  
  /* paramaters for create key */
  KMNG_KeyDataParameter_t   userKeyDataParam;
  
  /* configuration parameters */
  KMNG_KeyConfiguration_t   keyConfiguration;
  
  /* pointer to key ring key for the LLF use */
  KMNG_KeyRing_t*           keyRingStc_ptr;
  
  /* virtual slot pointer */
  DxUint8_t*                emptySlot_ptr;

  /* key types group */
  KMNG_KeyTypeGroup_t       keyTypeGroup;
  
  /* error */
  DxError_t                   error;
  
  /*------------------
      CODE
  ---------------------*/
  
  error = KMNG_OK;
  
  /* check paramaters */
  if( (keyRing_ptr == DX_NULL) ||
      (keyRingPassword_ptr == DX_NULL) ||
      (newKeyPassword_ptr == DX_NULL) || 
      (keyId_ptr == DX_NULL) ||
      (prime_ptr == DX_NULL) || 
      (generator_ptr == DX_NULL) ||
      (public_ptr == DX_NULL) ||
      (private_ptr == DX_NULL) )
  {
    return DX_KMNG_INPUT_ARG_NULL_POINTER_ERROR;
  }
  
   keyRingStc_ptr = (KMNG_KeyRing_t*)keyRing_ptr;  

   /* check if the Key Ring is valid - check the ValidTag */
  if (keyRingStc_ptr->ValidTag != KMNG_VALID_KEY_RING_TOKEN)
  {
	return KMNG_KEY_RING_CORRUPTED_ERR;
  }

  if( (keyRingPasswordLen > KMNG_KEY_PASSWORD_MAX_LENGTH_IN_BYTES) ||
      (newKeyPasswordLen > KMNG_KEY_PASSWORD_MAX_LENGTH_IN_BYTES) )
  {
    return DX_KMNG_KEY_PASSWORD_LENGTH_ERR;
  }

  /* check DH key size:  allowed key sizes  128, 256 bytes */
  if( (keySize != 128) && (keySize != 256))
  {
	return DX_KMNG_INVALID_KEY_SIZE_ERR;   	
  } 

  /* check DH key modulus, D and E sizes */
  if( (primeSize != keySize) ||
      (publicSize > primeSize) ||
      (privateSize > primeSize) ||
      (generatorSize > primeSize) )
  {
  	return DX_KMNG_INVALID_ASYM_KEY_COMPONENT_SIZE_ERR;  	
  }

  /* check restriction */
  if( keyUsage != KMNG_KEY_USAGE_LEGACY )
  {
       return DX_KMNG_NON_ALLOWED_KEY_USAGE_ERR; 	
  }
  
  /* find key group for key type with its checking */
  error = KMNG_ConvertKeyTypeToGroup( keyType, &keyTypeGroup);  
  if(error != KMNG_OK)
  {
    goto end_function;
  }

  
  if(keyTypeGroup != KMNG_DhKey)
  {
    return DX_KMNG_INVALID_KEY_TYPE_ERR;
  } 
   
 
  
  /* find empty spot */
  error = KMNG_FindUserKeyEmptySlot(keyRing_ptr , keyTypeGroup , &emptySlot_ptr , keyId_ptr);
  if(error != KMNG_OK)
  {
    goto end_function;
  }
  
  /* set key ring key paramaters */
  keyRingDataParam.keyPassword_ptr = keyRingPassword_ptr;
  keyRingDataParam.keyPasswordLen = keyRingPasswordLen;
  keyRingDataParam.encryptedKeyData_ptr = keyRingStc_ptr->protectionKey.encryptedKeyBuffer;
  keyRingDataParam.encryptedKeyDataLength = keyRingStc_ptr->protectionKey.generalData.keyDataLen;
  
  /* set user key paramaters */
  userKeyDataParam.keyPassword_ptr = newKeyPassword_ptr;
  userKeyDataParam.keyPasswordLen = newKeyPasswordLen;
  userKeyDataParam.encryptedKeyData_ptr = ((KMNG_DHKeyData_t*)emptySlot_ptr)->encryptedKeyBuffer;
  userKeyDataParam.encryptedKeyDataLength = KMNG_DH_ENCR_KEY_BUFF_SIZE_IN_BYTES;  
  
  /* set key configuration */
  keyConfiguration.type = keyType;
  keyConfiguration.usage = keyUsage;
  keyConfiguration.keySizeBytes = keySize;  
  keyConfiguration.restriction = keyRestriction;

  /* if UserSpecificKeyData is not NULL, then copy user specific data into configuration structure,
     else set it to 0  */
  if(UserSpecificKeyData != DX_NULL)
  {
	  keyConfiguration.UserSpecificKeyData[0] = UserSpecificKeyData[0];
	  keyConfiguration.UserSpecificKeyData[1] = UserSpecificKeyData[1];  	
  }
  
  else
  {
	  keyConfiguration.UserSpecificKeyData[0] = 0;
	  keyConfiguration.UserSpecificKeyData[1] = 0;  	
  	
  }
  
  /* create key */
  error = LLF_KMNG_ImportDHUserKey(&keyRingDataParam , 
                                   &keyConfiguration , 
                                   &userKeyDataParam , 
                                   prime_ptr,
                                   primeSize,
                                   generator_ptr,
                                   generatorSize,
                                   public_ptr,
                                   publicSize,
                                   private_ptr,
                                   privateSize);
  if(error != KMNG_OK)
  {
    goto end_function;
  }
  
  /* set user key general data */
  ((KMNG_DHKeyData_t*)emptySlot_ptr)->generalData.validFlag = DX_KMNG_VALID_FLAG_VALUE;
  ((KMNG_DHKeyData_t*)emptySlot_ptr)->generalData.keyDataLen =userKeyDataParam.encryptedKeyDataLength ;
 
  /* update the key ring data */
  keyRingStc_ptr->numActiveDHKeys++;
  
end_function:

  return error;
}


/**
 * @brief     This function exports a symmetric key from key ring
 *
 *
 * @param[in] keyRingPassword_ptr - address of the key ring password string
 * @param[in] keyRingPasswordLen - length of the key ring password
 * @param[in] userPassword_ptr - address of the new key password string
 * @param[in] userPasswordLen - length of the new key password
 * @param[in] keyId - the id of the exported key in the key ring
 * @param[out] key_ptr - symmetric key itself
 * @param[out] keyType_ptr - type of the key
 * @param[in]  keySize_ptr - size of the key in bytes
 * @param[out] keyUsage_ptr - usage of the key
 * @param[out] keyRestriction_ptr - restriction of the key
 * @param[in]  keyRing_ptr - key ring 
 * 
 * @return     DxError_t:  
 *                        
 */                                       
DxError_t KMNG_ExportSymUserKey(DxUint8_t*                keyRingPassword_ptr , 
                              DxUint32_t                  keyRingPasswordLen,
                              DxUint8_t*                  keyPassword_ptr , 
                              DxUint32_t                  keyPasswordLen,
                              DxUint32_t                  keyId,
                              DxUint8_t*                  key_ptr,
                              KMNG_KeyType_t*             keyType_ptr,
                              DxUint32_t*                 keySize_ptr,
                              DxUint32_t*                 keyUsage_ptr,
                              DxUint32_t*                 keyRestriction_ptr,
                              DxUint8_t*                  keyRing_ptr)
{
  /* paramaters for create key */
  KMNG_KeyDataParameter_t   keyRingDataParam;
  
  /* paramaters for create key */
  KMNG_KeyDataParameter_t   userKeyDataParam;
  
  /* configuration parameters */
  KMNG_KeyConfiguration_t   keyConfiguration;
  
  /* pointer to key ring */
  KMNG_KeyRing_t*           keyRingStc_ptr;
  
  /* virtual slot pointer */
  DxUint8_t*                keySlot_ptr;
  
  /* error */
  DxError_t                   error;
  /* Key Size [used as output]*/
  DxUint32_t                 KeySize = 0x0;;
  
  /*------------------
      CODE
  ---------------------*/
  
  error = KMNG_OK;
  
   /* check paramaters */
  if( (keyRing_ptr == DX_NULL) ||
      (keyRingPassword_ptr == DX_NULL) ||
      (keyPassword_ptr == DX_NULL) ||
      (key_ptr == DX_NULL) )
  {
    return DX_KMNG_INPUT_ARG_NULL_POINTER_ERROR;
  }
  
  keyRingStc_ptr = (KMNG_KeyRing_t*)keyRing_ptr;

  /* check if the Key Ring is valid - check the ValidTag */
  if (keyRingStc_ptr->ValidTag != KMNG_VALID_KEY_RING_TOKEN)
  {
	return KMNG_KEY_RING_CORRUPTED_ERR;
  }

  if( (keyRingPasswordLen > KMNG_KEY_PASSWORD_MAX_LENGTH_IN_BYTES) ||
      (keyPasswordLen > KMNG_KEY_PASSWORD_MAX_LENGTH_IN_BYTES) )
  {
    return DX_KMNG_KEY_PASSWORD_LENGTH_ERR;
  }
  
  
  
  /* find the key according to id */
  error = KMNG_FindKeyInKeyRing(keyRing_ptr , keyId , &keySlot_ptr);
  if(error != KMNG_OK)
  {
    goto end_function;
  }
  
  /* set key ring key paramaters */
  keyRingDataParam.keyPassword_ptr = keyRingPassword_ptr;
  keyRingDataParam.keyPasswordLen = keyRingPasswordLen;
  keyRingDataParam.encryptedKeyData_ptr = keyRingStc_ptr->protectionKey.encryptedKeyBuffer;
  keyRingDataParam.encryptedKeyDataLength = keyRingStc_ptr->protectionKey.generalData.keyDataLen;
  
  
  /* set user key paramaters */
  userKeyDataParam.keyPassword_ptr = keyPassword_ptr;
  userKeyDataParam.keyPasswordLen = keyPasswordLen;
  userKeyDataParam.encryptedKeyData_ptr = ((KMNG_SYMKeyData_t*)keySlot_ptr)->encryptedKeyBuffer;
  userKeyDataParam.encryptedKeyDataLength=((KMNG_SYMKeyData_t*)keySlot_ptr)->generalData.keyDataLen;

  /* export key */
  error = LLF_KMNG_ExportSymUserKey(&keyRingDataParam , 
                                    &keyConfiguration , 
                                    &userKeyDataParam , 
                                    key_ptr,
									&KeySize);
  
  /* set key configuration */
  *keyType_ptr = keyConfiguration.type;
  *keyUsage_ptr = keyConfiguration.usage;
  *keySize_ptr = keyConfiguration.keySizeBytes;  
  *keyRestriction_ptr = keyConfiguration.restriction;

  
end_function:

  return error;
}

/**
 * @brief     This function exports an RSA key from key ring
 *
 *
 * @param[in] keyRingPassword_ptr - address of the key ring password string
 * @param[in] keyRingPasswordLen - length of the key ring password
 * @param[in] userPassword_ptr - address of the new key password string
 * @param[in] userPasswordLen - length of the new key password
 * @param[in] keyId - the id of the exported key in the key ring
 * @param[in] modulus_ptr - modulus pointer
 * @param[in] modulusSize_ptr - modulus size
 * @param[in] N_ptr - N pointer
 * @param[in] N_Size_ptr - N size
 * @param[in] D_ptr - D pointer
 * @param[in] D_Size_ptr - D size
 * @param[in] keyRing_ptr - key ring 
 * 
 * @return     DxError_t:  
 *                        
 */                                           
DxError_t KMNG_ExportRSAUserKey(DxUint8_t*                     keyRingPassword_ptr , 
                                DxUint32_t                     keyRingPasswordLen,
                                DxUint8_t*                     keyPassword_ptr , 
                                DxUint32_t                     keyPasswordLen,
                                DxUint32_t                     keyId,
                                DxUint8_t*                     modulus_ptr,
                                DxUint32_t*                    modulusSize_ptr,
                                DxUint8_t*                     E_ptr,
                                DxUint32_t*                    E_Size_ptr,
                                DxUint8_t*                     D_ptr,
                                DxUint32_t*                    D_Size_ptr,
                                DxUint8_t*                     keyRing_ptr)
{
  /* paramaters for create key */
  KMNG_KeyDataParameter_t   keyRingDataParam;
  
  /* paramaters for create key */
  KMNG_KeyDataParameter_t   userKeyDataParam;
  
  /* configuration parameters */
  KMNG_KeyConfiguration_t   keyConfiguration;
  
  /* pointer to key ring */
  KMNG_KeyRing_t*           keyRingStc_ptr;
  
  /* virtual slot pointer */
  DxUint8_t*                keySlot_ptr;
  
  /* error */
  DxError_t                   error;
  
  /*------------------
      CODE
  ---------------------*/
  
  error = KMNG_OK;
  
  /* check paramaters */
  if( (keyRing_ptr == DX_NULL) ||
      (keyRingPassword_ptr == DX_NULL) ||
      (keyPassword_ptr == DX_NULL) ||
      (modulus_ptr == DX_NULL) || 
      (E_ptr == DX_NULL) ||
      (D_ptr == DX_NULL) )
  {
    return DX_KMNG_INPUT_ARG_NULL_POINTER_ERROR;
  }
  
  keyRingStc_ptr = (KMNG_KeyRing_t*)keyRing_ptr;

  /* check if the Key Ring is valid - check the ValidTag */
  if (keyRingStc_ptr->ValidTag != KMNG_VALID_KEY_RING_TOKEN)
  {
	return KMNG_KEY_RING_CORRUPTED_ERR;
  }

  if( (keyRingPasswordLen > KMNG_KEY_PASSWORD_MAX_LENGTH_IN_BYTES) ||
      (keyPasswordLen > KMNG_KEY_PASSWORD_MAX_LENGTH_IN_BYTES) )
  {
    return DX_KMNG_KEY_PASSWORD_LENGTH_ERR;
  }
  
  
  
  /* find the key according to id */
  error = KMNG_FindKeyInKeyRing(keyRing_ptr , keyId , &keySlot_ptr);
  if(error != KMNG_OK)
  {
    goto end_function;
  }
  
  /* set key ring key paramaters */
  keyRingDataParam.keyPassword_ptr = keyRingPassword_ptr;
  keyRingDataParam.keyPasswordLen = keyRingPasswordLen;
  keyRingDataParam.encryptedKeyData_ptr = keyRingStc_ptr->protectionKey.encryptedKeyBuffer;
  keyRingDataParam.encryptedKeyDataLength = keyRingStc_ptr->protectionKey.generalData.keyDataLen;
  
  /* set user Asy key paramaters */
  userKeyDataParam.keyPassword_ptr = keyPassword_ptr;
  userKeyDataParam.keyPasswordLen = keyPasswordLen;
  userKeyDataParam.encryptedKeyData_ptr = ((KMNG_RSAKeyData_t*)keySlot_ptr)->encryptedKeyBuffer;
  userKeyDataParam.encryptedKeyDataLength = ((KMNG_RSAKeyData_t*)keySlot_ptr)->generalData.keyDataLen;
 
  /* export key */
  error = LLF_KMNG_ExportRSAUserKey(&keyRingDataParam , 
                                    &keyConfiguration , 
                                    &userKeyDataParam , 
                                    modulus_ptr,
                                    modulusSize_ptr,
                                    E_ptr,
                                    E_Size_ptr,
                                    D_ptr,
                                    D_Size_ptr);
  
end_function:

  return error;
}

/**
 * @brief     This function exports an DH key from key ring
 *
 *
 * @param[in] keyRingPassword_ptr - address of the key ring password string
 * @param[in] keyRingPasswordLen - length of the key ring password
 * @param[in] userPassword_ptr - address of the new key password string
 * @param[in] userPasswordLen - length of the new key password
 * @param[in] keyId - the id of the exported key in the key ring
 * @param[in] modulus_ptr - modulus pointer
 * @param[in] modulusSize_ptr - modulus size
 * @param[in] generator_ptr - modulus pointer
 * @param[in] generatorSize_ptr - modulus size
 * @param[in] E_ptr - E pointer to public exponent
 * @param[in] E_Size_ptr - pointer to exponent size
 * @param[in] D_ptr - D pointer
 * @param[in] D_Size_ptr - D size
 * @param[in] keyRing_ptr - key ring 
 * 
 * @return     DxError_t:  
 *                        
 */                                           
DxError_t KMNG_ExportDHUserKey(
                            DxUint8_t*                     keyRingPassword_ptr , 
                            DxUint32_t                     keyRingPasswordLen,
                            DxUint8_t*                     keyPassword_ptr , 
                            DxUint32_t                     keyPasswordLen,
                            DxUint32_t                     keyId,
                            DxUint8_t*                     prime_ptr,
                            DxUint32_t*                    primeSize_ptr,
                            DxUint8_t*                     generator_ptr,
                            DxUint32_t*                    generatorSize_ptr,
                            DxUint8_t*                     public_ptr,
                            DxUint32_t*                    publicSize_ptr,
                            DxUint8_t*                     private_ptr,
                            DxUint32_t*                    privateSize_ptr,
                            DxUint8_t*                     keyRing_ptr)
{
  /* paramaters for export key */
  KMNG_KeyDataParameter_t   keyRingDataParam;
  
  /* paramaters for export key */
  KMNG_KeyDataParameter_t   userKeyDataParam;
  
  /* configuration parameters */
  KMNG_KeyConfiguration_t   keyConfiguration;
  
  /* pointer to key ring */
  KMNG_KeyRing_t*           keyRingStc_ptr;
  
  /* virtual slot pointer */
  DxUint8_t*                keySlot_ptr;
  
  /* error */
  DxError_t                   error;
  
  /*------------------
      CODE
  ---------------------*/
  
  error = KMNG_OK;
  
  /* check paramaters */
  if( (keyRing_ptr == DX_NULL) ||
      (keyRingPassword_ptr == DX_NULL) ||
      (keyPassword_ptr == DX_NULL) || 
      (prime_ptr == DX_NULL) || 
      (generator_ptr == DX_NULL) ||
      (public_ptr == DX_NULL) ||
      (private_ptr == DX_NULL))
  {
    return DX_KMNG_INPUT_ARG_NULL_POINTER_ERROR;
  }

  keyRingStc_ptr = (KMNG_KeyRing_t*)keyRing_ptr;

  /* check if the Key Ring is valid - check the ValidTag */
  if (keyRingStc_ptr->ValidTag != KMNG_VALID_KEY_RING_TOKEN)
  {
	return KMNG_KEY_RING_CORRUPTED_ERR;
  }

  if( (keyRingPasswordLen > KMNG_KEY_PASSWORD_MAX_LENGTH_IN_BYTES) ||
      (keyPasswordLen > KMNG_KEY_PASSWORD_MAX_LENGTH_IN_BYTES) )
  {
    return DX_KMNG_KEY_PASSWORD_LENGTH_ERR;
  }
  
  
  
  /* check if the Key Ring is valid - check the ValidTag */
  if (keyRingStc_ptr->ValidTag != KMNG_VALID_KEY_RING_TOKEN)
  {
	return KMNG_KEY_RING_CORRUPTED_ERR;
  }

  /* find the key according to id */
  error = KMNG_FindKeyInKeyRing(keyRing_ptr , keyId , &keySlot_ptr);
  if(error != KMNG_OK)
  {
    goto end_function;
  }
  
  /* set key ring key paramaters */
  keyRingDataParam.keyPassword_ptr = keyRingPassword_ptr;
  keyRingDataParam.keyPasswordLen = keyRingPasswordLen;
  keyRingDataParam.encryptedKeyData_ptr = keyRingStc_ptr->protectionKey.encryptedKeyBuffer;
  keyRingDataParam.encryptedKeyDataLength = keyRingStc_ptr->protectionKey.generalData.keyDataLen;
  
  /* set user key paramaters */
  userKeyDataParam.keyPassword_ptr = keyPassword_ptr;
  userKeyDataParam.keyPasswordLen = keyPasswordLen;
  userKeyDataParam.encryptedKeyData_ptr = ((KMNG_DHKeyData_t*)keySlot_ptr)->encryptedKeyBuffer;
  userKeyDataParam.encryptedKeyDataLength = ((KMNG_DHKeyData_t*)keySlot_ptr)->generalData.keyDataLen;
  
  /* export key */
  error = LLF_KMNG_ExportDHUserKey(&keyRingDataParam , 
                                   &keyConfiguration , 
                                   &userKeyDataParam , 
                                   prime_ptr,
                                   primeSize_ptr,
                                   generator_ptr,
                                   generatorSize_ptr,
                                   public_ptr,
                                   publicSize_ptr,
                                   private_ptr,
                                   privateSize_ptr);

  
end_function:

  return error;
}


/**
 * @brief     This function get the public DH key data from key ring
 *
 *
 * @param[in] keyRingPassword_ptr - address of the key ring password string
 * @param[in] keyRingPasswordLen - length of the key ring password
 * @param[in] userPassword_ptr - address of the new key password string
 * @param[in] userPasswordLen - length of the new key password
 * @param[in] keyId - the id of the exported key in the key ring
 * @param[in] modulus_ptr - modulus pointer
 * @param[in] modulusSize_ptr - modulus size
 * @param[in] generator_ptr - modulus pointer
 * @param[in] generatorSize_ptr - modulus size
 * @param[in] E_ptr - E pointer to public exponent
 * @param[in] E_Size_ptr - pointer to exponent size
 * @param[in] keyRing_ptr - key ring 
 * 
 * @return     DxError_t:  
 *                        
 */                                           
DxError_t KMNG_GetDHPublicKey(DxUint8_t*                     keyRingPassword_ptr , 
							                DxUint32_t                     keyRingPasswordLen,
                              DxUint8_t*                     keyPassword_ptr , 
                              DxUint32_t                     keyPasswordLen,
                              DxUint32_t                     keyId,
                              DxUint8_t*                     prime_ptr,
                              DxUint32_t*                    primeSize_ptr,
                              DxUint8_t*                     generator_ptr,
                              DxUint32_t*                    generatorSize_ptr,
                              DxUint8_t*                     public_ptr,
                              DxUint32_t*                    publicSize_ptr,
                              DxUint8_t*                     keyRing_ptr)
{
  /* paramaters for export key */
  KMNG_KeyDataParameter_t   keyRingDataParam;
  
  /* paramaters for export key */
  KMNG_KeyDataParameter_t   userKeyDataParam;
  
  /* configuration parameters */
  KMNG_KeyConfiguration_t   keyConfiguration;
  
  /* pointer to key ring */
  KMNG_KeyRing_t*           keyRingStc_ptr;
  
  /* virtual slot pointer */
  DxUint8_t*                keySlot_ptr;
  
  /* error */
  DxError_t					error;
  
  /*------------------
      CODE
  ---------------------*/
  
  error = KMNG_OK;
  
  /* check paramaters */
  if( (keyRing_ptr == DX_NULL) ||
      (keyRingPassword_ptr == DX_NULL) ||
      (keyPassword_ptr == DX_NULL) || 
      (prime_ptr == DX_NULL) || 
      (generator_ptr == DX_NULL) ||
      (public_ptr == DX_NULL))
  {
    return DX_KMNG_INPUT_ARG_NULL_POINTER_ERROR;
  }

  keyRingStc_ptr = (KMNG_KeyRing_t*)keyRing_ptr;

  /* check if the Key Ring is valid - check the ValidTag */
  if (keyRingStc_ptr->ValidTag != KMNG_VALID_KEY_RING_TOKEN)
  {
	return KMNG_KEY_RING_CORRUPTED_ERR;
  }

  if( (keyRingPasswordLen > KMNG_KEY_PASSWORD_MAX_LENGTH_IN_BYTES) ||
      (keyPasswordLen > KMNG_KEY_PASSWORD_MAX_LENGTH_IN_BYTES) )
  {
    return DX_KMNG_KEY_PASSWORD_LENGTH_ERR;
  }
  
  
  
  /* check if the Key Ring is valid - check the ValidTag */
  if (keyRingStc_ptr->ValidTag != KMNG_VALID_KEY_RING_TOKEN)
  {
	return KMNG_KEY_RING_CORRUPTED_ERR;
  }

  /* find the key according to id */
  error = KMNG_FindKeyInKeyRing(keyRing_ptr , keyId , &keySlot_ptr);
  if(error != KMNG_OK)
  {
    goto end_function;
  }
  
  /* set key ring key paramaters */
  keyRingDataParam.keyPassword_ptr = keyRingPassword_ptr;
  keyRingDataParam.keyPasswordLen = keyRingPasswordLen;
  keyRingDataParam.encryptedKeyData_ptr = keyRingStc_ptr->protectionKey.encryptedKeyBuffer;
  keyRingDataParam.encryptedKeyDataLength = keyRingStc_ptr->protectionKey.generalData.keyDataLen;

  /* set user key paramaters */
  userKeyDataParam.keyPassword_ptr = keyPassword_ptr;
  userKeyDataParam.keyPasswordLen = keyPasswordLen;
  userKeyDataParam.encryptedKeyData_ptr = ((KMNG_DHKeyData_t*)keySlot_ptr)->encryptedKeyBuffer;
  userKeyDataParam.encryptedKeyDataLength = ((KMNG_DHKeyData_t*)keySlot_ptr)->generalData.keyDataLen;
  
  /* export key */
  error = LLF_KMNG_ReadDHUserKey(&keyRingDataParam , 
                                 &keyConfiguration , 
                                 &userKeyDataParam , 
                                 prime_ptr,
                                 primeSize_ptr,
                                 generator_ptr,
                                 generatorSize_ptr,
                                 public_ptr,
                                 publicSize_ptr);

  
end_function:

  return error;
}
                                       
/**
 * @brief     This function deletes a key from key ring
 *
 *
 * @param[in] keyRingPassword_ptr - address of the key ring password string
 * @param[in] keyRingPasswordLen - length of the key ring password
 * @param[in] userPassword_ptr - address of the key password string
 * @param[in] userPasswordLen - length of the key password
 * @param[in] keyId - the id of the key in the key ring
 * @param[in] keyRing_ptr - key ring 
 * 
 * @return     DxError_t:  
 *                        
 */                                          
DxError_t KMNG_DeleteKey(
                      DxUint8_t*      keyRingPassword_ptr , 
                      DxUint32_t      keyRingPasswordLen,
                      DxUint8_t*      keyPassword_ptr , 
                      DxUint32_t      keyPasswordLen,
                      DxUint32_t      keyId,
                      DxUint8_t*      keyRing_ptr)
{
  /* paramaters for export key */
  KMNG_KeyDataParameter_t   keyRingDataParam;
  
  /* paramaters for export key */
  KMNG_KeyDataParameter_t   userKeyDataParam;
  
  /* pointer to key ring */
  KMNG_KeyRing_t*           keyRingStc_ptr;
  
  /* virtual slot pointer */
  DxUint8_t*                keySlot_ptr;
  
  /* group of key types */
  KMNG_KeyTypeGroup_t 		keyTypeGroup;

  /* error */
  DxError_t                 error;
  
  /*------------------
      CODE
  ---------------------*/
  
  error = KMNG_OK;
  
  /* check paramaters */
  if( (keyRing_ptr == DX_NULL) ||
      (keyRingPassword_ptr == DX_NULL) ||
      (keyPassword_ptr == DX_NULL) )
  {
    return DX_KMNG_INPUT_ARG_NULL_POINTER_ERROR;
  }
  
  keyRingStc_ptr = (KMNG_KeyRing_t*)keyRing_ptr;

  /* check if the Key Ring is valid - check the ValidTag */
  if (keyRingStc_ptr->ValidTag != KMNG_VALID_KEY_RING_TOKEN)
  {
	return KMNG_KEY_RING_CORRUPTED_ERR;
  }

  if( (keyRingPasswordLen > KMNG_KEY_PASSWORD_MAX_LENGTH_IN_BYTES) ||
      (keyPasswordLen > KMNG_KEY_PASSWORD_MAX_LENGTH_IN_BYTES) )
  {
    return DX_KMNG_KEY_PASSWORD_LENGTH_ERR;
  }
  
  
  
  /* find the key according to id */
  error = KMNG_FindKeyAndItsGroupInKeyRing(keyRing_ptr , keyId , &keySlot_ptr, &keyTypeGroup, DX_NULL);

  if(error != KMNG_OK)
  {
    goto end_function;
  }
  
  /* set key ring key paramaters */
  keyRingDataParam.keyPassword_ptr = keyRingPassword_ptr;
  keyRingDataParam.keyPasswordLen = keyRingPasswordLen;
  keyRingDataParam.encryptedKeyData_ptr = keyRingStc_ptr->protectionKey.encryptedKeyBuffer;
  keyRingDataParam.encryptedKeyDataLength = keyRingStc_ptr->protectionKey.generalData.keyDataLen;
  
  /* set user key paramaters */
  userKeyDataParam.keyPassword_ptr = keyPassword_ptr;
  userKeyDataParam.keyPasswordLen = keyPasswordLen;
  userKeyDataParam.encryptedKeyData_ptr = keySlot_ptr + sizeof(KMNG_UserKeyGeneralData_t);
  userKeyDataParam.encryptedKeyDataLength=((KMNG_SYMKeyData_t*)keySlot_ptr)->generalData.keyDataLen;

  /* export key */
  error = LLF_KMNG_AuthorizeKey(&keyRingDataParam,
                                &userKeyDataParam);
                                
  if(error != KMNG_OK)
  {
    goto end_function;
  }

 
  /* which key to delete */
  switch(keyTypeGroup)
  {
	case KMNG_SymmetricKey:
   
      /* symmetric key */
      keyRingStc_ptr->numActiveSymKeys--;	  
      break;
      
    case KMNG_RsaKey:
      
      /* RSA key */
      keyRingStc_ptr->numActiveRSAKeys--;	  
      break;
      
    case KMNG_DhKey:
      
      /* DH key */
      keyRingStc_ptr->numActiveDHKeys--;
      break;
      
    default:
      error = DX_KMNG_INVALID_KEY_TYPE_ERR;
      goto end_function;
  }
 
   /* set the key as invalid */
  ((KMNG_UserKeyGeneralData_t*)keySlot_ptr)->validFlag = 0;
  
  
end_function:

  return error;
} 

                                       
                                       
/**
 * @brief     This function transfers key from one key ring into another (actually decrypts it and then enctypts it with destination key ring key).
 *
 * @param[in] srcKeyRingPassword_ptr - password of the source key ring
 * @param[in] srcKeyRingPasswordLen - length of the password of the source key ring
 * @param[in] srcKeyPassword_ptr - password of the source key 
 * @param[in] srcKeyPasswordLen - length of the password of the source key
 * @param[in] dstKeyRingPassword_ptr - password of the destination key ring
 * @param[in] dstKeyRingPasswordLen - length of the password of the destination key ring
 * @param[in] dstKeyPassword_ptr - password of the destination key 
 * @param[in] dstKeyPasswordLen - length of the password of the destination key 
 * @param[in] srcKeyId - source key id
 * @param[out] dstKeyId_ptr - key id in the new key ring
 * @param[in] srcKeyRing_ptr -source key ring
 * @param[in] dstKeyRing_ptr - destination key ring
 *
 * @return     DxError_t:  
 *                        
 */                                
DxError_t KMNG_TransferKey(DxUint8_t*      srcKeyRingPassword_ptr , 
                           DxUint32_t      srcKeyRingPasswordLen,
                           DxUint8_t*      srcKeyPassword_ptr , 
                           DxUint32_t      srcKeyPasswordLen,
                           DxUint8_t*      dstKeyRingPassword_ptr , 
                           DxUint32_t      dstKeyRingPasswordLen,
                           DxUint8_t*      dstKeyPassword_ptr , 
                           DxUint32_t      dstKeyPasswordLen,
                           DxUint32_t      srcKeyId,
                           DxUint32_t*     dstKeyId_ptr,
                           DxUint8_t*      srcKeyRing_ptr,
                           DxUint8_t*      dstKeyRing_ptr)
{
  /* paramaters for source key ring */
  KMNG_KeyDataParameter_t   srcKeyRingDataParam;
  
  /* paramaters for destination key ring */
  KMNG_KeyDataParameter_t   dstKeyRingDataParam;
  
  /* paramaters for source key */
  KMNG_KeyDataParameter_t   srcKeyDataParam;
  
  /* paramaters for destination key */
  KMNG_KeyDataParameter_t   dstKeyDataParam;
  
  /* pointer to source key ring */
  KMNG_KeyRing_t*           keyRingSRC_ptr;
  
  /* pointer to destination key ring */
  KMNG_KeyRing_t*           keyRingDST_ptr;
  
  /* source key slot pointer */
  DxUint8_t*                srcKeySlot_ptr;
  
  /* destiantion key  slot pointer */
  DxUint8_t*                dstKeySlot_ptr;
  
  /* source key type flag */
  KMNG_KeyTypeGroup_t		srcKeyTypeGroup;
  
  /* error */
  DxError_t                   error;
  
  /*------------------
      CODE
  ---------------------*/
  
  error = KMNG_OK;
  
  /* check paramaters */
  if( (srcKeyRing_ptr == DX_NULL) ||
      (dstKeyRing_ptr == DX_NULL) ||
      (srcKeyRingPassword_ptr == DX_NULL) ||
      (srcKeyPassword_ptr == DX_NULL) ||
      (dstKeyRingPassword_ptr == DX_NULL) ||
      (dstKeyPassword_ptr == DX_NULL) ||
      (dstKeyId_ptr == DX_NULL) )
  {
    return DX_KMNG_INPUT_ARG_NULL_POINTER_ERROR;
  }
  
  keyRingSRC_ptr = (KMNG_KeyRing_t*)srcKeyRing_ptr;
  keyRingDST_ptr = (KMNG_KeyRing_t*)dstKeyRing_ptr;
  
   /* check if the Key Ring is valid - check the ValidTag */
  if ((keyRingSRC_ptr->ValidTag != KMNG_VALID_KEY_RING_TOKEN) ||
	  (keyRingDST_ptr->ValidTag != KMNG_VALID_KEY_RING_TOKEN) )
  {
	return KMNG_KEY_RING_CORRUPTED_ERR;
  }

  if( (srcKeyRingPasswordLen > KMNG_KEY_PASSWORD_MAX_LENGTH_IN_BYTES) ||
      (srcKeyPasswordLen > KMNG_KEY_PASSWORD_MAX_LENGTH_IN_BYTES) ||
      (dstKeyRingPasswordLen > KMNG_KEY_PASSWORD_MAX_LENGTH_IN_BYTES) ||
      (dstKeyPasswordLen > KMNG_KEY_PASSWORD_MAX_LENGTH_IN_BYTES) )
  {
    return DX_KMNG_KEY_PASSWORD_LENGTH_ERR;
  }
  
 
  /* find the key according to id */
  error = KMNG_FindKeyAndItsGroupInKeyRing(srcKeyRing_ptr , srcKeyId , &srcKeySlot_ptr, &srcKeyTypeGroup, DX_NULL);
  if(error != KMNG_OK)
  {
    goto end_function;
  }
  
  /* check if there is a place in the key ring */
  error = KMNG_FindUserKeyEmptySlot(dstKeyRing_ptr , srcKeyTypeGroup , &dstKeySlot_ptr , dstKeyId_ptr);
  if(error != KMNG_OK)
  {
    goto end_function;
  }
 
  if ( srcKeyTypeGroup >= KMNG_OffModeKey )
  { 
      error = DX_KMNG_INVALID_KEY_TYPE_ERR;
      goto end_function;
  } 
  
  /* set source key ring key paramaters */
  srcKeyRingDataParam.keyPassword_ptr = srcKeyRingPassword_ptr;
  srcKeyRingDataParam.keyPasswordLen = srcKeyRingPasswordLen;
  srcKeyRingDataParam.encryptedKeyData_ptr = keyRingSRC_ptr->protectionKey.encryptedKeyBuffer;
  srcKeyRingDataParam.encryptedKeyDataLength = keyRingSRC_ptr->protectionKey.generalData.keyDataLen;
  
  /* set destination key ring key paramaters */
  dstKeyRingDataParam.keyPassword_ptr = dstKeyRingPassword_ptr;
  dstKeyRingDataParam.keyPasswordLen = dstKeyRingPasswordLen;
  dstKeyRingDataParam.encryptedKeyData_ptr = keyRingDST_ptr->protectionKey.encryptedKeyBuffer;
  dstKeyRingDataParam.encryptedKeyDataLength = keyRingDST_ptr->protectionKey.generalData.keyDataLen;
  
  /* set source user key paramaters */
  srcKeyDataParam.keyPassword_ptr = srcKeyPassword_ptr;
  srcKeyDataParam.keyPasswordLen = srcKeyPasswordLen;
  srcKeyDataParam.encryptedKeyData_ptr = srcKeySlot_ptr + sizeof(KMNG_UserKeyGeneralData_t);
  srcKeyDataParam.encryptedKeyDataLength=((KMNG_SYMKeyData_t*)srcKeySlot_ptr)->generalData.keyDataLen;

  dstKeyDataParam.keyPassword_ptr = dstKeyPassword_ptr;
  dstKeyDataParam.keyPasswordLen = dstKeyPasswordLen;
  dstKeyDataParam.encryptedKeyData_ptr = dstKeySlot_ptr + sizeof(KMNG_UserKeyGeneralData_t);
  dstKeyDataParam.encryptedKeyDataLength=srcKeyDataParam.encryptedKeyDataLength;

  /* transfer the key */
  error = LLF_KMNG_TransferKey(&srcKeyRingDataParam,
                               &srcKeyDataParam,
                               &dstKeyRingDataParam,
                               &dstKeyDataParam);                                
  if(error != KMNG_OK)
  {
    goto end_function;
  }

  /* set the destination key genearl data */
  *((KMNG_UserKeyGeneralData_t*)dstKeySlot_ptr) = *((KMNG_UserKeyGeneralData_t*)srcKeySlot_ptr);  

  /* set the source key as invalid */
  ((KMNG_UserKeyGeneralData_t*)srcKeySlot_ptr)->validFlag = 0;

  /* update key ring data */
  switch( srcKeyTypeGroup )
  {
  	case KMNG_SymmetricKey:
  	
  		keyRingSRC_ptr->numActiveSymKeys--;
		keyRingDST_ptr->numActiveSymKeys++;
		break;
		
  	case KMNG_RsaKey:
  
		keyRingSRC_ptr->numActiveRSAKeys--;
		keyRingDST_ptr->numActiveRSAKeys++;
		break;
		
  	case KMNG_DhKey:		

		keyRingSRC_ptr->numActiveDHKeys--;
		keyRingDST_ptr->numActiveDHKeys++;
		break; 
     default:
        break;
  }
   
end_function:

  return error;
}
                                

/**
 * @brief    This function calculates the size of the buffer needed for storing the key ring
 *			 on flash
 *
 * @param[in] keyRing_ptr - key ring
 * @param[out] bufferSize_ptr - the size of the buffer
 *
 * @return     DxError_t:  
 *                        
 */                                
DxError_t KMNG_GetFlashBufferSize(DxUint8_t*   keyRing_ptr,
                                  DxUint32_t*  bufferSize_ptr)
{
  /* DECLARATIONS */
  
  /* pointer to key ring key for the LLF use */
  KMNG_KeyRing_t*           keyRingStc_ptr;
  
  DxUint32_t TempSize,PadSizeBytes;

  
  /* FUNCTION LOGIC */   

  if ( bufferSize_ptr == DX_NULL || keyRing_ptr == DX_NULL)
  {
     return DX_KMNG_INPUT_ARG_NULL_POINTER_ERROR;
  }
 
  keyRingStc_ptr = (KMNG_KeyRing_t*)keyRing_ptr;

  /* check if the Key Ring is valid - check the ValidTag */
  if (keyRingStc_ptr->ValidTag != KMNG_VALID_KEY_RING_TOKEN)
  {
	return KMNG_KEY_RING_CORRUPTED_ERR;
  }

  /* calculate size of the buffer for key ring */
  TempSize = sizeof(KMNG_SYMKeyData_t) * (keyRingStc_ptr->maxSymKeysNum) +
             sizeof(KMNG_RSAKeyData_t) * (keyRingStc_ptr->maxRSAKeysNum) +
             sizeof(KMNG_DHKeyData_t) * (keyRingStc_ptr->maxDHKeysNum) +
             sizeof(KMNG_KeyRing_t);

  /* calculate the padded bytes that needed for the CRYS_AES MAC operation */
   PadSizeBytes=(TempSize % CRYS_AES_BLOCK_SIZE_IN_BYTES);

  /* The size of the output buffer should be : 
	 TempSize = the Ring size
   + PadSizeBytes = padding for the CRYS AES MAC operation
   + CRYS_AES_BLOCK_SIZE_IN_BYTES = space for the MAC itself */
   *bufferSize_ptr = (TempSize + (CRYS_AES_BLOCK_SIZE_IN_BYTES-PadSizeBytes) + CRYS_AES_BLOCK_SIZE_IN_BYTES);
                
   return KMNG_OK;
}
 
/**
 * @brief    This function calculates the size of the buffer needed for storing the key ring
 *			 on flash.
 *			 TThe calculation is done according to the number of SymKeys, DHKeys and RSAKeys recived.
 *
 * @param[in] numSymKeys - number of symmetric keys in the key ring
 * @param[in] numSymKeys - number of RSA keys in the key ring
 * @param[in] numSymKeys - number of DH keys in the key ring
 * @param[out] bufferSize_ptr - the size of the buffer
 *
 * @return     DxError_t:  
 *                        
 */                                
DxError_t KMNG_CalcFlashBufferSize( DxUint32_t numSymKeys,
											   DxUint32_t numRSAKeys,
											   DxUint32_t numDHKeys,
											   DxUint32_t *bufferSize_ptr)

{
  /* DECLARATIONS */
  
   
  DxUint32_t TempSize,PadSizeBytes;

  
  /* FUNCTION LOGIC */   

  if ( bufferSize_ptr == DX_NULL )
  {
     return DX_KMNG_INPUT_ARG_NULL_POINTER_ERROR;
  }
 

  /* calculate size of the buffer for key ring */
  TempSize = sizeof(KMNG_SYMKeyData_t) * numSymKeys +
             sizeof(KMNG_RSAKeyData_t) * numRSAKeys +
             sizeof(KMNG_DHKeyData_t)  * numDHKeys  +
             sizeof(KMNG_KeyRing_t);

  /* calculate the padded bytes that needed for the CRYS_AES MAC operation */
   PadSizeBytes=(TempSize % CRYS_AES_BLOCK_SIZE_IN_BYTES);

  /* The size of the output buffer should be : 
	 TempSize = the Ring size
   + PadSizeBytes = padding for the CRYS AES MAC operation
   + CRYS_AES_BLOCK_SIZE_IN_BYTES = space for the MAC itself */
   *bufferSize_ptr = (TempSize + (CRYS_AES_BLOCK_SIZE_IN_BYTES-PadSizeBytes) + CRYS_AES_BLOCK_SIZE_IN_BYTES);
                
   return KMNG_OK;
}
 
/**
 * @brief     This function stores the key ring into memory buffer
 *
 * @param[in] keyRing_ptr - key ring
 * @param[in] buffer_ptr - memory buffer
 *
 * @return     DxError_t:  
 *                        
 */                                
DxError_t KMNG_SaveKeyRingToBuffer(DxUint8_t*    keyRing_ptr,
                									 DxUint8_t*    buffer_ptr,
                									 DxUint32_t    bufferSize)
{

	 /* paramaters for create key */
	KMNG_KeyDataParameter_t   keyRingDataParam;
  
	/* pointer to key ring key for the LLF use */
	KMNG_KeyRing_t*           keyRingStc_ptr;
 
	/* Temporary buffer for the MAC */
	DxUint8_t MacBuffer_ptr[CRYS_AES_BLOCK_SIZE_IN_BYTES];

	DxUint32_t error;
	
	/*------------------------
	  CODE
	---------------------------*/
	
	if ((buffer_ptr == DX_NULL) || (keyRing_ptr == DX_NULL))
	{
	  return DX_KMNG_INPUT_ARG_NULL_POINTER_ERROR;
	}	

	/* set the key ring key paramaters */
	keyRingStc_ptr = (KMNG_KeyRing_t*)keyRing_ptr;	

	/* check if the Key Ring is valid - check the ValidTag */
	if (keyRingStc_ptr->ValidTag != KMNG_VALID_KEY_RING_TOKEN)
	{
		return KMNG_KEY_RING_CORRUPTED_ERR;
	}

	if( bufferSize < CRYS_AES_BLOCK_SIZE_IN_BYTES)
	{
	  return DX_KMNG_INVALID_BUFFER_LENGTH_ERR;
	}	

	/* set ring key relevant paramaters */
	keyRingDataParam.encryptedKeyData_ptr = keyRingStc_ptr->protectionKey.encryptedKeyBuffer;
	keyRingDataParam.encryptedKeyDataLength = keyRingStc_ptr->protectionKey.generalData.keyDataLen;	
	/*This is just dummy setting the pWD is not used*/
	keyRingDataParam.keyPasswordLen = 0x1;	
	keyRingDataParam.keyPassword_ptr = (DxUint8_t*)&keyRingDataParam.keyPasswordLen;	
	
	/* calc and verify the AES MAC */
	error = LLF_KMNG_CalcKeyRingAesMAC(&keyRingDataParam,
										keyRing_ptr,
										(bufferSize-CRYS_AES_BLOCK_SIZE_IN_BYTES),
										MacBuffer_ptr);
	if(error != KMNG_OK)
	{
		goto end_function;
	}
	

	/* Copy the keyRing data to the user buffer */
	DX_VOS_FastMemCpy(buffer_ptr,
				   keyRing_ptr,
				   (bufferSize-CRYS_AES_BLOCK_SIZE_IN_BYTES));

	/* Copy/Chain the AES MAC data to the end of the user buffer */
	DX_VOS_FastMemCpy((buffer_ptr+bufferSize-CRYS_AES_BLOCK_SIZE_IN_BYTES),
							MacBuffer_ptr,
							CRYS_AES_BLOCK_SIZE_IN_BYTES);
	
end_function:
  
	return error;
}


/**
 * @brief     This function returns the parameters of the stores key ring: number of SYM, RSA and DH key that was originally intended
 *            to be stored in the key ring
 *
 * @param[in] imageBuffer_ptr - image of the key ring 
 * @param[in] imageBufferSize - size of the image of the key ring
 * @param[out] numSymKeys_ptr - number of symmetric keys in the key ring
 * @param[out] numRSAKeys_ptr - number of RSA keys in the key ring
 * @param[out] numDHKeys_ptr - number of DH keys in the key ring
 *
 * @return     DxError_t:  
 *                        
 */                                
DxError_t KMNG_GetKeyRingDataFromImage(DxUint8_t*      imageBuffer_ptr,
                                       DxUint32_t      imageBufferSize,
                                       DxUint32_t*     numSymKeys_ptr,
                                       DxUint32_t*     numRSAKeys_ptr,
                                       DxUint32_t*     numDHKeys_ptr)
{
	/* paramaters for create key */
	KMNG_KeyDataParameter_t   keyRingDataParam;
  
	/* pointer to key ring key for the LLF use */
	KMNG_KeyRing_t*           keyRingStc_ptr;
 
	/* Temporary buffer for the MAC */
	DxUint8_t MacBuffer_ptr[CRYS_AES_BLOCK_SIZE_IN_BYTES];

	DxUint32_t error;
	
	/*--------------------------
	    CODE
	-----------------------------*/

  if( (imageBuffer_ptr == DX_NULL) ||
      (numSymKeys_ptr == DX_NULL) ||
      (numRSAKeys_ptr == DX_NULL) ||
      (numDHKeys_ptr == DX_NULL) )
{
    return DX_KMNG_INPUT_ARG_NULL_POINTER_ERROR;
  }
	

	/* set the key ring key paramaters */
	keyRingStc_ptr = (KMNG_KeyRing_t*)imageBuffer_ptr;

	/* check if the Key Ring is valid - check the ValidTag */
	if (keyRingStc_ptr->ValidTag != KMNG_VALID_KEY_RING_TOKEN)
	{
		return KMNG_KEY_RING_CORRUPTED_ERR;
	}

	/* check that the size of the image buffer is minimum the MAC size */
	if( imageBufferSize < CRYS_AES_BLOCK_SIZE_IN_BYTES)
	{
	  return DX_KMNG_INVALID_BUFFER_LENGTH_ERR;
	}

	/* Copy/Chain the AES MAC data to the end of the user buffer */
	DX_VOS_FastMemCpy(	MacBuffer_ptr,
				   (imageBuffer_ptr+imageBufferSize-CRYS_AES_BLOCK_SIZE_IN_BYTES),
				    CRYS_AES_BLOCK_SIZE_IN_BYTES);
	/* set ring key relevant paramaters */
	keyRingDataParam.encryptedKeyData_ptr = keyRingStc_ptr->protectionKey.encryptedKeyBuffer;
	keyRingDataParam.encryptedKeyDataLength = keyRingStc_ptr->protectionKey.generalData.keyDataLen;
 	/*This is just dummy setting the pWD is not used*/
	keyRingDataParam.keyPasswordLen = 0x1;	
	keyRingDataParam.keyPassword_ptr = (DxUint8_t*)&keyRingDataParam.keyPasswordLen;	
 
	/* Call the calc and verify without deleteing any data in error case */
	error = LLF_KMNG_CalcAndVerifyKeyRingAesMAC(&keyRingDataParam,
												imageBuffer_ptr,
												(imageBufferSize-CRYS_AES_BLOCK_SIZE_IN_BYTES),
												MacBuffer_ptr);
	if(error != KMNG_OK)
	{
		goto end_function;
	}

	/* Verification OK - return the data */
	*numSymKeys_ptr = keyRingStc_ptr->maxSymKeysNum;
	*numRSAKeys_ptr = keyRingStc_ptr->maxRSAKeysNum;
	*numDHKeys_ptr = keyRingStc_ptr->maxDHKeysNum;
  
	
end_function:
  
	return error;

}
                                    
/**
 * @brief     This function restores the KeyRing from the flash image buffer into RAM buffer
 *
 * @param[in] imageBuffer_ptr - image of the key ring 
 * @param[in] imageBufferSize - size of the image of the key ring
 * @param[out] keyRing_ptr - key ring 
 * @param[out] keyRingBufferLen - length of the key ring buffer
 *
 * @return     DxError_t:  
 *                        
 */                                
DxError_t KMNG_RestoreKeyRingFromImage(DxUint8_t*      imageBuffer_ptr,
                    									 DxUint32_t      imageBufferSize,
                    									 DxUint8_t*      keyRing_ptr,
                    									 DxUint32_t      keyRingBufferLen)
{
	 /* paramaters for create key */
	KMNG_KeyDataParameter_t   keyRingDataParam;
  
	/* pointer to key ring key for the LLF use */
	KMNG_KeyRing_t*           keyRingStc_ptr;
 
	/* Temporary buffer for the MAC */
	DxUint8_t MacBuffer_ptr[CRYS_AES_BLOCK_SIZE_IN_BYTES];

	DxUint32_t error;
	
	/*----------------------
	    CODE
	-------------------------*/
	
	/* check parameters */
	if( (imageBuffer_ptr == DX_NULL) ||
      (keyRing_ptr == DX_NULL) )
  {
    return DX_KMNG_INPUT_ARG_NULL_POINTER_ERROR;
  }
  
	/* set the key ring key paramaters */
	keyRingStc_ptr = (KMNG_KeyRing_t*)imageBuffer_ptr;
	
	/* check if the Key Ring is valid - check the ValidTag */
	if (keyRingStc_ptr->ValidTag != KMNG_VALID_KEY_RING_TOKEN)
	{
		return KMNG_KEY_RING_CORRUPTED_ERR;
	}

	/* check that the size of the image buffer is minimum the MAC size */
	if( imageBufferSize < CRYS_AES_BLOCK_SIZE_IN_BYTES)
	{
	  return DX_KMNG_INVALID_BUFFER_LENGTH_ERR;
	}


	/* Copy/Chain the AES MAC data to the end of the user buffer */
	DX_VOS_FastMemCpy(	MacBuffer_ptr,
				   (imageBuffer_ptr+imageBufferSize-CRYS_AES_BLOCK_SIZE_IN_BYTES),
				    CRYS_AES_BLOCK_SIZE_IN_BYTES);
	/* set ring key relevant paramaters */
	keyRingDataParam.encryptedKeyData_ptr = keyRingStc_ptr->protectionKey.encryptedKeyBuffer;
	keyRingDataParam.encryptedKeyDataLength = keyRingStc_ptr->protectionKey.generalData.keyDataLen;
 	/*This is just dummy setting the pWD is not used*/
	keyRingDataParam.keyPasswordLen = 0x1;	
	keyRingDataParam.keyPassword_ptr = (DxUint8_t*)&keyRingDataParam.keyPasswordLen;	
  
	/* Call the calc and verify with deleteing the  keyRing data in error case */
	error = LLF_KMNG_CalcAndVerifyKeyRingAesMAC(&keyRingDataParam,
												 imageBuffer_ptr,
												 (imageBufferSize -CRYS_AES_BLOCK_SIZE_IN_BYTES),
												 MacBuffer_ptr);
												 
  if(error == KMNG_OK)
  {
    /* Copy the imageBuffer_ptr to the keyRing_ptr */
  	DX_VOS_FastMemCpy(keyRing_ptr,
  				   imageBuffer_ptr,
  				   keyRingBufferLen);

	/* reset the start address of the keys according to types, otherwise the previous key ring start addresses are set*/
	keyRingStc_ptr = (KMNG_KeyRing_t*)keyRing_ptr;
	keyRingStc_ptr->startSymKeysAddr = (DxUint32_t)keyRingStc_ptr + sizeof(KMNG_KeyRing_t);
	keyRingStc_ptr->startRSAKeysAddr = keyRingStc_ptr->startSymKeysAddr + sizeof(KMNG_SYMKeyData_t) * keyRingStc_ptr->maxSymKeysNum;
	keyRingStc_ptr->startDHKeysAddr = keyRingStc_ptr->startRSAKeysAddr + sizeof(KMNG_RSAKeyData_t) * keyRingStc_ptr->maxRSAKeysNum;
  }

return error;
}
                                    
                                    
/**
 * @brief     This function prepares the AES contest for CRYS function usage based on the
 *			  key ring AES key
 *
 * @param[in] keyRingPassword_ptr - password for access to key ring
 * @param[in] keyRingPasswordLen - key ring password length
 * @param[in] keyPassword_ptr - password for access to key data
 * @param[in] keyPasswordLen - key password length
 * @param[in] keyData_ptr - key data
 * @param[out]AES_WrappedKey_ptr - memory to stores created AES context  
 * 
 * @return     DxError_t:  
 *                        
 */
DxError_t KMNG_ActivateAESKey(DxUint8_t*  keyRingPassword_ptr,
                              DxUint32_t  keyRingPasswordLen,
                              DxUint8_t*  keyPassword_ptr,
                              DxUint32_t  keyPasswordLen,
                              DxUint32_t  keyId,
                              DxUint8_t*  keyRing_ptr,
                              KMNG_AES_WrappedKey_t	AES_WrappedKey_ptr)
{
  /* paramaters for source key ring */
  KMNG_KeyDataParameter_t   keyRingDataParam;
  
  /* paramaters for source key */
  KMNG_KeyDataParameter_t   userKeyDataParam;
  
  /* pointer to source key ring */
  KMNG_KeyRing_t*           keyRingStc_ptr;
  
  /* source key slot pointer */
  DxUint8_t*                keySlot_ptr;
  
  /* error */
  DxError_t                 error;
  
  /*--------------------
    CODE
  ------------------------*/
  
  /* check parameters */
	if( (keyRingPassword_ptr == DX_NULL) ||
      (keyPassword_ptr == DX_NULL) ||
      (keyRing_ptr == DX_NULL) ||
      (AES_WrappedKey_ptr == DX_NULL) )
  {
    return DX_KMNG_INPUT_ARG_NULL_POINTER_ERROR;
  }
  
  keyRingStc_ptr = (KMNG_KeyRing_t*)keyRing_ptr;
 
  /* check if the Key Ring is valid - check the ValidTag */
  if (keyRingStc_ptr->ValidTag != KMNG_VALID_KEY_RING_TOKEN)
  {
	return KMNG_KEY_RING_CORRUPTED_ERR;
  }

  /* find the key according to id */
  error = KMNG_FindKeyInKeyRing(keyRing_ptr , keyId , &keySlot_ptr);
  if(error != KMNG_OK)
  {
    goto end_function;
  }
  
  /* set key ring key paramaters */
  keyRingDataParam.keyPassword_ptr = keyRingPassword_ptr;
  keyRingDataParam.keyPasswordLen = keyRingPasswordLen;
  keyRingDataParam.encryptedKeyData_ptr = keyRingStc_ptr->protectionKey.encryptedKeyBuffer;
  keyRingDataParam.encryptedKeyDataLength=keyRingStc_ptr->protectionKey.generalData.keyDataLen;
  
  /* set user key paramaters */
  userKeyDataParam.keyPassword_ptr = keyPassword_ptr;
  userKeyDataParam.keyPasswordLen = keyPasswordLen;
  userKeyDataParam.encryptedKeyData_ptr = ((KMNG_SYMKeyData_t*)keySlot_ptr)->encryptedKeyBuffer;
  userKeyDataParam.encryptedKeyDataLength=((KMNG_SYMKeyData_t*)keySlot_ptr)->generalData.keyDataLen;
  
  error = LLF_KMNG_ActivateAESKey(&keyRingDataParam,
                                      &userKeyDataParam,
                                      (DxUint8_t*)AES_WrappedKey_ptr);
                                 
end_function:

  return error;
}

/**
 * @brief     This function prepares the AES contest for CRYS function usage based on the
 *			  key ring AES key
 *
 * @param[in] keyRingPassword_ptr - password for access to key ring
 * @param[in] keyRingPasswordLen - key ring password length
 * @param[in] keyPassword_ptr - password for access to key data
 * @param[in] keyPasswordLen - key password length
 * @param[in] keyData_ptr - key data
 * @param[out]DES_WrappedKey_ptr - memory to stores created DES context  
 * 
 * @return     DxError_t:  
 *                        
 */
DxError_t KMNG_ActivateDESKey(DxUint8_t*  keyRingPassword_ptr,
                              DxUint32_t  keyRingPasswordLen,
                              DxUint8_t*  keyPassword_ptr,
                              DxUint32_t  keyPasswordLen,
                              DxUint32_t  keyId,
                              DxUint8_t*  keyRing_ptr,
                              KMNG_DES_WrappedKey_t	DES_WrappedKey_ptr)
{
  /* paramaters for source key ring */
  KMNG_KeyDataParameter_t   keyRingDataParam;
  
  /* paramaters for source key */
  KMNG_KeyDataParameter_t   userKeyDataParam;
  
  /* pointer to source key ring */
  KMNG_KeyRing_t*           keyRingStc_ptr;
  
  /* source key slot pointer */
  DxUint8_t*                keySlot_ptr;
  
  /* error */
  DxError_t                 error;
  
  /*--------------------
    CODE
  ------------------------*/
  
  /* check parameters */
	if( (keyRingPassword_ptr == DX_NULL) ||
      (keyPassword_ptr == DX_NULL) ||
      (keyRing_ptr == DX_NULL) ||
      (DES_WrappedKey_ptr == DX_NULL) )
  {
    return DX_KMNG_INPUT_ARG_NULL_POINTER_ERROR;
  }
  
  keyRingStc_ptr = (KMNG_KeyRing_t*)keyRing_ptr;
 
  /* check if the Key Ring is valid - check the ValidTag */
  if (keyRingStc_ptr->ValidTag != KMNG_VALID_KEY_RING_TOKEN)
  {
	return KMNG_KEY_RING_CORRUPTED_ERR;
  }

  /* find the key according to id */
  error = KMNG_FindKeyInKeyRing(keyRing_ptr , keyId , &keySlot_ptr);
  if(error != KMNG_OK)
  {
    goto end_function;
  }
  
  /* set key ring key paramaters */
  keyRingDataParam.keyPassword_ptr = keyRingPassword_ptr;
  keyRingDataParam.keyPasswordLen = keyRingPasswordLen;
  keyRingDataParam.encryptedKeyData_ptr = keyRingStc_ptr->protectionKey.encryptedKeyBuffer;
  keyRingDataParam.encryptedKeyDataLength=keyRingStc_ptr->protectionKey.generalData.keyDataLen;
  
  /* set user key paramaters */
  userKeyDataParam.keyPassword_ptr = keyPassword_ptr;
  userKeyDataParam.keyPasswordLen = keyPasswordLen;
  userKeyDataParam.encryptedKeyData_ptr = ((KMNG_SYMKeyData_t*)keySlot_ptr)->encryptedKeyBuffer;
  userKeyDataParam.encryptedKeyDataLength=((KMNG_SYMKeyData_t*)keySlot_ptr)->generalData.keyDataLen;
  
  error = LLF_KMNG_ActivateDESKey(&keyRingDataParam,
                                      &userKeyDataParam,
                                      DES_WrappedKey_ptr);
                                 
end_function:

  return error;
}

/**
 * @brief     This function prepares the HMAC contest for CRYS function usage based on the key ring AES key
 *
 * @param[in] keyRingPassword_ptr - password for access to key ring
 * @param[in] keyRingPasswordLen - key ring password length
 * @param[in] keyPassword_ptr - password for access to key data
 * @param[in] keyPasswordLen - key password length
 * @param[in] keyData_ptr - key data
 * @param[out]HMAC_WrappedKey_ptr - memory to stores created HMAC context  
 * 
 * @return     DxError_t:  
 *                        
 */
DxError_t KMNG_ActivateHMACKey(DxUint8_t*  keyRingPassword_ptr,
                               DxUint32_t  keyRingPasswordLen,
                               DxUint8_t*  keyPassword_ptr,
                               DxUint32_t  keyPasswordLen,
                               DxUint32_t  keyId,
                               DxUint8_t*  keyRing_ptr,
                               KMNG_HMAC_WrappedKey_t	HMAC_WrappedKey_ptr)
{
  /* paramaters for source key ring */
  KMNG_KeyDataParameter_t   keyRingDataParam;
  
  /* paramaters for source key */
  KMNG_KeyDataParameter_t   userKeyDataParam;
  
  /* pointer to source key ring */
  KMNG_KeyRing_t*           keyRingStc_ptr;
  
  /* source key slot pointer */
  DxUint8_t*                keySlot_ptr;
  
  /* error */
  DxError_t                   error;
  
  /*--------------------
    CODE
  ------------------------*/
  
  /* check parameters */
	if( (keyRingPassword_ptr == DX_NULL) ||
      (keyPassword_ptr == DX_NULL) ||
      (keyRing_ptr == DX_NULL) ||
      (HMAC_WrappedKey_ptr == DX_NULL) )
  {
    return DX_KMNG_INPUT_ARG_NULL_POINTER_ERROR;
  }
  
  keyRingStc_ptr = (KMNG_KeyRing_t*)keyRing_ptr;
 
  /* check if the Key Ring is valid - check the ValidTag */
  if (keyRingStc_ptr->ValidTag != KMNG_VALID_KEY_RING_TOKEN)
  {
	return KMNG_KEY_RING_CORRUPTED_ERR;
  }

  /* find the key according to id */
  error = KMNG_FindKeyInKeyRing(keyRing_ptr , keyId , &keySlot_ptr);
  if(error != KMNG_OK)
  {
    goto end_function;
  }
 
  /* set key ring key paramaters */
  keyRingDataParam.keyPassword_ptr = keyRingPassword_ptr;
  keyRingDataParam.keyPasswordLen = keyRingPasswordLen;
  keyRingDataParam.encryptedKeyData_ptr = keyRingStc_ptr->protectionKey.encryptedKeyBuffer;
  keyRingDataParam.encryptedKeyDataLength=keyRingStc_ptr->protectionKey.generalData.keyDataLen;
  
  
  /* set user key paramaters */
  userKeyDataParam.keyPassword_ptr = keyPassword_ptr;
  userKeyDataParam.keyPasswordLen = keyPasswordLen;
  userKeyDataParam.encryptedKeyData_ptr = ((KMNG_SYMKeyData_t*)keySlot_ptr)->encryptedKeyBuffer;
  userKeyDataParam.encryptedKeyDataLength=((KMNG_SYMKeyData_t*)keySlot_ptr)->generalData.keyDataLen;
  
  error = LLF_KMNG_ActivateHMACKey(&keyRingDataParam,
                                    &userKeyDataParam,
                                     (DxUint8_t*)HMAC_WrappedKey_ptr);
                                 
end_function:

  return error;
}
                                     
/**
 * @brief     This function prepares the RSA contest for CRYS function usage based on the key ring RSA key (It can be used both for encryption and decryption)
 *
 * @param[in] keyRingPassword_ptr - password for access to key ring
 * @param[in] keyRingPasswordLen - key ring password length
 * @param[in] keyPassword_ptr - password for access to key data
 * @param[in] keyPasswordLen - key password length
 * @param[in] keyData_ptr - key data
 * @param[out]RSA_WrappedKey_ptr - memory to stores created HMAC context  
 * 
 * @return     DxError_t:  
 *                        
 */
DxError_t KMNG_ActivateRSAKey(DxUint8_t*                keyRingPassword_ptr,
                            DxUint32_t                  keyRingPasswordLen,
                            DxUint8_t*                  keyPassword_ptr,
                            DxUint32_t                  keyPasswordLen,
                            DxUint32_t                  keyId,
                            KMNG_RsaKeyOperationType_t  rsaOperationType,
                            DxUint8_t*                  keyRing_ptr,
                            KMNG_RSA_WrappedKey_t	      RSA_WrappedKey_ptr)
{
  /* paramaters for source key ring */
  KMNG_KeyDataParameter_t   keyRingDataParam;
  
  /* paramaters for source key */
  KMNG_KeyDataParameter_t   userKeyDataParam;
  
  /* pointer to source key ring */
  KMNG_KeyRing_t*           keyRingStc_ptr;
  
  /* source key slot pointer */
  DxUint8_t*                keySlot_ptr;
  
   /* error */
  DxError_t                   error;
   
  /* key size  */
  DxUint32_t                   KeySize;
  
  /*--------------------
    CODE
  ------------------------*/
  
  /* check parameters */
	if( (keyRingPassword_ptr == DX_NULL) ||
      (keyPassword_ptr == DX_NULL) ||
      (keyRing_ptr == DX_NULL) ||
      (RSA_WrappedKey_ptr == DX_NULL) )
  {
    return DX_KMNG_INPUT_ARG_NULL_POINTER_ERROR;
  }
  
  keyRingStc_ptr = (KMNG_KeyRing_t*)keyRing_ptr;
 
  /* check if the Key Ring is valid - check the ValidTag */
  if (keyRingStc_ptr->ValidTag != KMNG_VALID_KEY_RING_TOKEN)
  {
	return KMNG_KEY_RING_CORRUPTED_ERR;
  }

  /* find the key according to id */
  error = KMNG_FindKeyInKeyRing(keyRing_ptr , keyId , &keySlot_ptr);
  if(error != KMNG_OK)
  {
    goto end_function;
  }
  
  /* set key ring key paramaters */
  keyRingDataParam.keyPassword_ptr = keyRingPassword_ptr;
  keyRingDataParam.keyPasswordLen = keyRingPasswordLen;
  keyRingDataParam.encryptedKeyData_ptr = keyRingStc_ptr->protectionKey.encryptedKeyBuffer;
  keyRingDataParam.encryptedKeyDataLength=keyRingStc_ptr->protectionKey.generalData.keyDataLen;
  
  /* set user key paramaters */
  userKeyDataParam.keyPassword_ptr = keyPassword_ptr;
  userKeyDataParam.keyPasswordLen = keyPasswordLen;
  userKeyDataParam.encryptedKeyData_ptr = ((KMNG_RSAKeyData_t*)keySlot_ptr)->encryptedKeyBuffer;
  userKeyDataParam.encryptedKeyDataLength=((KMNG_SYMKeyData_t*)keySlot_ptr)->generalData.keyDataLen;
 
  KeySize  = sizeof(KMNG_RSA_WrappedKey_t);

  error = LLF_KMNG_ActivateRSAKey(&keyRingDataParam,
                                  &userKeyDataParam,
                                  rsaOperationType,
                                  (DxUint8_t*)RSA_WrappedKey_ptr,
                                  &KeySize);
                                
end_function:

  return error;
}
                                    
                                    
/**
 * @brief     This function prepares the DH contest for CRYS function usage based on the key ring DH key
 *
 * @param[in] keyRingPassword_ptr - password for access to key ring
 * @param[in] keyRingPasswordLen - key ring password length
 * @param[in] keyPassword_ptr - password for access to key data
 * @param[in] keyPasswordLen - key password length
 * @param[in] keyData_ptr - key data
 * @param[out]DH_WrappedKey_ptr - memory to stores created HMAC context  
 * 
 * @return     DxError_t:  
 *                        
 */
DxError_t KMNG_ActivateDHKey(DxUint8_t*  keyRingPassword_ptr,
                               DxUint32_t  keyRingPasswordLen,
                               DxUint8_t*  keyPassword_ptr,
                               DxUint32_t  keyPasswordLen,
                               DxUint32_t  keyId,
                               DxUint8_t*  keyRing_ptr,
                               KMNG_DH_WrappedKey_t	DH_WrappedKey_ptr)
{
  /* paramaters for source key ring */
  KMNG_KeyDataParameter_t   keyRingDataParam;
  
  /* paramaters for source key */
  KMNG_KeyDataParameter_t   userKeyDataParam;
  
  /* pointer to source key ring */
  KMNG_KeyRing_t*           keyRingStc_ptr;
  /* length of the wrapped key */
  DxUint32_t				wrappedKeyLen;
  
  /* source key slot pointer */
  DxUint8_t*                keySlot_ptr;
  
  /* error */
  DxError_t					error;
  
  /*--------------------
    CODE
  ------------------------*/
  
  /* check parameters */
	if( (keyRingPassword_ptr == DX_NULL) ||
      (keyPassword_ptr == DX_NULL) ||
      (keyRing_ptr == DX_NULL) ||
      (DH_WrappedKey_ptr == DX_NULL) )
  {
    return DX_KMNG_INPUT_ARG_NULL_POINTER_ERROR;
  }
  
  keyRingStc_ptr = (KMNG_KeyRing_t*)keyRing_ptr;
 
  /* check if the Key Ring is valid - check the ValidTag */
  if (keyRingStc_ptr->ValidTag != KMNG_VALID_KEY_RING_TOKEN)
  {
	return KMNG_KEY_RING_CORRUPTED_ERR;
  }

  /* find the key according to id */
  error = KMNG_FindKeyInKeyRing(keyRing_ptr , keyId , &keySlot_ptr);
  if(error != KMNG_OK)
  {
    goto end_function;
  }
  
  /* set key ring key paramaters */
  keyRingDataParam.keyPassword_ptr = keyRingPassword_ptr;
  keyRingDataParam.keyPasswordLen = keyRingPasswordLen;
  keyRingDataParam.encryptedKeyData_ptr = keyRingStc_ptr->protectionKey.encryptedKeyBuffer;
  keyRingDataParam.encryptedKeyDataLength=keyRingStc_ptr->protectionKey.generalData.keyDataLen;
  
  /* set user key paramaters */
  userKeyDataParam.keyPassword_ptr = keyPassword_ptr;
  userKeyDataParam.keyPasswordLen = keyPasswordLen;
  userKeyDataParam.encryptedKeyData_ptr = ((KMNG_DHKeyData_t*)keySlot_ptr)->encryptedKeyBuffer;
  userKeyDataParam.encryptedKeyDataLength=((KMNG_SYMKeyData_t*)keySlot_ptr)->generalData.keyDataLen;
  
  /* activate key */
  wrappedKeyLen = KMNG_DH_WRAP_KEY_LEN;
  error = LLF_KMNG_ActivateDHKey(&keyRingDataParam,
                                 &userKeyDataParam,
                                 DH_WrappedKey_ptr,
								                 &wrappedKeyLen);
                                 
end_function:

  return error;
}

/**
 * @brief     This function retrieve a wrapped key from the key ring given a key id.
 *
 * @param[in] keyRing_ptr - pointer to the key ring.
 * @param[in] keyId - the key id in the key ring.
 * @param[out] wrappedKey_ptr - pointer to the buffer to store the wrappedKey.
 * @param[in/out]wrappedKeySizeInBytes_ptr - get the length of the wrappedKey_ptr buffer.
 *											 return the actual size of the wrapped key.
 * @return     DxError_t:  
 *                        
 */
DxError_t KMNG_GetKeyFromKeyRing (DxUint8_t*                  keyRing_ptr,             
                                  DxUint32_t                  keyId,                    
                                  DxUint8_t*                  wrappedKey_ptr,           
                                  DxUint32_t*                 wrappedKeySizeInBytes_ptr)
{
 /* pointer to source key ring */
  KMNG_KeyRing_t*           keyRingStc_ptr;
  
  /* key slot pointer */
  DxUint8_t*                keySlot_ptr;
  
  /* error */
  DxError_t                 error;
  
  /* group of the key */
  KMNG_KeyTypeGroup_t       keyTypeGroup;
  

 /*------------------
      CODE
  ---------------------*/

   error = KMNG_OK;

	/* check parameters */
	if( (keyRing_ptr == DX_NULL) ||
      (wrappedKey_ptr == DX_NULL)||
	  (wrappedKeySizeInBytes_ptr == DX_NULL) )
	{
		return DX_KMNG_INPUT_ARG_NULL_POINTER_ERROR;
	}
  
	keyRingStc_ptr = (KMNG_KeyRing_t*)keyRing_ptr;
 
	/* check if the Key Ring is valid - check the ValidTag */
	if (keyRingStc_ptr->ValidTag != KMNG_VALID_KEY_RING_TOKEN)
	{
		error = KMNG_KEY_RING_CORRUPTED_ERR;
		goto end_function;
	}
	
                                    
	/* find the key, group, and size according to key id */
	error = KMNG_FindKeyAndItsGroupInKeyRing(keyRing_ptr,
											   keyId,
											   &keySlot_ptr,
											   &keyTypeGroup,
											   DX_NULL);
	if(error != KMNG_OK)
	{
		goto end_function;
	}
	 
	/* check if buffer size enough */
	if (*wrappedKeySizeInBytes_ptr < ((KMNG_UserKeyGeneralData_t*)keySlot_ptr)->keyDataLen)
	{
		error = DX_KMNG_WRAP_KEY_BUF_SIZE_INSUFFICIENT_ERR;
		goto end_function;
	}

	/* Copy the wrap key according to the type */
	switch (keyTypeGroup)
	{
		case KMNG_SymmetricKey:			
			DX_VOS_FastMemCpy (wrappedKey_ptr,
							  ((KMNG_SYMKeyData_t*)keySlot_ptr)->encryptedKeyBuffer,
				   			   ((KMNG_UserKeyGeneralData_t*)keySlot_ptr)->keyDataLen);			
			break;

		case KMNG_RsaKey:			
			DX_VOS_FastMemCpy (wrappedKey_ptr,
							  ((KMNG_RSAKeyData_t*)keySlot_ptr)->encryptedKeyBuffer,
				   			   ((KMNG_UserKeyGeneralData_t*)keySlot_ptr)->keyDataLen);			
			break;

		case KMNG_DhKey:			
			DX_VOS_FastMemCpy (wrappedKey_ptr,
							  ((KMNG_DHKeyData_t*)keySlot_ptr)->encryptedKeyBuffer,
				   			   ((KMNG_UserKeyGeneralData_t*)keySlot_ptr)->keyDataLen);			
			break;

		default: return DX_KMNG_INVALID_KEY_TYPE_ERR;
	}

	/* Update the actual size */
	*wrappedKeySizeInBytes_ptr = ((KMNG_UserKeyGeneralData_t*)keySlot_ptr)->keyDataLen;

end_function:
	
	return error;
}

/**
* @brief     This function retrieve a wrapped protection key from the key ring.
*
* @param[in] keyRing_ptr - pointer to the key ring.
* @param[out] wrappedKey_ptr - pointer to the buffer to store the wrapped protection key.
* @param[in/out]wrappedKeySizeInBytes_ptr - get the length of the wrappedKey_ptr buffer.
*											 return the actual size of the wrapped key.
* @return     DxError_t:  
*                        
*/
DxError_t KMNG_GetProtectionKeyFromKeyRing (DxUint8_t*                  keyRing_ptr,
                                            DxUint8_t*                  wrappedKey_ptr,
                                            DxUint32_t*                 wrappedKeySizeInBytes_ptr)
{
    /* pointer to source key ring */
    KMNG_KeyRing_t*           keyRingStc_ptr;

    /* error */
    DxError_t                 error;


    /*------------------
    CODE
    ---------------------*/

    error = KMNG_OK;

    /* check parameters */
    if( (keyRing_ptr == DX_NULL) ||
        (wrappedKey_ptr == DX_NULL)||
        (wrappedKeySizeInBytes_ptr == DX_NULL) )
    {
        return DX_KMNG_INPUT_ARG_NULL_POINTER_ERROR;
    }

    keyRingStc_ptr = (KMNG_KeyRing_t*)keyRing_ptr;

    /* check if the Key Ring is valid - check the ValidTag */
    if (keyRingStc_ptr->ValidTag != KMNG_VALID_KEY_RING_TOKEN)
    {
        error = KMNG_KEY_RING_CORRUPTED_ERR;
        goto end_function;
    }

    /* check if buffer size enough */
    if (*wrappedKeySizeInBytes_ptr < keyRingStc_ptr->protectionKey.generalData.keyDataLen)
    {
        error = DX_KMNG_WRAP_KEY_BUF_SIZE_INSUFFICIENT_ERR;
        goto end_function;
    }

    DX_VOS_FastMemCpy (wrappedKey_ptr , keyRingStc_ptr->protectionKey.encryptedKeyBuffer , keyRingStc_ptr->protectionKey.generalData.keyDataLen);
      
    /* Update the actual size */
    *wrappedKeySizeInBytes_ptr = keyRingStc_ptr->protectionKey.generalData.keyDataLen;
    
end_function:

    return error;
}


/**
 * @brief     This function store a wrapped key to the key ring, and return his id.
 *
 * @param[in] keyRing_ptr - pointer to the key ring.
 * @param[in] keyType - type of key.
 * @param[in] wrappedKey_ptr - pointer to the buffer of the wrappedKey.
 * @param[in] wrappedKeySizeInBytes_ptr - the length of the wrappedKey_ptr buffer.
 * @param[out]keyId_ptr - the returned id of this wrapped key in the key ring.
 *		
 * @return     DxError_t:  
 *                        
 */
DxError_t KMNG_StoreKeyInKeyRing (DxUint8_t*                  keyRing_ptr,
                                  KMNG_KeyType_t              keyType,
                                  DxUint8_t*                  wrappedKey_ptr,
                                  DxUint32_t                  wrappedKeySizeInBytes,
                                  DxUint32_t*                 keyId_ptr)
{ 
  /* pointer to key ring key for the LLF use */
  KMNG_KeyRing_t*           keyRingStc_ptr;
  
  /* virtual slot pointer */
  DxUint8_t*                emptySlot_ptr;

  /* key types group */
  KMNG_KeyTypeGroup_t       keyTypeGroup;
  
  /* error */
  DxError_t                 error;
  
  /*------------------
      CODE
  ---------------------*/
  
  error = KMNG_OK;
  
  /* check paramaters */
  if( (keyRing_ptr == DX_NULL) ||
      (keyId_ptr == DX_NULL) ||
      (wrappedKey_ptr == DX_NULL) )
  {
    return DX_KMNG_INPUT_ARG_NULL_POINTER_ERROR;
  }
  
    keyRingStc_ptr = (KMNG_KeyRing_t*)keyRing_ptr;
 
  /* check if the Key Ring is valid - check the ValidTag */
  if (keyRingStc_ptr->ValidTag != KMNG_VALID_KEY_RING_TOKEN)
  {
	return KMNG_KEY_RING_CORRUPTED_ERR;
  }

  /* get the type of the group */
  error = KMNG_ConvertKeyTypeToGroup(keyType, &keyTypeGroup);
  if(error != KMNG_OK)
  {
    goto end_function;
  }
 
  /* check the length of the wrappedKey according to the group type */
  switch( keyTypeGroup ) 
  {
  	case KMNG_SymmetricKey:
  	    if ( wrappedKeySizeInBytes > KMNG_SYM_ENCR_KEY_BUFF_SIZE_IN_BYTES )  	    	
  	    	return DX_KMNG_INVALID_KEY_SIZE_ERR;	    
  	    break;
  	    	
  	case KMNG_RsaKey:
  	    if ( wrappedKeySizeInBytes > KMNG_RSA_ENCR_KEY_BUFF_SIZE_IN_BYTES )  	    	
  	    	return DX_KMNG_INVALID_KEY_SIZE_ERR;	    
  	    break;  	    
  	
  	case KMNG_DhKey:
  	    if ( wrappedKeySizeInBytes > KMNG_DH_ENCR_KEY_BUFF_SIZE_IN_BYTES )  	    	
  	    	return DX_KMNG_INVALID_KEY_SIZE_ERR;	    
  	    break;
   	     
  	default:
  		return  DX_KMNG_INVALID_KEY_TYPE_ERR;  	    
  }
   
  /* find empty slot in the key ring to the new wrapped key*/
  error = KMNG_FindUserKeyEmptySlot(keyRing_ptr,
									keyTypeGroup,
									&emptySlot_ptr,
									keyId_ptr);
  if(error != KMNG_OK)
  {
    goto end_function;
  }

	/* 1. Copy the wrapped key data from user to the key ring
	   2. Update the relevant data in the key ring */
	switch( keyTypeGroup ) 
	{
  	case KMNG_SymmetricKey:
		DX_VOS_FastMemCpy(((KMNG_SYMKeyData_t*)emptySlot_ptr)->encryptedKeyBuffer,
							wrappedKey_ptr,
							wrappedKeySizeInBytes);		
		((KMNG_SYMKeyData_t*)emptySlot_ptr)->generalData.validFlag = DX_KMNG_VALID_FLAG_VALUE;													
		((KMNG_SYMKeyData_t*)emptySlot_ptr)->generalData.keyDataLen = wrappedKeySizeInBytes ;
		keyRingStc_ptr->numActiveSymKeys++;
  	    break;
  	    	
  	case KMNG_RsaKey:
		DX_VOS_FastMemCpy(((KMNG_RSAKeyData_t*)emptySlot_ptr)->encryptedKeyBuffer,
							wrappedKey_ptr,
							wrappedKeySizeInBytes);		
  	    ((KMNG_RSAKeyData_t*)emptySlot_ptr)->generalData.validFlag = DX_KMNG_VALID_FLAG_VALUE;
		((KMNG_RSAKeyData_t*)emptySlot_ptr)->generalData.keyDataLen = wrappedKeySizeInBytes ;	    
		keyRingStc_ptr->numActiveRSAKeys++;
  	    break;  	    
  	
  	case KMNG_DhKey:
		DX_VOS_FastMemCpy(((KMNG_DHKeyData_t*)emptySlot_ptr)->encryptedKeyBuffer,
							wrappedKey_ptr,
							wrappedKeySizeInBytes);		
 	    ((KMNG_DHKeyData_t*)emptySlot_ptr)->generalData.validFlag = DX_KMNG_VALID_FLAG_VALUE;
		((KMNG_DHKeyData_t*)emptySlot_ptr)->generalData.keyDataLen = wrappedKeySizeInBytes ;	        
		keyRingStc_ptr->numActiveDHKeys++;
  	    break;    
  }
 
  
end_function:

  return error;
}
/*-----------------------------------------
  Private functions
--------------------------------------------*/

/**
 * @brief     This function find the next empty slot for user key in key ring
 *			  according to the type of key
 *
 * @param[in] keyRing_ptr - key ring
 * @param[in] keyTypeGroup - defining a group of key types (symmetric, RSA, DH)
 * @param[out] emptySlot_ptr - pointer to empty slot (virtual)
 * @param[out] emptySlotId_ptr - Id (index of empty slot
 * 
 * @return     DxError_t:  
 *                        
 */
static DxError_t KMNG_FindUserKeyEmptySlot(
                                         DxUint8_t*             keyRing_ptr,
                                         KMNG_KeyTypeGroup_t    keyTypeGroup,
                                         DxUint8_t**            emptySlot_ptr,
                                         DxUint32_t*            emptySlotId_ptr)
{
   /* pointer to the key ring space for the LLF use */
  KMNG_KeyRing_t*           keyRingStc_ptr;
  
  /* maximum number of keys */
  DxUint32_t                maxNumKeys;
  
  /* active number of keys */
  DxUint32_t                activeNumKeys;
  
  /* current pointer into key ring */
  DxUint32_t                current_ptr;
  
  /* basic Id */
  DxUint32_t                basicId;
  
  /* key size */
  DxUint32_t                keySize;
  
  /* counter */
  DxUint32_t                counter;
  
  /* error */
  DxError_t                   error;
  
  /*------------------
      CODE
  ---------------------*/
  
  /* error */
  error = KMNG_OK;
  
  /* allocate memory for key ring entry */
  keyRingStc_ptr = (KMNG_KeyRing_t*)keyRing_ptr;
  
  switch(keyTypeGroup)
  {
    case KMNG_SymmetricKey:

      maxNumKeys = keyRingStc_ptr->maxSymKeysNum;
      activeNumKeys = keyRingStc_ptr->numActiveSymKeys;
      current_ptr = (DxUint32_t)keyRingStc_ptr->startSymKeysAddr;
      keySize = sizeof(KMNG_SYMKeyData_t);
      basicId = 0;
      break;
      
    case KMNG_RsaKey:

      maxNumKeys = keyRingStc_ptr->maxRSAKeysNum;
      activeNumKeys = keyRingStc_ptr->numActiveRSAKeys;
      current_ptr = (DxUint32_t)keyRingStc_ptr->startRSAKeysAddr;
      basicId = keyRingStc_ptr->maxSymKeysNum;
      keySize = sizeof(KMNG_RSAKeyData_t);
      break;
      
    case KMNG_DhKey:

      maxNumKeys = keyRingStc_ptr->maxDHKeysNum;
      activeNumKeys = keyRingStc_ptr->numActiveDHKeys;
      current_ptr = (DxUint32_t)keyRingStc_ptr->startDHKeysAddr;
      basicId = keyRingStc_ptr->maxSymKeysNum + keyRingStc_ptr->maxRSAKeysNum;
      keySize = sizeof(KMNG_DHKeyData_t);
      break;
      
    default:
      keySize = 0;
      basicId = 0;
      
      error = DX_KMNG_INVALID_KEY_TYPE_ERR;
      
      goto end_function;
  }
  
  if(activeNumKeys >= maxNumKeys)
  {
    error = DX_KMNG_KEY_RING_FULL_ERR;
    goto end_function;
  }
  
  /* get sym keys id */
  for(counter = 0; counter < maxNumKeys; counter++)
  {
    /* load the key ring data */
    if(!((KMNG_UserKeyGeneralData_t*)current_ptr)->validFlag)
    {
      /* found on empty entry */
      *emptySlot_ptr = (DxUint8_t*)current_ptr;
      *emptySlotId_ptr = counter + basicId;
      goto end_function;
    }
    
    current_ptr += keySize;
  }
  
  /* no slot available */
  error = DX_KMNG_KEY_RING_FULL_ERR;
  
end_function:

  return error; 
}

/**
 * @brief     This function finds the slot of the key defined by the key id
 *
 * @param[in]  keyRing_ptr - key ring
 * @param[in]  keyId - key id of the key to find
 * @param[out] keySlot_ptr - pointer to the found key slot
 * @param[out] keyTypeGroup - defining the group of types of keys (symmetric, RSA. DH)
 * @param[out] keyDataSize_ptr - pointer to the key data size (for the found group) 
 *
 * @return     DxError_t:  
 * 
 *  NOTE: If the user is not needed to recieve the keyTypeGroup or keyGroupSize, then he can set 
 *        appropriate pointers as NULL, or to use special macros KMNG_FindKeyInKeyRing() .
 *                        
 */
static DxError_t KMNG_FindKeyAndItsGroupInKeyRing(
                                     DxUint8_t*                 keyRing_ptr,
                                     DxUint32_t                 keyId,
                                     DxUint8_t**                keySlot_ptr,
                                     KMNG_KeyTypeGroup_t*       keyTypeGroup_ptr,
                                     DxUint32_t*                keyDataSize_ptr )
{
   /* pointer to the key ring space for the LLF use */
  KMNG_KeyRing_t*           keyRingStc_ptr;
  
  /* current pointer into key ring */
  DxUint32_t                current_ptr = 0; /* To avoid PC_LINT warning */
  
  /* flag defining the group of types of keys (symmetric, RSA. DH) */ 	
  KMNG_KeyTypeGroup_t       keyTypeGroup = KMNG_OffModeKey;
  
  /* key group size */
  DxUint32_t                keyDataSize = 0;
  
  /* error */
  DxError_t                 error;
  
  /*------------------
      CODE
  ---------------------*/
  
  /* error */
  error = KMNG_OK;
  
  keyRingStc_ptr = (KMNG_KeyRing_t*)keyRing_ptr;
  
  /* check key Id (key Id start from 0) */
  if(keyId >= keyRingStc_ptr->maxSymKeysNum +
			  keyRingStc_ptr->maxRSAKeysNum +
			  keyRingStc_ptr->maxDHKeysNum)
  {
    error = DX_KMNG_ILLEGAL_KEY_ID_ERR;
    goto end_function;
  }
  
  if(keyId < keyRingStc_ptr->maxSymKeysNum)
  {
    /* key id belongs to the symmetric keys */
    current_ptr = (DxUint32_t)keyRingStc_ptr->startSymKeysAddr + sizeof(KMNG_SYMKeyData_t) * keyId;
    
    keyTypeGroup = KMNG_SymmetricKey;
    
    keyDataSize = ((KMNG_UserKeyGeneralData_t*)current_ptr)->keyDataLen;
  }
  else
  {
    if(keyId < (keyRingStc_ptr->maxSymKeysNum + keyRingStc_ptr->maxRSAKeysNum))
    {
      /* key id belongs to the RSA key */
      current_ptr = (DxUint32_t)keyRingStc_ptr->startRSAKeysAddr + sizeof(KMNG_RSAKeyData_t) * (keyId - keyRingStc_ptr->maxSymKeysNum );
      
      keyTypeGroup = KMNG_RsaKey;
      
      keyDataSize = ((KMNG_UserKeyGeneralData_t*)current_ptr)->keyDataLen;
    }
    
    else if(keyId < (keyRingStc_ptr->maxSymKeysNum + keyRingStc_ptr->maxRSAKeysNum  + keyRingStc_ptr->maxDHKeysNum))
    {
      /* key id belongs to the DH key */
      current_ptr = (DxUint32_t)keyRingStc_ptr->startDHKeysAddr + sizeof(KMNG_DHKeyData_t) * (keyId - (keyRingStc_ptr->maxSymKeysNum + keyRingStc_ptr->maxRSAKeysNum));
      
      keyTypeGroup = KMNG_DhKey;
      
      keyDataSize = ((KMNG_UserKeyGeneralData_t*)current_ptr)->keyDataLen;
    }        
  }
  
  /* check the validity */
  if( !((KMNG_UserKeyGeneralData_t*)current_ptr)->validFlag)
  {
    error = DX_KMNG_INVALID_KEY_ENTRY_ERR;
    goto end_function;
  }
  
  /* output of the results */
  
  *keySlot_ptr = (DxUint8_t*)current_ptr; 
  
  if( keyTypeGroup_ptr != DX_NULL )
  {
  	*keyTypeGroup_ptr = keyTypeGroup;
  }
  
  if( keyDataSize_ptr != DX_NULL )
  {
  	*keyDataSize_ptr = keyDataSize;
  }

  
end_function:

  return error; 
}


/**
 * @brief     This function retrives a key information (besides key themself) from key ring.
 *
 *
 * @param[in] keyId - the id of the key in the key ring
 * @param[out] keyType_ptr - type of the key
 * @param[in]  keySize_ptr - size of the key in bytes
 * @param[out] keyUsage_ptr - usage of the key
 * @param[out] keyRestriction_ptr - restriction of the key
 * @param[in]  userSpecificKeyData - user specific data for key   
 * @param[in]  keyRing_ptr - key ring 
 * 
 * @return     DxError_t:  
 *                        
 */                                       
DxError_t KMNG_RetrieveUserKeyInform(DxUint32_t                  keyId,
                                     KMNG_KeyType_t*             keyType_ptr,
                                     DxUint32_t*                 keySize_ptr,
                                     DxUint32_t*                 keyUsage_ptr,
                                     DxUint32_t*                 keyRestriction_ptr,
                                     KMNG_UserSpecificKeyData_t  userSpecificKeyData,
                                     DxUint8_t*                  keyRing_ptr)
{
  /* DECLARATIONS */  
   
 /* paramaters for create key */
  KMNG_KeyDataParameter_t   keyRingDataParam;
  
  /* paramaters for create key */
  KMNG_KeyDataParameter_t   userKeyDataParam;
  
  /* configuration parameters */
  KMNG_KeyConfiguration_t   keyConfiguration;  // 
  
  /* pointer to key ring */
  KMNG_KeyRing_t*           keyRingStc_ptr;
  
  /* virtual slot pointer */
  DxUint8_t*                keySlot_ptr;
  
  /* key type group */
  KMNG_KeyTypeGroup_t       keyTypeGroup;

  /* Key group size (max size of key for this group) */
  DxUint32_t                keyGroupSize ;
  
  /* error */
  DxError_t                 error;
 
  
  /* FUNCTION LOGIC */   

  
  /*------------------
      CODE
  ---------------------*/
  
  error = KMNG_OK;
  
  /* check paramaters */
  if( (keyRing_ptr == DX_NULL) ||
      (keyType_ptr == DX_NULL) ||
      (keyUsage_ptr == DX_NULL) ||
      (keyRestriction_ptr == DX_NULL) )
  {
    return DX_KMNG_INPUT_ARG_NULL_POINTER_ERROR;
  }
  
  keyRingStc_ptr = (KMNG_KeyRing_t*)keyRing_ptr;

  /* check if the Key Ring is valid - check the ValidTag */
  if (keyRingStc_ptr->ValidTag != KMNG_VALID_KEY_RING_TOKEN)
  {
	return KMNG_KEY_RING_CORRUPTED_ERR;
  }
 
  /* find the key, its type group and group key size according to Id */
  error = KMNG_FindKeyAndItsGroupInKeyRing( keyRing_ptr , 
                                            keyId , 
                                            &keySlot_ptr,
                                            &keyTypeGroup,
                                            &keyGroupSize );
  if(error != KMNG_OK)
  {
    goto end_function;
  }
  
  /* set key ring key paramaters */
  keyRingDataParam.encryptedKeyData_ptr = keyRingStc_ptr->protectionKey.encryptedKeyBuffer;
  keyRingDataParam.encryptedKeyDataLength = keyRingStc_ptr->protectionKey.generalData.keyDataLen;
  
  /* SEP checks that the password and its length is not 0 or DX_NULL, therefore we set it to some value */
  keyRingDataParam.keyPasswordLen = 1;
  keyRingDataParam.keyPassword_ptr = (DxUint8_t*)&keyRingDataParam;
  
  /* set user key paramaters */
  userKeyDataParam.encryptedKeyData_ptr = ((KMNG_SYMKeyData_t*)keySlot_ptr)->encryptedKeyBuffer;
  userKeyDataParam.encryptedKeyDataLength = ((KMNG_SYMKeyData_t*)keySlot_ptr)->generalData.keyDataLen;

  /* SEP checks that the password and its length is not 0 or DX_NULL, therefore we set it to some value */
  userKeyDataParam.keyPasswordLen = 1;
  userKeyDataParam.keyPassword_ptr = (DxUint8_t*)&userKeyDataParam;

  /* retrieve key data */
  error = LLF_KMNG_RetrieveKeyConfiguration(&keyRingDataParam ,                                     
                                            &userKeyDataParam,
                                            &keyConfiguration );
  if(error != KMNG_OK)
  {
    goto end_function;
  }

  /* output of configuration data */                                   
  *keyType_ptr           = keyConfiguration.type;
  *keySize_ptr           = keyConfiguration.keySizeBytes;
  *keyUsage_ptr          = keyConfiguration.usage;
  *keyRestriction_ptr    = keyConfiguration.restriction;
  
  /* if UserSpecificKeyData is not NULL, then copy it into output buffer */
  if(userSpecificKeyData != DX_NULL)
  {
	  userSpecificKeyData[0] = keyConfiguration.UserSpecificKeyData[0];
	  userSpecificKeyData[1] = keyConfiguration.UserSpecificKeyData[1];                                 
  }
  

  
end_function:
    
	return error;
}
                             

/**
 * @brief     This function updates the user specific key data in key ring.
 *
 *
 * @param[in] keyRingPassword_ptr - address of the key ring password string
 * @param[in] keyRingPasswordLen - length of the key ring password
 * @param[in] userPassword_ptr - address of the new key password string
 * @param[in] userPasswordLen - length of the new key password
 * @param[in] keyId - the id of the key in the key ring
 * @param[in]  UserSpecificKeyData - user specific data for key   
 * @param[in]  keyRing_ptr - key ring 
 * 
 * @return     DxError_t:  
 *                        
 */                                       
DxError_t KMNG_UpdateUserSpecificKeyData(
                              DxUint8_t*                  keyRingPassword_ptr , 
                              DxUint32_t                  keyRingPasswordLen,
                              DxUint8_t*                  keyPassword_ptr , 
                              DxUint32_t                  keyPasswordLen,
                              DxUint32_t                  keyId,
                              KMNG_UserSpecificKeyData_t  UserSpecificKeyData,
                              DxUint8_t*                  keyRing_ptr)
{
  /* DECLARATIONS */  
   
 /* paramaters for create key */
  KMNG_KeyDataParameter_t   keyRingDataParam;
  
  /* paramaters for create key */
  KMNG_KeyDataParameter_t   userKeyDataParam;
  
  /* pointer to key ring */
  KMNG_KeyRing_t*           keyRingStc_ptr;
  
  /* virtual slot pointer */
  DxUint8_t*                keySlot_ptr;
  
  /* key type group */
  KMNG_KeyTypeGroup_t       keyTypeGroup;

  /* Key group size (max size of key for this group) */
  DxUint32_t                keyGroupSize ;
  
  /* error */
  DxError_t                 error;
  
 
  
  /* FUNCTION LOGIC */   

  
  /*------------------
      CODE
  ---------------------*/
  
  error = KMNG_OK;
  
  /* check paramaters */
  if( (keyRing_ptr == DX_NULL) ||
      (keyRingPassword_ptr == DX_NULL) ||
      (keyPassword_ptr == DX_NULL) ||       
      (UserSpecificKeyData == DX_NULL) )
  {
    return DX_KMNG_INPUT_ARG_NULL_POINTER_ERROR;
  }
  
  if( (keyRingPasswordLen > KMNG_KEY_PASSWORD_MAX_LENGTH_IN_BYTES) ||
      (keyPasswordLen > KMNG_KEY_PASSWORD_MAX_LENGTH_IN_BYTES) )
  {
    return DX_KMNG_KEY_PASSWORD_LENGTH_ERR;
  }  
  
  keyRingStc_ptr = (KMNG_KeyRing_t*)keyRing_ptr;
  
  /* find the key according to id */
  error = KMNG_FindKeyAndItsGroupInKeyRing( keyRing_ptr , 
                                            keyId , 
                                            &keySlot_ptr,
                                            &keyTypeGroup,
                                            &keyGroupSize );
  if(error != KMNG_OK)
  {
    goto end_function;
  }
  
  /* set key ring key paramaters */
  keyRingDataParam.keyPassword_ptr = keyRingPassword_ptr;
  keyRingDataParam.keyPasswordLen = keyRingPasswordLen;
  keyRingDataParam.encryptedKeyData_ptr = keyRingStc_ptr->protectionKey.encryptedKeyBuffer;
  keyRingDataParam.encryptedKeyDataLength = keyRingStc_ptr->protectionKey.generalData.keyDataLen;
  
  
  /* set user key paramaters */
  userKeyDataParam.keyPassword_ptr = keyPassword_ptr;
  userKeyDataParam.keyPasswordLen = keyPasswordLen;
  userKeyDataParam.encryptedKeyData_ptr = ((KMNG_SYMKeyData_t*)keySlot_ptr)->encryptedKeyBuffer;
  userKeyDataParam.encryptedKeyDataLength=((KMNG_SYMKeyData_t*)keySlot_ptr)->generalData.keyDataLen;;


  /* update key user data */
  error = LLF_KMNG_UpdateKeyUserData(
                                    &keyRingDataParam,                                     
                                    &userKeyDataParam,
                                    UserSpecificKeyData );
  
end_function:
    
	return error;
}
                              


/**
 * @brief This Api returnes the KMNG version.
 *
 * The version containes the following:
 *
 * component string - a string describing the nature of the release.
 * release type : 'D' - development , 'A' - alpha (passed to the Q.A) , 
 *                'B' - beta , 'R' - release , after Q.A testing.
 *
 * major , minor , sub , internal - the release digits.
 *
 * @param[in] version_ptr - a pointer to the version structure.
 *
 */

 void  KMNG_GetVersion(KMNG_Version_t *version_ptr)
 {
    /* LOCAL DECLARATIONS */
    
    /* FUNCTION LOGIC */
    
    /* ............... Check input parameter ................... */
    
    if(version_ptr == (KMNG_Version_t *)DX_NULL)
	  {
		  return;
	  }
    /* .............. clearing the version db .................. */
    
    DX_VOS_MemSet( version_ptr , 0 , sizeof(KMNG_Version_t) );
    
    /* .............. seting the CRYS version .................. */
    
    version_ptr->KMNG_Version.compName[0] = 'K';
    version_ptr->KMNG_Version.compName[1] = 'M';
    version_ptr->KMNG_Version.compName[2] = 'N';
    version_ptr->KMNG_Version.compName[3] = 'G';
    
    version_ptr->KMNG_Version.type     = KMNG_RELEASE_TYPE;
    version_ptr->KMNG_Version.major    = KMNG_MAJOR_VERSION_NUM;
    version_ptr->KMNG_Version.minor    = KMNG_MINOR_VERSION_NUM;
    version_ptr->KMNG_Version.sub      = KMNG_SUB_VERSION_NUM;
    version_ptr->KMNG_Version.internal = KMNG_INTERNAL_VERSION_NUM; 
  
	return;
 }
