~ubuntu-branches/ubuntu/precise/p7zip/precise-updates

« back to all changes in this revision

Viewing changes to CPP/7zip/Crypto/RarAES/RarAES.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Mohammed Adnène Trojette
  • Date: 2009-02-14 20:12:27 UTC
  • mfrom: (1.1.11 upstream) (2.1.3 sid)
  • Revision ID: james.westby@ubuntu.com-20090214201227-go63qxm9ozfdma60
Tags: 4.65~dfsg.1-1
* New upstream release.
* Remove wx2.8 Build-Depends added by mistakes (7zG is not yet
  intended to be built).
* Use dh_clean without -k.

Show diffs side-by-side

added added

removed removed

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