1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
  
     | 
    
      #ifndef _RAR_CRYPT_
#define _RAR_CRYPT_
enum CRYPT_METHOD {
  CRYPT_NONE,CRYPT_RAR13,CRYPT_RAR15,CRYPT_RAR20,CRYPT_RAR30,CRYPT_RAR50
};
#define SIZE_SALT50              16
#define SIZE_SALT30               8
#define SIZE_INITV               16
#define SIZE_PSWCHECK             8
#define SIZE_PSWCHECK_CSUM        4
#define CRYPT_BLOCK_SIZE         16
#define CRYPT_BLOCK_MASK         (CRYPT_BLOCK_SIZE-1) // 0xf
#define CRYPT5_KDF_LG2_COUNT     15 // LOG2 of PDKDF2 iteration count.
#define CRYPT5_KDF_LG2_COUNT_MAX 24 // LOG2 of maximum accepted iteration count.
#define CRYPT_VERSION             0 // Supported encryption version.
class CryptData
{
  struct KDF5CacheItem
  {
    SecPassword Pwd;
    byte Salt[SIZE_SALT50];
    byte Key[32];
    uint Lg2Count; // Log2 of PBKDF2 repetition count.
    byte PswCheckValue[SHA256_DIGEST_SIZE];
    byte HashKeyValue[SHA256_DIGEST_SIZE];
  };
  struct KDF3CacheItem
  {
    SecPassword Pwd;
    byte Salt[SIZE_SALT30];
    byte Key[16];
    byte Init[16];
    bool SaltPresent;
  };
  private:
    void SetKey13(const char *Password);
    void Decrypt13(byte *Data,size_t Count);
    void SetKey15(const char *Password);
    void Crypt15(byte *Data,size_t Count);
    void SetKey20(const char *Password);
    void Swap20(byte *Ch1,byte *Ch2);
    void UpdKeys20(byte *Buf);
    void EncryptBlock20(byte *Buf);
    void DecryptBlock20(byte *Buf);
    void SetKey30(bool Encrypt,SecPassword *Password,const wchar *PwdW,const byte *Salt);
    void SetKey50(bool Encrypt,SecPassword *Password,const wchar *PwdW,const byte *Salt,const byte *InitV,uint Lg2Cnt,byte *HashKey,byte *PswCheck);
    KDF3CacheItem KDF3Cache[4];
    uint KDF3CachePos;
    
    KDF5CacheItem KDF5Cache[4];
    uint KDF5CachePos;
    CRYPT_METHOD Method;
    Rijndael rin;
    uint CRCTab[256]; // For RAR 1.5 and RAR 2.0 encryption.
    
    byte SubstTable20[256];
    uint Key20[4];
    byte Key13[3];
    ushort Key15[4];
  public:
    CryptData();
    ~CryptData();
    bool SetCryptKeys(bool Encrypt,CRYPT_METHOD Method,SecPassword *Password,
         const byte *Salt,const byte *InitV,uint Lg2Cnt,
         byte *HashKey,byte *PswCheck);
    void SetAV15Encryption();
    void SetCmt13Encryption();
    void EncryptBlock(byte *Buf,size_t Size);
    void DecryptBlock(byte *Buf,size_t Size);
    static void SetSalt(byte *Salt,size_t SaltSize);
};
void GetRnd(byte *RndBuf,size_t BufSize);
void hmac_sha256(const byte *Key,size_t KeyLength,const byte *Data,
                 size_t DataLength,byte *ResDigest);
void pbkdf2(const byte *pass, size_t pass_len, const byte *salt,
            size_t salt_len,byte *key, byte *Value1, byte *Value2,
            uint rounds);
void ConvertHashToMAC(HashValue *Value,byte *Key);
#endif
 
     |