1cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky// 7zAes.cpp 2cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 3cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#include "StdAfx.h" 4cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 5cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#include "../../../C/Sha256.h" 6cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 7f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka#include "../../Common/ComTry.h" 8f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 9f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka#ifndef _7ZIP_ST 10cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#include "../../Windows/Synchronization.h" 11f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka#endif 12cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 13cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#include "../Common/StreamUtils.h" 14cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 15cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#include "7zAes.h" 16cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#include "MyAes.h" 17cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 18cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#ifndef EXTRACT_ONLY 19cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#include "RandGen.h" 20cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#endif 21cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 22cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckynamespace NCrypto { 23f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osakanamespace N7z { 24f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 25f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osakastatic const unsigned k_NumCyclesPower_Supported_MAX = 24; 26cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 27cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckybool CKeyInfo::IsEqualTo(const CKeyInfo &a) const 28cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{ 29cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (SaltSize != a.SaltSize || NumCyclesPower != a.NumCyclesPower) 30cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky return false; 31f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka for (unsigned i = 0; i < SaltSize; i++) 32cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (Salt[i] != a.Salt[i]) 33cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky return false; 34cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky return (Password == a.Password); 35cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky} 36cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 37f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osakavoid CKeyInfo::CalcKey() 38cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{ 39cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (NumCyclesPower == 0x3F) 40cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 41f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka unsigned pos; 42cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky for (pos = 0; pos < SaltSize; pos++) 43cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky Key[pos] = Salt[pos]; 44f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka for (unsigned i = 0; i < Password.Size() && pos < kKeySize; i++) 45cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky Key[pos++] = Password[i]; 46cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky for (; pos < kKeySize; pos++) 47cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky Key[pos] = 0; 48cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky } 49cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky else 50cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 51f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka size_t bufSize = 8 + SaltSize + Password.Size(); 52f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka CObjArray<Byte> buf(bufSize); 53f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka memcpy(buf, Salt, SaltSize); 54f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka memcpy(buf + SaltSize, Password, Password.Size()); 55f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 56cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky CSha256 sha; 57cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky Sha256_Init(&sha); 58f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 59f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka Byte *ctr = buf + SaltSize + Password.Size(); 60f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 61f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka for (unsigned i = 0; i < 8; i++) 62f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka ctr[i] = 0; 63f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 64f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka UInt64 numRounds = (UInt64)1 << NumCyclesPower; 65f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 66f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka do 67cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 68f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka Sha256_Update(&sha, buf, bufSize); 69f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka for (unsigned i = 0; i < 8; i++) 70f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka if (++(ctr[i]) != 0) 71cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky break; 72cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky } 73f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka while (--numRounds != 0); 74f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 75cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky Sha256_Final(&sha, Key); 76cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky } 77cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky} 78cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 79f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osakabool CKeyInfoCache::GetKey(CKeyInfo &key) 80cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{ 81cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky FOR_VECTOR (i, Keys) 82cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 83cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky const CKeyInfo &cached = Keys[i]; 84cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (key.IsEqualTo(cached)) 85cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 86f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka for (unsigned j = 0; j < kKeySize; j++) 87cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky key.Key[j] = cached.Key[j]; 88cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (i != 0) 89cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky Keys.MoveToFront(i); 90cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky return true; 91cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky } 92cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky } 93cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky return false; 94cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky} 95cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 96f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osakavoid CKeyInfoCache::FindAndAdd(const CKeyInfo &key) 97f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka{ 98f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka FOR_VECTOR (i, Keys) 99f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka { 100f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka const CKeyInfo &cached = Keys[i]; 101f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka if (key.IsEqualTo(cached)) 102f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka { 103f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka if (i != 0) 104f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka Keys.MoveToFront(i); 105f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka return; 106f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka } 107f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka } 108f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka Add(key); 109f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka} 110f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 111f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osakavoid CKeyInfoCache::Add(const CKeyInfo &key) 112cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{ 113cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (Keys.Size() >= Size) 114cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky Keys.DeleteBack(); 115cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky Keys.Insert(0, key); 116cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky} 117cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 118cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic CKeyInfoCache g_GlobalKeyCache(32); 119f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 120f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka#ifndef _7ZIP_ST 121f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka static NWindows::NSynchronization::CCriticalSection g_GlobalKeyCacheCriticalSection; 122f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka #define MT_LOCK NWindows::NSynchronization::CCriticalSectionLock lock(g_GlobalKeyCacheCriticalSection); 123f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka#else 124f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka #define MT_LOCK 125f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka#endif 126cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 127cd66d540cead3f8200b0c73bad9c276d67896c3dDavid SrbeckyCBase::CBase(): 128cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky _cachedKeys(16), 129cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky _ivSize(0) 130cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{ 131f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka for (unsigned i = 0; i < sizeof(_iv); i++) 132cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky _iv[i] = 0; 133cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky} 134cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 135f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osakavoid CBase::PrepareKey() 136cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{ 137f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka // BCJ2 threads use same password. So we use long lock. 138f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka MT_LOCK 139f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 140f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka bool finded = false; 141f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka if (!_cachedKeys.GetKey(_key)) 142cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 143f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka finded = g_GlobalKeyCache.GetKey(_key); 144f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka if (!finded) 145f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka _key.CalcKey(); 146cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky _cachedKeys.Add(_key); 147cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky } 148f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka if (!finded) 149f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka g_GlobalKeyCache.FindAndAdd(_key); 150cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky} 151cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 152cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#ifndef EXTRACT_ONLY 153cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 154cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky/* 155cd66d540cead3f8200b0c73bad9c276d67896c3dDavid SrbeckySTDMETHODIMP CEncoder::ResetSalt() 156cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{ 157cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky _key.SaltSize = 4; 158cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky g_RandomGenerator.Generate(_key.Salt, _key.SaltSize); 159cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky return S_OK; 160cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky} 161cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky*/ 162cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 163cd66d540cead3f8200b0c73bad9c276d67896c3dDavid SrbeckySTDMETHODIMP CEncoder::ResetInitVector() 164cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{ 165f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka for (unsigned i = 0; i < sizeof(_iv); i++) 166f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka _iv[i] = 0; 167cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky _ivSize = 8; 168f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka g_RandomGenerator.Generate(_iv, _ivSize); 169cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky return S_OK; 170cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky} 171cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 172cd66d540cead3f8200b0c73bad9c276d67896c3dDavid SrbeckySTDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream) 173cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{ 174f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka Byte props[2 + sizeof(_key.Salt) + sizeof(_iv)]; 175f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka unsigned propsSize = 1; 176cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 177f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka props[0] = (Byte)(_key.NumCyclesPower 178f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka | (_key.SaltSize == 0 ? 0 : (1 << 7)) 179f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka | (_ivSize == 0 ? 0 : (1 << 6))); 180cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 181f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka if (_key.SaltSize != 0 || _ivSize != 0) 182cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 183f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka props[1] = (Byte)( 184f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka ((_key.SaltSize == 0 ? 0 : _key.SaltSize - 1) << 4) 185f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka | (_ivSize == 0 ? 0 : _ivSize - 1)); 186f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka memcpy(props + 2, _key.Salt, _key.SaltSize); 187f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka propsSize = 2 + _key.SaltSize; 188f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka memcpy(props + propsSize, _iv, _ivSize); 189f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka propsSize += _ivSize; 190cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky } 191f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 192f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka return WriteStream(outStream, props, propsSize); 193cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky} 194cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 195f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo OsakaCEncoder::CEncoder() 196cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{ 197f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka // _key.SaltSize = 4; g_RandomGenerator.Generate(_key.Salt, _key.SaltSize); 198f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka // _key.NumCyclesPower = 0x3F; 199f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka _key.NumCyclesPower = 19; 200cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky _aesFilter = new CAesCbcEncoder(kKeySize); 201cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky} 202cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 203cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#endif 204cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 205f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo OsakaCDecoder::CDecoder() 206f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka{ 207f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka _aesFilter = new CAesCbcDecoder(kKeySize); 208f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka} 209f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 210cd66d540cead3f8200b0c73bad9c276d67896c3dDavid SrbeckySTDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size) 211cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{ 212f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka _key.ClearProps(); 213f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 214f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka _ivSize = 0; 215f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka unsigned i; 216cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky for (i = 0; i < sizeof(_iv); i++) 217cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky _iv[i] = 0; 218f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 219cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (size == 0) 220cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky return S_OK; 221f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 222f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka Byte b0 = data[0]; 223cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 224f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka _key.NumCyclesPower = b0 & 0x3F; 225f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka if ((b0 & 0xC0) == 0) 226f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka return size == 1 ? S_OK : E_INVALIDARG; 227cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 228f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka if (size <= 1) 229cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky return E_INVALIDARG; 230f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 231f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka Byte b1 = data[1]; 232f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 233f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka unsigned saltSize = ((b0 >> 7) & 1) + (b1 >> 4); 234f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka unsigned ivSize = ((b0 >> 6) & 1) + (b1 & 0x0F); 235cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 236f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka if (size != 2 + saltSize + ivSize) 237cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky return E_INVALIDARG; 238f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka _key.SaltSize = saltSize; 239f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka data += 2; 240f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka for (i = 0; i < saltSize; i++) 241f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka _key.Salt[i] = *data++; 242cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky for (i = 0; i < ivSize; i++) 243f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka _iv[i] = *data++; 244f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka return (_key.NumCyclesPower <= k_NumCyclesPower_Supported_MAX 245f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka || _key.NumCyclesPower == 0x3F) ? S_OK : E_NOTIMPL; 246cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky} 247cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 248f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 249cd66d540cead3f8200b0c73bad9c276d67896c3dDavid SrbeckySTDMETHODIMP CBaseCoder::CryptoSetPassword(const Byte *data, UInt32 size) 250cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{ 251f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka COM_TRY_BEGIN 252f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 253cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky _key.Password.CopyFrom(data, (size_t)size); 254cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky return S_OK; 255f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 256f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka COM_TRY_END 257cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky} 258cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 259cd66d540cead3f8200b0c73bad9c276d67896c3dDavid SrbeckySTDMETHODIMP CBaseCoder::Init() 260cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{ 261f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka COM_TRY_BEGIN 262f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 263f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka PrepareKey(); 264cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky CMyComPtr<ICryptoProperties> cp; 265cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky RINOK(_aesFilter.QueryInterface(IID_ICryptoProperties, &cp)); 266f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka if (!cp) 267f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka return E_FAIL; 268f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka RINOK(cp->SetKey(_key.Key, kKeySize)); 269cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky RINOK(cp->SetInitVector(_iv, sizeof(_iv))); 270cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky return _aesFilter->Init(); 271f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 272f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka COM_TRY_END 273cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky} 274cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 275cd66d540cead3f8200b0c73bad9c276d67896c3dDavid SrbeckySTDMETHODIMP_(UInt32) CBaseCoder::Filter(Byte *data, UInt32 size) 276cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{ 277cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky return _aesFilter->Filter(data, size); 278cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky} 279cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 280cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}} 281