// rsa_sign_verify.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "crypt2.h"
#include "stdio.h"
#include "conio.h"
/*------------------------------------------------
Functionality implemented:RSA sign and verify algorithm, digest algorithm
--------------------------------------------------*/
int main(int argc, char* argv[])
{
	R_RSA_PUBLIC_KEY    RpubKey;
	R_RSA_PRIVATE_KEY   RpriKey;
	int nRet = 0;
	int i = 0,j=0;
	char bIn[128],bOut[128];
	unsigned int inLen =0,outLen=0;

	//generate RSA key pair
	printf("Generate a pair of RSA key...please wait......\n");
	nRet = R_GenerateRsaKeys(&RpubKey,&RpriKey);
	if(nRet != RE_SUCCESS)
		printf("error! return: 0x%04x",nRet);
	else
	{
		printf("RSA public key:\n");
		for(i = 0, j=0; i < sizeof(R_RSA_PUBLIC_KEY); i++,j++)
		{
			printf("%02x ", ((BYTE *)&RpubKey)[i]);
			if(j == 15)
			{
				printf("\n");
				j = -1;
			}
		}

		printf("\nRSA private key:\n");
		for(i = 0, j=0; i < sizeof(R_RSA_PRIVATE_KEY); i++,j++)
		{
			printf("%02x ", ((BYTE *)&RpriKey)[i]);
			if(j == 15)
			{
				printf("\n");
				j = -1;
			}
		}

	}

	//Sign
	printf("\n\nSign.......\n");
	printf("\nPlease input the length of plaintext:");
	scanf("%d",&inLen);
	printf("\nPlease input the plaintext:");
	scanf("%s",bIn);
	
	int nSel;
	printf("\nPlease select algorithm(1: DA_MD2; 2: DA_MD5; 3: DA_SHS):");
	scanf("%d",&nSel);
	if(nSel == 1)
		nRet = Sign(DA_MD2,(unsigned char *)bIn,inLen,(unsigned char *)bOut,&outLen,&RpriKey);
	else if(nSel == 2)
		nRet = Sign(DA_MD5,(unsigned char *)bIn,inLen,(unsigned char *)bOut,&outLen,&RpriKey);
	else if(nSel == 3)
		//Digest function with DA_SHS flag is similar to the SES functions of Hash category,
		//the function is euqal to invoking SES function _rsa_sign with mode 3,that is
		//hashing and signing with PKCS mode.		
		nRet = Sign(DA_SHS,(unsigned char *)bIn,inLen,(unsigned char *)bOut,&outLen,&RpriKey);
	else
	{
		printf("error algorithm!\n");
		return 0;
	}

	if(nRet != RE_SUCCESS)
		printf("\nerror! return: 0x%04x",nRet);
	else
	{
		printf("\nsignature:\n");
		for(i = 0,j=0; i < outLen; i++,j++)
		{
			printf("%02x ", ((BYTE *)&bOut)[i]);
			if(j == 15)
			{
				printf("\n");
				j = -1;
			}
		}
		
		//verify
		printf("\nVerify ........\n");
		if(nSel == 1)
			nRet = Verify(DA_MD2,(unsigned char *)bIn,inLen,(unsigned char *)bOut,outLen,&RpubKey);
		else if(nSel == 2)
			nRet = Verify(DA_MD5,(unsigned char *)bIn,inLen,(unsigned char *)bOut,outLen,&RpubKey);
		else 
			//this function aggregate the functionality of SES functions of Hash category 
			//and _rsa_verify function with PKCS mode.
			//To implement the function in SES, call Hash category functions first, getting 
			//hash value which is kept in device somewhere, then invoke _rsa_veri(mode 2)
			// to verify the hash value of plain and the signature.			
			nRet = Verify(DA_SHS,(unsigned char *)bIn,inLen,(unsigned char *)bOut,outLen,&RpubKey);
		
		if(nRet != RE_SUCCESS)
			printf("\nerror! return: 0x%04x",nRet);
		else
		{
			printf("Verify signature : OK!\n");
		}
	}

	//digest
	printf("\n\nDigest.......\n");
	printf("\nPlease input the length of plaintext:");
	scanf("%d",&inLen);
	printf("\nPlease input the plaintext:");
	scanf("%s",bIn);
	printf("\nPlease select algorithm(1: DA_MD2; 2: DA_MD5; 3: DA_SHS):");
	scanf("%d",&nSel);

	if(nSel == 1)
		nRet = Digest(DA_MD2,(unsigned char *)bIn,inLen,(unsigned char *)bOut,&outLen);
	else if(nSel == 2)
		nRet = Digest(DA_MD5,(unsigned char *)bIn,inLen,(unsigned char *)bOut,&outLen);
	else if(nSel == 3)
		//equals to SES functions of hash category
		nRet = Digest(DA_SHS,(unsigned char *)bIn,inLen,(unsigned char *)bOut,&outLen);
	else
	{
		printf("error algorithm!\n");
		return 0;
	}

	if(nRet != RE_SUCCESS)
		printf("\nerror! return: 0x%04x",nRet);
	else
	{
		printf("\ndigest:\n");
		for(i = 0,j=0; i < outLen; i++,j++)
		{
			printf("%02x ", ((BYTE *)&bOut)[i]);
			if(j == 15)
			{
				printf("\n");
				j = -1;
			}
		}
	}
	getch();
	return 0;
}
