Welcome to mirror list, hosted at ThFree Co, Russian Federation.

crypt.cpp « unrar « thirdparty « src - github.com/mpc-hc/mpc-hc.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 1a97640088165fc6e7b4c0fc4b63a556f5bdc9d9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#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;
}




// 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)
  {
    static uint Count=0;
    RarTime CurTime;
    CurTime.SetCurrentTime();
    uint64 Random=CurTime.GetRaw()+clock();
    for (size_t I=0;I<BufSize;I++)
    {
      byte RndByte = byte (Random >> ( (I & 7) * 8 ));
      RndBuf[I]=byte( (RndByte ^ I) + Count++);
    }
  }
}