/*
  Copyright (c) 2004,   Beijing Senselock Data Security Centre
  All rights reserved.
  
  File£ºsample_32_hw.c
  
  Briefs£ºThis code will 
    
*/

#include <string.h>
#include "..\..\inc\hardware\ses_v3.h"
#include "..\inc\sample_32.h"

#define _DEBUG

/* global variable defination. */
unsigned char last_ses_error = 0; /* last SES error */
IO_PACKAGE out_pkg;  /* output package */
IO_PACKAGE *output = &out_pkg; 
IO_PACKAGE *input = (IO_PACKAGE *)pbInBuff; /* input package */
unsigned char tmp_buf[MAX_IO_DATA_SIZE];


/*
	Exit upon an error.
  
	Parameters:
		errcode[in]: error code
		msg[in]: additional error message
		msglen[in]: message length
  
	Return:
		none.

	Remarks:
		none.
*/
void error_exit(unsigned char errcode, unsigned char *msg, int msglen)
{
	output->tag = errcode;
	output->len = 0;
	
	/* for debug purpose only */
#ifdef  _DEBUG
	if (msglen != 0 && msg != NULL)
	{
		memcpy(output->buff, msg, msglen);
		output->len = msglen;
	}
#endif

	_set_response(2+output->len, (unsigned char *)output);
	_exit();
}

int enc_dec_ecb(unsigned char cmd, unsigned char *key, unsigned char *in,  unsigned char inlen, 
                                   unsigned char *out, unsigned char *outlen)
{
	unsigned char ret = 0;
	unsigned char length = 0;
	if ((inlen > 248)||(inlen < 1))
	{
		return ERR_INVALID_PARAMETER;
	} 
	length = ((inlen+7)>>3)<<3;
	if (*outlen < length) /* insufficient buffer size */
	{
		return ERR_INVALID_PARAMETER;
	} 
	ret = _mem_copy(tmp_buf, in, inlen);
	if (ret != SES_SUCCESS)
	{
		last_ses_error = ret;
		return ERR_SES;
	}
	switch(cmd)
	{
		case DES_ENC_ECB:
			ret = _des_enc(key, inlen, tmp_buf);			
		break;
		case DES_DEC_ECB:
			ret = _des_dec(key, inlen, tmp_buf);						
		break;
		case TDES_ENC_ECB:
			ret = _tdes_enc(key, inlen, tmp_buf);			
		break;
		case TDES_DEC_ECB:
			ret = _tdes_dec(key, inlen, tmp_buf);			
		break;		
		default:
			return ERR_INVALID_PARAMETER;
	}
	if (ret != SES_SUCCESS)
	{
		last_ses_error = ret;
		return ERR_SES;
	}
	ret = _mem_copy(out, tmp_buf, length);
	if (ret != SES_SUCCESS)
	{
		last_ses_error = ret;
		return ERR_SES;
	}
	*outlen = length;
	return ERR_SUCCESS;
}

void main()
{
	unsigned char ret = 0;
	unsigned char length = 0;
	unsigned char tmp_length = 0;
	unsigned char i = 0;
	HANDLE hFile ;
	unsigned char idata key[8] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07};//,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F};
	unsigned long tmp_sum = 0;
	unsigned char tmp_buf1[MAX_IO_DATA_SIZE];
	switch (input->tag)
	{
		case CMD_USE_SEC_FILE:
			length = 0;
			ret = _open(SEC_FILE_ID, &hFile);
			if (ret == SES_SUCCESS)
			{
				ret = _read(hFile, 0, 1, &length); 
				if (ret == SES_SUCCESS)
				{
					ret = _read(hFile, 1, length, tmp_buf1);
					if (ret == SES_SUCCESS)
					{
						tmp_length = MAX_IO_DATA_SIZE;
						ret = enc_dec_ecb(DES_DEC_ECB, key, tmp_buf1, length, tmp_buf1, &tmp_length);
						if (ret != ERR_SUCCESS)
						{
							_close(hFile);
							if (ret == ERR_SES)
							{
								error_exit(ERR_SES, &last_ses_error, 1);
							}
							error_exit(ret,	NULL, 0);
						}

						for ( i=0; i<tmp_length; i++)// use tmp_buf1 here, for example: calculate their sum 
						{
							tmp_sum += tmp_buf1[i];	
						}
						length  = sizeof(tmp_sum);
						CC_TO_LE32(&tmp_sum);

						ret = _mem_copy(output->buff, &tmp_sum, length);	
					}
				}
				_close(hFile);	
			}
		break;
		default:
			error_exit(ERR_INVALID_PARAMETER, NULL, 0);
	} 
	if (ret != SES_SUCCESS)
	{
		error_exit(ERR_SES, &ret, 1);
	}
	
	output->tag = ERR_SUCCESS;
	output->len = (unsigned char)length;
	_set_response(IO_PACKAGE_HEADER_SIZE+output->len, (unsigned char *)output);
	_exit();  
}
