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