📄 mycast.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 + -