/**@@@+++@@@@******************************************************************
**
** Microsoft Windows Media
** Copyright (C) Microsoft Corporation. All rights reserved.
**
***@@@---@@@@******************************************************************
*/

#include <drmcommon.h>
#include <drmdes.h>
#include "DX_VOS_BaseTypes.h"
#include "SEPDriver.h"
#include "error.h"
#include "wmdrm_host_op_code.h" 
#include "DX_VOS_Mem.h"



/******************************************************************************/
/* Function that sends the key and get context for the DES*/

DRM_VOID DRM_API DRM_DES_KeySetup(
    OUT       DESTable *pTable,
    IN  const DRM_BYTE  rgbKey[__CB_DECL(DES_KEYSIZE)] )
{
    DRM_RESULT Error = DRM_SUCCESS;
    /* offset into SRAM */
    DRM_ULONG   sramOffset;
    /* read param */
    DRM_ULONG   messageParam[2];
    /* max length */
    DRM_ULONG   maxLength;

	/* lock access to the SEP */
    Error = SEPDriver_Lock();
	if(Error != DX_OK)
    {
		return;
	}
	/*----------------------------
      start sending message to SEP 
   -----------------------------*/
   sramOffset = 0;
   
   /* start the message */
   SEPDriver_StartMessage(&sramOffset);
  
   /* prepare message */
   messageParam[0] = DX_SEP_HOST_SEP_PROTOCL_HOST_WMDRM_DES_KEY_SETUP_OP_CODE;
   /* send opcode */
   Error = SEPDriver_WriteParamater((DRM_ULONG)&messageParam[0],
                            sizeof(DRM_ULONG),
                            sizeof(DRM_ULONG),
                            &sramOffset,
                            DX_FALSE);
   if(Error != DX_OK)
   {
       goto end_function_unlock;
   }
   
   /* send data */
   Error = SEPDriver_WriteParamater((DRM_ULONG)rgbKey , 
                             DES_KEYSIZE ,
                             DES_KEYSIZE, 
                             &sramOffset , 
                             DX_FALSE);
   /* end message */
   SEPDriver_EndMessage(sramOffset);
            
   /* wait for the response */
   Error = SEPDriver_POLL_FOR_REPONSE();
   if(Error != DX_OK)
   {
     goto end_function_unlock;
   }
   
   /*-------------------
      start reading message from the SEP 
   ---------------------*/
   
   /* start the message */
   Error = SEPDriver_StartIncomingMessage(&sramOffset);
   if(Error)
   {
      goto end_function_unlock;
   }
   
   /* read opcode + status  */
   Error = SEPDriver_ReadParamater((DRM_ULONG)&messageParam[0],
                            sizeof(DRM_ULONG) * 2,
                            sizeof(DRM_ULONG) * 2,
                            &sramOffset ,
                            DX_FALSE);
   if(Error != DX_OK)
   {
       goto end_function_unlock;
   }
   
   /* check the opcode */
   if(messageParam[0] != DX_SEP_HOST_SEP_PROTOCL_HOST_WMDRM_DES_KEY_SETUP_OP_CODE)
   {
      Error = DX_WRONG_OPCODE_FROM_SEP_ERR;
      goto end_function_unlock;
   }
   
   /* check status */
   if(messageParam[1] != DRM_SUCCESS)
   {
      Error = messageParam[1];
      goto end_function_unlock;
   }
   
   /* read the context */
   maxLength = SEPDriver_ALIGNED_TO_MAX_LENGTH(sizeof(DESTable));

   Error = SEPDriver_ReadParamater((DRM_ULONG)pTable,
                           sizeof(DESTable),
                           maxLength ,
                           &sramOffset ,
                           DX_FALSE);

   if(Error != DX_OK)
   {
       goto end_function_unlock;
   }


end_function_unlock:   

   /* lock access to the SEP */
   SEPDriver_Unlock();

   return ;
}




