SetKey30(bool Encrypt,SecPassword * Password,const wchar * PwdW,const byte * Salt)1 void CryptData::SetKey30(bool Encrypt,SecPassword *Password,const wchar *PwdW,const byte *Salt)
2 {
3   byte AESKey[16],AESInit[16];
4 
5   bool Cached=false;
6   for (uint I=0;I<ASIZE(KDF3Cache);I++)
7     if (KDF3Cache[I].Pwd==*Password &&
8         (Salt==NULL && !KDF3Cache[I].SaltPresent || Salt!=NULL &&
9         KDF3Cache[I].SaltPresent && memcmp(KDF3Cache[I].Salt,Salt,SIZE_SALT30)==0))
10     {
11       memcpy(AESKey,KDF3Cache[I].Key,sizeof(AESKey));
12       SecHideData(AESKey,sizeof(AESKey),false,false);
13       memcpy(AESInit,KDF3Cache[I].Init,sizeof(AESInit));
14       Cached=true;
15       break;
16     }
17 
18   if (!Cached)
19   {
20     byte RawPsw[2*MAXPASSWORD+SIZE_SALT30];
21     WideToRaw(PwdW,RawPsw,ASIZE(RawPsw));
22     size_t RawLength=2*wcslen(PwdW);
23     if (Salt!=NULL)
24     {
25       memcpy(RawPsw+RawLength,Salt,SIZE_SALT30);
26       RawLength+=SIZE_SALT30;
27     }
28     sha1_context c;
29     sha1_init(&c);
30 
31     const uint HashRounds=0x40000;
32     for (uint I=0;I<HashRounds;I++)
33     {
34       sha1_process_rar29( &c, RawPsw, RawLength );
35       byte PswNum[3];
36       PswNum[0]=(byte)I;
37       PswNum[1]=(byte)(I>>8);
38       PswNum[2]=(byte)(I>>16);
39       sha1_process(&c, PswNum, 3);
40       if (I%(HashRounds/16)==0)
41       {
42         sha1_context tempc=c;
43         uint32 digest[5];
44         sha1_done( &tempc, digest );
45         AESInit[I/(HashRounds/16)]=(byte)digest[4];
46       }
47     }
48     uint32 digest[5];
49     sha1_done( &c, digest );
50     for (uint I=0;I<4;I++)
51       for (uint J=0;J<4;J++)
52         AESKey[I*4+J]=(byte)(digest[I]>>(J*8));
53 
54     KDF3Cache[KDF3CachePos].Pwd=*Password;
55     if ((KDF3Cache[KDF3CachePos].SaltPresent=(Salt!=NULL))==true)
56       memcpy(KDF3Cache[KDF3CachePos].Salt,Salt,SIZE_SALT30);
57     memcpy(KDF3Cache[KDF3CachePos].Key,AESKey,sizeof(AESKey));
58     SecHideData(KDF3Cache[KDF3CachePos].Key,sizeof(KDF3Cache[KDF3CachePos].Key),true,false);
59     memcpy(KDF3Cache[KDF3CachePos].Init,AESInit,sizeof(AESInit));
60     KDF3CachePos=(KDF3CachePos+1)%ASIZE(KDF3Cache);
61 
62     cleandata(RawPsw,sizeof(RawPsw));
63   }
64   rin.Init(Encrypt, AESKey, 128, AESInit);
65   cleandata(AESKey,sizeof(AESKey));
66   cleandata(AESInit,sizeof(AESInit));
67 }
68 
69