#ifndef CE2_TST_RSA_H
#define CE2_TST_RSA_H

/*
* All the includes that are needed for code using this module to
* Compile correctly should be #included here.
*/
#include "CryptoEngine2.h"
#include "CE2_TST_Config.h"
#include "CE2_TST_Common.h"
#include "math.h"
#include <stdio.h>

#ifdef __cplusplus
extern "C"
{
#endif

/*
* Creation date : Mon Mar 05 16:50:39 2007
* Last modified : %modify_time%
*/
/** @file
* \brief This file contains test functions for RSA cryptography
* which worked with LibTomCrypt.
* 
* \version CE2_RSA_TST.h#1:csrc:1
* \author Masiuk Aliaksandr
* \remarks Copyright (C) 2007 by Discretix Technologies Ltd.
* All Rights reserved
*/

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

/* General definitions */
#define TST_NAME_STRING_LEN 150
#define TST_FUNC_STRING_LEN 100
#define TST_MAX_DATA_VEC_SIZE_IN_BYTS 1536

/* General definitions */
#define TST_FAIL     1
#define TST_PASS     0
#define TST_ENCRYPT  0 
#define TST_DECRYPT  1
#define TST_NULL_PTR 0
#define TST_ZERO_DATA 	 0
#define TST_NOT_DEVIDE_8 1

#define TST_NAME_STRING_LEN 150
#define TST_FUNC_STRING_LEN 100
#define TST_DATA_VEC_SIZE_IN_WORDS 4
#define TST_DATA_BLOCK 512
#define TST_MAX_DATA_VEC_SIZE_IN_BYTS 1536
#define TST_IV_NULL  0
#define TST_IV_VALUE 1

#define TST_INTERNAL_KG 0
#define TST_EXTERNAL_KEYPAIR 1
#define TST_NO_INTERNAL_KEYGEN 1

/* RSA definitions */
#define TST_MAX_MOD_SIZE_IN_BYTES 264
#define TST_MAX_PRVT_EXP_SIZE_IN_BYTES 264
#define TST_MAX_PUB_EXP_SIZE_IN_BYTES 3
#define TST_MAX_SINGLE_RSA_SIGN_BLOCK_SIZE_IN_BYTS 16
#define TST_LESS_DATA_FOR_PKCS1V15_ENCRYPT	11 
#define TST_LESS_DATA_FOR_OAEP_ENCRYPT_SHA1	42
#define TST_LESS_DATA_FOR_OAEP_ENCRYPT_SHA224	58
#define TST_LESS_DATA_FOR_OAEP_ENCRYPT_SHA256	66
#define TST_LESS_DATA_FOR_OAEP_ENCRYPT_SHA384	98
#define TST_LESS_DATA_FOR_OAEP_ENCRYPT_SHA512	130
#define TST_NO_CRT 	 0
#define TST_CRT_MODE 1
#define TST_RSA_512_KEY_SIZE_IN_BYTES 64

/* Default log file name */
#define TST_RSA_STD_LOG_FILE_NAME "RSA_TEST_LOG.TXT"

/************************ Enums *******************************/
/************************ Typedefs ****************************/
/************************ Structs *****************************/

/* test structs defenition */
typedef struct TST_RSA_TestDataStruct
{	
	char					    TST_Name[TST_NAME_STRING_LEN];
    DxUint8_t					TST_PrivetExponent_D[TST_MAX_PRVT_EXP_SIZE_IN_BYTES];
    DxUint8_t					TST_PublicExponent_E[TST_MAX_PUB_EXP_SIZE_IN_BYTES];
    DxUint8_t					TST_Modulus_N[TST_MAX_MOD_SIZE_IN_BYTES];
	DxUint8_t					TST_P[TST_MAX_PRVT_EXP_SIZE_IN_BYTES/2]; 
	DxUint8_t					TST_Q[TST_MAX_PRVT_EXP_SIZE_IN_BYTES/2];  	   
	DxUint8_t					TST_dP[TST_MAX_PRVT_EXP_SIZE_IN_BYTES/2];
	DxUint8_t					TST_dQ[TST_MAX_PRVT_EXP_SIZE_IN_BYTES/2];
	DxUint8_t					TST_Qinv[TST_MAX_PRVT_EXP_SIZE_IN_BYTES/2];		  	
    DxUint16_t					TST_KeySize;
    DxUint16_t					TST_DPSize;
    DxUint16_t					TST_PubExponentSize; 
	DxUint8_t 					TST_input_data[TST_MAX_PRVT_EXP_SIZE_IN_BYTES];	
	DxUint8_t 					TST_output_data[TST_MAX_PRVT_EXP_SIZE_IN_BYTES];	
	DxUint8_t 					TST_Expected_output_data[TST_MAX_PRVT_EXP_SIZE_IN_BYTES];	      
} TST_RSA_TestDataStruct;

typedef struct TST_RSA_TestSignVerifyDataStruct
{	
	char					    TST_Name[TST_NAME_STRING_LEN];
    DxUint8_t					TST_PrivetExponent_D[TST_MAX_PRVT_EXP_SIZE_IN_BYTES];
    DxUint8_t					TST_PublicExponent_E[TST_MAX_PUB_EXP_SIZE_IN_BYTES];
    DxUint8_t					TST_Modulus_N[TST_MAX_MOD_SIZE_IN_BYTES];
	DxUint8_t					TST_P[TST_MAX_PRVT_EXP_SIZE_IN_BYTES/2]; 
	DxUint8_t					TST_Q[TST_MAX_PRVT_EXP_SIZE_IN_BYTES/2];  	   
	DxUint8_t					TST_dP[TST_MAX_PRVT_EXP_SIZE_IN_BYTES/2];
	DxUint8_t					TST_dQ[TST_MAX_PRVT_EXP_SIZE_IN_BYTES/2];
	DxUint8_t					TST_Qinv[TST_MAX_PRVT_EXP_SIZE_IN_BYTES/2];		  	
    DxUint16_t					TST_KeySize;
    DxUint16_t					TST_DPSize; 
    DxUint16_t					TST_PubExponentSize; 
    DxUint16_t					TST_SaltLength;
	DxUint8_t 					TST_input_data[TST_MAX_DATA_VEC_SIZE_IN_BYTS];
	DxUint16_t 					TST_input_dataSize;
	DxUint8_t 					TST_output_signiture[TST_MAX_PRVT_EXP_SIZE_IN_BYTES];	      
} TST_RSA_TestSignVerifyDataStruct;

typedef struct TST_RSA_TestExtHashSignVerifyDataStruct
{
	char					    TST_Name[TST_NAME_STRING_LEN];
    DxUint8_t					TST_PrivetExponent_D[TST_MAX_PRVT_EXP_SIZE_IN_BYTES];
    DxUint8_t					TST_PublicExponent_E[TST_MAX_PUB_EXP_SIZE_IN_BYTES];
    DxUint8_t					TST_Modulus_N[TST_MAX_MOD_SIZE_IN_BYTES];
	DxUint8_t					TST_P[TST_MAX_PRVT_EXP_SIZE_IN_BYTES/2]; 
	DxUint8_t					TST_Q[TST_MAX_PRVT_EXP_SIZE_IN_BYTES/2];  	   
	DxUint8_t					TST_dP[TST_MAX_PRVT_EXP_SIZE_IN_BYTES/2];
	DxUint8_t					TST_dQ[TST_MAX_PRVT_EXP_SIZE_IN_BYTES/2];
	DxUint8_t					TST_Qinv[TST_MAX_PRVT_EXP_SIZE_IN_BYTES/2];		  	
    DxUint16_t					TST_KeySize;
    DxUint16_t					TST_DPSize; 
    DxUint16_t					TST_PubExponentSize; 
    DxUint16_t					TST_SaltLength;   
	DxUint8_t 					TST_input_hash_SHA1[CE2_HASH_SHA1_DIGEST_SIZE_IN_BYTES];
	DxUint8_t 					TST_input_hash_MD5[CE2_HASH_MD5_DIGEST_SIZE_IN_BYTES];	
    DxUint8_t 					TST_input_hash_SHA224[CE2_HASH_SHA224_DIGEST_SIZE_IN_BYTES];
    DxUint8_t 					TST_input_hash_SHA256[CE2_HASH_SHA256_DIGEST_SIZE_IN_BYTES];	
    DxUint8_t 					TST_input_hash_SHA384[CE2_HASH_SHA384_DIGEST_SIZE_IN_BYTES];
    DxUint8_t 					TST_input_hash_SHA512[CE2_HASH_SHA512_DIGEST_SIZE_IN_BYTES];	
	DxUint8_t 					TST_output_signiture[TST_MAX_PRVT_EXP_SIZE_IN_BYTES];	      
} TST_RSA_TestExtHashSignVerifyDataStruct;

typedef struct TST_RSA_TestGetPrivKeyDataStruct
{	
	char					    TST_Name[TST_NAME_STRING_LEN];
    DxUint8_t					TST_PrivetExponent_D[TST_MAX_PRVT_EXP_SIZE_IN_BYTES];
	DxUint16_t					TST_PrivExponentSize; 
	DxUint8_t					TST_PublicExponent_E[TST_MAX_PUB_EXP_SIZE_IN_BYTES];
    DxUint16_t					TST_PubExponentSize; 
	DxUint8_t					TST_Modulus_N[TST_MAX_MOD_SIZE_IN_BYTES];
	DxUint16_t					TST_ModulusSize;

	DxUint8_t					TST_P[TST_MAX_PRVT_EXP_SIZE_IN_BYTES/2];
	DxUint16_t					TST_pSize; 
	DxUint8_t					TST_Q[TST_MAX_PRVT_EXP_SIZE_IN_BYTES/2];  	   
	DxUint16_t					TST_qSize; 
	DxUint8_t					TST_Dp[TST_MAX_PRVT_EXP_SIZE_IN_BYTES/2];
	DxUint16_t					TST_DpSize; 
	DxUint8_t					TST_Dq[TST_MAX_PRVT_EXP_SIZE_IN_BYTES/2];
	DxUint16_t					TST_DqSize; 
	DxUint8_t					TST_Qinv[TST_MAX_PRVT_EXP_SIZE_IN_BYTES/2];		  	
	DxUint16_t					TST_QinvSize; 
    
    /*
    DxUint16_t					TST_PubExponentSize; 
    DxUint16_t					TST_SaltLength;
	DxUint8_t 					TST_input_data[TST_MAX_DATA_VEC_SIZE_IN_BYTS];
	DxUint16_t 					TST_input_dataSize;
	DxUint8_t 					TST_output_signiture[TST_MAX_PRVT_EXP_SIZE_IN_BYTES];	      */
} TST_RSA_TestGetPrivKeyDataStruct;

/************************ Public Variables **********************/
/************************ Public Functions **********************/

/***************************************************************
* Function Name: 
*  CE2_TST_RSA_Acceptance_PRIME_EncDec
*
* Inputs:
*  @param out [in] - pointer to file to output debug information;
*
* Outputs: @returns \b
*  CE2Error_t  
*  - CE2_OK - On success
*  - Otherwise - error code.
*
* \brief \b
* Description:
*  This function Is a Acceptance test for RSA primitive encrypt and decrypt
*  This function Encrypts and Decrypts known vectors using RSA primitives
*  Vector/Keys sizes used (in bits) - 512/1024/2048
*  This also outputs the results to an output buffer or the same input buffer
*
* \b
* Algorithm:
*  -# Build the Private Key from external exponent and modulus;
*  -# Build the Public Key from External exponent and modulus;
*  -# Encrypt/Decrypt a known vector;
*  -# Compare the outputted result to the expected one.
***************************************************************/
CE2Error_t CE2_ATP_TST_RSA_Acceptance_PRIME_EncDec(FILE *out);

/***************************************************************
* Function Name:                                                           
*  CE2_TST_RSA_Acceptance_PRIME_SignVerify 		
*
* Inputs:
*  @param out [in] - pointer to file to output debug information;
*
* Outputs: @returns \b
*  CE2Error_t  
*  - CE2_OK - On success
*  - Otherwise - error code.
*
* \brief \b
* Description:
* 	This function Is a Acceptance test for RSA primitive Sign & Verify					
* 	This function signs and verifies known vectors using RSA primitives
*  Vector/Keys sizes used (in bits) - 512/1024/2048														
* 	This also outputs the results to an output buffer or the same input buffer
*
* \b
* Algorithm:
*  -# Build the Private Key from external exponent and modulus
*  -# Build the Public Key from External exponent and modulus
*  -# sign/verify a known vector
*  -# Compare the outputted result to the expected one					
***************************************************************/
CE2Error_t CE2_ATP_TST_RSA_Acceptance_PRIME_SignVerify(FILE *out);

/***************************************************************
* Function Name:                                                           
* 	CE2_TST_RSA_Acceptance_PKCS1v15_EncDec 		
* 
* Inputs:
*  @param TST_KeyGeneration_TestStatus [in] -
*         A parameter defining if to run the test with internal key generation 
*         - TST_INTERNAL_KG - Run the test with internal key generation and external keys 
*         - TST_EXTERNAL_KEYPAIR  - Run the test with external key only - NO keyGen
*  @param out [in] - pointer to file to output debug information;
*
* Outputs: @returns \b
*  CE2Error_t  
*  - CE2_OK - On success
*  - Otherwise - error code.
*
* \brief \b
* Description:
*  This function Is a Acceptance test for RSA PKCS1v15 encrypt and decrypt
*  According to PKCS#1 Ver1.5
*  Including RSA KeyGeneration
*  This function Encrypts and Decrypts known vectors
*  Vector/Keys sizes used (in bits) - 512/1024/2048 also CRT private														
*  This also outputs the results to an output buffer or the same input buffer
*
* \b
* Algorithm:
*  -# Prepare keys	
*     a. Generate keys 
*     or
*     a. Build the Private Key from external exponent and modulus
*     b. Build the Public Key from External exponent and modulus
*  -# Encrypt/Decrypt a known vector
*  -# Compare the outputted result to the expected one					
***************************************************************/
CE2Error_t CE2_ATP_TST_RSA_Acceptance_PKCS1v15_EncDec(int TST_KeyGeneration_TestStatus, FILE *out);

/***************************************************************
* Function Name:                                                           
* 	CE2_TST_RSA_Acceptance_PKCS1v15_Integrated_SignVerify 		
* 
* Inputs:
*  @param TST_KeyGeneration_TestStatus [in] -
*         A parameter defining if to run the test with internal key generation 
*         - TST_INTERNAL_KG - Run the test with internal key generation and external keys 
*         - TST_EXTERNAL_KEYPAIR  - Run the test with external key only - NO keyGen
*  @param out [in] - pointer to file to output debug information;
*
* Outputs: @returns \b
*  CE2Error_t  
*  - CE2_OK - On success
*  - Otherwise - error code.
*
* \brief \b
* Description:
*  This function Is a Acceptance test for RSA PKCS1v15 Sign & Verify					
*  This function Signs & Verify known vectors using RSA PKCS1v15
*  Vectors sizes used (in byte) - 16/32/512														
*  Key sizes used     (in bits) - 512/1024/2048
*  This also outputs the results to an output buffer or the same input buffer
*
* \b
* Algorithm:
*  -# Prepare keys	
*     a. Generate keys 
*     or
*     a. Build the Private Key from external exponent and modulus
*     b. Build the Public Key from External exponent and modulus
*  -# Call the CE2_RSA_PKCS1v15_Sign to preform the Sign operation
*  -# Call the CE2_RSA_PKCS1v15_Verify to complete the verification operation
*  -# Compare the outputted result to the expected one					
***************************************************************/
CE2Error_t CE2_ATP_TST_RSA_Acceptance_PKCS1v15_Integrated_SignVerify(int TST_KeyGeneration_TestStatus, FILE *out);

/***************************************************************
* Function Name:                                                           
* 	CE2_TST_RSA_Acceptance_OAEP_EncDec 		
* 
* Inputs:
*  @param TST_KeyGeneration_TestStatus [in] -
*         A parameter defining if to run the test with internal key generation 
*         - TST_INTERNAL_KG - Run the test with internal key generation and external keys 
*         - TST_EXTERNAL_KEYPAIR  - Run the test with external key only - NO keyGen
*  @param out [in] - pointer to file to output debug information;
*
* Outputs: @returns \b
*  CE2Error_t  
*  - CE2_OK - On success
*  - Otherwise - error code.
*
* \brief \b
* Description:
*  This function Is a Acceptance test for RSA OAEP encrypt and decrypt
*  According to PKCS#1 Ver2.1
*  This function Encrypts and Decrypts known vectors
*  Vector/Keys sizes used (in bits) - 512/1024/2048														
*  This also outputs the results to an output buffer or the same input buffer
*
* \b
* Algorithm:
*  -# Prepare keys	
*     a. Generate keys 
*     or
*     a. Build the Private Key from external exponent and modulus
*     b. Build the Public Key from External exponent and modulus 		
*  -# Encrypt/Decrypt a known vector
*  -# Compare the outputted result to the expected one					
***************************************************************/
CE2Error_t CE2_ATP_TST_RSA_Acceptance_OAEP_EncDec(int TST_KeyGeneration_TestStatus, FILE *out);

/***************************************************************
* Function Name:                                                           
* 	CE2_TST_RSA_Acceptance_PSS_Integrated_SignVerify 		
* 
* Inputs:
*  @param TST_KeyGeneration_TestStatus [in] -
*         A parameter defining if to run the test with internal key generation 
*         - TST_INTERNAL_KG - Run the test with internal key generation and external keys 
*         - TST_EXTERNAL_KEYPAIR  - Run the test with external key only - NO keyGen
*  @param out [in] - pointer to file to output debug information;
*
* Outputs: @returns \b
*  CE2Error_t  
*  - CE2_OK - On success
*  - Otherwise - error code.
*
* \brief \b
* Description:
*  This function Is a Acceptance test for RSA PSS PKCS#1v2.1 sign & Verify 					
*  This function  signs & Verify known vectors using RSA PSS PKCS#1v2.1
*  Vectors sizes used (in byte) - 16/32/512														
*  Key sizes used     (in bits) - 512/1024/2048
*  This also outputs the results to an output buffer or the same input buffer
*
* \b
* Algorithm:
*  -# Prepare keys	
*     a. Generate keys 
*     or
*     a. Build the Private Key from external exponent and modulus
*     b. Build the Public Key from External exponent and modulus 	
*  -# Call the CE2_RSA_PSS_Sign to preform the Sign operation
*  -# Call the RSA_PSS_Verify to preform the verification operation					
***************************************************************/
CE2Error_t CE2_ATP_TST_RSA_Acceptance_PSS_Integrated_SignVerify(int TST_KeyGeneration_TestStatus, FILE *out);

/***************************************************************
* Function Name:                                                           
* 	CE2_TST_RSA_Build_Get_PubKey 		
* 
* Inputs:
*  @param out [in] - pointer to file to output debug information;
*
* Outputs: @returns \b
*  CE2Error_t  
*  - CE2_OK - On success
*  - Otherwise - error code.
*
* \brief \b
* Description:
*  This function tests generation and export and import functions
*  under public key
*  Vectors sizes used (in byte) - 16/32/512
*  Key sizes used     (in bits) - 512/1024/2048
*  This also outputs the results to an output buffer or the same input buffer
*
* \b
* Algorithm:
*  -# Prepare keys	
*     a. Generate key
*     or
*     a. Build the Public Key from External exponent and modulus 	
*  -# Call the CE2_RSA_Get_PubKey to preform the Get operation
*  -# Call the CE2_RSA_Build_PubKey to preform the build operation
*  -# Compare the outputted result to the expected one
***************************************************************/
CE2Error_t CE2_TST_RSA_Build_Get_PubKey(FILE * out);

/***************************************************************
* Function Name:                                                           
* 	CE2_TST_RSA_Build_Get_PrivKey 		
* 
* Inputs:
*  @param out [in] - pointer to file to output debug information;
*
* Outputs: @returns \b
*  CE2Error_t  
*  - CE2_OK - On success
*  - Otherwise - error code.
*
* \brief \b
* Description:
*  This function tests generation and export and import functions
*  under public key
*  Vectors sizes used (in byte) - 16/32/512
*  Key sizes used     (in bits) - 512/1024/2048
*  This also outputs the results to an output buffer or the same input buffer
*
*
* \b
* Algorithm:
*  -# Prepare keys	
*     a. Generate key
*     or
*     a. Build the Private Key from External exponent and modulus 	
*  -# Call the CE2_RSA_Get_PrivKey to preform the Get operation
*  -# Call the CE2_RSA_Build_PrivKey to preform the build operation
*  -# Compare the outputted result to the expected one
***************************************************************/
CE2Error_t CE2_TST_RSA_Build_Get_PrivKey(int TST_KeyGeneration_TestStatus, FILE * out);

/***************************************************************
* Function Name:                                                           
* 	CE2_TST_RSA_PRIME_Encrypt_Decrypt_PKCS1v15v21_Full 		
* 
* Inputs:
*  @param out [in] - pointer to file to output debug information;
*  @param testZeroMessage [in] - indicates whether test should use
*         zero message only;
*
* Outputs: @returns \b
*  CE2Error_t  
*  - CE2_OK - On success
*  - Otherwise - error code.
*
* \brief \b
* Description:
*  This function Is a Acceptance test for RSA PKCS1v15 encrypt and decrypt
*  According to PKCS#1 Ver1.5, to PKCS#1 Ver2.1
*  Including RSA KeyGeneration
*  This function Encrypts and Decrypts known vectors
*  Vector/Keys sizes used (in bits) - 512/1024/2048 also CRT private														
*  This also outputs the results to an output buffer or the same input buffer
*
* \b
* Algorithm:
*  -# Prepare keys	
*     a. Generate keys 
*     or
*     a. Build the Private Key from external exponent and modulus
*     b. Build the Public Key from External exponent and modulus
*  -# Encrypt/Decrypt a known vector
*  -# Compare the outputted result to the expected one
***************************************************************/
CE2Error_t CE2_TST_RSA_PRIME_Encrypt_Decrypt_PKCS1v15v21_Full(FILE *out, unsigned char testZeroMessage);

/* RSA Encrypt/Decrypt tests macro */
#define CE2_TST_RSA_PRIME_Encrypt_Decrypt_PKCS1v15v21(out) \
	CE2_TST_RSA_PRIME_Encrypt_Decrypt_PKCS1v15v21_Full(out, 0);

#define CE2_TST_RSA_PRIME_Encrypt_Decrypt_PKCS1v15v21_ZeroMessage(out) \
	CE2_TST_RSA_PRIME_Encrypt_Decrypt_PKCS1v15v21_Full(out, 1);

//Additional tests:
CE2Error_t CE2_TST_RSA_PRIME_EncDecTest(FILE * out);
CE2Error_t CE2_TST_RSA_PRIME_EncDecTest2(FILE * out);
CE2Error_t CE2_TST_RSA_UTILS_EASY_TST(FILE * out);

#ifdef __cplusplus
}
#endif

#endif /* CE2_TST_RSA_H */
