#include "rar.hpp" #ifndef SFX_MODULE #include "crypt1.cpp" #include "crypt2.cpp" #endif #include "crypt3.cpp" #include "crypt5.cpp" CryptData::CryptData() { Method=CRYPT_NONE; memset(KDF3Cache,0,sizeof(KDF3Cache)); memset(KDF5Cache,0,sizeof(KDF5Cache)); KDF3CachePos=0; KDF5CachePos=0; memset(CRCTab,0,sizeof(CRCTab)); } CryptData::~CryptData() { cleandata(KDF3Cache,sizeof(KDF3Cache)); cleandata(KDF5Cache,sizeof(KDF5Cache)); } void CryptData::DecryptBlock(byte *Buf,size_t Size) { switch(Method) { #ifndef SFX_MODULE case CRYPT_RAR13: Decrypt13(Buf,Size); break; case CRYPT_RAR15: Crypt15(Buf,Size); break; case CRYPT_RAR20: for (size_t I=0;IIsSet() || Method==CRYPT_NONE) return false; CryptData::Method=Method; wchar PwdW[MAXPASSWORD]; Password->Get(PwdW,ASIZE(PwdW)); char PwdA[MAXPASSWORD]; WideToChar(PwdW,PwdA,ASIZE(PwdA)); switch(Method) { #ifndef SFX_MODULE case CRYPT_RAR13: SetKey13(PwdA); break; case CRYPT_RAR15: SetKey15(PwdA); break; case CRYPT_RAR20: SetKey20(PwdA); break; #endif case CRYPT_RAR30: SetKey30(Encrypt,Password,PwdW,Salt); break; case CRYPT_RAR50: SetKey50(Encrypt,Password,PwdW,Salt,InitV,Lg2Cnt,HashKey,PswCheck); break; } cleandata(PwdA,sizeof(PwdA)); cleandata(PwdW,sizeof(PwdW)); return true; } // Use the current system time to additionally randomize data. static void TimeRandomize(byte *RndBuf,size_t BufSize) { static uint Count=0; RarTime CurTime; CurTime.SetCurrentTime(); uint64 Random=CurTime.GetWin()+clock(); for (size_t I=0;I> ( (I & 7) * 8 )); RndBuf[I]=byte( (RndByte ^ I) + Count++); } } // Fill buffer with random data. void GetRnd(byte *RndBuf,size_t BufSize) { bool Success=false; #if defined(_WIN_ALL) HCRYPTPROV hProvider = 0; if (CryptAcquireContext(&hProvider, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) { Success=CryptGenRandom(hProvider, (DWORD)BufSize, RndBuf) == TRUE; CryptReleaseContext(hProvider, 0); } #elif defined(_UNIX) FILE *rndf = fopen("/dev/urandom", "r"); if (rndf!=NULL) { Success=fread(RndBuf, BufSize, 1, rndf) == BufSize; fclose(rndf); } #endif // We use this code only as the last resort if code above failed. if (!Success) TimeRandomize(RndBuf,BufSize); }