
  /*
   *  Object %name    : %
   *  State           :  %state%
   *  Creation date   :  Tue Feb 01 17:15:04 2005
   *  Last modified   :  %modify_time%
   */
  /** @file
   *  \brief A brief description of this module
   *
   *  \version CRYS_DH.c#1:csrc:8
   *  \author ohads
   *  \remarks Copyright (C) 2004 by Discretix Technologies Ltd.
   *           All Rights reserved
   */



/************* Include Files ****************/
#include "DX_VOS_Mem.h"
#include "CRYS_DH_errors.h"
#include "CRYS.h"
#include "PLAT_SystemDep.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 *********************************/

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

/**
 * @brief 
 	_DX_DH_GeneratePubPrv has 2 functionalities:
 	1. randomly generates the Client private key 
 	2. compute the Client public key which is 
 		ClientPub = Generator ^ Prv mod Prime 
 		
 	Note: All buffers arguments are represented in Big-Endian
 	
  @param[in] Generator_ptr 		- Pointer to the Generator octet string
  @param[in] GeneratorSize 		- Size of the Generator String (in bytes)
  @param[in] Prime_ptr 			- Pointer to the Prime octet string
  @param[in] PrimeSize 			- Size of the Prime string (in bytes)
  @param[in] L 					- Relevant only for PKCS#3, the private value length in bits
  								  If L != 0 then - force the private key to be 2^(L-1) <= Prv < 2^l
  				 					if L 0 then: 0< Prv < P-1
  				 				  In ANSI X9.42 L is irrelevant  
  @param[in] Q_ptr 				- Relevant only for ANSI X9.42 - Pointer to the Q octet string
  									1<= Prv <= q-1   or   1< Prv < q-1
  @param[in] QSize	 			- Relevant only for ANSI X9.42 - Size of the Q string (in bytes)  				 				  
  @param[in] DH_mode			- enum declaring weather this is PKCS#3 or ANSI X9.42
  
  @param[in] UserPubKey_ptr		- a pointer to the publick key structure. used for the Exp operation function
  									the struct doesn't need to be initialized
  @param[in] PrimeData_ptr 		- a pointer to a structure containing internal buffers  
                                    the struct doesn't need to be initialized
  @param[out] ClientPrvKey_ptr  - Pointer to the Private key octet string - 
  							  	  In PKCS#3 This buffer should be at least the following size
	  							  	  2^L - 1 - if L is provided (size of buffer*8 >= L).
	  							  	  P-1	  - if L is DX_NULL (size of buffer >= PrimeSize).
								  In X9.42 size of buffer >= QSize.	  							  	  
  @param[in/out] ClientPrvKeySize_ptr - The user should provide the size of the buffer indicated by ClientPrvKey_ptr
                                        The function returns the actual size in bytes of the Private key Size
  @param[out] ClientPub_ptr 	- Pointer to the Public key octet string
  						  		  This Buffer should be at least PrimeSize bytes
  							  
  @param[in/out] ClientPubSize_ptr -    The user should provide the size of the buffer indicated by ClientPub_ptr
                                        The function returns the actual size in bytes of the client public buffer
 
  @return CRYSError_t - On success CRYS_OK is returned, on failure an ERROR as defined CRYS_DH_error.h:
                        CRYS_DH_INVALID_ARGUMENT_POINTER_ERROR;      
   						CRYS_DH_INVALID_ARGUMENT_SIZE_ERROR;
    					CRYS_DH_INVALID_ARGUMENT_OPERATION_MODE_ERROR;   						
						CRYS_DH_ARGUMENT_GENERATOR_SMALLER_THAN_ZERO_ERROR;
						CRYS_DH_ARGUMENT_PRIME_SMALLER_THAN_GENERATOR_ERROR;						
						CRYS_DH_INVALID_L_ARGUMENT_ERROR;
						CRYS_DH_ARGUMENT_PRV_SIZE_ERROR;						
    					CRYS_DH_INVALID_ARGUMENT_OPERATION_MODE_ERROR;
 */

