xref: /aosp_15_r20/external/lzma/CPP/7zip/Crypto/WzAes.h (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1 // Crypto/WzAes.h
2 /*
3 This code implements Brian Gladman's scheme
4 specified in "A Password Based File Encryption Utility":
5   - AES encryption (128,192,256-bit) in Counter (CTR) mode.
6   - HMAC-SHA1 authentication for encrypted data (10 bytes)
7   - Keys are derived by PPKDF2(RFC2898)-HMAC-SHA1 from ASCII password and
8     Salt (saltSize = aesKeySize / 2).
9   - 2 bytes contain Password Verifier's Code
10 */
11 
12 #ifndef ZIP7_INC_CRYPTO_WZ_AES_H
13 #define ZIP7_INC_CRYPTO_WZ_AES_H
14 
15 #include "../../Common/MyBuffer.h"
16 
17 #include "../IPassword.h"
18 
19 #include "HmacSha1.h"
20 #include "MyAes.h"
21 
22 namespace NCrypto {
23 namespace NWzAes {
24 
25 /* ICompressFilter::Init() does nothing for this filter.
26 
27   Call to init:
28     Encoder:
29       CryptoSetPassword();
30       WriteHeader();
31     Decoder:
32       [CryptoSetPassword();]
33       ReadHeader();
34       [CryptoSetPassword();] Init_and_CheckPassword();
35       [CryptoSetPassword();] Init_and_CheckPassword();
36 */
37 
38 const UInt32 kPasswordSizeMax = 99; // 128;
39 
40 const unsigned kSaltSizeMax = 16;
41 const unsigned kPwdVerifSize = 2;
42 const unsigned kMacSize = 10;
43 
44 enum EKeySizeMode
45 {
46   kKeySizeMode_AES128 = 1,
47   kKeySizeMode_AES192 = 2,
48   kKeySizeMode_AES256 = 3
49 };
50 
51 struct CKeyInfo
52 {
53   EKeySizeMode KeySizeMode;
54   Byte Salt[kSaltSizeMax];
55   Byte PwdVerifComputed[kPwdVerifSize];
56 
57   CByteBuffer Password;
58 
GetKeySizeCKeyInfo59   unsigned GetKeySize()  const { return (8 * KeySizeMode + 8); }
GetSaltSizeCKeyInfo60   unsigned GetSaltSize() const { return (4 * KeySizeMode + 4); }
GetNumSaltWordsCKeyInfo61   unsigned GetNumSaltWords() const { return (KeySizeMode + 1); }
62 
CKeyInfoCKeyInfo63   CKeyInfo(): KeySizeMode(kKeySizeMode_AES256) {}
64 
WipeCKeyInfo65   void Wipe()
66   {
67     Password.Wipe();
68     Z7_memset_0_ARRAY(Salt);
69     Z7_memset_0_ARRAY(PwdVerifComputed);
70   }
71 
~CKeyInfoCKeyInfo72   ~CKeyInfo() { Wipe(); }
73 };
74 
75 /*
76 struct CAesCtr2
77 {
78   unsigned pos;
79   CAlignedBuffer aes;
80   UInt32 *Aes() { return (UInt32 *)(Byte *)aes; }
81 
82   // unsigned offset;
83   // UInt32 aes[4 + AES_NUM_IVMRK_WORDS + 3];
84   // UInt32 *Aes() { return aes + offset; }
85   CAesCtr2();
86 };
87 
88 void AesCtr2_Init(CAesCtr2 *p);
89 void AesCtr2_Code(CAesCtr2 *p, Byte *data, SizeT size);
90 */
91 
92 class CBaseCoder:
93   public ICompressFilter,
94   public ICryptoSetPassword,
95   public CMyUnknownImp
96 {
97   Z7_COM_UNKNOWN_IMP_1(ICryptoSetPassword)
98   Z7_COM7F_IMP(Init())
99 public:
100   Z7_IFACE_COM7_IMP(ICryptoSetPassword)
101 protected:
102   CKeyInfo _key;
103 
104   // NSha1::CHmac _hmac;
105   // NSha1::CHmac *Hmac() { return &_hmac; }
106   CAlignedBuffer1 _hmacBuf;
107   UInt32 _hmacOverCalc;
108 
Hmac()109   NSha1::CHmac *Hmac() { return (NSha1::CHmac *)(void *)(Byte *)_hmacBuf; }
110 
111   // CAesCtr2 _aes;
112   CAesCoder *_aesCoderSpec;
113   CMyComPtr<ICompressFilter> _aesCoder;
CBaseCoder()114   CBaseCoder():
115     _hmacBuf(sizeof(NSha1::CHmac))
116   {
117     _aesCoderSpec = new CAesCtrCoder(32);
118     _aesCoder = _aesCoderSpec;
119   }
120 
121   void Init2();
122 public:
GetHeaderSize()123   unsigned GetHeaderSize() const { return _key.GetSaltSize() + kPwdVerifSize; }
GetAddPackSize()124   unsigned GetAddPackSize() const { return GetHeaderSize() + kMacSize; }
125 
SetKeyMode(unsigned mode)126   bool SetKeyMode(unsigned mode)
127   {
128     if (mode < kKeySizeMode_AES128 || mode > kKeySizeMode_AES256)
129       return false;
130     _key.KeySizeMode = (EKeySizeMode)mode;
131     return true;
132   }
133 
~CBaseCoder()134   virtual ~CBaseCoder() {}
135 };
136 
137 class CEncoder Z7_final:
138   public CBaseCoder
139 {
140   Z7_COM7F_IMP2(UInt32, Filter(Byte *data, UInt32 size))
141 public:
142   HRESULT WriteHeader(ISequentialOutStream *outStream);
143   HRESULT WriteFooter(ISequentialOutStream *outStream);
144 };
145 
146 class CDecoder Z7_final:
147   public CBaseCoder
148   // public ICompressSetDecoderProperties2
149 {
150   Byte _pwdVerifFromArchive[kPwdVerifSize];
151   Z7_COM7F_IMP2(UInt32, Filter(Byte *data, UInt32 size))
152 public:
153   // Z7_IFACE_COM7_IMP(ICompressSetDecoderProperties2)
154   HRESULT ReadHeader(ISequentialInStream *inStream);
155   bool Init_and_CheckPassword();
156   HRESULT CheckMac(ISequentialInStream *inStream, bool &isOK);
157 };
158 
159 }}
160 
161 #endif
162