crypt3.cpp 2.1 KB

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