CEXPORT_C CRYSError_t _DX_DH_GeneratePubPrv(DxUint8_t *Generator_ptr,
                                    DxUint16_t GeneratorSize,
                                    DxUint8_t *Prime_ptr,
                                    DxUint16_t PrimeSize,
                                    DxUint16_t L,
                                    DxUint8_t *Q_ptr,
                                    DxUint16_t QSize,
                                    CRYS_DH_OpMode_t DH_mode,
                                    CRYS_DHUserPubKey_t *UserPubKey_ptr,
                                    CRYS_DHPrimeData_t  *PrimeData_ptr,
                                    DxUint8_t *ClientPrvKey_ptr,
                                    DxUint16_t *ClientPrvKeySize_ptr,
                                    DxUint8_t *ClientPub1_ptr,
                                    DxUint16_t *ClientPubSize_ptr)

{
  
 	return DX_HW_Dispatcher_ptr( DX_SEP_HOST_SEP_PROTOCOL_HOST_DH_GEN_PUB_PRV_OP_CODE, 14,
	   							 /* PARAMETERS: */
							 	 Generator_ptr,
                                 GeneratorSize,
                                 Prime_ptr,
                                 PrimeSize,
                                 L,
                                 Q_ptr, QSize,
                                 DH_mode,
                                 UserPubKey_ptr,
                                 PrimeData_ptr,
                                 ClientPrvKey_ptr,
                                 ClientPrvKeySize_ptr,
                                 ClientPub1_ptr,
                                 ClientPubSize_ptr ); 

    
}/* END OF _DX_DH_GeneratePubPrv */				                    



/****************************************************************/
/**
 * @brief CRYS_DH_PKCS3_GetSecretKey computes the shared secret key in the following computation:
 	SecretKey = ServerPubKey ^ ClientPrvKey mod Prime
 
  	Note: All buffers arguments are represented in Big-Endian
 
  @param[in] ClientPrvKey_ptr 	- Pointer to the Private key octet string - 
  @param[in] ClientPrvKeySize  	- The Private key Size (in bytes)
  @param[in] ServerPubKey_ptr   - Pointer to the Server public key octet string - 
  @param[in] ServerPubKeySize   - The Server Public key Size (in bytes)
  @param[in] Prime_ptr 			- Pointer to the Prime octet string
  @param[in] PrimeSize 			- Size of the Prime string
  @param[in] UserPubKey_ptr		- a pointer to the publick key structure. used for the Exp operation function
                                  the struct doesn't need to be initialized
  @param[in] PrimeData_ptr 		- a pointer to a structure containing internal buffers
                                  the struct doesn't need to be initialized    
  @param[out] SecretKey_ptr 	- Pointer to the secret key octet string.
  							  	  This buffer should be at least PrimeSize Bytes
  							  
  @param[in/out] SecretKeySize_ptr - The user should provide the actual size in bytes of the buffer indicated by SecretKey_ptr
                                    The function will return the actual size in bytes of the output secret key

  @return CRYSError_t - On success CRYS_OK is returned, on failure an ERROR as defined CRYS_DH_error.h:
					    CRYS_DH_INVALID_ARGUMENT_POINTER_ERROR;      
   					    CRYS_DH_INVALID_ARGUMENT_SIZE_ERROR;
					    CRYS_DH_SECRET_KEY_SIZE_OUTPUT_ERROR;

*/

 CEXPORT_C CRYSError_t CRYS_DH_PKCS3_GetSecretKey(DxUint8_t *ClientPrvKey_ptr,
				                    DxUint16_t ClientPrvKeySize,
 				                    DxUint8_t *ServerPubKey_ptr,
				                    DxUint16_t ServerPubKeySize,				                    
				                    DxUint8_t *Prime_ptr,
				                    DxUint16_t PrimeSize,
                                    CRYS_DHUserPubKey_t *UserPubKey_ptr,
                                    CRYS_DHPrimeData_t  *PrimeData_ptr, 				                    
				                    DxUint8_t *SecretKey_ptr,
				                    DxUint16_t *SecretKeySize_ptr)
				                    
				                    
{
  
 	return DX_HW_Dispatcher_ptr( DX_SEP_HOST_SEP_PROTOCOL_HOST_DH_GET_SEC_KEY_OP_CODE, 10,
	   							 /* PARAMETERS: */
								 ClientPrvKey_ptr,
				                 ClientPrvKeySize,
 				                 ServerPubKey_ptr,
				                 ServerPubKeySize,				                    
				                 Prime_ptr,
				                 PrimeSize,
                                 UserPubKey_ptr,
                                 PrimeData_ptr, 				                    
				                 SecretKey_ptr,
				                 SecretKeySize_ptr );
    
}

