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