
  /*
   *  Object %name    : %
   *  State           :  %state%
   *  Creation date   :  17 Jul. 2007
   *  Last modified   :  %modify_time%
   */
  /** @file
   *  \brief A brief description of this module
   *
   *  \version CRYS_DH.c#1:csrc:8
   *  \author R.Levin
   *  \remarks Copyright (C) 2007 by Discretix Technologies Ltd.
   *           All Rights reserved
   */



/************* Include Files ****************/
#include "DX_VOS_Mem.h"
#include "PLAT_SystemDep.h"
#include "CRYS.h"
#include "CRYS_KDF.h"
#include "CRYS_KDF_error.h"
#include "dx_hw_defs.h"
#include "crys_host_op_code.h"


/************************ Defines *******************************/

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

/************************ Enums *********************************/

/************************ macros ********************************/

/* this macro is required to remove compilers warnings if the HASH or PKI is not supported */

#if( defined CRYS_NO_HASH_SUPPORT || defined CRYS_NO_KDF_SUPPORT )
#define RETURN_IF_KDF_UNSUPPORTED( a , b , c , d , e , f , g , h , i , j , k , l , a1 , b1 , c1 , d1 , e1 , f1 , g1 , h1 , i1 , j1) \
  (a)=0;(b)=0;(c)=0;(d)=0;(e)=0;(f)=0;(g)=0;(h)=0;(i)=0;(j)=0;(k)=0;(l)=0; \
  (a1)=0;(b1)=0;(c1)=0;(d1)=0;(e1)=0;(f1)=0;(g1)=0;(h1)=0;(i1)=0;(j1)=0; \
  (a)=(a);(b)=(b);(c)=(c);(d)=(d);(e)=(e);(f)=(f);(g)=(g);(h)=(h);(i)=(i);(j)=(j);(k)=(k);(l)=(l); \
  (a1)=(a1);(b1)=(b1);(c1)=(c1);(d1)=(d1);(e1)=(e1);(f1)=(f1);(g1)=(g1);(h1)=(h1);(i1)=(i1);(j1)=(j1); \
  return CRYS_KDF_IS_NOT_SUPPORTED
#else  /* CRYS_NO_HASH_SUPPORT */
#define RETURN_IF_KDF_UNSUPPORTED( a , b , c , d , e , f , g , h , i , j , k , l , a1 , b1 , c1 , d1 , e1 , f1 , g1 , h1 , i1 , j1) 
#endif /* !CRYS_NO_KDF_SUPPORT !CRYS_NO_HASH_SUPPORT */


/************************ Public Functions ******************************/


/****************************************************************/
/**
 * @brief _DX_KDF_KeyDerivFunc performs key derivation according to one of some modes defined in standards: 
 			   ANSI X9.42-2001, ANSI X9.63, OMA_TS_DRM_DRM_V2_0-20050712-C.

			   The present implementation of the function allows the following operation modes:
			   - CRYS_KDF_ASN1_DerivMode - mode based on  ASN.1 DER encoding;
			   - CRYS_KDF_ConcatDerivMode - mode based on concatenation;
               - CRYS_KDF_X963_DerivMode = CRYS_KDF_ConcatDerivMode;
 			   - CRYS_KDF_OMA_DRM_DerivMode - specific mode for OMA DRM.

 			The purpose of this function is to derive a keying data from the shared secret value and some 
			other optional shared information (SharedInfo).
 			
	The actual APIs that will be used by the user are:
		- CRYS_KDF_ASN1_KeyDerivFunc ;			
		- CRYS_KDF_ConcatKeyDerivFunc ;
        - CRYS_KDF_OMADRM_DerivFunc .
 			
  \note The length in Bytes of the hash result buffer is denoted by "hashlen".
  \note All buffers arguments are represented in Big-Endian format.
 
  @param[in] ZZSecret_ptr 	 - A pointer to shared secret value octet string. 
  @param[in] ZZSecretSize  	 - The shared secret value Size, in bytes.
  @param[in] OtherInfo       - The pointer to structure, containing pointers and sizes of optional data shared  
                               by two entities intended to share the secret value. This argument is optional 
							   (if not needed - set it to NULL).
  @param[in] KDFhashMode	 - The KDF identifier of hash function to be used. The hash function output must be at least 160 bits.
  @param[out] KeyingData_ptr - A pointer to the keying data derived from the secret key, of length KeyLenInBits
  @param[in] KeyingDataSizeBytes	 - The size in bytes of the keying data to be generated. In our implementation - 
  							   KeyLenInBytes <= 2^32-1 .
  @param[in] derivation_mode - Specifies one of above described derivation modes.

      NOTE: 
	        1.  The size of shared secret value , and size of each of parties of OtherInfo must be less than 
			    maximal size of input data for used HASH function.
  							  
  @return CRYSError_t - On success the value CRYS_OK is returned, 
			            and on failure an ERROR as defined in CRYS_KDF_error.h:
						CRYS_KDF_INVALID_ARGUMENT_POINTER_ERROR
						CRYS_KDF_INVALID_KEY_DERIVATION_MODE_ERROR
						CRYS_KDF_INVALID_SHARED_SECRET_VALUE_SIZE_ERROR
						CRYS_KDF_INVALID_SIZE_OF_DATA_TO_HASHING_ERROR
						CRYS_KDF_INVALID_ARGUMENT_HASH_MODE_ERROR
						CRYS_KDF_INVALID_OTHER_INFO_SIZE_ERROR
						CRYS_KDF_INVALID_KEYING_DATA_SIZE_ERROR
*/

CEXPORT_C CRYSError_t  _DX_KDF_KeyDerivFunc( 
	                                  DxUint8_t                *ZZSecret_ptr,
									  DxUint32_t                ZZSecretSize,
									  CRYS_KDF_OtherInfo_t     *OtherInfo_ptr,
				  				      CRYS_KDF_HASH_OpMode_t    KDFhashMode,
				                      CRYS_KDF_DerivFuncMode_t  derivation_mode,
				                      DxUint8_t                *KeyingData_ptr,
				                      DxUint32_t                KeyingDataSizeBytes )				                    
{

 	return DX_HW_Dispatcher_ptr( DX_SEP_HOST_SEP_PROTOCOL_HOST_KDF_KEY_DERIV_FUNC_OP_CODE, 7,
	   							 /* PARAMETERS: */
                                 ZZSecret_ptr,
								 ZZSecretSize,
								 OtherInfo_ptr,
			  				     KDFhashMode,
			                     derivation_mode,
			                     KeyingData_ptr,
			                     KeyingDataSizeBytes );

}/* END OF _DX_KDF_KeyDerivationFunc */	