/****************************************************************/
/**
 * @brief _DX_DH_KeyDerivationFunc specifies the key derivation function, either based on ASN.1 DER encoding
 			or based on the concatanation of fields as specified in ANSI X9.42-2001.
 			The purpose of this function is to derive a key data from the shared secret value.
 			
	The actual APIs that will be used by the user are:
		CRYS_DH_ASN1_KeyDerivation_SHA1Func 			
		CRYS_DH_Concat_KeyDerivation_SHA1Func
 			
  \note The length in Bytes of the hash result buffer is denoted by "hashlen".
  \note The standard states that optional "other info" may be passed as input to
        the derivation function. This implementation does not support this option.
  \note All buffers arguments are represented in Big-Endian format.
 
  @param[in] ZZSecret_ptr 	- A pointer to shared secret key octet string 
  @param[in] ZZSecretSize  	- The shared secret key Size, in bytes
  @param[in] hashFunc 		- The hash function to be used. The hash function output must be at least 160 bits.
  @param[in] KeyLenInBits	- The size in Bits of the keying data to be generated - 
  								KeyLenInBits < hashlen*(2^32-1) - in our implementation the size should not 
  								be larger than the maximum input size to the Hash function
  @param[in] derivation_mode - Specifies whether we use an ASN.1-based derivation function 
                               or a derivation based on concatenation.
  @param[out] KeyingData_ptr - A pointer to the keying data derived from the secret key, of length KeyLenInBits
  							  
  @return CRYSError_t - On success the value CRYS_OK is returned, and on failure an ERROR as defined in CRYS_DH_error.h:
  						CRYS_DH_INVALID_ARGUMENT_POINTER_ERROR;
   						CRYS_DH_INVALID_ARGUMENT_SIZE_ERROR;
   						CRYS_DH_INVALID_ARGUMENT_HASH_MODE_ERROR;

*/

