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