/// \file DataBlockEncryptor.h
/// \internal
/// \brief Encrypts and decrypts data blocks.  Used as part of secure connections.
///
/// This file is part of RakNet Copyright 2003 Jenkins Software LLC
///
/// Raknet is available under the terms of the GPLv3 license, see /usr/local/share/licenses/raknet-3.9.2,1/GPLv3.


#ifndef __DATA_BLOCK_ENCRYPTOR_H
#define __DATA_BLOCK_ENCRYPTOR_H

#include "Rijndael.h"
#include "RakMemoryOverride.h"
class RakNetRandom;

/// Encrypts and decrypts data blocks.
class DataBlockEncryptor
{

public:
	
	// Constructor
	DataBlockEncryptor();
	
	// Destructor
	~DataBlockEncryptor();
	
	/// \return true if SetKey has been called previously 
	bool IsKeySet( void ) const;
	
	/// \brief Set the encryption key 
	/// \param[in] key The new encryption key 
	void SetKey( const unsigned char key[ 16 ] );
	
	/// \brief Unset the encryption key 
	void UnsetKey( void );
	
	/// \brief Encryption adds 6 data bytes and then pads the number of bytes to be a multiple of 16.  
	/// \details Output should be large enough to hold this.
	/// Output can be the same memory block as input
	/// \param[in] input the input buffer to encrypt 
	/// \param[in] inputLength the size of the @em input buffer 
	/// \param[in] output the output buffer to store encrypted data 
	/// \param[in] outputLength the size of the output buffer 
	void Encrypt( unsigned char *input, unsigned int inputLength, unsigned char *output, unsigned int *outputLength, RakNetRandom *rnr );
	
	/// \brief Decryption removes bytes, as few as 6. 
	/// \details Output should be large enough to hold this.
	/// Output can be the same memory block as input
	/// \param[in] input the input buffer to decrypt 
	/// \param[in] inputLength the size of the @em input buffer 
	/// \param[in] output the output buffer to store decrypted data 
	/// \param[in] outputLength the size of the @em output buffer 
	/// \return False on bad checksum or input, true on success
	bool Decrypt( unsigned char *input, unsigned int inputLength, unsigned char *output, unsigned int *outputLength );
	
protected:
	
 	keyInstance keyEncrypt;
	keyInstance keyDecrypt;
	cipherInstance cipherInst;
	bool keySet;
};

#endif