CEXPORT_C CRYSError_t _DX_DH_KeyDerivationFunc(DxUint8_t *ZZSecret_ptr,
                                      DxUint16_t ZZSecretSize,
                                      CRYS_DH_HASH_OpMode_t hashFunc,				                    
                                      DxUint32_t KeyLenInBits,				                    
                                      DxUint8_t *KeyingData_ptr,
                                      CRYS_DH_DerivationFunc_Mode derivation_mode)
{
  
 	return DX_HW_Dispatcher_ptr( DX_SEP_HOST_SEP_PROTOCOL_HOST_DH_DER_KEY_OP_CODE, 6,
	   							 /* PARAMETERS: */
								 ZZSecret_ptr,
                                 ZZSecretSize,
                                 hashFunc,				                    
                                 KeyLenInBits,				                    
                                 KeyingData_ptr,
                                 derivation_mode );
    
}/* END OF _DX_DH_KeyDerivationFunc */				                    
				                    
				                    
/****************************************************************/
/**
 * @brief _DX_DH_X942_GetSecretData computes the shared secret key as follows:
 		1. OPTIONAL - validate the correctness of the argument keys
 		2. SecretKey = ServerPubKey ^ ClientPrvKey mod Prime
 		3. Use of Derivation function to derive a data key from the secret key 
 
 	The actual APIs that will be used by the user are:
 	CRYS_DH_X942_GetSecret_ASN1_2_Data
 	CRYS_DH_X942_GetSecret_Concat_2_Data
 
  	Note: All buffers arguments are represented in Big-Endian format

  @param[in] UserPubKey_ptr		- A pointer to the public key data structure. Not initialized.
  @param[in] PrimeData_ptr 		- A pointer to a CRYS_RSAPrimeData_t structure 
   								  that is used for the Exp operation
  @param[in] hashFunc			- The hash function to be used
  @param[in] ClientPrvKey_ptr 	- A pointer to the Private key octet string 
  @param[in] ClientPrvKeySize  	- The Private key size, in bytes
  @param[in] ServerPubKey_ptr   - A pointer to the Server public key octet string - 
  @param[in] ServerPubKeySize   - The Server Public key size, in bytes
  @param[in] Prime_ptr 			- A pointer to the Prime octet string
  @param[in] PrimeSize 			- The size of the Prime string
  @param[in] DerFunc_mode 		- The type of function to derive the secret key to the key data.
  								  We use ASN.1-based function or Hash concatenation function mode.
  @param[out] SecretKeyData_ptr	- A pointer to the secret key octet string. 
				  				  This buffer should be at least PrimeSize bytes.
  @param[in] SecretKeyDataSizeBitsNeeded - Specifies the derived Secret Key data size needed in Bits. This value converted to bytes 
                                  cannot be larger than PrimeSize (required by implementation)

  @return CRYSError_t - On success CRYS_OK is returned, on failure an ERROR as defined CRYS_DH_error.h:
						CRYS_DH_SECRET_KEY_SIZE_NEEDED_ERROR;
						CRYS_DH_SECRET_KEY_SIZE_NEEDED_BIGGER_THAN_PRIME_SIZE;
*/
CEXPORT_C CRYSError_t _DX_DH_X942_GetSecretData(CRYS_DHUserPubKey_t *UserPubKey_ptr,
                                       CRYS_DHPrimeData_t  *PrimeData_ptr, 
                                       CRYS_DH_HASH_OpMode_t hashFunc,									
                                       DxUint8_t *ClientPrvKey_ptr,
                                       DxUint16_t ClientPrvKeySize,
                                       DxUint8_t *ServerPubKey_ptr,
                                       DxUint16_t ServerPubKeySize,				                    
                                       DxUint8_t *Prime_ptr,
                                       DxUint16_t PrimeSize,
                                       CRYS_DH_DerivationFunc_Mode DerFunc_mode,
                                       DxUint8_t *SecretKeyData_ptr,
                                       DxUint16_t SecretKeyDataSizeBitsNeeded)
{
   
 	return DX_HW_Dispatcher_ptr( DX_SEP_HOST_SEP_PROTOCOL_HOST_DH_X942_GET_SEC_DATA_OP_CODE, 12,
	   							 /* PARAMETERS: */
								 UserPubKey_ptr,
                                 PrimeData_ptr, 
                                 hashFunc,									
                                 ClientPrvKey_ptr,
                                 ClientPrvKeySize,
                                 ServerPubKey_ptr,
                                 ServerPubKeySize,				                    
                                 Prime_ptr,
                                 PrimeSize,
                                 DerFunc_mode,
                                 SecretKeyData_ptr,
                                 SecretKeyDataSizeBitsNeeded );

}/* END OF _DX_DH_X942_GetSecretData */				                    


