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

crypt3.cpp « unrar « thirdparty « src - github.com/mpc-hc/mpc-hc.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: bcc7cfa6d49c74a66259785d51b3f3e73f6e7df6 (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
void CryptData::SetKey30(bool Encrypt,SecPassword *Password,const wchar *PwdW,const byte *Salt)
{
  byte AESKey[16],AESInit[16];

  bool Cached=false;
  for (uint I=0;I<ASIZE(KDF3Cache);I++)
    if (KDF3Cache[I].Pwd==*Password &&
        (Salt==NULL && !KDF3Cache[I].SaltPresent || Salt!=NULL &&
        KDF3Cache[I].SaltPresent && memcmp(KDF3Cache[I].Salt,Salt,SIZE_SALT30)==0))
    {
      memcpy(AESKey,KDF3Cache[I].Key,sizeof(AESKey));
      memcpy(AESInit,KDF3Cache[I].Init,sizeof(AESInit));
      Cached=true;
      break;
    }

  if (!Cached)
  {
    byte RawPsw[2*MAXPASSWORD+SIZE_SALT30];
    WideToRaw(PwdW,RawPsw,ASIZE(RawPsw));
    size_t RawLength=2*wcslen(PwdW);
    if (Salt!=NULL)
    {
      memcpy(RawPsw+RawLength,Salt,SIZE_SALT30);
      RawLength+=SIZE_SALT30;
    }
    sha1_context c;
    sha1_init(&c);

    const int HashRounds=0x40000;
    for (int I=0;I<HashRounds;I++)
    {
      sha1_process( &c, RawPsw, RawLength, false);
      byte PswNum[3];
      PswNum[0]=(byte)I;
      PswNum[1]=(byte)(I>>8);
      PswNum[2]=(byte)(I>>16);
      sha1_process( &c, PswNum, 3, false);
      if (I%(HashRounds/16)==0)
      {
        sha1_context tempc=c;
        uint32 digest[5];
        sha1_done( &tempc, digest, false);
        AESInit[I/(HashRounds/16)]=(byte)digest[4];
      }
    }
    uint32 digest[5];
    sha1_done( &c, digest, false);
    for (int I=0;I<4;I++)
      for (int J=0;J<4;J++)
        AESKey[I*4+J]=(byte)(digest[I]>>(J*8));

    KDF3Cache[KDF3CachePos].Pwd=*Password;
    if ((KDF3Cache[KDF3CachePos].SaltPresent=(Salt!=NULL))==true)
      memcpy(KDF3Cache[KDF3CachePos].Salt,Salt,SIZE_SALT30);
    memcpy(KDF3Cache[KDF3CachePos].Key,AESKey,sizeof(AESKey));
    memcpy(KDF3Cache[KDF3CachePos].Init,AESInit,sizeof(AESInit));
    KDF3CachePos=(KDF3CachePos+1)%ASIZE(KDF3Cache);

    cleandata(RawPsw,sizeof(RawPsw));
  }
  rin.Init(Encrypt, AESKey, 128, AESInit);
  cleandata(AESKey,sizeof(AESKey));
  cleandata(AESInit,sizeof(AESInit));
}