| 129 | |
| 130 | |
| 131 | void CryptData::SetKey50(bool Encrypt,SecPassword *Password,const wchar *PwdW, |
| 132 | const byte *Salt,const byte *InitV,uint Lg2Cnt,byte *HashKey, |
| 133 | byte *PswCheck) |
| 134 | { |
| 135 | if (Lg2Cnt>CRYPT5_KDF_LG2_COUNT_MAX) |
| 136 | return; |
| 137 | |
| 138 | byte Key[32],PswCheckValue[SHA256_DIGEST_SIZE],HashKeyValue[SHA256_DIGEST_SIZE]; |
| 139 | bool Found=false; |
| 140 | for (uint I=0;I<ASIZE(KDF5Cache);I++) |
| 141 | { |
| 142 | KDF5CacheItem *Item=KDF5Cache+I; |
| 143 | if (Item->Lg2Count==Lg2Cnt && Item->Pwd==*Password && |
| 144 | memcmp(Item->Salt,Salt,SIZE_SALT50)==0) |
| 145 | { |
| 146 | memcpy(Key,Item->Key,sizeof(Key)); |
| 147 | SecHideData(Key,sizeof(Key),false,false); |
| 148 | |
| 149 | memcpy(PswCheckValue,Item->PswCheckValue,sizeof(PswCheckValue)); |
| 150 | memcpy(HashKeyValue,Item->HashKeyValue,sizeof(HashKeyValue)); |
| 151 | Found=true; |
| 152 | break; |
| 153 | } |
| 154 | } |
| 155 | |
| 156 | if (!Found) |
| 157 | { |
| 158 | char PwdUtf[MAXPASSWORD*4]; |
| 159 | WideToUtf(PwdW,PwdUtf,ASIZE(PwdUtf)); |
| 160 | |
| 161 | pbkdf2((byte *)PwdUtf,strlen(PwdUtf),Salt,SIZE_SALT50,Key,HashKeyValue,PswCheckValue,(1<<Lg2Cnt)); |
| 162 | cleandata(PwdUtf,sizeof(PwdUtf)); |
| 163 | |
| 164 | KDF5CacheItem *Item=KDF5Cache+(KDF5CachePos++ % ASIZE(KDF5Cache)); |
| 165 | Item->Lg2Count=Lg2Cnt; |
| 166 | Item->Pwd=*Password; |
| 167 | memcpy(Item->Salt,Salt,SIZE_SALT50); |
| 168 | memcpy(Item->Key,Key,sizeof(Item->Key)); |
| 169 | memcpy(Item->PswCheckValue,PswCheckValue,sizeof(PswCheckValue)); |
| 170 | memcpy(Item->HashKeyValue,HashKeyValue,sizeof(HashKeyValue)); |
| 171 | SecHideData(Item->Key,sizeof(Item->Key),true,false); |
| 172 | } |
| 173 | if (HashKey!=NULL) |
| 174 | memcpy(HashKey,HashKeyValue,SHA256_DIGEST_SIZE); |
| 175 | if (PswCheck!=NULL) |
| 176 | { |
| 177 | memset(PswCheck,0,SIZE_PSWCHECK); |
| 178 | for (uint I=0;I<SHA256_DIGEST_SIZE;I++) |
| 179 | PswCheck[I%SIZE_PSWCHECK]^=PswCheckValue[I]; |
| 180 | cleandata(PswCheckValue,sizeof(PswCheckValue)); |
| 181 | } |
| 182 | |
| 183 | // NULL initialization vector is possible if we only need the password |
| 184 | // check value for archive encryption header. |
| 185 | if (InitV!=NULL) |
| 186 | rin.Init(Encrypt, Key, 256, InitV); |
| 187 | |
| 188 | cleandata(Key,sizeof(Key)); |
nothing calls this directly
no test coverage detected