  /*
   *  Object %CRYS_AES_WRAP.c    : %
   *  State           :  %state%
   *  Creation date   :  Sept 28 2006
   *  Last modified   :  %modify_time%
   */
  /** @file
   *  \brief This file contains the primitives performing AES Key Wrap algorithms 
   *         according to [1] - RFC3394 September 2002 .
   * 
   *  \version CRYS_AES_WRAP.c#1:csrc:1
   *  \author  R.Levin.
   *  \remarks Copyright (C) 2006 by Discretix Technologies Ltd.
   *           All Rights reserved
   */


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

#include "DX_VOS_Mem.h"
#include "DX_VOS_Errors.h"
#include "CRYS.h" 
#include "CRYS_AES_error.h" 
#include "dx_hw_defs.h"
#include "crys_host_op_code.h"



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

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

/************************ Typedefs **************************************/

/************************ Global Data ***********************************/


/************* Private function prototype *******************************/

/************************ Public Functions ******************************/
#ifndef _INTERNAL_CRYS_NO_AES_WRAP_SUPPORT
/**************************************************************************
 *	              CRYS_AES_Wrap function                                 *
 **************************************************************************/
/**
   @brief  The CRYS_AES_Wrap function implements the following algorithm 
           (rfc3394, Sept. 2002):  
   
   Inputs:  Plaintext DataIn, n 64-bit values {P1, P2, ..., Pn}, 
            KeyData, K (the KEK).                
   Outputs: Ciphertext, WrapDataOut (n+1) 64-bit values {C0, C1, ..., Cn}.
  
   Steps:
		   1. Initialize variables.
		       Set A = IV, an initial value (see 2.2.3)
		       For i = 1 to n
		           R[i] = P[i]
		   2. Calculate intermediate values.
		       For j = 0 to 5
		           For i=1 to n
		               B = AES(K, A | R[i])
		               A = MSB(64, B) ^ t ,   
		                    where: t = (n*j)+i  and  "^"  is the  XOR  operation.   
		               R[i] = LSB(64, B)
		   3. Output the result C.
		       Set C[0] = A
		       For i = 1 to n
		           C[i] = R[i].
	
   @param[in]  DataIn_ptr - A pointer to plain text data to be wrapped
                            NOTE: Overlapping between the data input and data output buffer
                                  is not allowed, except the inplace case that is legal . 			
   @param[in]  DataInLen  - Length of data in bytes. DataLen must be multiple of 
                            8 bytes and  must be in range [8,2^28].
   @param[in]  KeyData	  - A pointer to  key data (key encryption key - KEK). 
   @param[in]  KeySize	  - Enumerator variable, defines length of key.
   @param[in]  isSecretKey - Variable, defining is secret key used (1) or not (0).
   @param[out] WrapDataOut_ptr -	A pointer to buffer for output of wrapped data.
   @param[in/out] WrapDataLen_ptr - A pointer to a buffer for input of size of 
                                    user passed buffer and for output actual 
                                    size of unwrapped data in bytes. Buffer size must 
                                    be not less than DataLen+CRYS_AES_WRAP_BLOCK_SIZE_IN_BYTES. 
      
   @return CRYSError_t - CRYS_OK, or error message                         
                         CRYS_AES_WRAP_ILLEGAL_DATA_PTR_ERROR            
                         CRYS_AES_WRAP_DATA_LENGTH_ERROR                 
                         CRYS_AES_WRAP_ILLEGAL_KEY_PTR_ERROR             
                         CRYS_AES_WRAP_KEY_LENGTH_ERROR                  
                         CRYS_AES_WRAP_ILLEGAL_WRAP_DATA_PTR_ERROR      
                         CRYS_AES_WRAP_ILLEGAL_WRAP_DATA_LEN_PTR_ERROR  
                         CRYS_AES_WRAP_ILLEGAL_WRAP_DATA_LENGTH_ERROR
						 CRYS_AES_WRAP_DATA_OUT_DATA_IN_OVERLAP_ERROR
                         CRYS_AES_WRAP_IS_SECRET_KEY_FLAG_ILLEGAL_ERROR

    NOTE:  On error exiting from function the output buffer may be zeroed by the function.
   
*/
CEXPORT_C  CRYSError_t CRYS_AES_Wrap (
                               DxUint8_t            *DataIn_ptr,      /*in*/   
                               DxUint32_t            DataInLen,       /*in*/
                               CRYS_AES_Key_t        KeyData,         /*in*/
                               CRYS_AES_KeySize_t    KeySize,         /*in*/
							   DxInt8_t              isSecretKey,     /*in*/
                               DxUint8_t            *WrapDataOut_ptr, /*out*/
                               DxUint32_t           *WrapDataLen_ptr  /*in/out*/ ) 
{
	
	return DX_HW_Dispatcher_ptr( DX_SEP_HOST_SEP_PROTOCL_HOST_AES_WRAP_OP_CODE, 7,
	   							 /* PARAMETERS: */
								 DataIn_ptr, DataInLen,
								 KeyData, KeySize,
								 isSecretKey,
								 WrapDataOut_ptr, WrapDataLen_ptr);

}/* End of CRYS_AES_Wrap */