/******************************************************************************/
/* Encrypt or decrypt a block of data in ECB mode */
DRM_VOID DRM_API DRM_DES_Cipher(
    const DRM_BYTE  rgbIn [__CB_DECL(DES_BLOCKLEN)],
          DRM_BYTE  rgbOut[__CB_DECL(DES_BLOCKLEN)],
          DESTable *pTable,
          DRM_INT   op)
{
    DRM_RESULT Error = DRM_SUCCESS;
    /* offset into SRAM */
    DRM_ULONG   sramOffset;
    /* read param */
    DRM_ULONG   messageParam[2];
    /* max length */
    DRM_ULONG   maxLength;

	/* lock access to the SEP */
    Error = SEPDriver_Lock();
	if(Error != DX_OK)
    {
		return;
	}
	/*----------------------------
      start sending message to SEP 
   -----------------------------*/
   sramOffset = 0;
   
   /* start the message */
   SEPDriver_StartMessage(&sramOffset);
  
   /* prepare message */
   messageParam[0] = DX_SEP_HOST_SEP_PROTOCL_HOST_WMDRM_DES_CIPHER_OP_CODE;
   /* send opcode */
   Error = SEPDriver_WriteParamater((DRM_ULONG)&messageParam[0],
                            sizeof(DRM_ULONG),
                            sizeof(DRM_ULONG),
                            &sramOffset,
                            DX_FALSE);
   if(Error != DX_OK)
   {
       goto end_function_unlock;
   }
   
   /* send opcode */
   Error = SEPDriver_WriteParamater((DRM_ULONG)&op , 
                             sizeof(DRM_INT) ,
                             sizeof(DRM_INT), 
                             &sramOffset , 
                             DX_FALSE);
   
   /* send data */
   Error = SEPDriver_WriteParamater((DRM_ULONG)rgbIn , 
                             DES_BLOCKLEN ,
                             DES_BLOCKLEN, 
                             &sramOffset , 
                             DX_FALSE);

   /* send the context */
   maxLength = SEPDriver_ALIGNED_TO_MAX_LENGTH(sizeof(DESTable));
   Error = SEPDriver_WriteParamater((DRM_ULONG)pTable,
                           sizeof(DESTable),
                           maxLength ,
                           &sramOffset ,
                           DX_FALSE);

   if(Error != DX_OK)
   {
       goto end_function_unlock;
   }

   /* end message */
   SEPDriver_EndMessage(sramOffset);
            
   /* wait for the response */
   Error = SEPDriver_POLL_FOR_REPONSE();
   if(Error != DX_OK)
   {
     goto end_function_unlock;
   }
   
   /*-------------------
      start reading message from the SEP 
   ---------------------*/
   
   /* start the message */
   Error = SEPDriver_StartIncomingMessage(&sramOffset);
   if(Error)
   {
      goto end_function_unlock;
   }
   
   /* read opcode + status  */
   Error = SEPDriver_ReadParamater((DRM_ULONG)&messageParam[0],
                            sizeof(DRM_ULONG) * 2,
                            sizeof(DRM_ULONG) * 2,
                            &sramOffset ,
                            DX_FALSE);
   if(Error != DX_OK)
   {
       goto end_function_unlock;
   }
   
   /* check the opcode */
   if(messageParam[0] != DX_SEP_HOST_SEP_PROTOCL_HOST_WMDRM_DES_CIPHER_OP_CODE)
   {
      Error = DX_WRONG_OPCODE_FROM_SEP_ERR;
      goto end_function_unlock;
   }
   
   /* check status */
   if(messageParam[1] != DRM_SUCCESS)
   {
      Error = messageParam[1];
      goto end_function_unlock;
   }
   
   /* read the data */

   Error = SEPDriver_ReadParamater((DRM_ULONG)rgbOut,
                           DES_BLOCKLEN,
                           DES_BLOCKLEN ,
                           &sramOffset ,
                           DX_FALSE);

   if(Error != DX_OK)
   {
       goto end_function_unlock;
   }


end_function_unlock:   

   /* lock access to the SEP */
   SEPDriver_Unlock();

   return ;
}


