File: crypt.cpp

package info (click to toggle)
unrar-nonfree 1%3A5.2.7-0.1%2Bdeb8u1
  • links: PTS
  • area: non-free
  • in suites: jessie
  • size: 1,344 kB
  • ctags: 3,512
  • sloc: cpp: 24,411; makefile: 124; sh: 10
file content (129 lines) | stat: -rw-r--r-- 2,683 bytes parent folder | download | duplicates (3)
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++);
    }
  }
}