123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134 |
- #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;I<Size;I+=CRYPT_BLOCK_SIZE)
- DecryptBlock20(Buf+I);
- break;
- #endif
- case CRYPT_RAR30:
- case CRYPT_RAR50:
- rin.blockDecrypt(Buf,Size,Buf);
- break;
- }
- }
- bool CryptData::SetCryptKeys(bool Encrypt,CRYPT_METHOD Method,
- SecPassword *Password,const byte *Salt,
- const byte *InitV,uint Lg2Cnt,byte *HashKey,byte *PswCheck)
- {
- if (!Password->IsSet() || 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<BufSize;I++)
- {
- byte RndByte = byte (Random >> ( (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);
- }
|