~ubuntu-branches/ubuntu/vivid/unrar-nonfree/vivid

« back to all changes in this revision

Viewing changes to rijndael.cpp

  • Committer: Package Import Robot
  • Author(s): Martin Meredith
  • Date: 2015-02-03 12:58:01 UTC
  • mfrom: (1.1.18) (5.1.18 sid)
  • Revision ID: package-import@ubuntu.com-20150203125801-od6ev8cqy1er51vz
Tags: 1:5.2.5-1
New upstream release

Show diffs side-by-side

added added

removed removed

Lines of Context:
7
7
 ***************************************************************************/
8
8
#include "rar.hpp"
9
9
 
 
10
#ifdef USE_SSE
 
11
#include <wmmintrin.h>
 
12
#endif
 
13
 
10
14
static byte S[256],S5[256],rcon[30];
11
15
static byte T1[256][4],T2[256][4],T3[256][4],T4[256][4];
12
16
static byte T5[256][4],T6[256][4],T7[256][4],T8[256][4];
13
17
static byte U1[256][4],U2[256][4],U3[256][4],U4[256][4];
14
18
 
15
19
 
16
 
inline void Xor128(byte *dest,const byte *arg1,const byte *arg2)
 
20
inline void Xor128(void *dest,const void *arg1,const void *arg2)
17
21
{
18
 
#if defined(PRESENT_INT32) && defined(ALLOW_NOT_ALIGNED_INT)
 
22
#if defined(PRESENT_INT32) && defined(ALLOW_MISALIGNED)
19
23
  ((uint32*)dest)[0]=((uint32*)arg1)[0]^((uint32*)arg2)[0];
20
24
  ((uint32*)dest)[1]=((uint32*)arg1)[1]^((uint32*)arg2)[1];
21
25
  ((uint32*)dest)[2]=((uint32*)arg1)[2]^((uint32*)arg2)[2];
22
26
  ((uint32*)dest)[3]=((uint32*)arg1)[3]^((uint32*)arg2)[3];
23
27
#else
24
28
  for (int I=0;I<16;I++)
25
 
    dest[I]=arg1[I]^arg2[I];
 
29
    ((byte*)dest)[I]=((byte*)arg1)[I]^((byte*)arg2)[I];
26
30
#endif
27
31
}
28
32
 
30
34
inline void Xor128(byte *dest,const byte *arg1,const byte *arg2,
31
35
                   const byte *arg3,const byte *arg4)
