⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mycast.cpp

📁 采用CAST-256位加密的Back Orifice 2000(BO2000)插件
💻 CPP
字号:
/*	CAST-256 Strong Encryption Plugin for Back Orifice 2000
	Copyright (C) 1999, Daniel Roethlisberger

	This program is free software; you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation; either version 2 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program; if not, write to the Free Software
	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

	The author of this program may be contacted at admin@roe.ch.
*/

#include <windows.h>
#include <encryption.h>
#include <config.h>
#include "bo_cast.h"
#include "md5.h"
#include "cast256.h"
#include "mycast.h"

ENCRYPTION_ENGINE g_CASTengine = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};

// called when engine is inserted into handler
int __cdecl CAST_Insert(void)
{
	if(GetCfgStr(g_szCASTEncryptOptions, CAST_CONFIG_KEY_STRING) == NULL)
		return -1;
	return 0;
}

// called when engine is removed from handler
int __cdecl CAST_Remove(void)
{
	return 0;
}

// returns the ID string of the engine
char * __cdecl CAST_Query(void)
{
	return CAST_QUERY_STRING;
}

// called before any key or encryption takes place to initialise
void * __cdecl CAST_Startup(void)
{
	// read the configuration
	char *svKey = GetCfgStr(g_szCASTEncryptOptions, CAST_CONFIG_KEY_STRING);
	if(svKey == NULL)
		return NULL;
	if(svKey[0] == '\0')
		return NULL;
	BOOL bCBC = GetCfgBool(g_szCASTEncryptOptions, CAST_CONFIG_CBC_MODE);

	// allocate a context structure
	CAST_CTX *data;
	data = (CAST_CTX*)malloc(sizeof(CAST_CTX));
	if(data == NULL)
		return NULL;

	// let the CAST256 engine fill in internal tables
	CAST256TableInit();

	// set the configuration
	data->bCASTCBC = bCBC;
	CAST_SetKey((void*)data, svKey);

	return data;
}

// called after encryption has been finished to clean up
int __cdecl CAST_Shutdown(void *pInternal)
{
	CAST_CTX *data = (CAST_CTX*)pInternal;
	free(data);
	return 0;
}

// called to set key string
int __cdecl CAST_SetKey(void *pInternal, char *svKey)
{
	CAST_CTX *data = (CAST_CTX*)pInternal;

	MD5_CTX ctx;
	char buf1[] = CAST_MDSTRING1;
	char buf2[] = CAST_MDSTRING2;
	char buf3[] = CAST_MDSTRING3;
	char buf4[] = CAST_MDSTRING4;

	// generate user key from key string and magic strings
	MD5Init(&ctx);
	MD5Update(&ctx, (BYTE*)buf1, strlen(buf1));
	MD5Update(&ctx, (BYTE*)svKey, strlen(svKey));
	MD5Final((BYTE*)&data->CASTUserKey, &ctx);

	MD5Init(&ctx);
	MD5Update(&ctx, (BYTE*)svKey, strlen(svKey));
	MD5Update(&ctx, (BYTE*)buf2, strlen(buf2));
	MD5Final((((BYTE*)&data->CASTUserKey) + 16), &ctx);

	// generate initialisation vector from key string
	MD5Init(&ctx);
	MD5Update(&ctx, (BYTE*)buf3, strlen(buf3));
	MD5Update(&ctx, (BYTE*)svKey, strlen(svKey));
	MD5Update(&ctx, (BYTE*)buf4, strlen(buf4));
	MD5Final((BYTE*)&data->CASTInitVect, &ctx);

	strcpy(data->svCASTKey, svKey);

	// let the CAST256 engine initialise the key context
	CAST256KeyInit(data->CASTKr, data->CASTKm, data->CASTUserKey);

	return 0;
}

// returns key string
char * __cdecl CAST_GetKey(void *pInternal)
{
	CAST_CTX *data = (CAST_CTX*)pInternal;
	return data->svCASTKey;
}

// returns encrypted buffer that must be freed
BYTE * __cdecl CAST_Encrypt(void *pInternal, BYTE *pBuffer, int nBufLen, int *pnOutBufLen)
{
	CAST_CTX *data = (CAST_CTX*)pInternal;

	BYTE *buf;
	int blocks, baselen, leftover;

	// check on length (must be a multiple of 128)
	leftover = nBufLen & 15;
	baselen = nBufLen + (leftover ? 16-leftover : 0);

	// add padding
	if(leftover)
	{
		buf = (BYTE*)malloc(baselen);
		memset(buf, 0, baselen);
		buf[baselen-1] = 16 - leftover;
	}
	else
	{
		baselen = nBufLen + 16;
		buf = (BYTE*)malloc(baselen);
		memset(buf, 0, baselen);
		buf[baselen-1] = 16;
	}

	memcpy(buf, pBuffer, nBufLen);

	// number of blocks to encode
	blocks = baselen >> 4;

	if(data->bCASTCBC)
	{
		// CBC Mode: cypherblock = enc(plainblock XOR lastcypherblock)
		for(int i = 0; i < blocks; i++)
		{
			for(int j = 0; j < CAST_BLOCK_SIZE; j++)
			{
				buf[i*CAST_BLOCK_SIZE+j] = buf[i*CAST_BLOCK_SIZE+j] ^ data->CASTInitVect[j];
			}
			CAST256Encrypt(data->CASTKr, data->CASTKm, (BETA*)&buf[i*CAST_BLOCK_SIZE]);
			memcpy(&data->CASTInitVect, &buf[i*CAST_BLOCK_SIZE], CAST_BLOCK_SIZE);
		}
	}
	else
	{
		// ECB Mode: cypherblock = enc(plainblock XOR initvect)
		for(int i = 0; i < blocks; i++)
		{
			for(int j = 0; j < CAST_BLOCK_SIZE; j++)
			{
				buf[i*CAST_BLOCK_SIZE+j] = buf[i*CAST_BLOCK_SIZE+j] ^ data->CASTInitVect[j];
			}
			CAST256Encrypt(data->CASTKr, data->CASTKm, (BETA*)&buf[i*CAST_BLOCK_SIZE]);
		}
	}
	*pnOutBufLen = baselen;
	
	return buf;
}

