Mercurial > vba-linux
view 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 source
1 // 7zAes.cpp3 #include "StdAfx.h"5 extern "C"6 {7 #include "../../../C/Sha256.h"8 }10 #include "Windows/Synchronization.h"11 #include "../Common/StreamObjects.h"12 #include "../Common/StreamUtils.h"13 #include "7zAes.h"14 #include "MyAes.h"16 #ifndef EXTRACT_ONLY17 #include "RandGen.h"18 #endif20 using namespace NWindows;22 namespace NCrypto {23 namespace NSevenZ {25 bool CKeyInfo::IsEqualTo(const CKeyInfo &a) const26 {27 if (SaltSize != a.SaltSize || NumCyclesPower != a.NumCyclesPower)28 return false;29 for (UInt32 i = 0; i < SaltSize; i++)30 if (Salt[i] != a.Salt[i])31 return false;32 return (Password == a.Password);33 }35 void CKeyInfo::CalculateDigest()36 {37 if (NumCyclesPower == 0x3F)38 {39 UInt32 pos;40 for (pos = 0; pos < SaltSize; pos++)41 Key[pos] = Salt[pos];42 for (UInt32 i = 0; i < Password.GetCapacity() && pos < kKeySize; i++)43 Key[pos++] = Password[i];44 for (; pos < kKeySize; pos++)45 Key[pos] = 0;46 }47 else48 {49 CSha256 sha;50 Sha256_Init(&sha);51 const UInt64 numRounds = UInt64(1) << (NumCyclesPower);52 Byte temp[8] = { 0,0,0,0,0,0,0,0 };53 for (UInt64 round = 0; round < numRounds; round++)54 {55 Sha256_Update(&sha, Salt, (size_t)SaltSize);56 Sha256_Update(&sha, Password, Password.GetCapacity());57 Sha256_Update(&sha, temp, 8);58 for (int i = 0; i < 8; i++)59 if (++(temp[i]) != 0)60 break;61 }62 Sha256_Final(&sha, Key);63 }64 }66 bool CKeyInfoCache::Find(CKeyInfo &key)67 {68 for (int i = 0; i < Keys.Size(); i++)69 {70 const CKeyInfo &cached = Keys[i];71 if (key.IsEqualTo(cached))72 {73 for (int j = 0; j < kKeySize; j++)74 key.Key[j] = cached.Key[j];75 if (i != 0)76 {77 Keys.Insert(0, cached);78 Keys.Delete(i+1);79 }80 return true;81 }82 }83 return false;84 }86 void CKeyInfoCache::Add(CKeyInfo &key)87 {88 if (Find(key))89 return;90 if (Keys.Size() >= Size)91 Keys.DeleteBack();92 Keys.Insert(0, key);93 }95 static CKeyInfoCache g_GlobalKeyCache(32);96 static NSynchronization::CCriticalSection g_GlobalKeyCacheCriticalSection;98 CBase::CBase():99 _cachedKeys(16),100 _ivSize(0)101 {102 for (int i = 0; i < sizeof(_iv); i++)103 _iv[i] = 0;104 }106 void CBase::CalculateDigest()107 {108 NSynchronization::CCriticalSectionLock lock(g_GlobalKeyCacheCriticalSection);109 if (_cachedKeys.Find(_key))110 g_GlobalKeyCache.Add(_key);111 else112 {113 if (!g_GlobalKeyCache.Find(_key))114 {115 _key.CalculateDigest();116 g_GlobalKeyCache.Add(_key);117 }118 _cachedKeys.Add(_key);119 }120 }122 #ifndef EXTRACT_ONLY124 /*125 STDMETHODIMP CEncoder::ResetSalt()126 {127 _key.SaltSize = 4;128 g_RandomGenerator.Generate(_key.Salt, _key.SaltSize);129 return S_OK;130 }131 */133 STDMETHODIMP CEncoder::ResetInitVector()134 {135 _ivSize = 8;136 g_RandomGenerator.Generate(_iv, (unsigned)_ivSize);137 return S_OK;138 }140 STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)141 {142 // _key.Init();143 for (UInt32 i = _ivSize; i < sizeof(_iv); i++)144 _iv[i] = 0;146 UInt32 ivSize = _ivSize;148 // _key.NumCyclesPower = 0x3F;149 _key.NumCyclesPower = 19;151 Byte firstByte = (Byte)(_key.NumCyclesPower |152 (((_key.SaltSize == 0) ? 0 : 1) << 7) |153 (((ivSize == 0) ? 0 : 1) << 6));154 RINOK(outStream->Write(&firstByte, 1, NULL));155 if (_key.SaltSize == 0 && ivSize == 0)156 return S_OK;157 Byte saltSizeSpec = (Byte)((_key.SaltSize == 0) ? 0 : (_key.SaltSize - 1));158 Byte ivSizeSpec = (Byte)((ivSize == 0) ? 0 : (ivSize - 1));159 Byte secondByte = (Byte)(((saltSizeSpec) << 4) | ivSizeSpec);160 RINOK(outStream->Write(&secondByte, 1, NULL));161 if (_key.SaltSize > 0)162 {163 RINOK(WriteStream(outStream, _key.Salt, _key.SaltSize));164 }165 if (ivSize > 0)166 {167 RINOK(WriteStream(outStream, _iv, ivSize));168 }169 return S_OK;170 }172 HRESULT CEncoder::CreateFilter()173 {174 _aesFilter = new CAesCbcEncoder;175 return S_OK;176 }178 #endif180 STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size)181 {182 _key.Init();183 UInt32 i;184 for (i = 0; i < sizeof(_iv); i++)185 _iv[i] = 0;186 if (size == 0)187 return S_OK;188 UInt32 pos = 0;189 Byte firstByte = data[pos++];191 _key.NumCyclesPower = firstByte & 0x3F;192 if ((firstByte & 0xC0) == 0)193 return S_OK;194 _key.SaltSize = (firstByte >> 7) & 1;195 UInt32 ivSize = (firstByte >> 6) & 1;197 if (pos >= size)198 return E_INVALIDARG;199 Byte secondByte = data[pos++];201 _key.SaltSize += (secondByte >> 4);202 ivSize += (secondByte & 0x0F);204 if (pos + _key.SaltSize + ivSize > size)205 return E_INVALIDARG;206 for (i = 0; i < _key.SaltSize; i++)207 _key.Salt[i] = data[pos++];208 for (i = 0; i < ivSize; i++)209 _iv[i] = data[pos++];210 return S_OK;211 }213 STDMETHODIMP CBaseCoder::CryptoSetPassword(const Byte *data, UInt32 size)214 {215 _key.Password.SetCapacity((size_t)size);216 memcpy(_key.Password, data, (size_t)size);217 return S_OK;218 }220 STDMETHODIMP CBaseCoder::Init()221 {222 CalculateDigest();223 if (_aesFilter == 0)224 {225 RINOK(CreateFilter());226 }227 CMyComPtr<ICryptoProperties> cp;228 RINOK(_aesFilter.QueryInterface(IID_ICryptoProperties, &cp));229 RINOK(cp->SetKey(_key.Key, sizeof(_key.Key)));230 RINOK(cp->SetInitVector(_iv, sizeof(_iv)));231 return S_OK;232 }234 STDMETHODIMP_(UInt32) CBaseCoder::Filter(Byte *data, UInt32 size)235 {236 return _aesFilter->Filter(data, size);237 }239 HRESULT CDecoder::CreateFilter()240 {241 _aesFilter = new CAesCbcDecoder;242 return S_OK;243 }245 }}