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