Mercurial > vba-linux
diff src/win32/7zip/7z/CPP/7zip/Crypto/7zAes.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/7zAes.cpp Sat Mar 03 10:31:27 2012 -0600 1.3 @@ -0,0 +1,245 @@ 1.4 +// 7zAes.cpp 1.5 + 1.6 +#include "StdAfx.h" 1.7 + 1.8 +extern "C" 1.9 +{ 1.10 +#include "../../../C/Sha256.h" 1.11 +} 1.12 + 1.13 +#include "Windows/Synchronization.h" 1.14 +#include "../Common/StreamObjects.h" 1.15 +#include "../Common/StreamUtils.h" 1.16 +#include "7zAes.h" 1.17 +#include "MyAes.h" 1.18 + 1.19 +#ifndef EXTRACT_ONLY 1.20 +#include "RandGen.h" 1.21 +#endif 1.22 + 1.23 +using namespace NWindows; 1.24 + 1.25 +namespace NCrypto { 1.26 +namespace NSevenZ { 1.27 + 1.28 +bool CKeyInfo::IsEqualTo(const CKeyInfo &a) const 1.29 +{ 1.30 + if (SaltSize != a.SaltSize || NumCyclesPower != a.NumCyclesPower) 1.31 + return false; 1.32 + for (UInt32 i = 0; i < SaltSize; i++) 1.33 + if (Salt[i] != a.Salt[i]) 1.34 + return false; 1.35 + return (Password == a.Password); 1.36 +} 1.37 + 1.38 +void CKeyInfo::CalculateDigest() 1.39 +{ 1.40 + if (NumCyclesPower == 0x3F) 1.41 + { 1.42 + UInt32 pos; 1.43 + for (pos = 0; pos < SaltSize; pos++) 1.44 + Key[pos] = Salt[pos]; 1.45 + for (UInt32 i = 0; i < Password.GetCapacity() && pos < kKeySize; i++) 1.46 + Key[pos++] = Password[i]; 1.47 + for (; pos < kKeySize; pos++) 1.48 + Key[pos] = 0; 1.49 + } 1.50 + else 1.51 + { 1.52 + CSha256 sha; 1.53 + Sha256_Init(&sha); 1.54 + const UInt64 numRounds = UInt64(1) << (NumCyclesPower); 1.55 + Byte temp[8] = { 0,0,0,0,0,0,0,0 }; 1.56 + for (UInt64 round = 0; round < numRounds; round++) 1.57 + { 1.58 + Sha256_Update(&sha, Salt, (size_t)SaltSize); 1.59 + Sha256_Update(&sha, Password, Password.GetCapacity()); 1.60 + Sha256_Update(&sha, temp, 8); 1.61 + for (int i = 0; i < 8; i++) 1.62 + if (++(temp[i]) != 0) 1.63 + break; 1.64 + } 1.65 + Sha256_Final(&sha, Key); 1.66 + } 1.67 +} 1.68 + 1.69 +bool CKeyInfoCache::Find(CKeyInfo &key) 1.70 +{ 1.71 + for (int i = 0; i < Keys.Size(); i++) 1.72 + { 1.73 + const CKeyInfo &cached = Keys[i]; 1.74 + if (key.IsEqualTo(cached)) 1.75 + { 1.76 + for (int j = 0; j < kKeySize; j++) 1.77 + key.Key[j] = cached.Key[j]; 1.78 + if (i != 0) 1.79 + { 1.80 + Keys.Insert(0, cached); 1.81 + Keys.Delete(i+1); 1.82 + } 1.83 + return true; 1.84 + } 1.85 + } 1.86 + return false; 1.87 +} 1.88 + 1.89 +void CKeyInfoCache::Add(CKeyInfo &key) 1.90 +{ 1.91 + if (Find(key)) 1.92 + return; 1.93 + if (Keys.Size() >= Size) 1.94 + Keys.DeleteBack(); 1.95 + Keys.Insert(0, key); 1.96 +} 1.97 + 1.98 +static CKeyInfoCache g_GlobalKeyCache(32); 1.99 +static NSynchronization::CCriticalSection g_GlobalKeyCacheCriticalSection; 1.100 + 1.101 +CBase::CBase(): 1.102 + _cachedKeys(16), 1.103 + _ivSize(0) 1.104 +{ 1.105 + for (int i = 0; i < sizeof(_iv); i++) 1.106 + _iv[i] = 0; 1.107 +} 1.108 + 1.109 +void CBase::CalculateDigest() 1.110 +{ 1.111 + NSynchronization::CCriticalSectionLock lock(g_GlobalKeyCacheCriticalSection); 1.112 + if (_cachedKeys.Find(_key)) 1.113 + g_GlobalKeyCache.Add(_key); 1.114 + else 1.115 + { 1.116 + if (!g_GlobalKeyCache.Find(_key)) 1.117 + { 1.118 + _key.CalculateDigest(); 1.119 + g_GlobalKeyCache.Add(_key); 1.120 + } 1.121 + _cachedKeys.Add(_key); 1.122 + } 1.123 +} 1.124 + 1.125 +#ifndef EXTRACT_ONLY 1.126 + 1.127 +/* 1.128 +STDMETHODIMP CEncoder::ResetSalt() 1.129 +{ 1.130 + _key.SaltSize = 4; 1.131 + g_RandomGenerator.Generate(_key.Salt, _key.SaltSize); 1.132 + return S_OK; 1.133 +} 1.134 +*/ 1.135 + 1.136 +STDMETHODIMP CEncoder::ResetInitVector() 1.137 +{ 1.138 + _ivSize = 8; 1.139 + g_RandomGenerator.Generate(_iv, (unsigned)_ivSize); 1.140 + return S_OK; 1.141 +} 1.142 + 1.143 +STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream) 1.144 +{ 1.145 + // _key.Init(); 1.146 + for (UInt32 i = _ivSize; i < sizeof(_iv); i++) 1.147 + _iv[i] = 0; 1.148 + 1.149 + UInt32 ivSize = _ivSize; 1.150 + 1.151 + // _key.NumCyclesPower = 0x3F; 1.152 + _key.NumCyclesPower = 19; 1.153 + 1.154 + Byte firstByte = (Byte)(_key.NumCyclesPower | 1.155 + (((_key.SaltSize == 0) ? 0 : 1) << 7) | 1.156 + (((ivSize == 0) ? 0 : 1) << 6)); 1.157 + RINOK(outStream->Write(&firstByte, 1, NULL)); 1.158 + if (_key.SaltSize == 0 && ivSize == 0) 1.159 + return S_OK; 1.160 + Byte saltSizeSpec = (Byte)((_key.SaltSize == 0) ? 0 : (_key.SaltSize - 1)); 1.161 + Byte ivSizeSpec = (Byte)((ivSize == 0) ? 0 : (ivSize - 1)); 1.162 + Byte secondByte = (Byte)(((saltSizeSpec) << 4) | ivSizeSpec); 1.163 + RINOK(outStream->Write(&secondByte, 1, NULL)); 1.164 + if (_key.SaltSize > 0) 1.165 + { 1.166 + RINOK(WriteStream(outStream, _key.Salt, _key.SaltSize)); 1.167 + } 1.168 + if (ivSize > 0) 1.169 + { 1.170 + RINOK(WriteStream(outStream, _iv, ivSize)); 1.171 + } 1.172 + return S_OK; 1.173 +} 1.174 + 1.175 +HRESULT CEncoder::CreateFilter() 1.176 +{ 1.177 + _aesFilter = new CAesCbcEncoder; 1.178 + return S_OK; 1.179 +} 1.180 + 1.181 +#endif 1.182 + 1.183 +STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size) 1.184 +{ 1.185 + _key.Init(); 1.186 + UInt32 i; 1.187 + for (i = 0; i < sizeof(_iv); i++) 1.188 + _iv[i] = 0; 1.189 + if (size == 0) 1.190 + return S_OK; 1.191 + UInt32 pos = 0; 1.192 + Byte firstByte = data[pos++]; 1.193 + 1.194 + _key.NumCyclesPower = firstByte & 0x3F; 1.195 + if ((firstByte & 0xC0) == 0) 1.196 + return S_OK; 1.197 + _key.SaltSize = (firstByte >> 7) & 1; 1.198 + UInt32 ivSize = (firstByte >> 6) & 1; 1.199 + 1.200 + if (pos >= size) 1.201 + return E_INVALIDARG; 1.202 + Byte secondByte = data[pos++]; 1.203 + 1.204 + _key.SaltSize += (secondByte >> 4); 1.205 + ivSize += (secondByte & 0x0F); 1.206 + 1.207 + if (pos + _key.SaltSize + ivSize > size) 1.208 + return E_INVALIDARG; 1.209 + for (i = 0; i < _key.SaltSize; i++) 1.210 + _key.Salt[i] = data[pos++]; 1.211 + for (i = 0; i < ivSize; i++) 1.212 + _iv[i] = data[pos++]; 1.213 + return S_OK; 1.214 +} 1.215 + 1.216 +STDMETHODIMP CBaseCoder::CryptoSetPassword(const Byte *data, UInt32 size) 1.217 +{ 1.218 + _key.Password.SetCapacity((size_t)size); 1.219 + memcpy(_key.Password, data, (size_t)size); 1.220 + return S_OK; 1.221 +} 1.222 + 1.223 +STDMETHODIMP CBaseCoder::Init() 1.224 +{ 1.225 + CalculateDigest(); 1.226 + if (_aesFilter == 0) 1.227 + { 1.228 + RINOK(CreateFilter()); 1.229 + } 1.230 + CMyComPtr<ICryptoProperties> cp; 1.231 + RINOK(_aesFilter.QueryInterface(IID_ICryptoProperties, &cp)); 1.232 + RINOK(cp->SetKey(_key.Key, sizeof(_key.Key))); 1.233 + RINOK(cp->SetInitVector(_iv, sizeof(_iv))); 1.234 + return S_OK; 1.235 +} 1.236 + 1.237 +STDMETHODIMP_(UInt32) CBaseCoder::Filter(Byte *data, UInt32 size) 1.238 +{ 1.239 + return _aesFilter->Filter(data, size); 1.240 +} 1.241 + 1.242 +HRESULT CDecoder::CreateFilter() 1.243 +{ 1.244 + _aesFilter = new CAesCbcDecoder; 1.245 + return S_OK; 1.246 +} 1.247 + 1.248 +}}