Mercurial > vba-linux
diff src/win32/7zip/7z/CPP/7zip/Crypto/WzAes.cpp @ 1:f9f4f1b99eed
importing src directory
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 03 Mar 2012 10:31:27 -0600 |
parents | |
children |
line wrap: on
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/win32/7zip/7z/CPP/7zip/Crypto/WzAes.cpp Sat Mar 03 10:31:27 2012 -0600 1.3 @@ -0,0 +1,209 @@ 1.4 +// Crypto/WzAes.cpp 1.5 +/* 1.6 +This code implements Brian Gladman's scheme 1.7 +specified in password Based File Encryption Utility. 1.8 + 1.9 +Note: you must include MyAes.cpp to project to initialize AES tables 1.10 +*/ 1.11 + 1.12 +#include "StdAfx.h" 1.13 + 1.14 +#include "../Common/StreamObjects.h" 1.15 +#include "../Common/StreamUtils.h" 1.16 + 1.17 +#include "Pbkdf2HmacSha1.h" 1.18 +#include "RandGen.h" 1.19 +#include "WzAes.h" 1.20 + 1.21 +// define it if you don't want to use speed-optimized version of Pbkdf2HmacSha1 1.22 +// #define _NO_WZAES_OPTIMIZATIONS 1.23 + 1.24 +namespace NCrypto { 1.25 +namespace NWzAes { 1.26 + 1.27 +const unsigned int kAesKeySizeMax = 32; 1.28 + 1.29 +static const UInt32 kNumKeyGenIterations = 1000; 1.30 + 1.31 +STDMETHODIMP CBaseCoder::CryptoSetPassword(const Byte *data, UInt32 size) 1.32 +{ 1.33 + if(size > kPasswordSizeMax) 1.34 + return E_INVALIDARG; 1.35 + _key.Password.SetCapacity(size); 1.36 + memcpy(_key.Password, data, size); 1.37 + return S_OK; 1.38 +} 1.39 + 1.40 +#define SetUi32(p, d) { UInt32 x = (d); (p)[0] = (Byte)x; (p)[1] = (Byte)(x >> 8); \ 1.41 + (p)[2] = (Byte)(x >> 16); (p)[3] = (Byte)(x >> 24); } 1.42 + 1.43 +void CBaseCoder::EncryptData(Byte *data, UInt32 size) 1.44 +{ 1.45 + unsigned int pos = _blockPos; 1.46 + for (; size > 0; size--) 1.47 + { 1.48 + if (pos == AES_BLOCK_SIZE) 1.49 + { 1.50 + if (++_counter[0] == 0) 1.51 + _counter[1]++; 1.52 + UInt32 temp[4]; 1.53 + Aes_Encode32(&Aes, temp, _counter); 1.54 + SetUi32(_buffer, temp[0]); 1.55 + SetUi32(_buffer + 4, temp[1]); 1.56 + SetUi32(_buffer + 8, temp[2]); 1.57 + SetUi32(_buffer + 12, temp[3]); 1.58 + pos = 0; 1.59 + } 1.60 + *data++ ^= _buffer[pos++]; 1.61 + } 1.62 + _blockPos = pos; 1.63 +} 1.64 + 1.65 +#ifndef _NO_WZAES_OPTIMIZATIONS 1.66 + 1.67 +static void BytesToBeUInt32s(const Byte *src, UInt32 *dest, int destSize) 1.68 +{ 1.69 + for (int i = 0 ; i < destSize; i++) 1.70 + dest[i] = 1.71 + ((UInt32)(src[i * 4 + 0]) << 24) | 1.72 + ((UInt32)(src[i * 4 + 1]) << 16) | 1.73 + ((UInt32)(src[i * 4 + 2]) << 8) | 1.74 + ((UInt32)(src[i * 4 + 3])); 1.75 +} 1.76 + 1.77 +#endif 1.78 + 1.79 +STDMETHODIMP CBaseCoder::Init() 1.80 +{ 1.81 + UInt32 keySize = _key.GetKeySize(); 1.82 + UInt32 keysTotalSize = 2 * keySize + kPwdVerifCodeSize; 1.83 + Byte buf[2 * kAesKeySizeMax + kPwdVerifCodeSize]; 1.84 + 1.85 + // for (int ii = 0; ii < 1000; ii++) 1.86 + { 1.87 + #ifdef _NO_WZAES_OPTIMIZATIONS 1.88 + 1.89 + NSha1::Pbkdf2Hmac( 1.90 + _key.Password, _key.Password.GetCapacity(), 1.91 + _key.Salt, _key.GetSaltSize(), 1.92 + kNumKeyGenIterations, 1.93 + buf, keysTotalSize); 1.94 + 1.95 + #else 1.96 + 1.97 + UInt32 buf32[(2 * kAesKeySizeMax + kPwdVerifCodeSize + 3) / 4]; 1.98 + UInt32 key32SizeTotal = (keysTotalSize + 3) / 4; 1.99 + UInt32 salt[kSaltSizeMax * 4]; 1.100 + UInt32 saltSizeInWords = _key.GetSaltSize() / 4; 1.101 + BytesToBeUInt32s(_key.Salt, salt, saltSizeInWords); 1.102 + NSha1::Pbkdf2Hmac32( 1.103 + _key.Password, _key.Password.GetCapacity(), 1.104 + salt, saltSizeInWords, 1.105 + kNumKeyGenIterations, 1.106 + buf32, key32SizeTotal); 1.107 + for (UInt32 j = 0; j < keysTotalSize; j++) 1.108 + buf[j] = (Byte)(buf32[j / 4] >> (24 - 8 * (j & 3))); 1.109 + 1.110 + #endif 1.111 + } 1.112 + 1.113 + _hmac.SetKey(buf + keySize, keySize); 1.114 + memcpy(_key.PwdVerifComputed, buf + 2 * keySize, kPwdVerifCodeSize); 1.115 + 1.116 + _blockPos = AES_BLOCK_SIZE; 1.117 + for (int i = 0; i < 4; i++) 1.118 + _counter[i] = 0; 1.119 + 1.120 + Aes_SetKeyEncode(&Aes, buf, keySize); 1.121 + return S_OK; 1.122 +} 1.123 + 1.124 +/* 1.125 +STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream) 1.126 +{ 1.127 + Byte keySizeMode = 3; 1.128 + return outStream->Write(&keySizeMode, 1, NULL); 1.129 +} 1.130 +*/ 1.131 + 1.132 +HRESULT CEncoder::WriteHeader(ISequentialOutStream *outStream) 1.133 +{ 1.134 + UInt32 saltSize = _key.GetSaltSize(); 1.135 + g_RandomGenerator.Generate(_key.Salt, saltSize); 1.136 + Init(); 1.137 + RINOK(WriteStream(outStream, _key.Salt, saltSize)); 1.138 + return WriteStream(outStream, _key.PwdVerifComputed, kPwdVerifCodeSize); 1.139 +} 1.140 + 1.141 +HRESULT CEncoder::WriteFooter(ISequentialOutStream *outStream) 1.142 +{ 1.143 + Byte mac[kMacSize]; 1.144 + _hmac.Final(mac, kMacSize); 1.145 + return WriteStream(outStream, mac, kMacSize); 1.146 +} 1.147 + 1.148 +STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size) 1.149 +{ 1.150 + if (size != 1) 1.151 + return E_INVALIDARG; 1.152 + _key.Init(); 1.153 + Byte keySizeMode = data[0]; 1.154 + if (keySizeMode < 1 || keySizeMode > 3) 1.155 + return E_INVALIDARG; 1.156 + _key.KeySizeMode = keySizeMode; 1.157 + return S_OK; 1.158 +} 1.159 + 1.160 +HRESULT CDecoder::ReadHeader(ISequentialInStream *inStream) 1.161 +{ 1.162 + UInt32 saltSize = _key.GetSaltSize(); 1.163 + UInt32 extraSize = saltSize + kPwdVerifCodeSize; 1.164 + Byte temp[kSaltSizeMax + kPwdVerifCodeSize]; 1.165 + RINOK(ReadStream_FAIL(inStream, temp, extraSize)); 1.166 + UInt32 i; 1.167 + for (i = 0; i < saltSize; i++) 1.168 + _key.Salt[i] = temp[i]; 1.169 + for (i = 0; i < kPwdVerifCodeSize; i++) 1.170 + _pwdVerifFromArchive[i] = temp[saltSize + i]; 1.171 + return S_OK; 1.172 +} 1.173 + 1.174 +static bool CompareArrays(const Byte *p1, const Byte *p2, UInt32 size) 1.175 +{ 1.176 + for (UInt32 i = 0; i < size; i++) 1.177 + if (p1[i] != p2[i]) 1.178 + return false; 1.179 + return true; 1.180 +} 1.181 + 1.182 +bool CDecoder::CheckPasswordVerifyCode() 1.183 +{ 1.184 + return CompareArrays(_key.PwdVerifComputed, _pwdVerifFromArchive, kPwdVerifCodeSize); 1.185 +} 1.186 + 1.187 +HRESULT CDecoder::CheckMac(ISequentialInStream *inStream, bool &isOK) 1.188 +{ 1.189 + isOK = false; 1.190 + Byte mac1[kMacSize]; 1.191 + RINOK(ReadStream_FAIL(inStream, mac1, kMacSize)); 1.192 + Byte mac2[kMacSize]; 1.193 + _hmac.Final(mac2, kMacSize); 1.194 + isOK = CompareArrays(mac1, mac2, kMacSize); 1.195 + return S_OK; 1.196 +} 1.197 + 1.198 +STDMETHODIMP_(UInt32) CEncoder::Filter(Byte *data, UInt32 size) 1.199 +{ 1.200 + EncryptData(data, size); 1.201 + _hmac.Update(data, size); 1.202 + return size; 1.203 +} 1.204 + 1.205 +STDMETHODIMP_(UInt32) CDecoder::Filter(Byte *data, UInt32 size) 1.206 +{ 1.207 + _hmac.Update(data, size); 1.208 + EncryptData(data, size); 1.209 + return size; 1.210 +} 1.211 + 1.212 +}}