/****************************************************************/
/**
 * @brief _DX_DH_X942_Hybrid_GetSecretData computes the shared secret key as follows:
 		1. OPTIONAL - validate the correctness of the argument keys
 		2. SecretKey1 = ServerPubKey1 ^ ClientPrvKey1 mod Prime
 		3. SecretKey2 = ServerPubKey2 ^ ClientPrvKey2 mod Prime
 		3. Use of Derivation function to derive a data key from the 2 secret keys 
 
 	The actual APIs that will be used by the user are:
 	CRYS_DH_X942_Hybrid_GetSecret_ASN1_2_Data
 	CRYS_DH_X942_Hybrid_GetSecret_Concat_2_Data
 
  	Note: All buffers arguments are represented in Big-Endian format.
 
  @param[in] UserPubKey_ptr		- A pointer to the public key data structure. Not initialized.
  @param[in] PrimeData_ptr 		- A pointer to a CRYS_RSAPrimeData_t structure 
                                  that is used for the Exp operation
  @param[in] hashFunc			- The hash function to be used
  @param[in] ClientPrvKey_ptr1 	- A pointer to the First Private key octet string number 
  @param[in] ClientPrvKeySize1 	- The First Private key Size, in bytes
  @param[in] ClientPrvKey_ptr2 	- A pointer to the Second Private key octet string
  @param[in] ClientPrvKeySize2 	- The Second Private key Size, in bytes
  @param[in] ServerPubKey_ptr1  - A pointer to the First Server public key octet string
  @param[in] ServerPubKeySize1  - The First Server Public key Size, in bytes
  @param[in] ServerPubKey_ptr2  - A pointer to the Second Server public key octet string
  @param[in] ServerPubKeySize2  - The Second Server Public key Size, in bytes
  @param[in] Prime_ptr 			- A pointer to the Prime octet string
  @param[in] PrimeSize 			- The size of the Prime string
  @param[in] DerFunc_mode 		- The type of function to derive the secret key to the key data.
                                  We use an ASN.1-based function or a Hash concatenation function mode.
  @param[out] SecretKeyData_ptr - A pointer to the secret key octet string.
			  	                  This buffer should be at least 2*PrimeSize bytes.
  							  
  @param[in] SecretKeyDataSizeBitsNeeded - Specifies the derived Secret Key data size needed in Bits. This value converted to bytes 
                                  cannot be larger than PrimeSize (required by implementation)

  @return CRYSError_t - On success the value CRYS_OK is returned, and on failure an ERROR as defined in CRYS_DH_error.h:
						CRYS_DH_SECRET_KEY_SIZE_NEEDED_ERROR;
						CRYS_DH_SECRET_KEY_SIZE_NEEDED_BIGGER_THAN_PRIME_SIZE;
						CRYS_DH_X942_HYBRID_SIZE1_BUFFER_ERROR;
                        CRYS_DH_INVALID_ARGUMENT_POINTER_ERROR;      
   						CRYS_DH_INVALID_ARGUMENT_SIZE_ERROR;
    					CRYS_DH_INVALID_ARGUMENT_OPERATION_MODE_ERROR;   						
						CRYS_DH_ARGUMENT_GENERATOR_SMALLER_THAN_ZERO_ERROR;
						CRYS_DH_ARGUMENT_PRIME_SMALLER_THAN_GENERATOR_ERROR;						
						CRYS_DH_INVALID_L_ARGUMENT_ERROR;
						CRYS_DH_ARGUMENT_PRV_SIZE_ERROR;						
    					CRYS_DH_INVALID_ARGUMENT_OPERATION_MODE_ERROR;
*/
CEXPORT_C CRYSError_t _DX_DH_X942_Hybrid_GetSecretData(CRYS_DHUserPubKey_t *UserPubKey_ptr,
                                              CRYS_DHPrimeData_t  *PrimeData_ptr, 
                                              CRYS_DH_HASH_OpMode_t hashFunc,		
                                              DxUint8_t *ClientPrvKey_ptr1,
                                              DxUint16_t ClientPrvKeySize1,
                                              DxUint8_t *ClientPrvKey_ptr2,
                                              DxUint16_t ClientPrvKeySize2,				                    
                                              DxUint8_t *ServerPubKey_ptr1,
                                              DxUint16_t ServerPubKeySize1,
                                              DxUint8_t *ServerPubKey_ptr2,
                                              DxUint16_t ServerPubKeySize2,				                    				                    
                                              DxUint8_t *Prime_ptr,
                                              DxUint16_t PrimeSize,
                                              CRYS_DH_DerivationFunc_Mode DerFunc_mode,
                                              DxUint8_t *SecretKeyData_ptr,
                                              DxUint16_t SecretKeyDataSizeBitsNeeded)

{
  
 	return DX_HW_Dispatcher_ptr( DX_SEP_HOST_SEP_PROTOCOL_HOST_DH_X942_GET_HYBRID_SEC_DATA_OP_CODE, 16,
	   							 /* PARAMETERS: */
								 UserPubKey_ptr,
                                 PrimeData_ptr, 
                                 hashFunc,		
                                 ClientPrvKey_ptr1,
                                 ClientPrvKeySize1,
                                 ClientPrvKey_ptr2,
                                 ClientPrvKeySize2,				                    
                                 ServerPubKey_ptr1,
                                 ServerPubKeySize1,
                                 ServerPubKey_ptr2,
                                 ServerPubKeySize2,				                    				                    
                                 Prime_ptr,
                                 PrimeSize,
                                 DerFunc_mode,
                                 SecretKeyData_ptr,
                                 SecretKeyDataSizeBitsNeeded );

}/* END OF _DX_DH_X942_Hybrid_GetSecretData */				                    

                          
