/*****************************************************************************************
*  Copyright (c) 2004, Beijing Senselock Data Security Centre
*  All rights reserved.
*
*  Filename£ºsample_32_win32.c
*          
*  Briefs£º  The purpose of this snippet is to demonstrate how to 
*            use encrypted file in SenseLock EL. 
*            
*  History:        
*  --------------------------------------------------------        
*            10/28/2004 v1.0.0.0 Lihua created
*            
*            
*******************************************************************************************/

#include <stdio.h>
#include <conio.h>
#include <assert.h>

#include "..\..\inc\win32\sense4.h"
#include "..\..\inc\win32\crypt2.h"
#include "..\..\inc\win32\ses_err_msg.h"/* for debug purpose only */
#include "..\..\common\common.h"

#include "..\inc\sample_32.h"


/* global variables definition */
SENSE4_CONTEXT stS4Ctx = {0};
unsigned long dwResult = 0;
unsigned long dwBytesReturned = 0;

IO_PACKAGE stDataPkgIn = {0};
IO_PACKAGE stDataPkgOut = {0};

#define S4_EXE_FILE_ID "ef32"
#define SEC_FILE_SIZE 2000 // secret file size
#define SEC_FILE_ID_STR "0132" 
/* for debug purpose only : handle results returned by stDataPkgOut.tag */
#ifdef _DEBUG
void HandleError(unsigned char bErrCode, unsigned char *pbErrInfo)
{
	switch(bErrCode)
	{
	case ERR_SUCCESS:
		printf("Success!\n");
		break;
	case ERR_SES:
		printf("Error during SES Execution :\n%s\n", SesErrMsgs[*pbErrInfo]);
		break;
	case ERR_INVALID_PARAMETER:
		printf("Invalid input,pls check your input data\n");
		break;
	default:
		printf("Undefined error code!\n");
		break;
	}
	return;
}
#else
void HandleError(unsigned char bErrCode, unsigned char *pbErrInfo)
{
	return;
}	
#endif

/* check result for S4Execute(...) */
unsigned long CheckS4ExecutionResult(unsigned long dwResult,unsigned long dwBytesReturned,unsigned char tag)
{
	
	if (dwResult != S4_SUCCESS) 
	{
		printf("S4 Execution failed! <error code: 0x%08x>\n", dwResult);
		return 0;
	}
	
	if (dwBytesReturned < 2)
	{
		printf("Invalid data package returned!\n");
		return 0;
	}
	
	if (tag != ERR_SUCCESS)
	{
		HandleError(stDataPkgOut.tag, stDataPkgOut.buff);
		return 0;
	}
	return 1;
}


