mirror of
https://github.com/despawnerer/freearc
synced 2026-08-23 02:23:04 -04:00
389 lines
15 KiB
C++
389 lines
15 KiB
C++
|
|
extern "C" {
|
|||
|
|
#include "7zAES/Aes.c"
|
|||
|
|
#include "7zAES/CpuArch.c"
|
|||
|
|
|
|||
|
|
#include "C_Encryption.h"
|
|||
|
|
#define LTC_NO_CIPHERS
|
|||
|
|
#define LTC_BLOWFISH
|
|||
|
|
#define LTC_RIJNDAEL
|
|||
|
|
#define ENCRYPT_ONLY
|
|||
|
|
#define LTC_TWOFISH
|
|||
|
|
#define LTC_SERPENT
|
|||
|
|
#define LTC_NO_MODES
|
|||
|
|
#define LTC_CFB_MODE
|
|||
|
|
#define LTC_CTR_MODE
|
|||
|
|
#define LTC_NO_HASHES
|
|||
|
|
#define LTC_SHA512
|
|||
|
|
#define LTC_NO_MACS
|
|||
|
|
#define LTC_HMAC
|
|||
|
|
#define LTC_NO_MATH
|
|||
|
|
#define LTC_NO_PK
|
|||
|
|
#define LTC_MECC
|
|||
|
|
#define LTC_NO_TEST
|
|||
|
|
#include "ciphers/aes/aes.c"
|
|||
|
|
#include "ciphers/blowfish.c"
|
|||
|
|
#include "ciphers/twofish/twofish.c"
|
|||
|
|
#include "ciphers/serpent.c"
|
|||
|
|
#include "crypt/crypt_argchk.c"
|
|||
|
|
#include "crypt/crypt_cipher_descriptor.c"
|
|||
|
|
#include "crypt/crypt_cipher_is_valid.c"
|
|||
|
|
#include "crypt/crypt_find_cipher.c"
|
|||
|
|
#include "crypt/crypt_find_hash.c"
|
|||
|
|
#include "crypt/crypt_find_prng.c"
|
|||
|
|
#include "crypt/crypt_hash_descriptor.c"
|
|||
|
|
#include "crypt/crypt_hash_is_valid.c"
|
|||
|
|
#include "crypt/crypt_prng_descriptor.c"
|
|||
|
|
#include "crypt/crypt_prng_is_valid.c"
|
|||
|
|
#include "crypt/crypt_register_cipher.c"
|
|||
|
|
#include "crypt/crypt_register_hash.c"
|
|||
|
|
#include "crypt/crypt_register_prng.c"
|
|||
|
|
#include "hashes/helper/hash_memory.c"
|
|||
|
|
#include "hashes/sha2/sha512.c"
|
|||
|
|
#include "mac/hmac/hmac_done.c"
|
|||
|
|
#include "mac/hmac/hmac_init.c"
|
|||
|
|
#include "mac/hmac/hmac_memory.c"
|
|||
|
|
#include "mac/hmac/hmac_process.c"
|
|||
|
|
#include "misc/error_to_string.c"
|
|||
|
|
#include "misc/pkcs5/pkcs_5_2.c"
|
|||
|
|
#include "misc/zeromem.c"
|
|||
|
|
#include "modes/ctr/ctr_decrypt.c"
|
|||
|
|
#include "modes/ctr/ctr_done.c"
|
|||
|
|
#include "modes/ctr/ctr_encrypt.c"
|
|||
|
|
#include "modes/ctr/ctr_start.c"
|
|||
|
|
#include "modes/cfb/cfb_decrypt.c"
|
|||
|
|
#include "modes/cfb/cfb_done.c"
|
|||
|
|
#include "modes/cfb/cfb_encrypt.c"
|
|||
|
|
#include "modes/cfb/cfb_start.c"
|
|||
|
|
#include "prngs/fortuna.c"
|
|||
|
|
}
|
|||
|
|
#include "../MultiThreading.h"
|
|||
|
|
|
|||
|
|
|
|||
|
|
/*-------------------------------------------------*/
|
|||
|
|
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> LibTomCrypt */
|
|||
|
|
/*-------------------------------------------------*/
|
|||
|
|
|
|||
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
int register_all()
|
|||
|
|
{
|
|||
|
|
register_cipher (&aes_enc_desc);
|
|||
|
|
register_cipher (&blowfish_desc);
|
|||
|
|
register_cipher (&serpent_desc);
|
|||
|
|
register_cipher (&twofish_desc);
|
|||
|
|
// register_hash (&sha1_desc);
|
|||
|
|
register_hash (&sha512_desc);
|
|||
|
|
#ifndef LTC_NO_TEST
|
|||
|
|
CHECK (FREEARC_ERRCODE_INTERNAL, blowfish_test()==CRYPT_OK, (s,"blowfish_test failed!"));
|
|||
|
|
// CHECK (FREEARC_ERRCODE_INTERNAL, rijndael_test()==CRYPT_OK, (s,"rijndael_test failed!"));
|
|||
|
|
CHECK (FREEARC_ERRCODE_INTERNAL, serpent_test ()==CRYPT_OK, (s,"serpent_test failed!"));
|
|||
|
|
CHECK (FREEARC_ERRCODE_INTERNAL, twofish_test ()==CRYPT_OK, (s,"twofish_test failed!"));
|
|||
|
|
// CHECK (FREEARC_ERRCODE_INTERNAL, sha1_test ()==CRYPT_OK, (s,"sha1_test failed!"));
|
|||
|
|
CHECK (FREEARC_ERRCODE_INTERNAL, sha512_test ()==CRYPT_OK, (s,"sha512_test failed!"));
|
|||
|
|
// CHECK (FREEARC_ERRCODE_INTERNAL, hmac_test ()==CRYPT_OK, (s,"hmac_test failed!"));
|
|||
|
|
// CHECK (FREEARC_ERRCODE_INTERNAL, ctr_test ()==CRYPT_OK, (s,"ctr_test failed!"));
|
|||
|
|
// CHECK (FREEARC_ERRCODE_INTERNAL, cfb_test ()==CRYPT_OK, (s,"cfb_test failed!"));
|
|||
|
|
#endif
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
int call_register_all = register_all();
|
|||
|
|
|
|||
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Fortuna PRNG
|
|||
|
|
int fortuna_size (void)
|
|||
|
|
{
|
|||
|
|
return sizeof(prng_state);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
/*------------------------------------------------------*/
|
|||
|
|
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (CFB,CTR) */
|
|||
|
|
/*------------------------------------------------------*/
|
|||
|
|
|
|||
|
|
#define roundup_ptr(p,n) ((p)+(n)-ptrdiff_t(p)%(n))
|
|||
|
|
|
|||
|
|
struct EncryptionMode
|
|||
|
|
{
|
|||
|
|
enum {CTR,CFB} mode;
|
|||
|
|
union
|
|||
|
|
{
|
|||
|
|
symmetric_CTR ctr;
|
|||
|
|
symmetric_CFB cfb;
|
|||
|
|
char aesbuf [AES_NUM_IVMRK_WORDS*sizeof(UInt32) + AES_BLOCK_SIZE]; // buffer for g_AesCtr_Code
|
|||
|
|
};
|
|||
|
|
char *aesctr;
|
|||
|
|
|
|||
|
|
EncryptionMode (int _mode) {mode = (_mode==0? CTR:CFB);}
|
|||
|
|
|
|||
|
|
char *name()
|
|||
|
|
{
|
|||
|
|
switch (mode) {
|
|||
|
|
case CTR: return "ctr";
|
|||
|
|
case CFB: return "cfb";
|
|||
|
|
default: abort();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int start (int cipher, BYTE *iv, BYTE *key, int keysize, int rounds)
|
|||
|
|
{
|
|||
|
|
// 7-zip code implements only AES-CTR with default number of rounds
|
|||
|
|
if (strequ(cipher_descriptor[cipher].name,"aes") && mode==CTR && rounds==0)
|
|||
|
|
{
|
|||
|
|
// Init the AES-CTR library
|
|||
|
|
static Mutex exclusive_access;
|
|||
|
|
{
|
|||
|
|
Lock _(exclusive_access);
|
|||
|
|
static volatile bool initialized = false;
|
|||
|
|
if (!initialized)
|
|||
|
|
{
|
|||
|
|
initialized = true;
|
|||
|
|
AesGenTables();
|
|||
|
|
if (CPU_Is_Aes_Supported())
|
|||
|
|
{
|
|||
|
|
FARPROC Fast_AesCtr_Code = LoadFromDLL("Fast_AesCtr_Code");
|
|||
|
|
if (Fast_AesCtr_Code) g_AesCtr_Code = (AES_CODE_FUNC) Fast_AesCtr_Code;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// aesctr[] should be aligned to 16-byte boundary
|
|||
|
|
aesctr = roundup_ptr (aesbuf, AES_BLOCK_SIZE);
|
|||
|
|
// Store in aesctr[] InitVector-1 (since 7-zip code does *pre*increment of counter)
|
|||
|
|
memcpy (aesctr, iv, AES_BLOCK_SIZE);
|
|||
|
|
for (int i=0; i<AES_BLOCK_SIZE; i++)
|
|||
|
|
if(aesctr[i]--) break;
|
|||
|
|
// Calculate and store in aesctr[] number of rounds and roundKeys
|
|||
|
|
Aes_SetKey_Enc ((UInt32*)(aesctr+AES_BLOCK_SIZE), key, keysize);
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
aesctr = NULL;
|
|||
|
|
|
|||
|
|
switch (mode) {
|
|||
|
|
case CTR: return ctr_start (cipher, iv, key, keysize, rounds, CTR_COUNTER_LITTLE_ENDIAN, &ctr);
|
|||
|
|
case CFB: return cfb_start (cipher, iv, key, keysize, rounds, &cfb);
|
|||
|
|
default: abort();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int encrypt (BYTE *buf, int len)
|
|||
|
|
{
|
|||
|
|
if (aesctr)
|
|||
|
|
{
|
|||
|
|
g_AesCtr_Code ((UInt32*)aesctr, buf, len/AES_BLOCK_SIZE);
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
switch (mode) {
|
|||
|
|
case CTR: return ctr_encrypt (buf, buf, len, &ctr);
|
|||
|
|
case CFB: return cfb_encrypt (buf, buf, len, &cfb);
|
|||
|
|
default: abort();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int decrypt (BYTE *buf, int len)
|
|||
|
|
{
|
|||
|
|
if (aesctr)
|
|||
|
|
{
|
|||
|
|
g_AesCtr_Code ((UInt32*)aesctr, buf, len/AES_BLOCK_SIZE);
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
switch (mode) {
|
|||
|
|
case CTR: return ctr_decrypt (buf, buf, len, &ctr);
|
|||
|
|
case CFB: return cfb_decrypt (buf, buf, len, &cfb);
|
|||
|
|
default: abort();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int done()
|
|||
|
|
{
|
|||
|
|
if (aesctr)
|
|||
|
|
{
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
switch (mode) {
|
|||
|
|
case CTR: return ctr_done (&ctr);
|
|||
|
|
case CFB: return cfb_done (&cfb);
|
|||
|
|
default: abort();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
int find_mode (char *name)
|
|||
|
|
{
|
|||
|
|
if (strequ(name,"ctr")) return 0;
|
|||
|
|
if (strequ(name,"cfb")) return 1;
|
|||
|
|
else return -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
/*-------------------------------------------------*/
|
|||
|
|
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
|||
|
|
/*-------------------------------------------------*/
|
|||
|
|
|
|||
|
|
// Generate key from password and salt using numIterations of sha-512 hashing (PKCS5#2)
|
|||
|
|
void Pbkdf2Hmac (const BYTE *pwd, int pwdSize, const BYTE *salt, int saltSize,
|
|||
|
|
int numIterations, BYTE *key, int keySize)
|
|||
|
|
{
|
|||
|
|
int hash = find_hash("sha512");
|
|||
|
|
unsigned long ulKeySize = keySize;
|
|||
|
|
pkcs_5_alg2 (pwd, pwdSize, salt, saltSize, numIterations, hash, key, &ulKeySize);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> DoEncryption
|
|||
|
|
int docrypt (enum TEncrypt DoEncryption, int cipher, int mode, BYTE *key, int keysize, int rounds, BYTE *iv,
|
|||
|
|
CALLBACK_FUNC *callback, void *auxdata)
|
|||
|
|
{
|
|||
|
|
EncryptionMode encryptor(mode);
|
|||
|
|
encryptor.start (cipher, iv, key, keysize, rounds);
|
|||
|
|
|
|||
|
|
int InSize = FREEARC_ERRCODE_NOT_ENOUGH_MEMORY; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
int RemainderSize = 0; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> (<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 0 <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
|
|||
|
|
BYTE* Buf0 = (BYTE*)malloc(LARGE_BUFFER_SIZE+AES_BLOCK_SIZE); // <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
if (!Buf0) goto Exit; // <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
{BYTE* Buf = roundup_ptr (Buf0, AES_BLOCK_SIZE);
|
|||
|
|
|
|||
|
|
while ( (InSize = callback ("read", Buf+RemainderSize, LARGE_BUFFER_SIZE-RemainderSize, auxdata)) >= 0 ) // <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
{
|
|||
|
|
bool LastBlock = (InSize==0); // True for the last block that should be processed in the special way
|
|||
|
|
if ((InSize+=RemainderSize)==0) break; // break if there's no more data
|
|||
|
|
|
|||
|
|
int OutSize = encryptor.aesctr==NULL? InSize // process all input data unless optimized AES-CTR code used
|
|||
|
|
: LastBlock? roundUp (InSize, AES_BLOCK_SIZE) // process more data if these are the last bytes in input stream
|
|||
|
|
: roundDown (InSize, AES_BLOCK_SIZE), x; // process less data and move the rest to the next processing cycle
|
|||
|
|
|
|||
|
|
DoEncryption==ENCRYPT
|
|||
|
|
? encryptor.encrypt(Buf, OutSize)
|
|||
|
|
: encryptor.decrypt(Buf, OutSize);
|
|||
|
|
|
|||
|
|
if (OutSize>InSize) OutSize=InSize;
|
|||
|
|
|
|||
|
|
if( (x=callback("write",Buf,OutSize,auxdata))<0 ) {InSize=x; break;} // break on write rror
|
|||
|
|
if( LastBlock ) {InSize=0; break;} // break if the last block
|
|||
|
|
RemainderSize = InSize-OutSize;
|
|||
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
if (RemainderSize>0) memmove (Buf, Buf+OutSize, RemainderSize);
|
|||
|
|
}}
|
|||
|
|
Exit:
|
|||
|
|
encryptor.done();
|
|||
|
|
free (Buf0);
|
|||
|
|
return InSize; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> 0 <20><><EFBFBD><EFBFBD> <20><><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
/*-------------------------------------------------*/
|
|||
|
|
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ENCRYPTION_METHOD */
|
|||
|
|
/*-------------------------------------------------*/
|
|||
|
|
|
|||
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
ENCRYPTION_METHOD::ENCRYPTION_METHOD()
|
|||
|
|
{
|
|||
|
|
cipher = -1;
|
|||
|
|
mode = -1;
|
|||
|
|
numIterations = 1000;
|
|||
|
|
rounds = 0;
|
|||
|
|
keySize = -1;
|
|||
|
|
fixed = FALSE;
|
|||
|
|
strcpy(key, "");
|
|||
|
|
strcpy(iv, "");
|
|||
|
|
strcpy(salt, "");
|
|||
|
|
strcpy(code, "");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> "encryption?", "KeySize" <20> "IVSize"
|
|||
|
|
int ENCRYPTION_METHOD::doit (char *what, int param, void *data, CALLBACK_FUNC *callback)
|
|||
|
|
{
|
|||
|
|
if (strequ (what, "encryption?")) return 1; // <20><>, <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
else if (strequ (what, "keySize")) return keySize; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
else if (strequ (what, "ivSize")) return ivSize; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> InitVector, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
else if (strequ (what, "numIterations")) return numIterations; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><> password+salt
|
|||
|
|
else return COMPRESSION_METHOD::doit (what, param, data, callback); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
int ENCRYPTION_METHOD::decompress (CALLBACK_FUNC *callback, void *auxdata)
|
|||
|
|
{
|
|||
|
|
BYTE key_bytes[MAXKEYSIZE]; fixed? decode16 (key, key_bytes) : buggy_decode16 (key, key_bytes);
|
|||
|
|
BYTE iv_bytes [MAXKEYSIZE]; fixed? decode16 (iv, iv_bytes) : buggy_decode16 (iv, iv_bytes);
|
|||
|
|
return docrypt (DECRYPT, cipher, mode, key_bytes, strlen(key)/2, rounds, iv_bytes, callback, auxdata);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#ifndef FREEARC_DECOMPRESS_ONLY
|
|||
|
|
|
|||
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
int ENCRYPTION_METHOD::compress (CALLBACK_FUNC *callback, void *auxdata)
|
|||
|
|
{
|
|||
|
|
BYTE key_bytes[MAXKEYSIZE]; fixed? decode16 (key, key_bytes) : buggy_decode16 (key, key_bytes);
|
|||
|
|
BYTE iv_bytes [MAXKEYSIZE]; fixed? decode16 (iv, iv_bytes) : buggy_decode16 (iv, iv_bytes);
|
|||
|
|
return docrypt (ENCRYPT, cipher, mode, key_bytes, strlen(key)/2, rounds, iv_bytes, callback, auxdata);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#endif // !defined (FREEARC_DECOMPRESS_ONLY)
|
|||
|
|
|
|||
|
|
|
|||
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> buf[MAX_METHOD_STRLEN] <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> parse_ENCRYPTION)
|
|||
|
|
void ENCRYPTION_METHOD::ShowCompressionMethod (char *buf, bool purify)
|
|||
|
|
{
|
|||
|
|
sprintf (buf, "%s-%d/%s%s:n%d:r%d%s%s%s%s%s%s%s%s"
|
|||
|
|
, cipher_descriptor[cipher].name, keySize*8
|
|||
|
|
, EncryptionMode(mode).name()
|
|||
|
|
, fixed? ":f" : ""
|
|||
|
|
, numIterations
|
|||
|
|
, rounds
|
|||
|
|
, *key ?":k":"", key
|
|||
|
|
, *iv ?":i":"", iv
|
|||
|
|
, *salt?":s":"", salt
|
|||
|
|
, *code?":c":"", code
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> ENCRYPTION_METHOD <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
// <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> NULL, <20><><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
COMPRESSION_METHOD* parse_ENCRYPTION (char** parameters)
|
|||
|
|
{
|
|||
|
|
int error = 0; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>, <20><><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|
|||
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> split <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
char local_method[MAX_METHOD_STRLEN];
|
|||
|
|
strncopy (local_method, parameters[0], MAX_METHOD_STRLEN);
|
|||
|
|
|
|||
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 2 <20><><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> '/'
|
|||
|
|
// <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, "aes/cfb")
|
|||
|
|
char *parts[3];
|
|||
|
|
split (local_method, '/', parts, 3);
|
|||
|
|
int mode = parts[1]? find_mode(parts[1]) : 0;
|
|||
|
|
|
|||
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 2 <20><><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> '-'
|
|||
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD> '-' <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD> (<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, "aes-128")
|
|||
|
|
split (local_method, '-', parts, 3);
|
|||
|
|
|
|||
|
|
int cipher = find_cipher(parts[0]);
|
|||
|
|
int keySize = parts[1]? parseInt (parts[1], &error)/8 : 0;
|
|||
|
|
if (mode<0 || cipher<0 || error) return NULL; // <20><><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD> ENCRYPTION
|
|||
|
|
|
|||
|
|
ENCRYPTION_METHOD *p = new ENCRYPTION_METHOD;
|
|||
|
|
p->cipher = cipher;
|
|||
|
|
p->mode = mode;
|
|||
|
|
p->keySize = keySize? keySize : cipher_descriptor[cipher].max_key_length;
|
|||
|
|
p->ivSize = cipher_descriptor[cipher].block_length;
|
|||
|
|
|
|||
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (<28><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
|
|||
|
|
while (*++parameters && !error)
|
|||
|
|
{
|
|||
|
|
char* param = *parameters;
|
|||
|
|
if (strequ (param, "f")) {
|
|||
|
|
p->fixed = TRUE; continue;
|
|||
|
|
}
|
|||
|
|
switch (*param) { // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
case 'k': strncopy (p->key, param+1, sizeof (p->key)); continue;
|
|||
|
|
case 'i': strncopy (p->iv, param+1, sizeof (p->iv)); continue;
|
|||
|
|
case 's': strncopy (p->salt, param+1, sizeof (p->salt)); continue;
|
|||
|
|
case 'c': strncopy (p->code, param+1, sizeof (p->code)); continue;
|
|||
|
|
case 'n': p->numIterations = parseInt (param+1, &error); continue;
|
|||
|
|
case 'r': p->rounds = parseInt (param+1, &error); continue;
|
|||
|
|
default : error=1; continue;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
if (error) {delete p; return NULL;} // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
return p;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
static int ENCRYPTION_x = AddCompressionMethod (parse_ENCRYPTION); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ENCRYPTION
|