32
36
{
33
 
#if defined(PRESENT_INT32) && defined(ALLOW_NOT_ALIGNED_INT)
 
37
#if defined(PRESENT_INT32) && defined(ALLOW_MISALIGNED)
34
38
  (*(uint32*)dest)=(*(uint32*)arg1)^(*(uint32*)arg2)^(*(uint32*)arg3)^(*(uint32*)arg4);
35
39
#else
36
40
  for (int I=0;I<4;I++)
41
45
 
42
46
inline void Copy128(byte *dest,const byte *src)
43
47
{
44
 
#if defined(PRESENT_INT32) && defined(ALLOW_NOT_ALIGNED_INT)
 
48
#if defined(PRESENT_INT32) && defined(ALLOW_MISALIGNED)
45
49
  ((uint32*)dest)[0]=((uint32*)src)[0];
46
50
  ((uint32*)dest)[1]=((uint32*)src)[1];
47
51
  ((uint32*)dest)[2]=((uint32*)src)[2];
61
65
{
62
66
  if (S[0]==0)
63
67
    GenerateTables();
 
68
  CBCMode = true; // Always true for RAR.
64
69
}
65
70
 
66
71
 
67
72
void Rijndael::Init(bool Encrypt,const byte *key,uint keyLen,const byte * initVector)
68
73
{
 
74
#ifdef USE_SSE
 
75
  // Check SSE here instead of constructor, so if object is a part of some
 
76
  // structure memset'ed before use, this variable is not lost.
 
77
  int CPUInfo[4];
 
78
  __cpuid(CPUInfo, 1);
 
79
  AES_NI=(CPUInfo[2] & 0x2000000)!=0;
 
80
#endif
 
81
 
69
82
  uint uKeyLenInBytes;
70
83
  switch(keyLen)
71
84
  {
88
101
  for(uint i = 0; i < uKeyLenInBytes; i++)
89
102
    keyMatrix[i >> 2][i & 3] = key[i]; 
90
103
 
91
 
  for(int i = 0; i < MAX_IV_SIZE; i++)
92
 
    m_initVector[i] = initVector[i];
 
104
  if (initVector==NULL)
 
105
    memset(m_initVector, 0, sizeof(m_initVector));
 
106
  else
 
107
    for(int i = 0; i < MAX_IV_SIZE; i++)
 
108
      m_initVector[i] = initVector[i];
93
109
 
94
110
  keySched(keyMatrix);
95
111
 
99
115
 
100
116
 
101
117
  
102
 
size_t Rijndael::blockDecrypt(const byte *input, size_t inputLen, byte *outBuffer)
 
118
void Rijndael::blockDecrypt(const byte *input, size_t inputLen, byte *outBuffer)
103
119
{
104
 
  if (input == 0 || inputLen <= 0)
105
 
    return 0;
 
120
  if (inputLen <= 0)
 
121
    return;
 
122
 
 
123
  size_t numBlocks=inputLen/16;
 
124
#ifdef USE_SSE
 
125
  if (AES_NI)
 
126
  {
 
127
    blockDecryptSSE(input,numBlocks,outBuffer);
 
128
    return;
 
129
  }
 
130
#endif
106
131
 
107
132
  byte block[16], iv[4][4];
108
133
  memcpy(iv,m_initVector,16); 
109
134
 
110
 
  size_t numBlocks=inputLen/16;
111
135
  for (size_t i = numBlocks; i > 0; i--)
112
136
  {
113
 
    decrypt(input, block);
114
 
    Xor128(block,block,(byte*)iv);
115
 
#if STRICT_ALIGN
116
 
    memcpy(iv, input, 16);
117
 
    memcpy(outBuf, block, 16);
118
 
#else
 
137
    byte temp[4][4];
 
138
    
 
139
    Xor128(temp,input,m_expandedKey[m_uRounds]);
 
140
 
 
141
    Xor128(block,   T5[temp[0][0]],T6[temp[3][1]],T7[temp[2][2]],T8[temp[1][3]]);
 
142
    Xor128(block+4, T5[temp[1][0]],T6[temp[0][1]],T7[temp[3][2]],T8[temp[2][3]]);
 
143
    Xor128(block+8, T5[temp[2][0]],T6[temp[1][1]],T7[temp[0][2]],T8[temp[3][3]]);
 
144
    Xor128(block+12,T5[temp[3][0]],T6[temp[2][1]],T7[temp[1][2]],T8[temp[0][3]]);
 
145
 
 
146
    for(int r = m_uRounds-1; r > 1; r--)
 
147
    {
 
148
      Xor128(temp,block,m_expandedKey[r]);
 
149
      Xor128(block,   T5[temp[0][0]],T6[temp[3][1]],T7[temp[2][2]],T8[temp[1][3]]);
 
150
      Xor128(block+4, T5[temp[1][0]],T6[temp[0][1]],T7[temp[3][2]],T8[temp[2][3]]);
 
151
      Xor128(block+8, T5[temp[2][0]],T6[temp[1][1]],T7[temp[0][2]],T8[temp[3][3]]);
 
152
      Xor128(block+12,T5[temp[3][0]],T6[temp[2][1]],T7[temp[1][2]],T8[temp[0][3]]);
 
153
    }
 
154
   
 
155
    Xor128(temp,block,m_expandedKey[1]);
 
156
    block[ 0] = S5[temp[0][0]];
 
157
    block[ 1] = S5[temp[3][1]];
 
158
    block[ 2] = S5[temp[2][2]];
 
159
    block[ 3] = S5[temp[1][3]];
 
160
    block[ 4] = S5[temp[1][0]];
 
161
    block[ 5] = S5[temp[0][1]];
 
162
    block[ 6] = S5[temp[3][2]];
 
163
    block[ 7] = S5[temp[2][3]];
 
164
    block[ 8] = S5[temp[2][0]];
 
165
    block[ 9] = S5[temp[1][1]];
 
166
    block[10] = S5[temp[0][2]];
 
167
    block[11] = S5[temp[3][3]];
 
168
    block[12] = S5[temp[3][0]];
 
169
    block[13] = S5[temp[2][1]];
 
170
    block[14] = S5[temp[1][2]];
 
171
    block[15] = S5[temp[0][3]];
 
172
    Xor128(block,block,m_expandedKey[0]);
 
173
 
 
174
    if (CBCMode)
 
175
      Xor128(block,block,iv);
 
176
 
119
177
    Copy128((byte*)iv,input);
120
178
    Copy128(outBuffer,block);
121
 
#endif
 
179
 
122
180
    input += 16;
123
181
    outBuffer += 16;
124
182
  }
125
183
 
126
184
  memcpy(m_initVector,iv,16);
127
 
  
128
 
  return 16*numBlocks;
129
 
}
 
185
}
 
186
 
 
187
 
 
188
#ifdef USE_SSE
 
189
void Rijndael::blockDecryptSSE(const byte *input, size_t numBlocks, byte *outBuffer)
 
190
{
 
191
  __m128i initVector = _mm_loadu_si128((__m128i*)m_initVector);
 
192
  __m128i *src=(__m128i*)input;
 
193
  __m128i *dest=(__m128i*)outBuffer;
 
194
  __m128i *rkey=(__m128i*)m_expandedKey;
 
195
  while (numBlocks > 0)
 
196
  {
 
197
    __m128i rl = _mm_loadu_si128(rkey + m_uRounds);
 
198
    __m128i d = _mm_loadu_si128(src++);
 
199
    __m128i v = _mm_xor_si128(rl, d);
 
200
 
 
201
    for (int i=m_uRounds-1; i>0; i--)
 
202
    {
 
203
      __m128i ri = _mm_loadu_si128(rkey + i);
 
204
      v = _mm_aesdec_si128(v, ri);
 
205
    }
 
206
    
 
207
    __m128i r0 = _mm_loadu_si128(rkey);
 
208
    v = _mm_aesdeclast_si128(v, r0);
 
209
 
 
210
    if (CBCMode)
 
211
      v = _mm_xor_si128(v, initVector);
 
212
    initVector = d;
 
213
    _mm_storeu_si128(dest++,v);
 
214
    numBlocks--;
 
215
  }
 
216
  _mm_storeu_si128((__m128i*)m_initVector,initVector);
 
217
}
 
218
#endif
130
219
 
131
220
 
132
221
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
221
310
222
311
 
223
312
 
224
 
void Rijndael::decrypt(const byte a[16], byte b[16])
225
 
{
226
 
  int r;
227
 
  byte temp[4][4];
228
 
  
229
 
  Xor128((byte*)temp,(byte*)a,(byte*)m_expandedKey[m_uRounds]);
230
 
 
231
 
  Xor128(b,   T5[temp[0][0]],T6[temp[3][1]],T7[temp[2][2]],T8[temp[1][3]]);
232
 
  Xor128(b+4, T5[temp[1][0]],T6[temp[0][1]],T7[temp[3][2]],T8[temp[2][3]]);
233
 
  Xor128(b+8, T5[temp[2][0]],T6[temp[1][1]],T7[temp[0][2]],T8[temp[3][3]]);
234
 
  Xor128(b+12,T5[temp[3][0]],T6[temp[2][1]],T7[temp[1][2]],T8[temp[0][3]]);
235
 
 
236
 
  for(r = m_uRounds-1; r > 1; r--)
237
 
  {
238
 
    Xor128((byte*)temp,(byte*)b,(byte*)m_expandedKey[r]);
239
 
    Xor128(b,   T5[temp[0][0]],T6[temp[3][1]],T7[temp[2][2]],T8[temp[1][3]]);
240
 
    Xor128(b+4, T5[temp[1][0]],T6[temp[0][1]],T7[temp[3][2]],T8[temp[2][3]]);
241
 
    Xor128(b+8, T5[temp[2][0]],T6[temp[1][1]],T7[temp[0][2]],T8[temp[3][3]]);
242
 
    Xor128(b+12,T5[temp[3][0]],T6[temp[2][1]],T7[temp[1][2]],T8[temp[0][3]]);
243
 
  }
244
 
 
245
 
  Xor128((byte*)temp,(byte*)b,(byte*)m_expandedKey[1]);
246
 
  b[ 0] = S5[temp[0][0]];
247
 
  b[ 1] = S5[temp[3][1]];
248
 
  b[ 2] = S5[temp[2][2]];
249
 
  b[ 3] = S5[temp[1][3]];
250
 
  b[ 4] = S5[temp[1][0]];
251
 
  b[ 5] = S5[temp[0][1]];
252
 
  b[ 6] = S5[temp[3][2]];
253
 
  b[ 7] = S5[temp[2][3]];
254
 
  b[ 8] = S5[temp[2][0]];
255
 
  b[ 9] = S5[temp[1][1]];
256
 
  b[10] = S5[temp[0][2]];
257
 
  b[11] = S5[temp[3][3]];
258
 
  b[12] = S5[temp[3][0]];
259
 
  b[13] = S5[temp[2][1]];
260
 
  b[14] = S5[temp[1][2]];
261
 
  b[15] = S5[temp[0][3]];
262
 
  Xor128((byte*)b,(byte*)b,(byte*)m_expandedKey[0]);
263
 
}
264
 
 
265
313
#define ff_poly 0x011b
266
314
#define ff_hi   0x80
267
315