int main(int argc, char* argv[])
{
	unsigned char lpUserPin[8] = "12345678";
	unsigned char lpDevPin[24] = "123456781234567812345678";
	unsigned char key[8] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07};
    
	FILE *fp = NULL;
	DWORD sum = 0;
	unsigned char pt_buff[252]; // plaintext buffer
	unsigned char ct_buff[252]; // ciphertext buffer
	unsigned char ptlen = 0;   // maximum 0xFC
	unsigned char ctlen = 0;   // maximum 0xFC		
	unsigned long dwBytesWritten = 0;
	unsigned char c = 0;
    if (!(dwResult = OpenS4ByIndex(FIRST_S4_INDEX,&stS4Ctx)))
	{
		return 1;
	}   
	
	dwResult = S4ChangeDir(&stS4Ctx, "\\");
	if (dwResult != S4_SUCCESS) 
	{
		printf("Change directory failed! <error code: 0x%08x>\n",dwResult);
		S4Close(&stS4Ctx);
		return dwResult;
	}
	while (c != '3')
	{
		printf("1.Write DES-encrypted data file into SenseLock EL[dev mode];\
		\n2.Use data file in SenseLock EL to do some calculation [user mode];\
		\n3.Exit;\
		\nYour choice:");
		c = getch();
		switch(c) 
		{
		case '1':
			fp = fopen("plaintext.txt", "r");	
			if (fp == NULL)
			{
				printf("file not open!\n");
				S4Close(&stS4Ctx);
				return 1;
			}
			while (!feof(fp)) 
			{
				unsigned char ch;
				if (EOF != fscanf(fp, "%d", &ch))
				{
					pt_buff[ptlen++] = ch;
					sum += ch; 
				}
			}
			fclose(fp);
			
			ctlen = ((ptlen + 7)>>3)<<3;
			ct_buff[0] = ctlen;
			
			dwResult = DES(key, 1, ct_buff+1, pt_buff, ctlen);
			if (dwResult)
			{
				printf("Software DES encryption failed!\n");
				S4Close(&stS4Ctx);
				return dwResult;
			}
			dwResult = S4VerifyPin(&stS4Ctx, lpDevPin, sizeof(lpDevPin), S4_DEV_PIN);
			if (dwResult != S4_SUCCESS) 
			{
				printf("Verify DEV-Pin failed! <error code: 0x%08x>\n",dwResult);
				S4Close(&stS4Ctx);
				return dwResult;
			}	
			
			dwResult = S4WriteFile(&stS4Ctx, SEC_FILE_ID_STR, 0, ct_buff, ctlen+1, SEC_FILE_SIZE, &dwBytesWritten, 
				S4_CREATE_NEW , S4_DATA_FILE);
			if ((dwResult != S4_SUCCESS) && (dwResult != S4_FILE_EXIST))
			{
				printf("write file failed! <error code: 0x%08x>\n",dwResult);
				ResetAndCloseS4(&stS4Ctx);
				return dwResult;
			}
			else if (dwResult == S4_FILE_EXIST)
			{
				dwResult = S4WriteFile(&stS4Ctx, SEC_FILE_ID_STR, 0, ct_buff, ctlen+1, 0, &dwBytesWritten, 
					S4_UPDATE_FILE, S4_DATA_FILE);
				if (dwResult != S4_SUCCESS)
				{
					printf("write file failed! <error code: 0x%08x>\n",dwResult);
					ResetAndCloseS4(&stS4Ctx);
					return dwResult;
				}
			}/**/
			printf("Success!\n");
			printf("The sum of all the data in plaintext file %d\n", sum);
			
			break;
		case '2':
			// Call S4VerifyPin(...) to verify User PIN so as to get the privilege to execute the program in SenseLock EL.
			dwResult = S4VerifyPin(&stS4Ctx, lpUserPin, sizeof(lpUserPin), S4_USER_PIN);
			if (dwResult != S4_SUCCESS) 
			{
				printf("Verify USER-Pin failed! <error code: 0x%08x>\n",dwResult);
				S4Close(&stS4Ctx);
				return dwResult;
			}	

			stDataPkgIn.tag = CMD_USE_SEC_FILE;
			stDataPkgIn.len = 0; /* no input data */
			printf("Use secret file stored in SenseLock EL start...\n");
			dwResult = S4Execute(&stS4Ctx, S4_EXE_FILE_ID, &stDataPkgIn, 
				IO_PACKAGE_HEADER_SIZE+stDataPkgIn.len,
				&stDataPkgOut, sizeof(IO_PACKAGE), &dwBytesReturned);
			if (!CheckS4ExecutionResult(dwResult, dwBytesReturned, stDataPkgOut.tag))
			{
				ResetAndCloseS4(&stS4Ctx);
				return 1;
			}
			printf("Success!\n");
			printf("The sum of all the data returned from SenseLock EL:%d\n", *((DWORD *)stDataPkgOut.buff));
			break;
		case '3':
			break;
		default:
			printf("Incorrect input!\n");
		}
	}
	
	/* for better security,use the following instead of using S4close() directly */
	ResetAndCloseS4(&stS4Ctx);
	return dwResult;
}




















































