#endif /*_INTERNAL_CRYS_NO_AES_WRAP_SUPPORT */

#ifndef _INTERNAL_CRYS_NO_AES_UNWRAP_SUPPORT
/**************************************************************************
 *	              CRYS_AES_Unwrap function                                *
 **************************************************************************/
/**
   @brief  The CRYS_AES_Unwrap function performs inverse AES_Wrap transformation 
           and implements the following algorithm (rfc3394, Sept. 2002):  

   Inputs:  Ciphertext, WrapDataIn (n+1) 64-bit values {C0, C1, ..., Cn}, and
            K  - key (the KEK).
   Outputs: Plaintext, DataOut n 64-bit values {P1, P2, ..., Pn}.
   
   Steps:
		   1. Initialize variables:
		       Set A = C[0]
		       For i = 1 to n
		           R[i] = C[i]
		   2. Compute intermediate values:
		       For j = 5 to 0
		           For i = n to 1
		               B = AES-1(K, (A ^ t) | R[i]) , 
		                    where:  t = n*j+i  and  "^" is the  XOR  operation.   
		               A = MSB(64, B)
		               R[i] = LSB(64, B)
		   3. Output results:
		   If A is an appropriate initial value (see 2.2.3), then
		       For i = 1 to n
		           P[i] = R[i]
		   Else
		       Return an error.
		       
   @param[in]  WrapDataIn_ptr - A pointer to wrapped data to be unwrapped 
                                NOTE: Overlapping between the data input and data output buffer
                                      is not allowed, except the inplace case that is legal . 			
   @param[in]  WrapDataInLen  - Length of wrapped data in bytes. DataLen must be multiple of 
                                8 bytes and  must be in range [16, (2^28+8)].
   @param[in]  KeyData        - A pointer to  key data (key encryption key - KEK). 
   @param[in]  KeySize        - Enumerator variable, defines length of key.
   @param[in]  isSecretKey    - Variable, defining is secret key used (1) or not (0).
   @param[out] DataOut_ptr    - A pointer to buffer for output of unwrapped data.
   @param[in/out]  DataOutLen_ptr - A pointer to a buffer for input of size of user passed 
                              buffer and for output of actual size of unwrapped data in bytes.
                              DataOutLen must be multiple of 8 bytes and must be not less
                              than WrapDataInLen - CRYS_AES_WRAP_BLOCK_SIZE_IN_BYTES.
                           
   @return CRYSError_t - CRYS_OK, or error message 
                         CRYS_AES_UNWRAP_WRAP_DATA_LENGTH_ERROR          
                         CRYS_AES_UNWRAP_ILLEGAL_KEY_PTR_ERROR           
                         CRYS_AES_UNWRAP_KEY_LEN_ERROR                   
                         CRYS_AES_UNWRAP_ILLEGAL_DATA_PTR_ERROR          
                         CRYS_AES_UNWRAP_ILLEGAL_DATA_LEN_PTR_ERROR      
                         CRYS_AES_UNWRAP_ILLEGAL_DATA_LENGTH_ERROR       
                         CRYS_AES_UNWRAP_FUNCTION_FAILED_ERROR 
						 CRYS_AES_UNWRAP_DATA_OUT_DATA_IN_OVERLAP_ERROR 
						 CRYS_AES_UNWRAP_IS_SECRET_KEY_FLAG_ILLEGAL_ERROR

    NOTE:  On error exiting from function the output buffer may be zeroed by the function.
*/ 

CEXPORT_C  CRYSError_t CRYS_AES_Unwrap(
                                   DxUint8_t            *WrapDataIn_ptr,  /*in*/   
                                   DxUint32_t            WrapDataInLen,   /*in*/
                                   CRYS_AES_Key_t        KeyData,         /*in*/
                                   CRYS_AES_KeySize_t    KeySize,         /*in*/ 
								   DxInt8_t              isSecretKey,     /*in*/
                                   DxUint8_t            *DataOut_ptr,     /*out*/
                                   DxUint32_t           *DataOutLen_ptr   /*in/out*/ )
                                
{
  /*****************  LOCAL DECLARATIONS  ********************************/

	return DX_HW_Dispatcher_ptr( DX_SEP_HOST_SEP_PROTOCL_HOST_AES_UNWRAP_OP_CODE, 7,
	   							 /* PARAMETERS: */
								 WrapDataIn_ptr, WrapDataInLen,
								 KeyData, KeySize,
								 isSecretKey,
								 DataOut_ptr, DataOutLen_ptr);
 
}/* End of CRYS_AES_Uwnrap */

#endif /* _INTERNAL_CRYS_NO_AES_UNWRAP_SUPPORT */