// returns decrypted buffer that must be freed
BYTE * __cdecl CAST_Decrypt(void *pInternal, BYTE *pBuffer, int nBufLen, int *pnOutBufLen)
{
	CAST_CTX *data = (CAST_CTX*)pInternal;

	BYTE *buf;
	int blocks = 0;
	BYTE NewInitVect[CAST_BLOCK_SIZE] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

	// check on length (must be a multiple of 128)
	if (nBufLen & 15)
		return NULL;

	buf = (BYTE*)malloc(nBufLen);
	
	memcpy(buf, pBuffer, nBufLen);

	// number of blocks to encode
	blocks = nBufLen >> 4;

	if(data->bCASTCBC)
	{
		// CBC Mode: plainblock = dec(cypherblock) XOR lastcypherblock
		for(int i = 0; i < blocks; i++)
		{
			memcpy(NewInitVect, &buf[i*CAST_BLOCK_SIZE], CAST_BLOCK_SIZE);
			CAST256Decrypt(data->CASTKr, data->CASTKm, (BETA*)&buf[i*CAST_BLOCK_SIZE]);
			for(int j = 0; j < CAST_BLOCK_SIZE; j++)
			{
				buf[i*CAST_BLOCK_SIZE+j] = buf[i*CAST_BLOCK_SIZE+j] ^ data->CASTInitVect[j];
			}
			memcpy(data->CASTInitVect, NewInitVect, CAST_BLOCK_SIZE);
		}
	}
	else
	{
		// ECB Mode: plainblock = dec(cypherblock) XOR initvect
		for(int i = 0; i < blocks; i++)
		{
			CAST256Decrypt(data->CASTKr, data->CASTKm, (BETA*)&buf[i*CAST_BLOCK_SIZE]);
			for(int j = 0; j < CAST_BLOCK_SIZE; j++)
			{
				buf[i*CAST_BLOCK_SIZE+j] = buf[i*CAST_BLOCK_SIZE+j] ^ data->CASTInitVect[j];
			}
		}
	}
	
	// remove padding
	nBufLen -= buf[nBufLen-1];

	// crop buf here if the extra trailing zero bytes turn out to be fatal
	// cannot imagine how they could though

	*pnOutBufLen = nBufLen;

	return buf;
}

// generate new keys, we just get them from the config string
int __cdecl CAST_CreateNewKeys(void *pInternal)
{
	char *svKey = GetCfgStr(g_szCASTEncryptOptions, CAST_CONFIG_KEY_STRING);
	if(svKey == NULL)
		return -1;
	if(svKey[0] == '\0')
		return -1;

	CAST_CTX *data = (CAST_CTX*)pInternal;
	free(data);
	data = (CAST_CTX*)malloc(sizeof(CAST_CTX));
	if(data == NULL)
		return -1;
	
	CAST_SetKey((void*)data, svKey);

	return 0;
}

// free buffers returned by CAST_Encrypt or CAST_Decrypt
void __cdecl CAST_Free(void *pInternal, BYTE *pBuffer)
{
	free(pBuffer);
}

// returns a struct containing the function addresses
ENCRYPTION_ENGINE *GetCASTEncryptionEngine(void)
{
	g_CASTengine.pInsert = CAST_Insert;
	g_CASTengine.pRemove = CAST_Remove;
	g_CASTengine.pQuery = CAST_Query;
	g_CASTengine.pStartup = CAST_Startup;
	g_CASTengine.pShutdown = CAST_Shutdown;
	g_CASTengine.pSetEncryptKey = CAST_SetKey;
	g_CASTengine.pSetDecryptKey = CAST_SetKey;
	g_CASTengine.pGetEncryptKey = CAST_GetKey;
	g_CASTengine.pGetDecryptKey = CAST_GetKey;
	g_CASTengine.pEncrypt = CAST_Encrypt;
	g_CASTengine.pDecrypt = CAST_Decrypt;
	g_CASTengine.pCreateNewKeys = CAST_CreateNewKeys;
	g_CASTengine.pFree = CAST_Free;
	
	return &g_CASTengine;
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -