/* * * * * * * * * * * * * * * * 
 * 	 ______     __  __     ______     __  __     ______     ______     __  __    
 *	/\  __ \   /\ \/\ \   /\  == \   /\ \_\ \   /\  __ \   /\  ___\   /\ \/ /    
 *	\ \ \/\ \  \ \ \_\ \  \ \  __<   \ \  __ \  \ \  __ \  \ \ \____  \ \  _"-.  
 *	 \ \_____\  \ \_____\  \ \_____\  \ \_\ \_\  \ \_\ \_\  \ \_____\  \ \_\ \_\ 
 *	  \/_____/   \/_____/   \/_____/   \/_/\/_/   \/_/\/_/   \/_____/   \/_/\/_/ 
 *
 *  - Version : 3L
 *  - By Oubliette
 * * * * * * * * * * * * * * * */

#include "oubhack_aes.h"
#include <iostream>
#include <iomanip>
#include "oubhack.h"

std::string AES::decrypt(std::string sText, byte bKey[], byte bIV[]){

	std::string sReturn = "";

	try { 

		CryptoPP::AES::Decryption aesDecryption(bKey, CryptoPP::AES::DEFAULT_KEYLENGTH);
		CryptoPP::CBC_Mode_ExternalCipher::Decryption cbcDecryption( aesDecryption, bIV );

		CryptoPP::StreamTransformationFilter stfDecryptor(cbcDecryption, new CryptoPP::StringSink( sReturn ) );

		stfDecryptor.Put( reinterpret_cast<const unsigned char*>( sText.c_str() ), sText.size() );
		stfDecryptor.MessageEnd();

	}
	catch ( std::exception e ){

		oubhack->Error((std::string( "failed - " ) + std::string( e.what() )).c_str());
		return (std::string( "failed - " ) + std::string( e.what() )).c_str();

	}

	return sReturn;

}

std::string AES::encrypt(const char* ccData, byte bKey[], byte bIV[]){

	std::string sReturn = "";

	try { 

		CryptoPP::AES::Encryption aesEncryption(bKey, CryptoPP::AES::DEFAULT_KEYLENGTH);
		CryptoPP::CBC_Mode_ExternalCipher::Encryption cbcEncryption( aesEncryption, bIV );

		CryptoPP::StreamTransformationFilter stfEncryptor(cbcEncryption, new CryptoPP::StringSink( sReturn ) );
		stfEncryptor.Put( reinterpret_cast<const unsigned char*>( ccData ), strlen( ccData ) );
		stfEncryptor.MessageEnd();

	}
	catch ( CryptoPP::Exception e ){

		return (std::string( "failed - " ) + std::string( e.GetWhat() )).c_str();

	}

	return sReturn;

}

/*
extern "C" {

	__declspec(dllexport) void __stdcall encrypt(const char* ccData, byte bKey[], byte bIV[], unsigned char* *sBuf, int* iSize){

		AES aes;

		std::string enc = aes.encrypt( ccData, bKey, bIV );
		*iSize = enc.size();

		unsigned char* tchr = new unsigned char[*iSize];

		for (int i = 0; i < enc.size(); i++){

			tchr[ i ] = enc[i];

		}

		*sBuf = tchr;

	}

	__declspec(dllexport) void __stdcall decrypt(byte bData[], byte bKey[], byte bIV[], unsigned char* *sBuf, int inpSize, int* iSize){

		AES aes;

		std::string encdata;

		for (int i = 0; i < inpSize; i++){

			encdata += bData[i];

		}

		std::string dec = aes.decrypt( encdata, bKey, bIV );

		*iSize = dec.size() - 1;
		unsigned char* tchr = new unsigned char[*iSize];

		for (int i = 0; i < *iSize; i++){

			tchr[i] = dec[i];

		}

		*sBuf = tchr;

	}

}

BOOL __stdcall DllMain(HMODULE hModule, DWORD dwReason, LPVOID lpReserved){
	
	std::cout << "something : " << dwReason << '\n';
	/*
	byte key[16], iv[16];

	memset(key, 0x01, 16);
	memset(iv, 0x01, 16);

	char* *outBuf;
	int* outSize;

	encrypt("hi", key, iv, outBuf, outSize );

	std::cout << "Encrypted : " << outBuf << '\n';

	decrypt(*outBuf, key, iv, outBuf, outSize);

	std::cout << "Decrypted : " << outBuf << '\n';
	
	switch(dwReason){
	case DLL_PROCESS_ATTACH:

		

		break;

	case DLL_PROCESS_DETACH:

		break;
	}

	return TRUE;

}

*/