?? crypack.cpp
字號:
// Crypack.cpp : DLL 傾僾儕働乕僔儑儞偺僄儞僩儕 億僀儞僩傪掕媊偟傑偡丅
//
#include "stdafx.h"
#include "Crypack.h"
#define BLOCK_LEN 16
#define READ_ERROR -7
#define WRITE_ERROR -8
#ifdef LINUX
#define file_len(x) (unsigned long)x.__pos
#else
#define file_len(x) (unsigned long)x
#endif
#define BYTE_PER_CHARACTER ((CHAR_BIT + 3) / 4)
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return TRUE;
}
extern "C" __declspec(dllexport)
int FileEncrypt(char* FileIn, char* FileOut, char* Pass,
CallbackFunc* Callback, LPARAM lParam)
{
int Result;
char Pass1[17], Hex1[33], Hex2[33];
char* Pass2;
strncpy(Pass1, Pass, 16);
if(strlen(Pass) > 16)
{
Pass1[16] = 0;
}
CharToHex(Hex1, Pass1);
sprintf(Hex2, "%032s", Hex1);
Pass2 = Hex2;
Result = CodeFile(FileIn, FileOut, Pass2, 1, Callback, lParam);
if(Result != 0)
{
::DeleteFile(FileOut);
}
return Result;
}
extern "C" __declspec(dllexport)
int FileDecrypt(char* FileIn, char* FileOut, char* Pass,
CallbackFunc* Callback, LPARAM lParam)
{
int Result;
char Pass1[17], Hex1[33], Hex2[33];
char* Pass2;
strncpy(Pass1, Pass, 16);
if(strlen(Pass) > 16)
{
Pass1[16] = 0;
}
CharToHex(Hex1, Pass1);
sprintf(Hex2, "%032s", Hex1);
Pass2 = Hex2;
Result = CodeFile(FileIn, FileOut, Pass2, 2, Callback, lParam);
if(Result != 0)
{
::DeleteFile(FileOut);
}
return Result;
}
void CharToHex(char* m_cBuffer, char* m_cSource)
{
char * src = m_cSource;
size_t size, i;
size = strlen(src);
for (i = 0; i < size; ++i)
{
if(src[i] < 0)
{
src[i] = -src[i]; //慡妏暥帤張棟偺偨傔
}
#if BYTE_PER_CHARACTER == 2
m_cBuffer[i * 2] = "0123456789ABCDEF"[src[i] / 0x10];
m_cBuffer[i * 2 + 1] = "0123456789ABCDEF"[src[i] % 0x10];
#else //1僶僀僩偑8價僢僩傛?zhèn)钁鍌珎垪潓n
unsigned char data;
int j;
data = src[i];
for (j = BYTE_PER_CHARACTER - 1; j >= 0; --j)
{
m_cBuffer[i * BYTE_PER_CHARACTER + j] = "0123456789ABCDEF"[data % 0x10];
data /= 0x10;
}
#endif
}
m_cBuffer[i * BYTE_PER_CHARACTER] = 0;
}
int CodeFile(char* m_cFileIn, char* m_cFileOut,
char* m_cPass, int m_iType,
CallbackFunc* Callback, LPARAM lParam)
{
FILE *fin = 0, *fout = 0;
char *cp, ch, key[32], *FileIn = m_cFileIn, *FileOut = m_cFileOut, *Pass = m_cPass;
int i = 0, by = 0, key_len = 0, err = 0, m_iResult = 0;
gen_tabs();
cp = Pass;
while(i < 64 && *cp)
{
ch = toupper(*cp++);
if(ch >= '0' && ch <= '9')
by = (by << 4) + ch - '0';
else if(ch >= 'A' && ch <= 'F')
by = (by << 4) + ch - 'A' + 10;
else
{
m_iResult = 1;
}
if(i++ & 1)
key[i / 2 - 1] = by & 0xff;
}
if(*cp)
{
m_iResult = 1;
}
else if(i < 32 || (i & 15))
{
m_iResult = 1;
}
if(m_iResult == 0)
{
key_len = i / 2;
if(!(fin = fopen(FileIn, "rb")))
{
m_iResult = 2;
}
if(!(fout = fopen(FileOut, "wb")))
{
m_iResult = 2;
}
if(m_iResult == 0)
{
if(m_iType == 1)
{
aese.key((unsigned char*)key, key_len);
err = EncodeFile(fin, fout, FileIn, FileOut, Callback, lParam);
}
else if(m_iType == 2)
{
aesd.key((unsigned char*)key, key_len);
err = DecodeFile(fin, fout, FileIn, FileOut, Callback, lParam);
}
if(err == 0)
{
m_iResult = 0;
}
else if(err == READ_ERROR)
{
m_iResult = 2;
}
else if(err == WRITE_ERROR)
{
m_iResult = 2;
}
}
}
if(fout)
{
fclose(fout);
}
if(fin)
{
fclose(fin);
}
return m_iResult;
}
int EncodeFile(FILE* fin, FILE* fout,
const char* ifn, const char* ofn,
CallbackFunc* Callback, LPARAM lParam)
{
char buf[BLOCK_LEN], dbuf[2 * BLOCK_LEN];
fpos_t flen;
int m_iProgress;
unsigned long i, len, rlen, brlen;
MSG message;
m_iProgress = 0;
if(Callback)
Callback(m_iProgress, lParam);
// set a random IV
Fillrand(dbuf, BLOCK_LEN);
// find the file length
fseek(fin, 0, SEEK_END);
fgetpos(fin, &flen);
rlen = file_len(flen);
brlen = file_len(flen);
// reset to start
fseek(fin, 0, SEEK_SET);
if(rlen <= BLOCK_LEN)
{ // if the file length is less than or equal to 16 bytes
// read the bytes of the file into the buffer and verify length
len = (unsigned long) fread(dbuf + BLOCK_LEN, 1, BLOCK_LEN, fin);
rlen -= len;
if(rlen > 0)
return READ_ERROR;
// pad the file bytes with zeroes
for(i = len; i < BLOCK_LEN; ++i)
dbuf[i + BLOCK_LEN] = 0;
// xor the file bytes with the IV bytes
for(i = 0; i < BLOCK_LEN; ++i)
dbuf[i + BLOCK_LEN] ^= dbuf[i];
m_iProgress = 50;
if(Callback)
Callback(m_iProgress, lParam);
// encrypt the top 16 bytes of the buffer
aese.encrypt((unsigned char*)dbuf + BLOCK_LEN, (unsigned char*)dbuf + len);
len += BLOCK_LEN;
// write the IV and the encrypted file bytes
if(fwrite(dbuf, 1, len, fout) != len)
return WRITE_ERROR;
m_iProgress = 100;
if(Callback)
Callback(m_iProgress, lParam);
}
else
{ // if the file length is more 16 bytes
// write the IV
if(fwrite(dbuf, 1, BLOCK_LEN, fout) != BLOCK_LEN)
return WRITE_ERROR;
// read the file a block at a time
while(rlen > 0 && !feof(fin))
{
if(::PeekMessage(&message, NULL, 0, 0, PM_REMOVE))
{
::TranslateMessage(&message);
::DispatchMessage(&message);
}
// read a block and reduce the remaining byte count
len = (unsigned long)fread(buf, 1, BLOCK_LEN, fin);
rlen -= len;
m_iProgress = (int)(((brlen-rlen)*50/brlen)*2);
if(Callback)
// Pass i and userData. If the callback
// returns false, stop processing.
if (!Callback(m_iProgress, lParam))
return READ_ERROR;
// verify length of block
if(len != BLOCK_LEN)
return READ_ERROR;
// do CBC chaining prior to encryption
for(i = 0; i < BLOCK_LEN; ++i)
buf[i] ^= dbuf[i];
if(::PeekMessage(&message, NULL, 0, 0, PM_REMOVE))
{
::TranslateMessage(&message);
::DispatchMessage(&message);
}
// encrypt the block
aese.encrypt((unsigned char*)buf, (unsigned char*)dbuf);
if(::PeekMessage(&message, NULL, 0, 0, PM_REMOVE))
{
::TranslateMessage(&message);
::DispatchMessage(&message);
}
// if there is only one more block do ciphertext stealing
if(rlen > 0 && rlen < BLOCK_LEN)
{
// move the previous ciphertext to top half of double buffer
// since rlen bytes of this are output last
for(i = 0; i < BLOCK_LEN; ++i)
dbuf[i + BLOCK_LEN] = dbuf[i];
// read last part of plaintext into bottom half of buffer
if(fread(dbuf, 1, rlen, fin) != rlen)
return READ_ERROR;
// clear the remainder of the bottom half of buffer
for(i = 0; i < BLOCK_LEN - rlen; ++i)
dbuf[rlen + i] = 0;
// do CBC chaining from previous ciphertext
for(i = 0; i < BLOCK_LEN; ++i)
dbuf[i] ^= dbuf[i + BLOCK_LEN];
if(::PeekMessage(&message, NULL, 0, 0, PM_REMOVE))
{
::TranslateMessage(&message);
::DispatchMessage(&message);
}
// encrypt the final block
aese.encrypt((unsigned char*)dbuf, (unsigned char*)dbuf);
if(::PeekMessage(&message, NULL, 0, 0, PM_REMOVE))
{
::TranslateMessage(&message);
::DispatchMessage(&message);
}
// set the length of the final write
len = rlen + BLOCK_LEN; rlen = 0;
}
// write the encrypted block
if(fwrite(dbuf, 1, len, fout) != len)
return WRITE_ERROR;
if(::PeekMessage(&message, NULL, 0, 0, PM_REMOVE))
{
::TranslateMessage(&message);
::DispatchMessage(&message);
}
}
m_iProgress = 100;
}
if(Callback)
Callback(m_iProgress, lParam);
return 0;
}
int DecodeFile(FILE* fin, FILE* fout,
const char* ifn, const char* ofn,
CallbackFunc* Callback, LPARAM lParam)
{
char buf1[BLOCK_LEN], buf2[BLOCK_LEN], dbuf[2 * BLOCK_LEN];
char *b1, *b2, *bt;
fpos_t flen;
int m_iProgress;
unsigned long i, len, rlen, brlen;
MSG message;
m_iProgress = 0;
if(Callback)
Callback(m_iProgress, lParam);
// find the file length
fseek(fin, 0, SEEK_END);
fgetpos(fin, &flen);
rlen = file_len(flen);
brlen = file_len(flen);
// reset to start
fseek(fin, 0, SEEK_SET);
if(rlen <= 2 * BLOCK_LEN)
{ // if the original file length is less than or equal to 16 bytes
// read the bytes of the file and verify length
len = (unsigned long)fread(dbuf, 1, 2 * BLOCK_LEN, fin);
rlen -= len;
if(rlen > 0)
return READ_ERROR;
// set the original file length
len -= BLOCK_LEN;
m_iProgress = 50;
if(Callback)
Callback(m_iProgress, lParam);
// decrypt from position len to position len + BLOCK_LEN
aesd.decrypt((unsigned char*)dbuf + len, (unsigned char*)dbuf + BLOCK_LEN);
// undo CBC chaining
for(i = 0; i < len; ++i)
dbuf[i] ^= dbuf[i + BLOCK_LEN];
// output decrypted bytes
if(fwrite(dbuf, 1, len, fout) != len)
return WRITE_ERROR;
m_iProgress = 100;
if(Callback)
Callback(m_iProgress, lParam);
}
else
{ // we need two input buffers because we have to keep the previous
// ciphertext block - the pointers b1 and b2 are swapped once per
// loop so that b2 points to new ciphertext block and b1 to the
// last ciphertext block
rlen -= BLOCK_LEN; b1 = buf1; b2 = buf2;
// input the IV
if(fread(b1, 1, BLOCK_LEN, fin) != BLOCK_LEN)
return READ_ERROR;
// read the encrypted file a block at a time
while(rlen > 0 && !feof(fin))
{
if(::PeekMessage(&message, NULL, 0, 0, PM_REMOVE))
{
::TranslateMessage(&message);
::DispatchMessage(&message);
}
// input a block and reduce the remaining byte count
len = (unsigned long)fread(b2, 1, BLOCK_LEN, fin);
rlen -= len;
m_iProgress = (int)(((brlen-rlen)*50/brlen)*2);
if(Callback)
// Pass i and userData. If the callback
// returns false, stop processing.
if(!Callback(m_iProgress, lParam))
return READ_ERROR;
// verify the length of the read operation
if(len != BLOCK_LEN)
return READ_ERROR;
if(::PeekMessage(&message, NULL, 0, 0, PM_REMOVE))
{
::TranslateMessage(&message);
::DispatchMessage(&message);
}
// decrypt input buffer
aesd.decrypt((unsigned char*)b2, (unsigned char*)dbuf);
if(::PeekMessage(&message, NULL, 0, 0, PM_REMOVE))
{
::TranslateMessage(&message);
::DispatchMessage(&message);
}
// if there is only one more block do ciphertext stealing
if(rlen > 0 && rlen < BLOCK_LEN)
{
// read last ciphertext block
if(fread(b2, 1, rlen, fin) != rlen)
return READ_ERROR;
// append high part of last decrypted block
for(i = rlen; i < BLOCK_LEN; ++i)
b2[i] = dbuf[i];
// decrypt last block of plaintext
for(i = 0; i < rlen; ++i)
dbuf[i + BLOCK_LEN] = dbuf[i] ^ b2[i];
if(::PeekMessage(&message, NULL, 0, 0, PM_REMOVE))
{
::TranslateMessage(&message);
::DispatchMessage(&message);
}
// decrypt last but one block of plaintext
aesd.decrypt((unsigned char*)b2, (unsigned char*)dbuf);
if(::PeekMessage(&message, NULL, 0, 0, PM_REMOVE))
{
::TranslateMessage(&message);
::DispatchMessage(&message);
}
// adjust length of last output block
len = rlen + BLOCK_LEN; rlen = 0;
}
// unchain CBC using the last ciphertext block
for(i = 0; i < BLOCK_LEN; ++i)
dbuf[i] ^= b1[i];
// write decrypted block
if(fwrite(dbuf, 1, len, fout) != len)
return WRITE_ERROR;
// swap the buffer pointers
bt = b1, b1 = b2, b2 = bt;
if(::PeekMessage(&message, NULL, 0, 0, PM_REMOVE))
{
::TranslateMessage(&message);
::DispatchMessage(&message);
}
}
m_iProgress = 100;
}
if(Callback)
Callback(m_iProgress, lParam);
return 0;
}
void Cycles(volatile unsigned __int64* rtn)
{
#if defined(_MSC_VER)
__asm // read the Pentium Time Stamp Counter
{ cpuid
rdtsc
mov ecx,rtn
mov [ecx],eax
mov [ecx+4],edx
cpuid
}
#else
time_t tt;
tt = time(NULL);
rtn[0] = tt;
rtn[1] = tt & -36969l;
return;
#endif
}
#define RAND(a,b) (((a = 36969 * (a & 65535) + (a >> 16)) << 16) + \
(b = 18000 * (b & 65535) + (b >> 16)) )
void Fillrand(char* buf, const int len)
{
static unsigned long a[2], mt = 1, count = 4;
static char r[4];
int i;
if(mt) { mt = 0; Cycles((unsigned __int64 *)a); }
for(i = 0; i < len; ++i)
{
if(count == 4)
{
*(unsigned long*)r = RAND(a[0], a[1]);
count = 0;
}
buf[i] = r[count++];
}
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -