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