// Common, group Crypto
// Copyright Alexander Liss

#ifndef __CRYPTOBASE_H__
#define __CRYPTOBASE_H__

#include "commbuf.h"

	// interfaces 

	// storage of secrets (private key, etc.)
	// authorization level: have to put with this level
	// to get it or to drop it
class SecretsStorage
{
public:
virtual	~SecretsStorage(){}

// for symmetric and MAC keys
virtual int put(unsigned int& secrets_handle,const CommBuffer& s,ReadControl& c, int type, int auth)=0;
virtual int get(int& type, CommBuffer& d,unsigned int secrets_handle, int auth)=0;
virtual int drop(unsigned int secrets_handle, int auth)=0;


// for PKS keys, secrets_handle is pub_key
virtual int put(const CommBuffer& s,ReadControl& c,const CommBuffer& secrets_handle,ReadControl& cs, int type, int auth)=0;
virtual int get(int& type, CommBuffer& d,const CommBuffer& secrets_handle,ReadControl& c, int auth)=0;
virtual int drop(const CommBuffer& secrets_handle,ReadControl& c, int auth)=0;

static SecretsStorage* new_object(int type);
};

class CryptoRandom
{
public:
virtual ~CryptoRandom(){}

virtual int seed(const CommBuffer& s,ReadControl& c){return 0;}

virtual unsigned char byte()=0;

static CryptoRandom* new_object(int gen_type);
};

class SymmetricKey
{
public:
SymmetricKey():crypto_random(0){}
virtual ~SymmetricKey(){}
int set(CryptoRandom& z){crypto_random=&z;return 0;}
virtual int generate(CommBuffer& key,const CommBuffer& param, ReadControl& c)=0;

static SymmetricKey* new_object(int type,int gen_type);
protected:

	CryptoRandom* crypto_random;
};

class PKSKey
{
public:
PKSKey():crypto_random(0){}
virtual ~PKSKey(){}
int set(CryptoRandom& z){crypto_random=&z;return 0;}
virtual int generate(CommBuffer& pub_key,CommBuffer& priv_key,const CommBuffer& param, ReadControl& c)=0;

static PKSKey* new_object(int type,int gen_type);
protected:

	CryptoRandom* crypto_random;
};

class MACKey
{
public:
MACKey():crypto_random(0){}
virtual ~MACKey(){}
int set(CryptoRandom& z){crypto_random=&z;return 0;}
virtual int generate(CommBuffer& key,const CommBuffer& param, ReadControl& c)=0;

static MACKey* new_object(int type,int gen_type);
protected:

	CryptoRandom* crypto_random;
};

class CryptoHashImp
{
public:
virtual ~CryptoHashImp(){}
virtual int set_key(const CommBuffer& key,ReadControl& c){return 0;}

// chain
virtual int next(const CommBuffer& s, ReadControl& c)=0;
virtual int get(CommBuffer& hash)=0;

static CryptoHashImp* new_object(int type, int comp_type);
};


	// if blocked cbc - set iv for a channel in the beginning
	// encryption and decryption can work in parallel
class CryptoSymmetricImp
{
public:
virtual ~CryptoSymmetricImp(){}
virtual int set_key(const CommBuffer& key,ReadControl& c)=0;

// bytes
virtual int block_size()const{return 0;}

// one block
virtual int encrypt_block(CommBuffer& d,const CommBuffer& s, ReadControl&){return 1;}
virtual int decrypt_block(CommBuffer& d,const CommBuffer& s, ReadControl&){return 1;}

// encryption chain
virtual int start_encrypt(const CommBuffer& iv,ReadControl& c){return 1;}
virtual int next_encrypt(CommBuffer& d,const CommBuffer& s, ReadControl&,bool last)=0;

// decryption chain
virtual int start_decrypt(CommBuffer& iv,const CommBuffer& s, ReadControl&){return 1;}
virtual int next_decrypt(CommBuffer& d,const CommBuffer& s, ReadControl&,bool last)=0;

static CryptoSymmetricImp* new_object(int type, int comp_type);
};


class CryptoPKSImp
{
public:
virtual ~CryptoPKSImp(){}

virtual int get_public(CommBuffer& pub_key,const CommBuffer& priv_key,ReadControl& c)=0;

virtual int encrypt_block_bits(const CommBuffer& pub_key,ReadControl& c)const=0;
virtual int decrypt_block_bits(const CommBuffer& pub_key,ReadControl& c)const=0;

virtual int encrypt_public(CommBuffer& d,const CommBuffer& s,ReadControl& c, const CommBuffer& key,ReadControl& ck)=0;
virtual int decrypt_public(CommBuffer& d,const CommBuffer& s,ReadControl& c, const CommBuffer& key,ReadControl& ck)=0;
virtual int encrypt_private(CommBuffer& d,const CommBuffer& s,ReadControl& c, const CommBuffer& key,ReadControl& ck)=0;
virtual int decrypt_private(CommBuffer& d,const CommBuffer& s,ReadControl& c, const CommBuffer& key,ReadControl& ck)=0;

static CryptoPKSImp* new_object(int type, int comp_type);
};


class CryptoSignImp
{
public:
CryptoSignImp():pks(0){}
virtual ~CryptoSignImp(){delete pks;}

virtual int pks_type()=0;
virtual int sign(CommBuffer& closed,const CommBuffer& open,ReadControl& c, const CommBuffer& key,ReadControl& ck)=0;
virtual int verify(CommBuffer& open,const CommBuffer& closed,ReadControl& c, const CommBuffer& key,ReadControl& ck)=0;

static CryptoSignImp* new_object(int type,int pks_comp_type);

protected:

	CryptoPKSImp* pks;
};


#endif