Mercurial > vba-linux
view 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 source
1 // Crypto/RarAes.cpp2 // Note: you must include MyAes.cpp to project to initialize AES tables4 #include "StdAfx.h"6 #include "RarAes.h"7 #include "Sha1.h"9 namespace NCrypto {10 namespace NRar29 {12 CDecoder::CDecoder():13 _thereIsSalt(false),14 _needCalculate(true),15 _rar350Mode(false)16 {17 for (int i = 0; i < sizeof(_salt); i++)18 _salt[i] = 0;19 }21 STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size)22 {23 bool thereIsSaltPrev = _thereIsSalt;24 _thereIsSalt = false;25 if (size == 0)26 return S_OK;27 if (size < 8)28 return E_INVALIDARG;29 _thereIsSalt = true;30 bool same = false;31 if (_thereIsSalt == thereIsSaltPrev)32 {33 same = true;34 if (_thereIsSalt)35 {36 for (int i = 0; i < sizeof(_salt); i++)37 if (_salt[i] != data[i])38 {39 same = false;40 break;41 }42 }43 }44 for (int i = 0; i < sizeof(_salt); i++)45 _salt[i] = data[i];46 if (!_needCalculate && !same)47 _needCalculate = true;48 return S_OK;49 }51 static const int kMaxPasswordLength = 127 * 2;53 STDMETHODIMP CDecoder::CryptoSetPassword(const Byte *data, UInt32 size)54 {55 if (size > kMaxPasswordLength)56 size = kMaxPasswordLength;57 bool same = false;58 if (size == buffer.GetCapacity())59 {60 same = true;61 for (UInt32 i = 0; i < size; i++)62 if (data[i] != buffer[i])63 {64 same = false;65 break;66 }67 }68 if (!_needCalculate && !same)69 _needCalculate = true;70 buffer.SetCapacity(size);71 memcpy(buffer, data, size);72 return S_OK;73 }75 STDMETHODIMP CDecoder::Init()76 {77 Calculate();78 Aes_SetKeyDecode(&Aes.aes, aesKey, kRarAesKeySize);79 AesCbc_Init(&Aes, aesInit);80 return S_OK;81 }83 STDMETHODIMP_(UInt32) CDecoder::Filter(Byte *data, UInt32 size)84 {85 return (UInt32)AesCbc_Decode(&Aes, data, size);86 }88 void CDecoder::Calculate()89 {90 if (_needCalculate)91 {92 const int kSaltSize = 8;94 Byte rawPassword[kMaxPasswordLength + kSaltSize];96 memcpy(rawPassword, buffer, buffer.GetCapacity());98 size_t rawLength = buffer.GetCapacity();100 if (_thereIsSalt)101 {102 memcpy(rawPassword + rawLength, _salt, kSaltSize);103 rawLength += kSaltSize;104 }106 NSha1::CContext sha;107 sha.Init();109 // seems rar reverts hash for sha.110 const int hashRounds = 0x40000;111 int i;112 for (i = 0; i < hashRounds; i++)113 {114 sha.Update(rawPassword, rawLength, _rar350Mode);115 Byte pswNum[3] = { (Byte)i, (Byte)(i >> 8), (Byte)(i >> 16) };116 sha.Update(pswNum, 3, _rar350Mode);117 if (i % (hashRounds / 16) == 0)118 {119 NSha1::CContext shaTemp = sha;120 Byte digest[NSha1::kDigestSize];121 shaTemp.Final(digest);122 aesInit[i / (hashRounds / 16)] = (Byte)digest[4 * 4 + 3];123 }124 }125 /*126 // it's test message for sha127 const char *message = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq";128 sha.Update((const Byte *)message, strlen(message));129 */130 Byte digest[20];131 sha.Final(digest);132 for (i = 0; i < 4; i++)133 for (int j = 0; j < 4; j++)134 aesKey[i * 4 + j] = (digest[i * 4 + 3 - j]);135 }136 _needCalculate = false;137 }139 }}