crypt.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. #include "rar.hpp"
  2. #ifndef SFX_MODULE
  3. #include "crypt1.cpp"
  4. #include "crypt2.cpp"
  5. #endif
  6. #include "crypt3.cpp"
  7. #include "crypt5.cpp"
  8. CryptData::CryptData()
  9. {
  10. Method=CRYPT_NONE;
  11. memset(KDF3Cache,0,sizeof(KDF3Cache));
  12. memset(KDF5Cache,0,sizeof(KDF5Cache));
  13. KDF3CachePos=0;
  14. KDF5CachePos=0;
  15. memset(CRCTab,0,sizeof(CRCTab));
  16. }
  17. CryptData::~CryptData()
  18. {
  19. cleandata(KDF3Cache,sizeof(KDF3Cache));
  20. cleandata(KDF5Cache,sizeof(KDF5Cache));
  21. }
  22. void CryptData::DecryptBlock(byte *Buf,size_t Size)
  23. {
  24. switch(Method)
  25. {
  26. #ifndef SFX_MODULE
  27. case CRYPT_RAR13:
  28. Decrypt13(Buf,Size);
  29. break;
  30. case CRYPT_RAR15:
  31. Crypt15(Buf,Size);
  32. break;
  33. case CRYPT_RAR20:
  34. for (size_t I=0;I<Size;I+=CRYPT_BLOCK_SIZE)
  35. DecryptBlock20(Buf+I);
  36. break;
  37. #endif
  38. case CRYPT_RAR30:
  39. case CRYPT_RAR50:
  40. rin.blockDecrypt(Buf,Size,Buf);
  41. break;
  42. }
  43. }
  44. bool CryptData::SetCryptKeys(bool Encrypt,CRYPT_METHOD Method,
  45. SecPassword *Password,const byte *Salt,
  46. const byte *InitV,uint Lg2Cnt,byte *HashKey,byte *PswCheck)
  47. {
  48. if (!Password->IsSet() || Method==CRYPT_NONE)
  49. return false;
  50. CryptData::Method=Method;
  51. wchar PwdW[MAXPASSWORD];
  52. Password->Get(PwdW,ASIZE(PwdW));
  53. char PwdA[MAXPASSWORD];
  54. WideToChar(PwdW,PwdA,ASIZE(PwdA));
  55. switch(Method)
  56. {
  57. #ifndef SFX_MODULE
  58. case CRYPT_RAR13:
  59. SetKey13(PwdA);
  60. break;
  61. case CRYPT_RAR15:
  62. SetKey15(PwdA);
  63. break;
  64. case CRYPT_RAR20:
  65. SetKey20(PwdA);
  66. break;
  67. #endif
  68. case CRYPT_RAR30:
  69. SetKey30(Encrypt,Password,PwdW,Salt);
  70. break;
  71. case CRYPT_RAR50:
  72. SetKey50(Encrypt,Password,PwdW,Salt,InitV,Lg2Cnt,HashKey,PswCheck);
  73. break;
  74. }
  75. cleandata(PwdA,sizeof(PwdA));
  76. cleandata(PwdW,sizeof(PwdW));
  77. return true;
  78. }
  79. // Use the current system time to additionally randomize data.
  80. static void TimeRandomize(byte *RndBuf,size_t BufSize)
  81. {
  82. static uint Count=0;
  83. RarTime CurTime;
  84. CurTime.SetCurrentTime();
  85. uint64 Random=CurTime.GetWin()+clock();
  86. for (size_t I=0;I<BufSize;I++)
  87. {
  88. byte RndByte = byte (Random >> ( (I & 7) * 8 ));
  89. RndBuf[I]=byte( (RndByte ^ I) + Count++);
  90. }
  91. }
  92. // Fill buffer with random data.
  93. void GetRnd(byte *RndBuf,size_t BufSize)
  94. {
  95. bool Success=false;
  96. #if defined(_WIN_ALL)
  97. HCRYPTPROV hProvider = 0;
  98. if (CryptAcquireContext(&hProvider, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT))
  99. {
  100. Success=CryptGenRandom(hProvider, (DWORD)BufSize, RndBuf) == TRUE;
  101. CryptReleaseContext(hProvider, 0);
  102. }
  103. #elif defined(_UNIX)
  104. FILE *rndf = fopen("/dev/urandom", "r");
  105. if (rndf!=NULL)
  106. {
  107. Success=fread(RndBuf, BufSize, 1, rndf) == BufSize;
  108. fclose(rndf);
  109. }
  110. #endif
  111. // We use this code only as the last resort if code above failed.
  112. if (!Success)
  113. TimeRandomize(RndBuf,BufSize);
  114. }