rlm@1
|
1 // Crypto/WzAes.h
|
rlm@1
|
2 /*
|
rlm@1
|
3 This code implements Brian Gladman's scheme
|
rlm@1
|
4 specified in password Based File Encryption Utility:
|
rlm@1
|
5 - AES encryption (128,192,256-bit) in Counter (CTR) mode.
|
rlm@1
|
6 - HMAC-SHA1 authentication for encrypted data (10 bytes)
|
rlm@1
|
7 - Keys are derived by PPKDF2(RFC2898)-HMAC-SHA1 from ASCII password and
|
rlm@1
|
8 Salt (saltSize = aesKeySize / 2).
|
rlm@1
|
9 - 2 bytes contain Password Verifier's Code
|
rlm@1
|
10 */
|
rlm@1
|
11
|
rlm@1
|
12 #ifndef __CRYPTO_WZ_AES_H
|
rlm@1
|
13 #define __CRYPTO_WZ_AES_H
|
rlm@1
|
14
|
rlm@1
|
15 extern "C"
|
rlm@1
|
16 {
|
rlm@1
|
17 #include "../../../C/Aes.h"
|
rlm@1
|
18 }
|
rlm@1
|
19
|
rlm@1
|
20 #include "Common/Buffer.h"
|
rlm@1
|
21 #include "Common/MyCom.h"
|
rlm@1
|
22 #include "Common/MyVector.h"
|
rlm@1
|
23
|
rlm@1
|
24 #include "../ICoder.h"
|
rlm@1
|
25 #include "../IPassword.h"
|
rlm@1
|
26
|
rlm@1
|
27 #include "HmacSha1.h"
|
rlm@1
|
28
|
rlm@1
|
29 namespace NCrypto {
|
rlm@1
|
30 namespace NWzAes {
|
rlm@1
|
31
|
rlm@1
|
32 const unsigned int kSaltSizeMax = 16;
|
rlm@1
|
33 const unsigned int kMacSize = 10;
|
rlm@1
|
34
|
rlm@1
|
35 const UInt32 kPasswordSizeMax = 99; // 128;
|
rlm@1
|
36
|
rlm@1
|
37 // Password Verification Code Size
|
rlm@1
|
38 const unsigned int kPwdVerifCodeSize = 2;
|
rlm@1
|
39
|
rlm@1
|
40 class CKeyInfo
|
rlm@1
|
41 {
|
rlm@1
|
42 public:
|
rlm@1
|
43 Byte KeySizeMode; // 1 - 128-bit , 2 - 192-bit , 3 - 256-bit
|
rlm@1
|
44 Byte Salt[kSaltSizeMax];
|
rlm@1
|
45 Byte PwdVerifComputed[kPwdVerifCodeSize];
|
rlm@1
|
46
|
rlm@1
|
47 CByteBuffer Password;
|
rlm@1
|
48
|
rlm@1
|
49 UInt32 GetKeySize() const { return (8 * (KeySizeMode & 3) + 8); }
|
rlm@1
|
50 UInt32 GetSaltSize() const { return (4 * (KeySizeMode & 3) + 4); }
|
rlm@1
|
51
|
rlm@1
|
52 CKeyInfo() { Init(); }
|
rlm@1
|
53 void Init() { KeySizeMode = 3; }
|
rlm@1
|
54 };
|
rlm@1
|
55
|
rlm@1
|
56 class CBaseCoder:
|
rlm@1
|
57 public ICompressFilter,
|
rlm@1
|
58 public ICryptoSetPassword,
|
rlm@1
|
59 public CMyUnknownImp
|
rlm@1
|
60 {
|
rlm@1
|
61 protected:
|
rlm@1
|
62 CKeyInfo _key;
|
rlm@1
|
63 UInt32 _counter[AES_BLOCK_SIZE / 4];
|
rlm@1
|
64 Byte _buffer[AES_BLOCK_SIZE];
|
rlm@1
|
65 NSha1::CHmac _hmac;
|
rlm@1
|
66 unsigned int _blockPos;
|
rlm@1
|
67 Byte _pwdVerifFromArchive[kPwdVerifCodeSize];
|
rlm@1
|
68
|
rlm@1
|
69 void EncryptData(Byte *data, UInt32 size);
|
rlm@1
|
70
|
rlm@1
|
71 CAes Aes;
|
rlm@1
|
72
|
rlm@1
|
73 public:
|
rlm@1
|
74 STDMETHOD(Init)();
|
rlm@1
|
75 STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size) = 0;
|
rlm@1
|
76
|
rlm@1
|
77 STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size);
|
rlm@1
|
78
|
rlm@1
|
79 UInt32 GetHeaderSize() const { return _key.GetSaltSize() + kPwdVerifCodeSize; }
|
rlm@1
|
80 };
|
rlm@1
|
81
|
rlm@1
|
82 class CEncoder:
|
rlm@1
|
83 public CBaseCoder
|
rlm@1
|
84 // public ICompressWriteCoderProperties
|
rlm@1
|
85 {
|
rlm@1
|
86 public:
|
rlm@1
|
87 MY_UNKNOWN_IMP1(ICryptoSetPassword)
|
rlm@1
|
88 // ICompressWriteCoderProperties
|
rlm@1
|
89 // STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream);
|
rlm@1
|
90 STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size);
|
rlm@1
|
91 HRESULT WriteHeader(ISequentialOutStream *outStream);
|
rlm@1
|
92 HRESULT WriteFooter(ISequentialOutStream *outStream);
|
rlm@1
|
93 bool SetKeyMode(Byte mode)
|
rlm@1
|
94 {
|
rlm@1
|
95 if (mode < 1 || mode > 3)
|
rlm@1
|
96 return false;
|
rlm@1
|
97 _key.KeySizeMode = mode;
|
rlm@1
|
98 return true;
|
rlm@1
|
99 }
|
rlm@1
|
100 };
|
rlm@1
|
101
|
rlm@1
|
102 class CDecoder:
|
rlm@1
|
103 public CBaseCoder,
|
rlm@1
|
104 public ICompressSetDecoderProperties2
|
rlm@1
|
105 {
|
rlm@1
|
106 public:
|
rlm@1
|
107 MY_UNKNOWN_IMP2(
|
rlm@1
|
108 ICryptoSetPassword,
|
rlm@1
|
109 ICompressSetDecoderProperties2)
|
rlm@1
|
110 STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size);
|
rlm@1
|
111 STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);
|
rlm@1
|
112 HRESULT ReadHeader(ISequentialInStream *inStream);
|
rlm@1
|
113 bool CheckPasswordVerifyCode();
|
rlm@1
|
114 HRESULT CheckMac(ISequentialInStream *inStream, bool &isOK);
|
rlm@1
|
115 };
|
rlm@1
|
116
|
rlm@1
|
117 }}
|
rlm@1
|
118
|
rlm@1
|
119 #endif
|