Mercurial > vba-linux
diff src/win32/7zip/7z/CPP/7zip/Crypto/RarAes.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/RarAes.cpp Sat Mar 03 10:31:27 2012 -0600 1.3 @@ -0,0 +1,139 @@ 1.4 +// Crypto/RarAes.cpp 1.5 +// Note: you must include MyAes.cpp to project to initialize AES tables 1.6 + 1.7 +#include "StdAfx.h" 1.8 + 1.9 +#include "RarAes.h" 1.10 +#include "Sha1.h" 1.11 + 1.12 +namespace NCrypto { 1.13 +namespace NRar29 { 1.14 + 1.15 +CDecoder::CDecoder(): 1.16 + _thereIsSalt(false), 1.17 + _needCalculate(true), 1.18 + _rar350Mode(false) 1.19 +{ 1.20 + for (int i = 0; i < sizeof(_salt); i++) 1.21 + _salt[i] = 0; 1.22 +} 1.23 + 1.24 +STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size) 1.25 +{ 1.26 + bool thereIsSaltPrev = _thereIsSalt; 1.27 + _thereIsSalt = false; 1.28 + if (size == 0) 1.29 + return S_OK; 1.30 + if (size < 8) 1.31 + return E_INVALIDARG; 1.32 + _thereIsSalt = true; 1.33 + bool same = false; 1.34 + if (_thereIsSalt == thereIsSaltPrev) 1.35 + { 1.36 + same = true; 1.37 + if (_thereIsSalt) 1.38 + { 1.39 + for (int i = 0; i < sizeof(_salt); i++) 1.40 + if (_salt[i] != data[i]) 1.41 + { 1.42 + same = false; 1.43 + break; 1.44 + } 1.45 + } 1.46 + } 1.47 + for (int i = 0; i < sizeof(_salt); i++) 1.48 + _salt[i] = data[i]; 1.49 + if (!_needCalculate && !same) 1.50 + _needCalculate = true; 1.51 + return S_OK; 1.52 +} 1.53 + 1.54 +static const int kMaxPasswordLength = 127 * 2; 1.55 + 1.56 +STDMETHODIMP CDecoder::CryptoSetPassword(const Byte *data, UInt32 size) 1.57 +{ 1.58 + if (size > kMaxPasswordLength) 1.59 + size = kMaxPasswordLength; 1.60 + bool same = false; 1.61 + if (size == buffer.GetCapacity()) 1.62 + { 1.63 + same = true; 1.64 + for (UInt32 i = 0; i < size; i++) 1.65 + if (data[i] != buffer[i]) 1.66 + { 1.67 + same = false; 1.68 + break; 1.69 + } 1.70 + } 1.71 + if (!_needCalculate && !same) 1.72 + _needCalculate = true; 1.73 + buffer.SetCapacity(size); 1.74 + memcpy(buffer, data, size); 1.75 + return S_OK; 1.76 +} 1.77 + 1.78 +STDMETHODIMP CDecoder::Init() 1.79 +{ 1.80 + Calculate(); 1.81 + Aes_SetKeyDecode(&Aes.aes, aesKey, kRarAesKeySize); 1.82 + AesCbc_Init(&Aes, aesInit); 1.83 + return S_OK; 1.84 +} 1.85 + 1.86 +STDMETHODIMP_(UInt32) CDecoder::Filter(Byte *data, UInt32 size) 1.87 +{ 1.88 + return (UInt32)AesCbc_Decode(&Aes, data, size); 1.89 +} 1.90 + 1.91 +void CDecoder::Calculate() 1.92 +{ 1.93 + if (_needCalculate) 1.94 + { 1.95 + const int kSaltSize = 8; 1.96 + 1.97 + Byte rawPassword[kMaxPasswordLength + kSaltSize]; 1.98 + 1.99 + memcpy(rawPassword, buffer, buffer.GetCapacity()); 1.100 + 1.101 + size_t rawLength = buffer.GetCapacity(); 1.102 + 1.103 + if (_thereIsSalt) 1.104 + { 1.105 + memcpy(rawPassword + rawLength, _salt, kSaltSize); 1.106 + rawLength += kSaltSize; 1.107 + } 1.108 + 1.109 + NSha1::CContext sha; 1.110 + sha.Init(); 1.111 + 1.112 + // seems rar reverts hash for sha. 1.113 + const int hashRounds = 0x40000; 1.114 + int i; 1.115 + for (i = 0; i < hashRounds; i++) 1.116 + { 1.117 + sha.Update(rawPassword, rawLength, _rar350Mode); 1.118 + Byte pswNum[3] = { (Byte)i, (Byte)(i >> 8), (Byte)(i >> 16) }; 1.119 + sha.Update(pswNum, 3, _rar350Mode); 1.120 + if (i % (hashRounds / 16) == 0) 1.121 + { 1.122 + NSha1::CContext shaTemp = sha; 1.123 + Byte digest[NSha1::kDigestSize]; 1.124 + shaTemp.Final(digest); 1.125 + aesInit[i / (hashRounds / 16)] = (Byte)digest[4 * 4 + 3]; 1.126 + } 1.127 + } 1.128 + /* 1.129 + // it's test message for sha 1.130 + const char *message = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"; 1.131 + sha.Update((const Byte *)message, strlen(message)); 1.132 + */ 1.133 + Byte digest[20]; 1.134 + sha.Final(digest); 1.135 + for (i = 0; i < 4; i++) 1.136 + for (int j = 0; j < 4; j++) 1.137 + aesKey[i * 4 + j] = (digest[i * 4 + 3 - j]); 1.138 + } 1.139 + _needCalculate = false; 1.140 +} 1.141 + 1.142 +}}